Merge branch 'as/tree-walk-fix-aggressive-short-cut'

* as/tree-walk-fix-aggressive-short-cut:
  tree_entry_interesting: match against all pathspecs
diff --git a/.gitignore b/.gitignore
index 6b1fd1b..b5f9def 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 /GIT-CFLAGS
 /GIT-LDFLAGS
 /GIT-PREFIX
+/GIT-PERL-DEFINES
 /GIT-PYTHON-VARS
 /GIT-SCRIPT-DEFINES
 /GIT-USER-AGENT
@@ -75,7 +76,6 @@
 /git-init-db
 /git-instaweb
 /git-log
-/git-lost-found
 /git-ls-files
 /git-ls-remote
 /git-ls-tree
@@ -105,7 +105,6 @@
 /git-pack-refs
 /git-parse-remote
 /git-patch-id
-/git-peek-remote
 /git-prune
 /git-prune-packed
 /git-pull
@@ -131,7 +130,6 @@
 /git-remote-testsvn
 /git-repack
 /git-replace
-/git-repo-config
 /git-request-pull
 /git-rerere
 /git-reset
@@ -159,7 +157,6 @@
 /git-svn
 /git-symbolic-ref
 /git-tag
-/git-tar-tree
 /git-unpack-file
 /git-unpack-objects
 /git-update-index
@@ -202,6 +199,7 @@
 /test-string-list
 /test-subprocess
 /test-svn-fe
+/test-urlmatch-normalization
 /test-wildmatch
 /common-cmds.h
 *.tar.gz
diff --git a/.mailmap b/.mailmap
index 1c1f5ec..11057cb 100644
--- a/.mailmap
+++ b/.mailmap
@@ -218,7 +218,9 @@
 Ted Percival <ted@midg3t.net> <ted.percival@quest.com>
 Theodore Ts'o <tytso@mit.edu>
 Thomas Ackermann <th.acker@arcor.de> <th.acker66@arcor.de>
-Thomas Rast <trast@inf.ethz.ch> <trast@student.ethz.ch>
+Thomas Rast <tr@thomasrast.ch> <trast@student.ethz.ch>
+Thomas Rast <tr@thomasrast.ch> <trast@inf.ethz.ch>
+Thomas Rast <tr@thomasrast.ch> <trast@google.com>
 Timo Hirvonen <tihirvon@gmail.com> <tihirvon@ee.oulu.fi>
 Toby Allsopp <Toby.Allsopp@navman.co.nz> <toby.allsopp@navman.co.nz>
 Tom Grennan <tmgrennan@gmail.com> <tgrennan@redback.com>
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines
index 559d5f9..ef67b53 100644
--- a/Documentation/CodingGuidelines
+++ b/Documentation/CodingGuidelines
@@ -145,6 +145,14 @@
    they were describing changes.  Often splitting a function
    into two makes the intention of the code much clearer.
 
+ - Multi-line comments include their delimiters on separate lines from
+   the text.  E.g.
+
+	/*
+	 * A very long
+	 * multi-line comment.
+	 */
+
  - Double negation is often harder to understand than no negation
    at all.
 
@@ -242,11 +250,21 @@
  processed into HTML and manpages (e.g. git.html and git.1 in the
  same directory).
 
+ The documentation liberally mixes US and UK English (en_US/UK)
+ norms for spelling and grammar, which is somewhat unfortunate.
+ In an ideal world, it would have been better if it consistently
+ used only one and not the other, and we would have picked en_US
+ (if you wish to correct the English of some of the existing
+ documentation, please see the documentation-related advice in the
+ Documentation/SubmittingPatches file).
+
  Every user-visible change should be reflected in the documentation.
  The same general rule as for code applies -- imitate the existing
- conventions.  A few commented examples follow to provide reference
- when writing or modifying command usage strings and synopsis sections
- in the manual pages:
+ conventions.
+
+ A few commented examples follow to provide reference when writing or
+ modifying command usage strings and synopsis sections in the manual
+ pages:
 
  Placeholders are spelled in lowercase and enclosed in angle brackets:
    <file>
@@ -296,3 +314,29 @@
    Use 'git' (all lowercase) when talking about commands i.e. something
    the user would type into a shell and use 'Git' (uppercase first letter)
    when talking about the version control system and its properties.
+
+ A few commented examples follow to provide reference when writing or
+ modifying paragraphs or option/command explanations that contain options
+ or commands:
+
+ Literal examples (e.g. use of command-line options, command names, and
+ configuration variables) are typeset in monospace, and if you can use
+ `backticks around word phrases`, do so.
+   `--pretty=oneline`
+   `git rev-list`
+   `remote.pushdefault`
+
+ Word phrases enclosed in `backtick characters` are rendered literally
+ and will not be further expanded. The use of `backticks` to achieve the
+ previous rule means that literal examples should not use AsciiDoc
+ escapes.
+   Correct:
+      `--pretty=oneline`
+   Incorrect:
+      `\--pretty=oneline`
+
+ If some place in the documentation needs to typeset a command usage
+ example with inline substitutions, it is fine to use +monospaced and
+ inline substituted text+ instead of `monospaced literal text`, and with
+ the former, the part that should not get substituted must be
+ quoted/escaped.
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 0cfdc36..fc6b2cf 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -2,6 +2,9 @@
 MAN1_TXT =
 MAN5_TXT =
 MAN7_TXT =
+TECH_DOCS =
+ARTICLES =
+SP_ARTICLES =
 
 MAN1_TXT += $(filter-out \
 		$(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
@@ -37,12 +40,12 @@
 OBSOLETE_HTML = git-remote-helpers.html
 DOC_HTML = $(MAN_HTML) $(OBSOLETE_HTML)
 
-ARTICLES = howto-index
+ARTICLES += howto-index
 ARTICLES += everyday
 ARTICLES += git-tools
 ARTICLES += git-bisect-lk2009
 # with their own formatting rules.
-SP_ARTICLES = user-manual
+SP_ARTICLES += user-manual
 SP_ARTICLES += howto/new-command
 SP_ARTICLES += howto/revert-branch-rebase
 SP_ARTICLES += howto/using-merge-subtree
@@ -53,13 +56,15 @@
 SP_ARTICLES += howto/separating-topic-branches
 SP_ARTICLES += howto/revert-a-faulty-merge
 SP_ARTICLES += howto/recover-corrupted-blob-object
+SP_ARTICLES += howto/recover-corrupted-object-harder
 SP_ARTICLES += howto/rebuild-from-update-hook
 SP_ARTICLES += howto/rebase-from-internal-branch
 SP_ARTICLES += howto/maintain-git
 API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))
 SP_ARTICLES += $(API_DOCS)
 
-TECH_DOCS = technical/index-format
+TECH_DOCS += technical/http-protocol
+TECH_DOCS += technical/index-format
 TECH_DOCS += technical/pack-format
 TECH_DOCS += technical/pack-heuristics
 TECH_DOCS += technical/pack-protocol
@@ -103,6 +108,7 @@
 INSTALL_INFO = install-info
 DOCBOOK2X_TEXI = docbook2x-texi
 DBLATEX = dblatex
+ASCIIDOC_DBLATEX_DIR = /etc/asciidoc/dblatex
 ifndef PERL_PATH
 	PERL_PATH = /usr/bin/perl
 endif
@@ -322,7 +328,7 @@
 
 user-manual.xml: user-manual.txt user-manual.conf
 	$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
-	$(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d book -o $@+ $< && \
+	$(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d article -o $@+ $< && \
 	mv $@+ $@
 
 technical/api-index.txt: technical/api-index-skel.txt \
@@ -354,7 +360,7 @@
 
 user-manual.pdf: user-manual.xml
 	$(QUIET_DBLATEX)$(RM) $@+ $@ && \
-	$(DBLATEX) -o $@+ -p /etc/asciidoc/dblatex/asciidoc-dblatex.xsl -s /etc/asciidoc/dblatex/asciidoc-dblatex.sty $< && \
+	$(DBLATEX) -o $@+ -p $(ASCIIDOC_DBLATEX_DIR)/asciidoc-dblatex.xsl -s $(ASCIIDOC_DBLATEX_DIR)/asciidoc-dblatex.sty $< && \
 	mv $@+ $@
 
 gitman.texi: $(MAN_XML) cat-texi.perl
diff --git a/Documentation/RelNotes/1.7.11.2.txt b/Documentation/RelNotes/1.7.11.2.txt
index a0d24d1..f0cfd02 100644
--- a/Documentation/RelNotes/1.7.11.2.txt
+++ b/Documentation/RelNotes/1.7.11.2.txt
@@ -31,7 +31,7 @@
  * "git diff --no-index" did not work with pagers correctly.
 
  * "git diff COPYING HEAD:COPYING" gave a nonsense error message that
-   claimed that the treeish HEAD did not have COPYING in it.
+   claimed that the tree-ish HEAD did not have COPYING in it.
 
  * When "git log" gets "--simplify-merges/by-decoration" together with
    "--first-parent", the combination of these options makes the
diff --git a/Documentation/RelNotes/1.8.5.1.txt b/Documentation/RelNotes/1.8.5.1.txt
new file mode 100644
index 0000000..7236aaf
--- /dev/null
+++ b/Documentation/RelNotes/1.8.5.1.txt
@@ -0,0 +1,9 @@
+Git v1.8.5.1 Release Notes
+==========================
+
+Fixes since v1.8.5
+------------------
+
+ * "git submodule init" copied "submodule.$name.update" settings from
+   .gitmodules to .git/config without making sure if the suggested
+   value was sensible.
diff --git a/Documentation/RelNotes/1.8.5.2.txt b/Documentation/RelNotes/1.8.5.2.txt
new file mode 100644
index 0000000..3ac4984
--- /dev/null
+++ b/Documentation/RelNotes/1.8.5.2.txt
@@ -0,0 +1,20 @@
+Git v1.8.5.2 Release Notes
+==========================
+
+Fixes since v1.8.5.1
+--------------------
+
+ * "git diff -- ':(icase)makefile'" was unnecessarily rejected at the
+   command line parser.
+
+ * "git cat-file --batch-check=ok" did not check the existence of
+   the named object.
+
+ * "git am --abort" sometimes complained about not being able to write
+   a tree with an 0{40} object in it.
+
+ * Two processes creating loose objects at the same time could have
+   failed unnecessarily when the name of their new objects started
+   with the same byte value, due to a race condition.
+
+Also contains typofixes, documentation updates and trivial code clean-ups.
diff --git a/Documentation/RelNotes/1.8.5.3.txt b/Documentation/RelNotes/1.8.5.3.txt
new file mode 100644
index 0000000..3de2dd0
--- /dev/null
+++ b/Documentation/RelNotes/1.8.5.3.txt
@@ -0,0 +1,27 @@
+Git v1.8.5.3 Release Notes
+==========================
+
+Fixes since v1.8.5.2
+--------------------
+
+ * The "--[no-]informative-errors" options to "git daemon" were parsed
+   a bit too loosely, allowing any other string after these option
+   names.
+
+ * A "gc" process running as a different user should be able to stop a
+   new "gc" process from starting.
+
+ * An earlier "clean-up" introduced an unnecessary memory leak to the
+   credential subsystem.
+
+ * "git mv A B/", when B does not exist as a directory, should error
+   out, but it didn't.
+
+ * "git rev-parse <revs> -- <paths>" did not implement the usual
+   disambiguation rules the commands in the "git log" family used in
+   the same way.
+
+ * "git cat-file --batch=", an admittedly useless command, did not
+   behave very well.
+
+Also contains typofixes, documentation updates and trivial code clean-ups.
diff --git a/Documentation/RelNotes/1.8.5.txt b/Documentation/RelNotes/1.8.5.txt
new file mode 100644
index 0000000..602df0c
--- /dev/null
+++ b/Documentation/RelNotes/1.8.5.txt
@@ -0,0 +1,456 @@
+Git v1.8.5 Release Notes
+========================
+
+Backward compatibility notes (for Git 2.0)
+------------------------------------------
+
+When "git push [$there]" does not say what to push, we have used the
+traditional "matching" semantics so far (all your branches were sent
+to the remote as long as there already are branches of the same name
+over there).  In Git 2.0, the default will change to the "simple"
+semantics, which pushes:
+
+ - only the current branch to the branch with the same name, and only
+   when the current branch is set to integrate with that remote
+   branch, if you are pushing to the same remote as you fetch from; or
+
+ - only the current branch to the branch with the same name, if you
+   are pushing to a remote that is not where you usually fetch from.
+
+Use the user preference configuration variable "push.default" to
+change this.  If you are an old-timer who is used to the "matching"
+semantics, you can set the variable to "matching" to keep the
+traditional behaviour.  If you want to live in the future early, you
+can set it to "simple" today without waiting for Git 2.0.
+
+When "git add -u" (and "git add -A") is run inside a subdirectory and
+does not specify which paths to add on the command line, it
+will operate on the entire tree in Git 2.0 for consistency
+with "git commit -a" and other commands.  There will be no
+mechanism to make plain "git add -u" behave like "git add -u .".
+Current users of "git add -u" (without a pathspec) should start
+training their fingers to explicitly say "git add -u ."
+before Git 2.0 comes.  A warning is issued when these commands are
+run without a pathspec and when you have local changes outside the
+current directory, because the behaviour in Git 2.0 will be different
+from today's version in such a situation.
+
+In Git 2.0, "git add <path>" will behave as "git add -A <path>", so
+that "git add dir/" will notice paths you removed from the directory
+and record the removal.  Versions before Git 2.0, including this
+release, will keep ignoring removals, but the users who rely on this
+behaviour are encouraged to start using "git add --ignore-removal <path>"
+now before 2.0 is released.
+
+The default prefix for "git svn" will change in Git 2.0.  For a long
+time, "git svn" created its remote-tracking branches directly under
+refs/remotes, but it will place them under refs/remotes/origin/ unless
+it is told otherwise with its --prefix option.
+
+
+Updates since v1.8.4
+--------------------
+
+Foreign interfaces, subsystems and ports.
+
+ * "git-svn" has been taught to use the serf library, which is the
+   only option SVN 1.8.0 offers us when talking the HTTP protocol.
+
+ * "git-svn" talking over an https:// connection using the serf library
+   dumped core due to a bug in the serf library that SVN uses.  Work
+   around it on our side, even though the SVN side is being fixed.
+
+ * On MacOS X, we detected if the filesystem needs the "pre-composed
+   unicode strings" workaround, but did not automatically enable it.
+   Now we do.
+
+ * remote-hg remote helper misbehaved when interacting with a local Hg
+   repository relative to the home directory, e.g. "clone hg::~/there".
+
+ * imap-send ported to OS X uses Apple's security framework instead of
+   OpenSSL's.
+
+ * "git fast-import" treats an empty path given to "ls" as the root of
+   the tree.
+
+
+UI, Workflows & Features
+
+ * xdg-open can be used as a browser backend for "git web-browse"
+   (hence to show "git help -w" output), when available.
+
+ * "git grep" and "git show" pay attention to the "--textconv" option
+   when these commands are told to operate on blob objects (e.g. "git
+   grep -e pattern --textconv HEAD:Makefile").
+
+ * "git replace" helper no longer allows an object to be replaced with
+   another object of a different type to avoid confusion (you can
+   still manually craft such a replacement using "git update-ref", as an
+   escape hatch).
+
+ * "git status" no longer prints the dirty status information of
+   submodules for which submodule.$name.ignore is set to "all".
+
+ * "git rebase -i" honours core.abbrev when preparing the insn sheet
+   for editing.
+
+ * "git status" during a cherry-pick shows which original commit is
+   being picked.
+
+ * Instead of typing four capital letters "HEAD", you can say "@" now,
+   e.g. "git log @".
+
+ * "git check-ignore" follows the same rule as "git add" and "git
+   status" in that the ignore/exclude mechanism does not take effect
+   on paths that are already tracked.  With the "--no-index" option, it
+   can be used to diagnose which paths that should have been ignored
+   have been mistakenly added to the index.
+
+ * Some irrelevant "advice" messages that are shared with "git status"
+   output have been removed from the commit log template.
+
+ * "update-refs" learned a "--stdin" option to read multiple update
+   requests and perform them in an all-or-none fashion.
+
+ * Just like "make -C <directory>", "git -C <directory> ..." tells Git
+   to go there before doing anything else.
+
+ * Just like "git checkout -" knows to check out, and "git merge -"
+   knows to merge, the branch you were previously on, "git cherry-pick"
+   now understands "git cherry-pick -" to pick from the previous
+   branch.
+
+ * "git status" now omits the prefix to make its output a comment in a
+   commit log editor, which is not necessary for human consumption.
+   Scripts that parse the output of "git status" are advised to use
+   "git status --porcelain" instead, as its format is stable and easier
+   to parse.
+
+ * The ref syntax "foo^{tag}" (with the literal string "{tag}") peels a
+   tag ref to itself, i.e. it's a no-op., and fails if
+   "foo" is not a tag.  "git rev-parse --verify v1.0^{tag}" is
+   a more convenient way than "test $(git cat-file -t v1.0) = tag" to
+   check if v1.0 is a tag.
+
+ * "git branch -v -v" (and "git status") did not distinguish among a
+   branch that is not based on any other branch, a branch that is in
+   sync with its upstream branch, and a branch that is configured with an
+   upstream branch that no longer exists.
+
+ * Earlier we started rejecting any attempt to add the 0{40} object name to
+   the index and to tree objects, but it sometimes is necessary to
+   allow this to be able to use tools like filter-branch to correct such
+   broken tree objects.  "filter-branch" can again be used to do this.
+
+ * "git config" did not provide a way to set or access numbers larger
+   than a native "int" on the platform; it now provides 64-bit signed
+   integers on all platforms.
+
+ * "git pull --rebase" always chose to do the bog-standard flattening
+   rebase.  You can tell it to run "rebase --preserve-merges" with
+   "git pull --rebase=preserve" or by
+   setting "pull.rebase" configuration to "preserve".
+
+ * "git push --no-thin" actually disables the "thin pack transfer"
+   optimization.
+
+ * Magic pathspecs like ":(icase)makefile" (matches both Makefile
+   and makefile) and ":(glob)foo/**/bar" (matches "bar" in "foo"
+   and any subdirectory of "foo") can be used in more places.
+
+ * The "http.*" variables can now be specified for individual URLs.
+   For example,
+
+   [http]
+       sslVerify = true
+   [http "https://weak.example.com/"]
+       sslVerify = false
+
+   would flip http.sslVerify off only when talking to that specific
+   site.
+
+ * "git mv A B" when moving a submodule has been taught to
+   relocate the submodule's working tree and to adjust the paths in the
+   .gitmodules file.
+
+ * "git blame" can now take more than one -L option to discover the
+   origin of multiple blocks of lines.
+
+ * The http transport clients can optionally ask to save cookies
+   with the http.savecookies configuration variable.
+
+ * "git push" learned a more fine grained control over a blunt
+   "--force" when requesting a non-fast-forward update with the
+   "--force-with-lease=<refname>:<expected object name>" option.
+
+ * "git diff --diff-filter=<classes of changes>" can now take
+   lowercase letters (e.g. "--diff-filter=d") to mean "show
+   everything but these classes".  "git diff-files -q" is now a
+   deprecated synonym for "git diff-files --diff-filter=d".
+
+ * "git fetch" (hence "git pull" as well) learned to check
+   "fetch.prune" and "remote.*.prune" configuration variables and
+   to behave as if the "--prune" command line option was given.
+
+ * "git check-ignore -z" applied the NUL termination to both its input
+   (with --stdin) and its output, but "git check-attr -z" ignored the
+   option on the output side. Make both honor -z on the input and
+   output side the same way.
+
+ * "git whatchanged" may still be used by old timers, but mention of
+   it in documents meant for new users will only waste readers' time
+   wondering what the difference is between it and "git log".  Make it
+   less prominent in the general part of the documentation and explain
+   that it is merely a "git log" with different default behaviour in
+   its own document.
+
+
+Performance, Internal Implementation, etc.
+
+ * "git for-each-ref" when asking for merely the object name does not
+   have to parse the object pointed at by the refs; the codepath has
+   been optimized.
+
+ * The HTTP transport will try to use TCP keepalive when able.
+
+ * "git repack" is now written in C.
+
+ * Build procedure for MSVC has been updated.
+
+ * If a build-time fallback is set to "cat" instead of "less", we
+   should apply the same "no subprocess or pipe" optimization as we
+   apply to user-supplied GIT_PAGER=cat.
+
+ * Many commands use a --dashed-option as an operation mode selector
+   (e.g. "git tag --delete") that excludes other operation modes
+   (e.g. "git tag --delete --verify" is nonsense) and that cannot be
+   negated (e.g. "git tag --no-delete" is nonsense).  The parse-options
+   API learned a new OPT_CMDMODE macro to make it easier to implement
+   such a set of options.
+
+ * OPT_BOOLEAN() in the parse-options API was misdesigned to be "counting
+   up" but many subcommands expect it to behave as "on/off". Update
+   them to use OPT_BOOL() which is a proper boolean.
+
+ * "git gc" exits early without doing any work when it detects
+   that another instance of itself is already running.
+
+ * Under memory pressure and/or file descriptor pressure, we used to
+   close pack windows that are not used and also closed filehandles to
+   open but unused packfiles. These are now controlled separately
+   to better cope with the load.
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v1.8.4
+------------------
+
+Unless otherwise noted, all the fixes since v1.8.4 in the maintenance
+track are contained in this release (see the maintenance releases' notes for
+details).
+
+ * An ancient How-To on serving Git repositories on an HTTP server
+   lacked a warning that it has been mostly superseded with a more
+   modern way.
+   (merge 6d52bc3 sc/doc-howto-dumb-http later to maint).
+
+ * The interaction between the use of Perl in our test suite and NO_PERL
+   has been clarified a bit.
+   (merge f8fc0ee jn/test-prereq-perl-doc later to maint).
+
+ * The synopsis section of the "git unpack-objects" documentation has been
+   clarified a bit.
+   (merge 61e2e22 vd/doc-unpack-objects later to maint).
+
+ * We did not generate the HTML version of the documentation to "git subtree"
+   in contrib/.
+   (merge 95c62fb jk/subtree-install-fix later to maint).
+
+ * A fast-import stream expresses a pathname with funny characters by
+   quoting them in C style; the remote-hg remote helper forgot to unquote
+   such a path.
+   (merge 1136265 ap/remote-hg-unquote-cquote later to maint).
+
+ * "git reset -p HEAD" has a codepath to special-case it to behave
+   differently from resetting to contents of other commits, but a
+   recent change broke it.
+
+ * Coloring around octopus merges in "log --graph" output was screwy.
+   (merge 339c17b hn/log-graph-color-octopus later to maint).
+
+ * "git checkout topic", when there is not yet a local "topic" branch
+   but there is a unique remote-tracking branch for a remote "topic"
+   branch, pretended as if "git checkout -t -b topic remote/$r/topic"
+   (for that unique remote $r) was run. This hack however was not
+   implemented for "git checkout topic --".
+   (merge bca3969 mm/checkout-auto-track-fix later to maint).
+
+ * One long-standing flaw in the pack transfer protocol used by "git
+   clone" was that there was no way to tell the other end which branch
+   "HEAD" points at, and the receiving end needed to guess.  A new
+   capability has been defined in the pack protocol to convey this
+   information so that cloning from a repository with more than one
+   branch pointing at the same commit where the HEAD is at now
+   reliably sets the initial branch in the resulting repository.
+   (merge 360a326 jc/upload-pack-send-symref later to maint).
+
+ * We did not handle cases where the http transport gets redirected during
+   the authorization request (e.g. from http:// to https://).
+   (merge 70900ed jk/http-auth-redirects later to maint).
+
+ * Bash prompting code to deal with an SVN remote as an upstream
+   was coded in a way unsupported by older Bash versions (3.x).
+   (merge 52ec889 sg/prompt-svn-remote-fix later to maint).
+
+ * The fall-back parsing of commit objects with broken author or
+   committer lines was less robust than ideal in picking up the
+   timestamps.
+   (merge 03818a4 jk/split-broken-ident later to maint).
+
+ * "git rev-list --objects ^v1.0^ v1.0" gave the v1.0 tag itself in the
+   output, but "git rev-list --objects v1.0^..v1.0" did not.
+   (merge 895c5ba jc/revision-range-unpeel later to maint).
+
+ * "git clone" wrote some progress messages to standard output, not
+   to standard error, and did not suppress them with the
+   --no-progress option.
+   (merge 643f918 jk/clone-progress-to-stderr later to maint).
+
+ * "format-patch --from=<whom>" forgot to omit an unnecessary in-body
+   from line, i.e. when <whom> is the same as the real author.
+   (merge 662cc30 jk/format-patch-from later to maint).
+
+ * "git shortlog" used to choke and die when there is a malformed
+   commit (e.g. missing authors); it now simply ignores such a commit
+   and keeps going.
+   (merge cd4f09e jk/shortlog-tolerate-broken-commit later to maint).
+
+ * "git merge-recursive" did not parse its "--diff-algorithm=" command
+   line option correctly.
+   (merge 6562928 jk/diff-algo later to maint).
+
+ * When running "fetch -q", a long silence while the sender side
+   computes the set of objects to send can be mistaken by proxies as
+   dropped connection.  The server side has been taught to send a
+   small empty messages to keep the connection alive.
+   (merge 115dedd jk/upload-pack-keepalive later to maint).
+
+ * "git rebase" had a portability regression in v1.8.4 that triggered a
+   bug in some BSD shell implementations.
+   (merge 99855dd mm/rebase-continue-freebsd-WB later to maint).
+
+ * "git branch --track" had a minor regression in v1.8.3.2 and later
+   that made it impossible to base your local work on anything but a
+   local branch of the upstream repository you are tracking.
+   (merge b0f49ff jh/checkout-auto-tracking later to maint).
+
+ * When the web server responds with "405 Method Not Allowed", "git
+   http-backend" should tell the client what methods are allowed with
+   the "Allow" header.
+   (merge 9247be0 bc/http-backend-allow-405 later to maint).
+
+ * When there is no sufficient overlap between old and new history
+   during a "git fetch" into a shallow repository, objects that the
+   sending side knows the receiving end has were unnecessarily sent.
+   (merge f21d2a7 nd/fetch-into-shallow later to maint).
+
+ * "git cvsserver" computed the permission mode bits incorrectly for
+   executable files.
+   (merge 1b48d56 jc/cvsserver-perm-bit-fix later to maint).
+
+ * When send-email obtains an error message to die with upon
+   failure to start an SSL session, it tried to read the error string
+   from a wrong place.
+   (merge 6cb0c88 bc/send-email-ssl-die-message-fix later to maint).
+
+ * The implementation of "add -i" has some crippling code to work around an
+   ActiveState Perl limitation but it by mistake also triggered on Git
+   for Windows where MSYS perl is used.
+   (merge df17e77 js/add-i-mingw later to maint).
+
+ * We made sure that we notice when the user-supplied GIT_DIR is actually a
+   gitfile, but did not do the same when the default ".git" is a
+   gitfile.
+   (merge 487a2b7 nd/git-dir-pointing-at-gitfile later to maint).
+
+ * When an object is not found after checking the packfiles and the
+   loose object directory, read_sha1_file() re-checks the packfiles to
+   prevent racing with a concurrent repacker; teach the same logic to
+   has_sha1_file().
+   (merge 45e8a74 jk/has-sha1-file-retry-packed later to maint).
+
+ * "git commit --author=$name", when $name is not in the canonical
+   "A. U. Thor <au.thor@example.xz>" format, looks for a matching name
+   from existing history, but did not consult mailmap to grab the
+   preferred author name.
+   (merge ea16794 ap/commit-author-mailmap later to maint).
+
+ * "git ls-files -k" needs to crawl only the part of the working tree
+   that may overlap the paths in the index to find killed files, but
+   shared code with the logic to find all the untracked files, which
+   made it unnecessarily inefficient.
+   (merge 680be04 jc/ls-files-killed-optim later to maint).
+
+ * The shortened commit object names in the insn sheet that is prepared at the
+   beginning of a "rebase -i" session can become ambiguous as the
+   rebasing progresses and the repository gains more commits. Make
+   sure the internal record is kept with full 40-hex object names.
+   (merge 75c6976 es/rebase-i-no-abbrev later to maint).
+
+ * "git rebase --preserve-merges" internally used the merge machinery
+   and as a side effect left the merge summary message in the log, but
+   when rebasing there is no need for the merge summary.
+   (merge a9f739c rt/rebase-p-no-merge-summary later to maint).
+
+ * A call to xread() was used without a loop around it to cope with short
+   reads in the codepath to stream new contents to a pack.
+   (merge e92527c js/xread-in-full later to maint).
+
+ * "git rebase -i" forgot that the comment character is
+   configurable while reading its insn sheet.
+   (merge 7bca7af es/rebase-i-respect-core-commentchar later to maint).
+
+ * The mailmap support code read past the allocated buffer when the
+   mailmap file ended with an incomplete line.
+   (merge f972a16 jk/mailmap-incomplete-line later to maint).
+
+ * We used to send a large request to read(2)/write(2) as a single
+   system call, which was bad from the latency point of view when
+   the operation needs to be killed, and also triggered an error on
+   broken 64-bit systems that refuse to read or write more than 2GB
+   in one go.
+   (merge a487916 sp/clip-read-write-to-8mb later to maint).
+
+ * "git fetch" that auto-followed tags incorrectly reused the
+   connection with Git-aware transport helper (like the sample "ext::"
+   helper shipped with Git).
+   (merge 0f73f8b jc/transport-do-not-use-connect-twice-in-fetch later to maint).
+
+ * "git log --full-diff -- <pathspec>" showed a huge diff for paths
+   outside the given <pathspec> for each commit, instead of showing
+   the change relative to the parent of the commit.  "git reflog -p"
+   had a similar problem.
+   (merge 838f9a1 tr/log-full-diff-keep-true-parents later to maint).
+
+ * Setting a submodule.*.path configuration variable to true (without
+   giving "= value") caused Git to segfault.
+   (merge 4b05440 jl/some-submodule-config-are-not-boolean later to maint).
+
+ * "git rebase -i" (there could be others, as the root cause is pretty
+   generic) fed a random, data dependent string to 'echo' and
+   expected it to come out literally, corrupting its error message.
+   (merge 89b0230 mm/no-shell-escape-in-die-message later to maint).
+
+ * Some people still use rather old versions of bash, which cannot
+   grok some constructs like 'printf -v varname' which the prompt and
+   completion code started to use recently.
+   (merge a44aa69 bc/completion-for-bash-3.0 later to maint).
+
+ * Code to read configuration from a blob object did not compile on
+   platforms with fgetc() etc. implemented as macros.
+   (merge 49d6cfa hv/config-from-blob later to maint-1.8.3).
+
+ * The recent "short-cut clone connectivity check" topic broke a
+   shallow repository when a fetch operation tries to auto-follow tags.
+   (merge 6da8bdc nd/fetch-pack-shallow-fix later to maint-1.8.3).
diff --git a/Documentation/RelNotes/1.9.txt b/Documentation/RelNotes/1.9.txt
new file mode 100644
index 0000000..7bcf371
--- /dev/null
+++ b/Documentation/RelNotes/1.9.txt
@@ -0,0 +1,326 @@
+Git v1.9 Release Notes
+======================
+
+Backward compatibility notes
+----------------------------
+
+"git submodule foreach $cmd $args" used to treat "$cmd $args" the same
+way "ssh" did, concatenating them into a single string and letting the
+shell unquote. Careless users who forget to sufficiently quote $args
+gets their argument split at $IFS whitespaces by the shell, and got
+unexpected results due to this. Starting from this release, the
+command line is passed directly to the shell, if it has an argument.
+
+Read-only support for experimental loose-object format, in which users
+could optionally choose to write in their loose objects for a short
+while between v1.4.3 to v1.5.3 era, has been dropped.
+
+The meanings of "--tags" option to "git fetch" has changed; the
+command fetches tags _in addition to_ what are fetched by the same
+command line without the option.
+
+The way "git push $there $what" interprets $what part given on the
+command line, when it does not have a colon that explicitly tells us
+what ref at the $there repository is to be updated, has been enhanced.
+
+A handful of ancient commands that have long been deprecated are
+finally gone (repo-config, tar-tree, lost-found, and peek-remote).
+
+
+Backward compatibility notes (for Git 2.0)
+------------------------------------------
+
+When "git push [$there]" does not say what to push, we have used the
+traditional "matching" semantics so far (all your branches were sent
+to the remote as long as there already are branches of the same name
+over there).  In Git 2.0, the default will change to the "simple"
+semantics, which pushes:
+
+ - only the current branch to the branch with the same name, and only
+   when the current branch is set to integrate with that remote
+   branch, if you are pushing to the same remote as you fetch from; or
+
+ - only the current branch to the branch with the same name, if you
+   are pushing to a remote that is not where you usually fetch from.
+
+Use the user preference configuration variable "push.default" to
+change this.  If you are an old-timer who is used to the "matching"
+semantics, you can set the variable to "matching" to keep the
+traditional behaviour.  If you want to live in the future early, you
+can set it to "simple" today without waiting for Git 2.0.
+
+When "git add -u" (and "git add -A") is run inside a subdirectory and
+does not specify which paths to add on the command line, it
+will operate on the entire tree in Git 2.0 for consistency
+with "git commit -a" and other commands.  There will be no
+mechanism to make plain "git add -u" behave like "git add -u .".
+Current users of "git add -u" (without a pathspec) should start
+training their fingers to explicitly say "git add -u ."
+before Git 2.0 comes.  A warning is issued when these commands are
+run without a pathspec and when you have local changes outside the
+current directory, because the behaviour in Git 2.0 will be different
+from today's version in such a situation.
+
+In Git 2.0, "git add <path>" will behave as "git add -A <path>", so
+that "git add dir/" will notice paths you removed from the directory
+and record the removal.  Versions before Git 2.0, including this
+release, will keep ignoring removals, but the users who rely on this
+behaviour are encouraged to start using "git add --ignore-removal <path>"
+now before 2.0 is released.
+
+The default prefix for "git svn" will change in Git 2.0.  For a long
+time, "git svn" created its remote-tracking branches directly under
+refs/remotes, but it will place them under refs/remotes/origin/ unless
+it is told otherwise with its --prefix option.
+
+
+Updates since v1.8.5
+--------------------
+
+Foreign interfaces, subsystems and ports.
+
+ * The HTTP transport, when talking GSS-Negotiate, uses "100
+   Continue" response to avoid having to rewind and resend a large
+   payload, which may not be always doable.
+
+ * Various bugfixes to remote-bzr and remote-hg (in contrib/).
+
+ * The build procedure is aware of MirBSD now.
+
+
+UI, Workflows & Features
+
+ * Fetching from a shallowly-cloned repository used to be forbidden,
+   primarily because the codepaths involved were not carefully vetted
+   and we did not bother supporting such usage. This release attempts
+   to allow object transfer out of a shallowly-cloned repository in a
+   more controlled way (i.e. the receiver become a shallow repository
+   with a truncated history).
+
+ * Just like we give a reasonable default for "less" via the LESS
+   environment variable, we now specify a reasonable default for "lv"
+   via the "LV" environment variable when spawning the pager.
+
+ * Two-level configuration variable names in "branch.*" and "remote.*"
+   hierarchies, whose variables are predominantly three-level, were
+   not completed by hitting a <TAB> in bash and zsh completions.
+
+ * Fetching 'frotz' branch with "git fetch", while 'frotz/nitfol'
+   remote-tracking branch from an earlier fetch was still there, would
+   error out, primarily because the command was not told that it is
+   allowed to lose any information on our side.  "git fetch --prune"
+   now can be used to remove 'frotz/nitfol' to make room to fetch and
+   store 'frotz' remote-tracking branch.
+
+ * "diff.orderfile=<file>" configuration variable can be used to
+   pretend as if the "-O<file>" option were given from the command
+   line of "git diff", etc.
+
+ * The negative pathspec syntax allows "git log -- . ':!dir'" to tell
+   us "I am interested in everything but 'dir' directory".
+
+ * "git difftool" shows how many different paths there are in total,
+   and how many of them have been shown so far, to indicate progress.
+
+ * "git push origin master" used to push our 'master' branch to update
+   the 'master' branch at the 'origin' repository.  This has been
+   enhanced to use the same ref mapping "git push origin" would use to
+   determine what ref at the 'origin' to be updated with our 'master'.
+   For example, with this configuration
+
+   [remote "origin"]
+      push = refs/heads/*:refs/review/*
+
+   that would cause "git push origin" to push out our local branches
+   to corresponding refs under refs/review/ hierarchy at 'origin',
+   "git push origin master" would update 'refs/review/master' over
+   there.  Alternatively, if push.default is set to 'upstream' and our
+   'master' is set to integrate with 'topic' from the 'origin' branch,
+   running "git push origin" while on our 'master' would update their
+   'topic' branch, and running "git push origin master" while on any
+   of our branches does the same.
+
+ * "gitweb" learned to treat ref hierarchies other than refs/heads as
+   if they are additional branch namespaces (e.g. refs/changes/ in
+   Gerrit).
+
+ * "git for-each-ref --format=..." learned a few formatting directives;
+   e.g. "%(color:red)%(HEAD)%(color:reset) %(refname:short) %(subject)".
+
+ * The command string given to "git submodule foreach" is passed
+   directly to the shell, without being eval'ed.  This is a backward
+   incompatible change that may break existing users.
+
+ * "git log" and friends learned the "--exclude=<glob>" option, to
+   allow people to say "list history of all branches except those that
+   match this pattern" with "git log --exclude='*/*' --branches".
+
+ * "git rev-parse --parseopt" learned a new "--stuck-long" option to
+   help scripts parse options with an optional parameter.
+
+ * The "--tags" option to "git fetch" no longer tells the command to
+   fetch _only_ the tags. It instead fetches tags _in addition to_
+   what are fetched by the same command line without the option.
+
+
+Performance, Internal Implementation, etc.
+
+ * When parsing a 40-hex string into the object name, the string is
+   checked to see if it can be interpreted as a ref so that a warning
+   can be given for ambiguity. The code kicked in even when the
+   core.warnambiguousrefs is set to false to squelch this warning, in
+   which case the cycles spent to look at the ref namespace were an
+   expensive no-op, as the result was discarded without being used.
+
+ * The naming convention of the packfiles has been updated; it used to
+   be based on the enumeration of names of the objects that are
+   contained in the pack, but now it also depends on how the packed
+   result is represented---packing the same set of objects using
+   different settings (or delta order) would produce a pack with
+   different name.
+
+ * "git diff --no-index" mode used to unnecessarily attempt to read
+   the index when there is one.
+
+ * The deprecated parse-options macro OPT_BOOLEAN has been removed;
+   use OPT_BOOL or OPT_COUNTUP in new code.
+
+ * A few duplicate implementations of prefix/suffix string comparison
+   functions have been unified to starts_with() and ends_with().
+
+ * The new PERLLIB_EXTRA makefile variable can be used to specify
+   additional directories Perl modules (e.g. the ones necessary to run
+   git-svn) are installed on the platform when building.
+
+ * "git merge-base" learned the "--fork-point" mode, that implements
+   the same logic used in "git pull --rebase" to find a suitable fork
+   point out of the reflog entries for the remote-tracking branch the
+   work has been based on.  "git rebase" has the same logic that can be
+   triggered with the "--fork-point" option.
+
+ * A third-party "receive-pack" (the responder to "git push") can
+   advertise the "no-thin" capability to tell "git push" not to use
+   the thin-pack optimization. Our receive-pack has always been
+   capable of accepting and fattening a thin-pack, and will continue
+   not to ask "git push" to use a non-thin pack.
+
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v1.8.5
+------------------
+
+Unless otherwise noted, all the fixes since v1.8.5 in the maintenance
+track are contained in this release (see the maintenance releases' notes
+for details).
+
+ * "submodule.*.update=checkout", when propagated from .gitmodules to
+   .git/config, turned into a "submodule.*.update=none", which did not
+   make much sense.
+   (merge efa8fd7 fp/submodule-checkout-mode later to maint).
+
+ * The implementation of 'git stash $cmd "stash@{...}"' did not quote
+   the stash argument properly and left it split at IFS whitespace.
+   (merge 2a07e43 ow/stash-with-ifs later to maint).
+
+ * The "--[no-]informative-errors" options to "git daemon" were parsed
+   a bit too loosely, allowing any other string after these option
+   names.
+   (merge 82246b7 nd/daemon-informative-errors-typofix later to maint).
+
+ * There is no reason to have a hardcoded upper limit of the number of
+   parents for an octopus merge, created via the graft mechanism, but
+   there was.
+   (merge e228c17 js/lift-parent-count-limit later to maint).
+
+ * The basic test used to leave unnecessary trash directories in the
+   t/ directory.
+   (merge 738a8be jk/test-framework-updates later to maint).
+
+ * "git merge-base --octopus" used to leave cleaning up suboptimal
+   result to the caller, but now it does the clean-up itself.
+   (merge 8f29299 bm/merge-base-octopus-dedup later to maint).
+
+ * A "gc" process running as a different user should be able to stop a
+   new "gc" process from starting, but it didn't.
+   (merge ed7eda8 km/gc-eperm later to maint).
+
+ * An earlier "clean-up" introduced an unnecessary memory leak.
+   (merge e1c1a32 jk/credential-plug-leak later to maint).
+
+ * "git add -A" (no other arguments) in a totally empty working tree
+   used to emit an error.
+   (merge 64ed07c nd/add-empty-fix later to maint).
+
+ * "git log --decorate" did not handle a tag pointed by another tag
+   nicely.
+   (merge 5e1361c bc/log-decoration later to maint).
+
+ * When we figure out how many file descriptors to allocate for
+   keeping packfiles open, a system with non-working getrlimit() could
+   cause us to die(), but because we make this call only to get a
+   rough estimate of how many is available and we do not even attempt
+   to use up all file descriptors available ourselves, it is nicer to
+   fall back to a reasonable low value rather than dying.
+   (merge 491a8de jh/rlimit-nofile-fallback later to maint).
+
+ * read_sha1_file(), that is the workhorse to read the contents given
+   an object name, honoured object replacements, but there was no
+   corresponding mechanism to sha1_object_info() that was used to
+   obtain the metainfo (e.g. type & size) about the object.  This led
+   callers to weird inconsistencies.
+   (merge 663a856 cc/replace-object-info later to maint).
+
+ * "git cat-file --batch=", an admittedly useless command, did not
+   behave very well.
+   (merge 6554dfa jk/cat-file-regression-fix later to maint).
+
+ * "git rev-parse <revs> -- <paths>" did not implement the usual
+   disambiguation rules the commands in the "git log" family used in
+   the same way.
+   (merge 62f162f jk/rev-parse-double-dashes later to maint).
+
+ * "git mv A B/", when B does not exist as a directory, should error
+   out, but it didn't.
+   (merge c57f628 mm/mv-file-to-no-such-dir-with-slash later to maint).
+
+ * A workaround to an old bug in glibc prior to glibc 2.17 has been
+   retired; this would remove a side effect of the workaround that
+   corrupts system error messages in non-C locales.
+
+ * SSL-related options were not passed correctly to underlying socket
+   layer in "git send-email".
+   (merge 5508f3e tr/send-email-ssl later to maint).
+
+ * "git commit -v" appends the patch to the log message before
+   editing, and then removes the patch when the editor returned
+   control. However, the patch was not stripped correctly when the
+   first modified path was a submodule.
+   (merge 1a72cfd jl/commit-v-strip-marker later to maint).
+
+ * "git fetch --depth=0" was a no-op, and was silently ignored.
+   Diagnose it as an error.
+   (merge 5594bca nd/transport-positive-depth-only later to maint).
+
+ * Remote repository URL expressed in scp-style host:path notation are
+   parsed more carefully (e.g. "foo/bar:baz" is local, "[::1]:/~user" asks
+   to connect to user's home directory on host at address ::1.
+   (merge a2036d7 tb/clone-ssh-with-colon-for-port later to maint).
+
+ * "git diff -- ':(icase)makefile'" was unnecessarily rejected at the
+   command line parser.
+   (merge 887c6c1 nd/magic-pathspec later to maint).
+
+ * "git cat-file --batch-check=ok" did not check the existence of
+   the named object.
+   (merge 4ef8d1d sb/sha1-loose-object-info-check-existence later to maint).
+
+ * "git am --abort" sometimes complained about not being able to write
+   a tree with an 0{40} object in it.
+   (merge 77b43ca jk/two-way-merge-corner-case-fix later to maint).
+
+ * Two processes creating loose objects at the same time could have
+   failed unnecessarily when the name of their new objects started
+   with the same byte value, due to a race condition.
+   (merge b2476a6 jh/loose-object-dirs-creation-race later to maint).
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index d0a4733..e6d46ed 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -65,7 +65,20 @@
 test suite passes after your commit.  Do not forget to update the
 documentation to describe the updated behaviour.
 
-Oh, another thing.  I am picky about whitespaces.  Make sure your
+Speaking of the documentation, it is currently a liberal mixture of US
+and UK English norms for spelling and grammar, which is somewhat
+unfortunate.  A huge patch that touches the files all over the place
+only to correct the inconsistency is not welcome, though.  Potential
+clashes with other changes that can result from such a patch are not
+worth it.  We prefer to gradually reconcile the inconsistencies in
+favor of US English, with small and easily digestible patches, as a
+side effect of doing some other real work in the vicinity (e.g.
+rewriting a paragraph for clarity, while turning en_UK spelling to
+en_US).  Obvious typographical fixes are much more welcomed ("teh ->
+"the"), preferably submitted as independent patches separate from
+other documentation changes.
+
+Oh, another thing.  We are picky about whitespaces.  Make sure your
 changes do not trigger errors with the sample pre-commit hook shipped
 in templates/hooks--pre-commit.  To help ensure this does not happen,
 run git diff --check on your changes before you commit.
@@ -126,8 +139,15 @@
 comment on the changes you are submitting.  It is important for
 a developer to be able to "quote" your changes, using standard
 e-mail tools, so that they may comment on specific portions of
-your code.  For this reason, all patches should be submitted
-"inline".  If your log message (including your name on the
+your code.  For this reason, each patch should be submitted
+"inline" in a separate message.
+
+Multiple related patches should be grouped into their own e-mail
+thread to help readers find all parts of the series.  To that end,
+send them as replies to either an additional "cover letter" message
+(see below), the first patch, or the respective preceding patch.
+
+If your log message (including your name on the
 Signed-off-by line) is not writable in ASCII, make sure that
 you send off a message in the correct encoding.
 
diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt
index 4e55b15..0cebc4f 100644
--- a/Documentation/blame-options.txt
+++ b/Documentation/blame-options.txt
@@ -11,12 +11,12 @@
 
 -L <start>,<end>::
 -L :<regex>::
-	Annotate only the given line range.  <start> and <end> are optional.
-	``-L <start>'' or ``-L <start>,'' spans from <start> to end of file.
-	``-L ,<end>'' spans from start of file to <end>.
+	Annotate only the given line range. May be specified multiple times.
+	Overlapping ranges are allowed.
 +
-<start> and <end> can take one of these forms:
-
+<start> and <end> are optional. ``-L <start>'' or ``-L <start>,'' spans from
+<start> to end of file. ``-L ,<end>'' spans from start of file to <end>.
++
 include::line-range-format.txt[]
 
 -l::
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 6b35578..5f4d793 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -170,8 +170,8 @@
 	pushNeedsForce::
 		Shown when linkgit:git-push[1] rejects an update that
 		tries to overwrite a remote ref that points at an
-		object that is not a committish, or make the remote
-		ref point at an object that is not a committish.
+		object that is not a commit-ish, or make the remote
+		ref point at an object that is not a commit-ish.
 	statusHints::
 		Show directions on how to proceed from the current
 		state in the output of linkgit:git-status[1], in
@@ -553,22 +553,24 @@
 	When not configured the default commit message editor is used instead.
 
 core.pager::
-	The command that Git will use to paginate output.  Can
-	be overridden with the `GIT_PAGER` environment
-	variable.  Note that Git sets the `LESS` environment
-	variable to `FRSX` if it is unset when it runs the
-	pager.  One can change these settings by setting the
-	`LESS` variable to some other value.  Alternately,
-	these settings can be overridden on a project or
-	global basis by setting the `core.pager` option.
-	Setting `core.pager` has no effect on the `LESS`
-	environment variable behaviour above, so if you want
-	to override Git's default settings this way, you need
-	to be explicit.  For example, to disable the S option
-	in a backward compatible manner, set `core.pager`
-	to `less -+S`.  This will be passed to the shell by
-	Git, which will translate the final command to
-	`LESS=FRSX less -+S`.
+	Text viewer for use by Git commands (e.g., 'less').  The value
+	is meant to be interpreted by the shell.  The order of preference
+	is the `$GIT_PAGER` environment variable, then `core.pager`
+	configuration, then `$PAGER`, and then the default chosen at
+	compile time (usually 'less').
++
+When the `LESS` environment variable is unset, Git sets it to `FRSX`
+(if `LESS` environment variable is set, Git does not change it at
+all).  If you want to selectively override Git's default setting
+for `LESS`, you can set `core.pager` to e.g. `less -+S`.  This will
+be passed to the shell by Git, which will translate the final
+command to `LESS=FRSX less -+S`. The environment tells the command
+to set the `S` option to chop long lines but the command line
+resets it to the default to fold long lines.
++
+Likewise, when the `LV` environment variable is unset, Git sets it
+to `-c`.  You can override this setting by exporting `LV` with
+another value or setting `core.pager` to `lv +c`.
 
 core.whitespace::
 	A comma separated list of common whitespace problems to
@@ -726,6 +728,8 @@
 	overridden by `branch.<name>.pushremote`.  If no remote is
 	configured, or if you are not on any branch, it defaults to
 	`origin` for fetching and `remote.pushdefault` for pushing.
+	Additionally, `.` (a period) is the current local repository
+	(a dot-repository), see `branch.<name>.merge`'s final note below.
 
 branch.<name>.pushremote::
 	When on branch <name>, it overrides `branch.<name>.remote` for
@@ -751,8 +755,8 @@
 	Specify multiple values to get an octopus merge.
 	If you wish to setup 'git pull' so that it merges into <name> from
 	another branch in the local repository, you can point
-	branch.<name>.merge to the desired branch, and use the special setting
-	`.` (a period) for branch.<name>.remote.
+	branch.<name>.merge to the desired branch, and use the relative path
+	setting `.` (a period) for branch.<name>.remote.
 
 branch.<name>.mergeoptions::
 	Sets default options for merging into branch <name>. The syntax and
@@ -766,6 +770,10 @@
 	"git pull" is run. See "pull.rebase" for doing this in a non
 	branch-specific manner.
 +
+	When preserve, also pass `--preserve-merges` along to 'git rebase'
+	so that locally committed merge commits will not be flattened
+	by running 'git pull'.
++
 *NOTE*: this is a possibly dangerous operation; do *not* use
 it unless you understand the implications (see linkgit:git-rebase[1]
 for details).
@@ -787,8 +795,8 @@
 	working repository in gitweb (see linkgit:git-instaweb[1]).
 
 clean.requireForce::
-	A boolean to make git-clean do nothing unless given -f
-	or -n.   Defaults to true.
+	A boolean to make git-clean do nothing unless given -f,
+	-i or -n.   Defaults to true.
 
 color.branch::
 	A boolean to enable/disable color in the output of
@@ -1061,6 +1069,10 @@
 	especially on slow filesystems.  If not set, the value of
 	`transfer.unpackLimit` is used instead.
 
+fetch.prune::
+	If true, fetch will automatically behave as if the `--prune`
+	option was given on the command line.  See also `remote.<name>.prune`.
+
 format.attach::
 	Enable multipart/mixed attachments as the default for
 	'format-patch'.  The value can also be a double quoted string
@@ -1445,7 +1457,11 @@
 	of the file to read cookies from should be plain HTTP headers or
 	the Netscape/Mozilla cookie file format (see linkgit:curl[1]).
 	NOTE that the file specified with http.cookiefile is only used as
-	input. No cookies will be stored in the file.
+	input unless http.saveCookies is set.
+
+http.savecookies::
+	If set, store cookies received during requests to the file specified by
+	http.cookiefile. Has no effect if http.cookiefile is unset.
 
 http.sslVerify::
 	Whether to verify the SSL certificate when fetching or pushing
@@ -1525,6 +1541,51 @@
 	of common USER_AGENT strings (but not including those like git/1.7.1).
 	Can be overridden by the 'GIT_HTTP_USER_AGENT' environment variable.
 
+http.<url>.*::
+	Any of the http.* options above can be applied selectively to some urls.
+	For a config key to match a URL, each element of the config key is
+	compared to that of the URL, in the following order:
++
+--
+. Scheme (e.g., `https` in `https://example.com/`). This field
+  must match exactly between the config key and the URL.
+
+. Host/domain name (e.g., `example.com` in `https://example.com/`).
+  This field must match exactly between the config key and the URL.
+
+. Port number (e.g., `8080` in `http://example.com:8080/`).
+  This field must match exactly between the config key and the URL.
+  Omitted port numbers are automatically converted to the correct
+  default for the scheme before matching.
+
+. Path (e.g., `repo.git` in `https://example.com/repo.git`). The
+  path field of the config key must match the path field of the URL
+  either exactly or as a prefix of slash-delimited path elements.  This means
+  a config key with path `foo/` matches URL path `foo/bar`.  A prefix can only
+  match on a slash (`/`) boundary.  Longer matches take precedence (so a config
+  key with path `foo/bar` is a better match to URL path `foo/bar` than a config
+  key with just path `foo/`).
+
+. User name (e.g., `user` in `https://user@example.com/repo.git`). If
+  the config key has a user name it must match the user name in the
+  URL exactly. If the config key does not have a user name, that
+  config key will match a URL with any user name (including none),
+  but at a lower precedence than a config key with a user name.
+--
++
+The list above is ordered by decreasing precedence; a URL that matches
+a config key's path is preferred to one that matches its user name. For example,
+if the URL is `https://user@example.com/foo/bar` a config key match of
+`https://example.com/foo` will be preferred over a config key match of
+`https://user@example.com`.
++
+All URLs are normalized before attempting any matching (the password part,
+if embedded in the URL, is always ignored for matching purposes) so that
+equivalent urls that are simply spelled differently will match properly.
+Environment variable settings always override any matches.  The urls that are
+matched against are those given directly to Git commands.  This means any URLs
+visited as a result of a redirection do not participate in matching.
+
 i18n.commitEncoding::
 	Character encoding the commit messages are stored in; Git itself
 	does not care per se, but this information is necessary e.g. when
@@ -1826,6 +1887,10 @@
 	pull" is run. See "branch.<name>.rebase" for setting this on a
 	per-branch basis.
 +
+	When preserve, also pass `--preserve-merges` along to 'git rebase'
+	so that locally committed merge commits will not be flattened
+	by running 'git pull'.
++
 *NOTE*: this is a possibly dangerous operation; do *not* use
 it unless you understand the implications (see linkgit:git-rebase[1]
 for details).
@@ -1965,6 +2030,10 @@
 	If set to true, git-receive-pack will run git-update-server-info
 	after receiving data from git-push and updating refs.
 
+receive.shallowupdate::
+	If set to true, .git/shallow can be updated when new refs
+	require new shallow roots. Otherwise those refs are rejected.
+
 remote.pushdefault::
 	The remote to push to by default.  Overrides
 	`branch.<name>.remote` for all branches, and is overridden by
@@ -2024,6 +2093,12 @@
 	Setting this to a value <vcs> will cause Git to interact with
 	the remote with the git-remote-<vcs> helper.
 
+remote.<name>.prune::
+	When set to true, fetching from this remote by default will also
+	remove any remote-tracking references that no longer exist on the
+	remote (as if the `--prune` option was given on the command line).
+	Overrides `fetch.prune` settings, if any.
+
 remotes.<group>::
 	The list of remotes which are fetched by "git remote update
 	<group>".  See linkgit:git-remote[1].
@@ -2118,6 +2193,13 @@
 	Set to true to enable --branch by default in linkgit:git-status[1].
 	The option --no-branch takes precedence over this variable.
 
+status.displayCommentPrefix::
+	If set to true, linkgit:git-status[1] will insert a comment
+	prefix before each output line (starting with
+	`core.commentChar`, i.e. `#` by default). This was the
+	behavior of linkgit:git-status[1] in Git 1.8.4 and previous.
+	Defaults to false.
+
 status.showUntrackedFiles::
 	By default, linkgit:git-status[1] and linkgit:git-commit[1] show
 	files which are not currently tracked by Git. Directories which
@@ -2142,7 +2224,14 @@
 	If this is set to a non zero number or true (identical to -1 or an
 	unlimited number), the submodule summary will be enabled and a
 	summary of commits for modified submodules will be shown (see
-	--summary-limit option of linkgit:git-submodule[1]).
+	--summary-limit option of linkgit:git-submodule[1]). Please note
+	that the summary output command will be suppressed for all
+	submodules when `diff.ignoreSubmodules` is set to 'all' or only
+	for those submodules where `submodule.<name>.ignore=all`. To
+	also view the summary for ignored submodules you can either use
+	the --ignore-submodules=dirty command line option or the 'git
+	submodule summary' command, which shows a similar output but does
+	not honor these settings.
 
 submodule.<name>.path::
 submodule.<name>.url::
@@ -2177,7 +2266,8 @@
 	submodules that have untracked files in their work tree as changed.
 	This setting overrides any setting made in .gitmodules for this submodule,
 	both settings can be overridden on the command line by using the
-	"--ignore-submodules" option.
+	"--ignore-submodules" option. The 'git submodule' commands are not
+	affected by this setting.
 
 tar.umask::
 	This variable can be used to restrict the permission bits of
@@ -2262,11 +2352,11 @@
 	environment variables.  See linkgit:git-commit-tree[1].
 
 user.signingkey::
-	If linkgit:git-tag[1] is not selecting the key you want it to
-	automatically when creating a signed tag, you can override the
-	default selection with this variable.  This option is passed
-	unchanged to gpg's --local-user parameter, so you may specify a key
-	using any method that gpg supports.
+	If linkgit:git-tag[1] or linkgit:git-commit[1] is not selecting the
+	key you want it to automatically when creating a signed tag or
+	commit, you can override the default selection with this variable.
+	This option is passed unchanged to gpg's --local-user parameter,
+	so you may specify a key using any method that gpg supports.
 
 web.browser::
 	Specify a web browser that may be used by some commands.
diff --git a/Documentation/date-formats.txt b/Documentation/date-formats.txt
index c000f08..ccd1fc8 100644
--- a/Documentation/date-formats.txt
+++ b/Documentation/date-formats.txt
@@ -8,9 +8,9 @@
 support the following date formats:
 
 Git internal format::
-	It is `<unix timestamp> <timezone offset>`, where `<unix
+	It is `<unix timestamp> <time zone offset>`, where `<unix
 	timestamp>` is the number of seconds since the UNIX epoch.
-	`<timezone offset>` is a positive or negative offset from UTC.
+	`<time zone offset>` is a positive or negative offset from UTC.
 	For example CET (which is 2 hours ahead UTC) is `+0200`.
 
 RFC 2822::
diff --git a/Documentation/diff-config.txt b/Documentation/diff-config.txt
index ac77050..f07b451 100644
--- a/Documentation/diff-config.txt
+++ b/Documentation/diff-config.txt
@@ -73,7 +73,11 @@
 	Sets the default value of --ignore-submodules. Note that this
 	affects only 'git diff' Porcelain, and not lower level 'diff'
 	commands such as 'git diff-files'. 'git checkout' also honors
-	this setting when reporting uncommitted changes.
+	this setting when reporting uncommitted changes. Setting it to
+	'all' disables the submodule summary normally shown by 'git commit'
+	and 'git status' when 'status.submodulesummary' is set unless it is
+	overridden by using the --ignore-submodules command line option.
+	The 'git submodule' commands are not affected by this setting.
 
 diff.mnemonicprefix::
 	If set, 'git diff' uses a prefix pair that is different from the
@@ -94,6 +98,11 @@
 diff.noprefix::
 	If set, 'git diff' does not show any source or destination prefix.
 
+diff.orderfile::
+	File indicating how to order files within a diff, using
+	one shell glob pattern per line.
+	Can be overridden by the '-O' option to linkgit:git-diff[1].
+
 diff.renameLimit::
 	The number of files to consider when performing the copy/rename
 	detection; equivalent to the 'git diff' option '-l'.
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index bbed2cd..9b37b2a 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -432,6 +432,9 @@
 -O<orderfile>::
 	Output the patch in the order specified in the
 	<orderfile>, which has one shell glob pattern per line.
+	This overrides the `diff.orderfile` configuration variable
+	(see linkgit:git-config[1]).  To cancel `diff.orderfile`,
+	use `-O/dev/null`.
 
 ifndef::git-format-patch[]
 -R::
diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt
index e1fba85..2a18c1f 100644
--- a/Documentation/everyday.txt
+++ b/Documentation/everyday.txt
@@ -304,7 +304,7 @@
   * linkgit:git-shell[1] can be used as a 'restricted login shell'
     for shared central repository users.
 
-link:howto/update-hook-example.txt[update hook howto] has a good
+link:howto/update-hook-example.html[update hook howto] has a good
 example of managing a shared central repository.
 
 
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index ba1fe49..92c68c3 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -14,8 +14,18 @@
 	branch history. Tags for the deepened commits are not fetched.
 
 --unshallow::
-	Convert a shallow repository to a complete one, removing all
-	the limitations imposed by shallow repositories.
+	If the source repository is complete, convert a shallow
+	repository to a complete one, removing all the limitations
+	imposed by shallow repositories.
++
+If the source repository is shallow, fetch as much as possible so that
+the current repository has the same history as the source repository.
+
+--update-shallow::
+	By default when fetching from a shallow repository,
+	`git fetch` refuses refs that require updating
+	.git/shallow. This option updates .git/shallow and accept such
+	refs.
 
 ifndef::git-pull[]
 --dry-run::
@@ -41,17 +51,20 @@
 
 -p::
 --prune::
-	After fetching, remove any remote-tracking branches which
-	no longer exist	on the remote.
+	After fetching, remove any remote-tracking references that no
+	longer exist on the remote.  Tags are not subject to pruning
+	if they are fetched only because of the default tag
+	auto-following or due to a --tags option.  However, if tags
+	are fetched due to an explicit refspec (either on the command
+	line or in the remote configuration, for example if the remote
+	was cloned with the --mirror option), then they are also
+	subject to pruning.
 endif::git-pull[]
 
-ifdef::git-pull[]
---no-tags::
-endif::git-pull[]
 ifndef::git-pull[]
 -n::
---no-tags::
 endif::git-pull[]
+--no-tags::
 	By default, tags that point at objects that are downloaded
 	from the remote repository are fetched and stored locally.
 	This option disables this automatic tag following. The default
@@ -61,11 +74,12 @@
 ifndef::git-pull[]
 -t::
 --tags::
-	This is a short-hand for giving `refs/tags/*:refs/tags/*`
-	refspec from the command line, to ask all tags to be fetched
-	and stored locally.  Because this acts as an explicit
-	refspec, the default refspecs (configured with the
-	remote.$name.fetch variable) are overridden and not used.
+	Fetch all tags from the remote (i.e., fetch remote tags
+	`refs/tags/*` into local tags with the same name), in addition
+	to whatever else would otherwise be fetched.  Using this
+	option alone does not subject tags to pruning, even if --prune
+	is used (though tags may be pruned anyway if they are also the
+	destination of an explicit refspec; see '--prune').
 
 --recurse-submodules[=yes|on-demand|no]::
 	This option controls if and under what conditions new commits of
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index 6cea7f1..8e70a61 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -9,7 +9,7 @@
 --------
 [verse]
 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
-	    [-L n,m | -L :fn] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
+	    [-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
 	    [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>] [--] <file>
 
 DESCRIPTION
@@ -18,7 +18,8 @@
 Annotates each line in the given file with information from the revision which
 last modified the line. Optionally, start annotating from the given revision.
 
-The command can also limit the range of lines annotated.
+When specified one or more times, `-L` restricts annotation to the requested
+lines.
 
 The origin of lines is automatically followed across whole-file
 renames (currently there is no option to turn the rename-following
@@ -102,7 +103,7 @@
 at least once for each commit:
 
 - the author name ("author"), email ("author-mail"), time
-  ("author-time"), and timezone ("author-tz"); similarly
+  ("author-time"), and time zone ("author-tz"); similarly
   for committer.
 - the filename in the commit that the line is attributed to.
 - the first line of the commit log message ("summary").
@@ -130,7 +131,10 @@
 
 Unlike 'git blame' and 'git annotate' in older versions of git, the extent
 of the annotation can be limited to both line ranges and revision
-ranges.  When you are interested in finding the origin for
+ranges. The `-L` option, which limits annotation to a range of lines, may be
+specified multiple times.
+
+When you are interested in finding the origin for
 lines 40-60 for file `foo`, you can use the `-L` option like so
 (they mean the same thing -- both ask for 21 lines starting at
 line 40):
diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index 10fbc6a..f6a16f4 100644
--- a/Documentation/git-cat-file.txt
+++ b/Documentation/git-cat-file.txt
@@ -54,7 +54,7 @@
 
 --textconv::
 	Show the content as transformed by a textconv filter. In this case,
-	<object> has be of the form <treeish>:<path>, or :<path> in order
+	<object> has be of the form <tree-ish>:<path>, or :<path> in order
 	to apply the filter to the content recorded in the index at <path>.
 
 --batch::
@@ -86,10 +86,9 @@
 ------------
 
 If `--batch` or `--batch-check` is given, `cat-file` will read objects
-from stdin, one per line, and print information about them.
-
-Each line is considered as a whole object name, and is parsed as if
-given to linkgit:git-rev-parse[1].
+from stdin, one per line, and print information about them. By default,
+the whole line is considered as an object, as if it were fed to
+linkgit:git-rev-parse[1].
 
 You can specify the information shown for each object by using a custom
 `<format>`. The `<format>` is copied literally to stdout for each
@@ -110,6 +109,18 @@
 	The size, in bytes, that the object takes up on disk. See the
 	note about on-disk sizes in the `CAVEATS` section below.
 
+`deltabase`::
+	If the object is stored as a delta on-disk, this expands to the
+	40-hex sha1 of the delta base object. Otherwise, expands to the
+	null sha1 (40 zeroes). See `CAVEATS` below.
+
+`rest`::
+	If this atom is used in the output string, input lines are split
+	at the first whitespace boundary. All characters before that
+	whitespace are considered to be the object name; characters
+	after that first run of whitespace (i.e., the "rest" of the
+	line) are output in place of the `%(rest)` atom.
+
 If no format is specified, the default format is `%(objectname)
 %(objecttype) %(objectsize)`.
 
@@ -146,10 +157,11 @@
 responsible for disk usage. The size of a packed non-delta object may be
 much larger than the size of objects which delta against it, but the
 choice of which object is the base and which is the delta is arbitrary
-and is subject to change during a repack. Note also that multiple copies
-of an object may be present in the object database; in this case, it is
-undefined which copy's size will be reported.
+and is subject to change during a repack.
 
+Note also that multiple copies of an object may be present in the object
+database; in this case, it is undefined which copy's size or delta base
+will be reported.
 
 GIT
 ---
diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt
index a7be80d..00e2aa2 100644
--- a/Documentation/git-check-attr.txt
+++ b/Documentation/git-check-attr.txt
@@ -31,8 +31,9 @@
 	Read file names from stdin instead of from the command-line.
 
 -z::
-	Only meaningful with `--stdin`; paths are separated with a
-	NUL character instead of a linefeed character.
+	The output format is modified to be machine-parseable.
+	If `--stdin` is also given, input paths are separated
+	with a NUL character instead of a linefeed character.
 
 \--::
 	Interpret all preceding arguments as attributes and all following
@@ -48,6 +49,10 @@
 The output is of the form:
 <path> COLON SP <attribute> COLON SP <info> LF
 
+unless `-z` is in effect, in which case NUL is used as delimiter:
+<path> NUL <attribute> NUL <info> NUL
+
+
 <path> is the path of a file being queried, <attribute> is an attribute
 being queried and <info> can be either:
 
diff --git a/Documentation/git-check-ignore.txt b/Documentation/git-check-ignore.txt
index d2df487..ee2e091 100644
--- a/Documentation/git-check-ignore.txt
+++ b/Documentation/git-check-ignore.txt
@@ -45,6 +45,13 @@
 	not be possible to distinguish between paths which match a
 	pattern and those which don't.
 
+--no-index::
+	Don't look in the index when undertaking the checks. This can
+	be used to debug why a path became tracked by e.g. `git add .`
+	and was not ignored by the rules as expected by the user or when
+	developing patterns including negation to match a path previously
+	added with `git add -f`.
+
 OUTPUT
 ------
 
diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
index a49be1b..fc02959 100644
--- a/Documentation/git-check-ref-format.txt
+++ b/Documentation/git-check-ref-format.txt
@@ -54,6 +54,8 @@
 
 . They cannot contain a sequence `@{`.
 
+. They cannot be the single character `@`.
+
 . They cannot contain a `\`.
 
 These rules make it easy for shell script based tools to parse
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index ca118ac..33ad2ad 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -9,7 +9,8 @@
 --------
 [verse]
 'git checkout' [-q] [-f] [-m] [<branch>]
-'git checkout' [-q] [-f] [-m] [--detach] [<commit>]
+'git checkout' [-q] [-f] [-m] --detach [<branch>]
+'git checkout' [-q] [-f] [-m] [--detach] <commit>
 'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
 'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
 'git checkout' [-p|--patch] [<tree-ish>] [--] [<paths>...]
@@ -62,7 +63,7 @@
 successful.
 
 'git checkout' --detach [<branch>]::
-'git checkout' <commit>::
+'git checkout' [--detach] <commit>::
 
 	Prepare to work on top of <commit>, by detaching HEAD at it
 	(see "DETACHED HEAD" section), and updating the index and the
@@ -71,10 +72,11 @@
 	tree will be the state recorded in the commit plus the local
 	modifications.
 +
-Passing `--detach` forces this behavior in the case of a <branch> (without
-the option, giving a branch name to the command would check out the branch,
-instead of detaching HEAD at it), or the current commit,
-if no <branch> is specified.
+When the <commit> argument is a branch name, the `--detach` option can
+be used to detach HEAD at the tip of the branch (`git checkout
+<branch>` would check out that branch without detaching HEAD).
++
+Omitting <branch> detaches HEAD at the tip of the current branch.
 
 'git checkout' [-p|--patch] [<tree-ish>] [--] <pathspec>...::
 
@@ -230,8 +232,8 @@
 	commit, your HEAD becomes "detached" and you are no longer on
 	any branch (see below for details).
 +
-As a special case, the `"@{-N}"` syntax for the N-th last branch
-checks out the branch (instead of detaching).  You may also specify
+As a special case, the `"@{-N}"` syntax for the N-th last branch/commit
+checks out branches (instead of detaching).  You may also specify
 `-` which is synonymous with `"@{-1}"`.
 +
 As a further special case, you may use `"A...B"` as a shortcut for the
diff --git a/Documentation/git-cherry.txt b/Documentation/git-cherry.txt
index f6c19c7..0ea921a 100644
--- a/Documentation/git-cherry.txt
+++ b/Documentation/git-cherry.txt
@@ -3,7 +3,7 @@
 
 NAME
 ----
-git-cherry - Find commits not merged upstream
+git-cherry - Find commits yet to be applied to upstream
 
 SYNOPSIS
 --------
@@ -12,47 +12,26 @@
 
 DESCRIPTION
 -----------
-The changeset (or "diff") of each commit between the fork-point and <head>
-is compared against each commit between the fork-point and <upstream>.
-The commits are compared with their 'patch id', obtained from
-the 'git patch-id' program.
+Determine whether there are commits in `<head>..<upstream>` that are
+equivalent to those in the range `<limit>..<head>`.
 
-Every commit that doesn't exist in the <upstream> branch
-has its id (sha1) reported, prefixed by a symbol.  The ones that have
-equivalent change already
-in the <upstream> branch are prefixed with a minus (-) sign, and those
-that only exist in the <head> branch are prefixed with a plus (+) symbol:
+The equivalence test is based on the diff, after removing whitespace
+and line numbers.  git-cherry therefore detects when commits have been
+"copied" by means of linkgit:git-cherry-pick[1], linkgit:git-am[1] or
+linkgit:git-rebase[1].
 
-               __*__*__*__*__> <upstream>
-              /
-    fork-point
-              \__+__+__-__+__+__-__+__> <head>
-
-
-If a <limit> has been given then the commits along the <head> branch up
-to and including <limit> are not reported:
-
-               __*__*__*__*__> <upstream>
-              /
-    fork-point
-              \__*__*__<limit>__-__+__> <head>
-
-
-Because 'git cherry' compares the changeset rather than the commit id
-(sha1), you can use 'git cherry' to find out if a commit you made locally
-has been applied <upstream> under a different commit id.  For example,
-this will happen if you're feeding patches <upstream> via email rather
-than pushing or pulling commits directly.
-
+Outputs the SHA1 of every commit in `<limit>..<head>`, prefixed with
+`-` for commits that have an equivalent in <upstream>, and `+` for
+commits that do not.
 
 OPTIONS
 -------
 -v::
-	Verbose.
+	Show the commit subjects next to the SHA1s.
 
 <upstream>::
-	Upstream branch to compare against.
-	Defaults to the first tracked remote branch, if available.
+	Upstream branch to search for equivalent commits.
+	Defaults to the upstream branch of HEAD.
 
 <head>::
 	Working branch; defaults to HEAD.
@@ -60,6 +39,103 @@
 <limit>::
 	Do not report commits up to (and including) limit.
 
+EXAMPLES
+--------
+
+Patch workflows
+~~~~~~~~~~~~~~~
+
+git-cherry is frequently used in patch-based workflows (see
+linkgit:gitworkflows[7]) to determine if a series of patches has been
+applied by the upstream maintainer.  In such a workflow you might
+create and send a topic branch like this:
+
+------------
+$ git checkout -b topic origin/master
+# work and create some commits
+$ git format-patch origin/master
+$ git send-email ... 00*
+------------
+
+Later, you can see whether your changes have been applied by saying
+(still on `topic`):
+
+------------
+$ git fetch  # update your notion of origin/master
+$ git cherry -v
+------------
+
+Concrete example
+~~~~~~~~~~~~~~~~
+
+In a situation where topic consisted of three commits, and the
+maintainer applied two of them, the situation might look like:
+
+------------
+$ git log --graph --oneline --decorate --boundary origin/master...topic
+* 7654321 (origin/master) upstream tip commit
+[... snip some other commits ...]
+* cccc111 cherry-pick of C
+* aaaa111 cherry-pick of A
+[... snip a lot more that has happened ...]
+| * cccc000 (topic) commit C
+| * bbbb000 commit B
+| * aaaa000 commit A
+|/
+o 1234567 branch point
+------------
+
+In such cases, git-cherry shows a concise summary of what has yet to
+be applied:
+
+------------
+$ git cherry origin/master topic
+- cccc000... commit C
++ bbbb000... commit B
+- aaaa000... commit A
+------------
+
+Here, we see that the commits A and C (marked with `-`) can be
+dropped from your `topic` branch when you rebase it on top of
+`origin/master`, while the commit B (marked with `+`) still needs to
+be kept so that it will be sent to be applied to `origin/master`.
+
+
+Using a limit
+~~~~~~~~~~~~~
+
+The optional <limit> is useful in cases where your topic is based on
+other work that is not in upstream.  Expanding on the previous
+example, this might look like:
+
+------------
+$ git log --graph --oneline --decorate --boundary origin/master...topic
+* 7654321 (origin/master) upstream tip commit
+[... snip some other commits ...]
+* cccc111 cherry-pick of C
+* aaaa111 cherry-pick of A
+[... snip a lot more that has happened ...]
+| * cccc000 (topic) commit C
+| * bbbb000 commit B
+| * aaaa000 commit A
+| * 0000fff (base) unpublished stuff F
+[... snip ...]
+| * 0000aaa unpublished stuff A
+|/
+o 1234567 merge-base between upstream and topic
+------------
+
+By specifying `base` as the limit, you can avoid listing commits
+between `base` and `topic`:
+
+------------
+$ git cherry origin/master topic base
+- cccc000... commit C
++ bbbb000... commit B
+- aaaa000... commit A
+------------
+
+
 SEE ALSO
 --------
 linkgit:git-patch-id[1]
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 450f158..4987857 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -181,12 +181,7 @@
 
 --depth <depth>::
 	Create a 'shallow' clone with a history truncated to the
-	specified number of revisions.  A shallow repository has a
-	number of limitations (you cannot clone or fetch from
-	it, nor push from nor into it), but is adequate if you
-	are only interested in the recent history of a large project
-	with a long history, and would want to send in fixes
-	as patches.
+	specified number of revisions.
 
 --[no-]single-branch::
 	Clone only the history leading to the tip of a single branch,
diff --git a/Documentation/git-column.txt b/Documentation/git-column.txt
index 5d6f1cc..03d1846 100644
--- a/Documentation/git-column.txt
+++ b/Documentation/git-column.txt
@@ -43,11 +43,6 @@
 --padding=<N>::
 	The number of spaces between columns. One space by default.
 
-
-Author
-------
-Written by Nguyen Thai Ngoc Duy <pclouds@gmail.com>
-
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 2dbe486..e9917b8 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -15,6 +15,7 @@
 'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
 'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
 'git config' [<file-option>] [type] [-z|--null] --get-regexp name_regex [value_regex]
+'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
 'git config' [<file-option>] --unset name [value_regex]
 'git config' [<file-option>] --unset-all name [value_regex]
 'git config' [<file-option>] --rename-section old_name new_name
@@ -95,6 +96,14 @@
 	in which section and variable names are lowercased, but subsection
 	names are not.
 
+--get-urlmatch name URL::
+	When given a two-part name section.key, the value for
+	section.<url>.key whose <url> part matches the best to the
+	given URL is returned (if no such key exists, the value for
+	section.key is used as a fallback).  When given just the
+	section as name, do so for all the keys in the section and
+	list them.
+
 --global::
 	For writing options: write to global `~/.gitconfig` file
 	rather than the repository `.git/config`, write to
@@ -295,6 +304,13 @@
 		gitproxy=proxy-command for kernel.org
 		gitproxy=default-proxy ; for all the rest
 
+	; HTTP
+	[http]
+		sslVerify
+	[http "https://weak.example.com"]
+		sslVerify = false
+		cookieFile = /tmp/cookie.txt
+
 you can set the filemode to true with
 
 ------------
@@ -380,6 +396,19 @@
 echo "${WS}your whitespace color or blue reverse${RESET}"
 ------------
 
+For URLs in `https://weak.example.com`, `http.sslVerify` is set to
+false, while it is set to `true` for all others:
+
+------------
+% git config --bool --get-urlmatch http.sslverify https://good.example.com
+true
+% git config --bool --get-urlmatch http.sslverify https://weak.example.com
+false
+% git config --get-urlmatch http https://weak.example.com
+http.cookiefile /tmp/cookie.txt
+http.sslverify false
+------------
+
 include::config.txt[]
 
 GIT
diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt
index 7da0f13..b211440 100644
--- a/Documentation/git-credential.txt
+++ b/Documentation/git-credential.txt
@@ -20,7 +20,7 @@
 interface to scripts which may want to retrieve, store, or prompt for
 credentials in the same manner as Git. The design of this scriptable
 interface models the internal C API; see
-link:technical/api-credentials.txt[the Git credential API] for more
+link:technical/api-credentials.html[the Git credential API] for more
 background on the concepts.
 
 git-credential takes an "action" option on the command-line (one of
diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt
index d1bcda2..2df9953 100644
--- a/Documentation/git-cvsimport.txt
+++ b/Documentation/git-cvsimport.txt
@@ -144,7 +144,7 @@
 	CVS by default uses the Unix username when writing its
 	commit logs. Using this option and an author-conv-file
 	maps the name recorded in CVS to author name, e-mail and
-	optional timezone:
+	optional time zone:
 +
 ---------
 	exon=Andreas Ericsson <ae@op5.se>
@@ -154,7 +154,7 @@
 +
 'git cvsimport' will make it appear as those authors had
 their GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL set properly
-all along.  If a timezone is specified, GIT_AUTHOR_DATE will
+all along.  If a time zone is specified, GIT_AUTHOR_DATE will
 have the corresponding offset applied.
 +
 For convenience, this data is saved to `$GIT_DIR/cvs-authors`
diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 9439cd6..d20ca40 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -9,7 +9,7 @@
 SYNOPSIS
 --------
 [verse]
-'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...
+'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] <commit-ish>...
 'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]
 
 DESCRIPTION
@@ -26,8 +26,8 @@
 
 OPTIONS
 -------
-<committish>...::
-	Committish object names to describe.
+<commit-ish>...::
+	Commit-ish object names to describe.
 
 --dirty[=<mark>]::
 	Describe the working tree.
@@ -57,7 +57,7 @@
 
 --candidates=<n>::
 	Instead of considering only the 10 most recent tags as
-	candidates to describe the input committish consider
+	candidates to describe the input commit-ish consider
 	up to <n> candidates.  Increasing <n> above 10 will take
 	slightly longer but may produce a more accurate result.
 	An <n> of 0 will cause only exact matches to be output.
@@ -145,7 +145,7 @@
 SEARCH STRATEGY
 ---------------
 
-For each committish supplied, 'git describe' will first look for
+For each commit-ish supplied, 'git describe' will first look for
 a tag which tags exactly that commit.  Annotated tags will always
 be preferred over lightweight tags, and tags with newer dates will
 always be preferred over tags with older dates.  If an exact match
@@ -154,12 +154,12 @@
 If an exact match was not found, 'git describe' will walk back
 through the commit history to locate an ancestor commit which
 has been tagged.  The ancestor's tag will be output along with an
-abbreviation of the input committish's SHA-1. If '--first-parent' was
+abbreviation of the input commit-ish's SHA-1. If '--first-parent' was
 specified then the walk will only consider the first parent of each
 commit.
 
 If multiple tags were found during the walk then the tag which
-has the fewest commits different from the input committish will be
+has the fewest commits different from the input commit-ish will be
 selected and output.  Here fewest commits different is defined as
 the number of commits which would be shown by `git log tag..input`
 will be the smallest number of commits possible.
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 78d6d50..33fbd8c 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -28,10 +28,15 @@
 	words, the differences are what you _could_ tell Git to
 	further add to the index but you still haven't.  You can
 	stage these changes by using linkgit:git-add[1].
-+
-If exactly two paths are given and at least one points outside
-the current repository, 'git diff' will compare the two files /
-directories. This behavior can be forced by --no-index.
+
+'git diff' --no-index [--options] [--] [<path>...]::
+
+	This form is to compare the given two paths on the
+	filesystem.  You can omit the `--no-index` option when
+	running the command in a working tree controlled by Git and
+	at least one of the paths points outside the working tree,
+	or when running the command outside a working tree
+	controlled by Git.
 
 'git diff' [--options] --cached [<commit>] [--] [<path>...]::
 
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index bf1a02a..fd22a9a 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -251,7 +251,7 @@
 If the local offset is not available in the source material, use
 ``+0000'', or the most common local offset.  For example many
 organizations have a CVS repository which has only ever been accessed
-by users who are located in the same location and timezone.  In this
+by users who are located in the same location and time zone.  In this
 case a reasonable offset from UTC could be assumed.
 +
 Unlike the `rfc2822` format, this format is very strict.  Any
@@ -271,7 +271,7 @@
 strings which Git will parse wrong, and yet consider valid.
 Seriously malformed strings will be rejected.
 +
-Unlike the `raw` format above, the timezone/UTC offset information
+Unlike the `raw` format above, the time zone/UTC offset information
 contained in an RFC 2822 date string is used to adjust the date
 value to UTC prior to storage.  Therefore it is important that
 this information be as accurate as possible.
@@ -287,13 +287,13 @@
 ambiguity in parsing.
 
 `now`::
-	Always use the current time and timezone.  The literal
+	Always use the current time and time zone.  The literal
 	`now` must always be supplied for `<when>`.
 +
-This is a toy format.  The current time and timezone of this system
+This is a toy format.  The current time and time zone of this system
 is always copied into the identity string at the time it is being
 created by fast-import.  There is no way to specify a different time or
-timezone.
+time zone.
 +
 This particular format is supplied as it's short to implement and
 may be useful to a process that wants to create a new commit
@@ -361,8 +361,8 @@
 	`--cat-blob-fd` or `stdout` if unspecified.
 
 `feature`::
-	Require that fast-import supports the specified feature, or
-	abort if it does not.
+	Enable the specified feature. This requires that fast-import
+	supports the specified feature, and aborts if it does not.
 
 `option`::
 	Specify any of the options listed under OPTIONS that do not
@@ -380,8 +380,8 @@
 	('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
 	'committer' (SP <name>)? SP LT <email> GT SP <when> LF
 	data
-	('from' SP <committish> LF)?
-	('merge' SP <committish> LF)?
+	('from' SP <commit-ish> LF)?
+	('merge' SP <commit-ish> LF)?
 	(filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)*
 	LF?
 ....
@@ -460,9 +460,9 @@
 be the first ancestor of the new commit.
 
 As `LF` is not valid in a Git refname or SHA-1 expression, no
-quoting or escaping syntax is supported within `<committish>`.
+quoting or escaping syntax is supported within `<commit-ish>`.
 
-Here `<committish>` is any of the following:
+Here `<commit-ish>` is any of the following:
 
 * The name of an existing branch already in fast-import's internal branch
   table.  If fast-import doesn't know the name, it's treated as a SHA-1
@@ -509,7 +509,7 @@
 it is suggested that frontends do not use more than 15 `merge`
 commands per commit; 16, if starting a new, empty branch.
 
-Here `<committish>` is any of the commit specification expressions
+Here `<commit-ish>` is any of the commit specification expressions
 also accepted by `from` (see above).
 
 `filemodify`
@@ -677,8 +677,8 @@
 `notemodify`
 ^^^^^^^^^^^^
 Included in a `commit` `<notes_ref>` command to add a new note
-annotating a `<committish>` or change this annotation contents.
-Internally it is similar to filemodify 100644 on `<committish>`
+annotating a `<commit-ish>` or change this annotation contents.
+Internally it is similar to filemodify 100644 on `<commit-ish>`
 path (maybe split into subdirectories). It's not advised to
 use any other commands to write to the `<notes_ref>` tree except
 `filedeleteall` to delete all existing notes in this tree.
@@ -691,7 +691,7 @@
 	commit that is to be annotated.
 +
 ....
-	'N' SP <dataref> SP <committish> LF
+	'N' SP <dataref> SP <commit-ish> LF
 ....
 +
 Here `<dataref>` can be either a mark reference (`:<idnum>`)
@@ -704,13 +704,13 @@
 	command.
 +
 ....
-	'N' SP 'inline' SP <committish> LF
+	'N' SP 'inline' SP <commit-ish> LF
 	data
 ....
 +
 See below for a detailed description of the `data` command.
 
-In both formats `<committish>` is any of the commit specification
+In both formats `<commit-ish>` is any of the commit specification
 expressions also accepted by `from` (see above).
 
 `mark`
@@ -741,7 +741,7 @@
 
 ....
 	'tag' SP <name> LF
-	'from' SP <committish> LF
+	'from' SP <commit-ish> LF
 	'tagger' (SP <name>)? SP LT <email> GT SP <when> LF
 	data
 ....
@@ -786,11 +786,11 @@
 
 ....
 	'reset' SP <ref> LF
-	('from' SP <committish> LF)?
+	('from' SP <commit-ish> LF)?
 	LF?
 ....
 
-For a detailed description of `<ref>` and `<committish>` see above
+For a detailed description of `<ref>` and `<commit-ish>` see above
 under `commit` and `from`.
 
 The `LF` after the command is optional (it used to be required).
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 1e71754..93b5067 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -12,7 +12,7 @@
 'git fetch-pack' [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag]
 	[--upload-pack=<git-upload-pack>]
 	[--depth=<n>] [--no-progress]
-	[-v] [<host>:]<directory> [<refs>...]
+	[-v] <repository> [<refs>...]
 
 DESCRIPTION
 -----------
@@ -90,22 +90,25 @@
 --no-progress::
 	Do not show the progress.
 
+--check-self-contained-and-connected::
+	Output "connectivity-ok" if the received pack is
+	self-contained and connected.
+
 -v::
 	Run verbosely.
 
-<host>::
-	A remote host that houses the repository.  When this
-	part is specified, 'git-upload-pack' is invoked via
-	ssh.
-
-<directory>::
-	The repository to sync from.
+<repository>::
+	The URL to the remote repository.
 
 <refs>...::
 	The remote heads to update from. This is relative to
 	$GIT_DIR (e.g. "HEAD", "refs/heads/master").  When
 	unspecified, update from all heads the remote side has.
 
+SEE ALSO
+--------
+linkgit:git-fetch[1]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index e08a028..5809aa4 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -24,19 +24,22 @@
 in `.git/FETCH_HEAD`.  This information is left for a later merge
 operation done by 'git merge'.
 
-When <refspec> stores the fetched result in remote-tracking branches,
-the tags that point at these branches are automatically
-followed.  This is done by first fetching from the remote using
-the given <refspec>s, and if the repository has objects that are
-pointed by remote tags that it does not yet have, then fetch
-those missing tags.  If the other end has tags that point at
-branches you are not interested in, you will not get them.
+By default, tags are auto-followed.  This means that when fetching
+from a remote, any tags on the remote that point to objects that exist
+in the local repository are fetched.  The effect is to fetch tags that
+point at branches that you are interested in.  This default behavior
+can be changed by using the --tags or --no-tags options, by
+configuring remote.<name>.tagopt, or by using a refspec that fetches
+tags explicitly.
 
 'git fetch' can fetch from either a single named repository,
 or from several repositories at once if <group> is given and
 there is a remotes.<group> entry in the configuration file.
 (See linkgit:git-config[1]).
 
+When no remote is specified, by default the `origin` remote will be used,
+unless there's an upstream branch configured for the current branch.
+
 OPTIONS
 -------
 include::fetch-options.txt[]
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index e4c8e82..2eba627 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -393,7 +393,7 @@
 Checklist for Shrinking a Repository
 ------------------------------------
 
-git-filter-branch is often used to get rid of a subset of files,
+git-filter-branch can be used to get rid of a subset of files,
 usually with some combination of `--index-filter` and
 `--subdirectory-filter`.  People expect the resulting repository to
 be smaller than the original, but you need a few more steps to
@@ -429,6 +429,37 @@
   (or if your git-gc is not new enough to support arguments to
   `--prune`, use `git repack -ad; git prune` instead).
 
+Notes
+-----
+
+git-filter-branch allows you to make complex shell-scripted rewrites
+of your Git history, but you probably don't need this flexibility if
+you're simply _removing unwanted data_ like large files or passwords.
+For those operations you may want to consider
+link:http://rtyley.github.io/bfg-repo-cleaner/[The BFG Repo-Cleaner],
+a JVM-based alternative to git-filter-branch, typically at least
+10-50x faster for those use-cases, and with quite different
+characteristics:
+
+* Any particular version of a file is cleaned exactly _once_. The BFG,
+  unlike git-filter-branch, does not give you the opportunity to
+  handle a file differently based on where or when it was committed
+  within your history. This constraint gives the core performance
+  benefit of The BFG, and is well-suited to the task of cleansing bad
+  data - you don't care _where_ the bad data is, you just want it
+  _gone_.
+
+* By default The BFG takes full advantage of multi-core machines,
+  cleansing commit file-trees in parallel. git-filter-branch cleans
+  commits sequentially (ie in a single-threaded manner), though it
+  _is_ possible to write filters that include their own parallellism,
+  in the scripts executed against each commit.
+
+* The link:http://rtyley.github.io/bfg-repo-cleaner/#examples[command options]
+  are much more restrictive than git-filter branch, and dedicated just
+  to the tasks of removing unwanted data- e.g:
+  `--strip-blobs-bigger-than 1M`.
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index f2e08d1..4240875 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -91,7 +91,19 @@
 upstream::
 	The name of a local ref which can be considered ``upstream''
 	from the displayed ref. Respects `:short` in the same way as
-	`refname` above.
+	`refname` above.  Additionally respects `:track` to show
+	"[ahead N, behind M]" and `:trackshort` to show the terse
+	version: ">" (ahead), "<" (behind), "<>" (ahead and behind),
+	or "=" (in sync).  Has no effect if the ref does not have
+	tracking information associated with it.
+
+HEAD::
+	'*' if HEAD matches current ref (the checked out branch), ' '
+	otherwise.
+
+color::
+	Change output color.  Followed by `:<colorname>`, where names
+	are described in `color.branch.*`.
 
 In addition to the above, for commit and tag objects, the header
 field names (`tree`, `parent`, `object`, `type`, and `tag`) can
@@ -207,13 +219,9 @@
 eval "$eval"
 ------------
 
-Author
-------
-Written by Junio C Hamano <gitster@pobox.com>.
-
-Documentation
--------------
-Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
+SEE ALSO
+--------
+linkgit:git-show-ref[1]
 
 GIT
 ---
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index e394276..5c0a4ab 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -242,6 +242,7 @@
 Note that the leading character does not have to be a dot; for example,
 you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`.
 
+-q::
 --quiet::
 	Do not print the names of the generated files to standard output.
 
@@ -437,7 +438,8 @@
 In Thunderbird 3:
 Edit..Preferences..Advanced..Config Editor.  Search for
 "mail.wrap_long_lines".
-Toggle it to make sure it is set to `false`.
+Toggle it to make sure it is set to `false`. Also, search for
+"mailnews.wraplength" and set the value to 0.
 
 3. Disable the use of format=flowed:
 Edit..Preferences..Advanced..Config Editor.  Search for
diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index 2402ed6..e158a3b 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -9,7 +9,7 @@
 SYNOPSIS
 --------
 [verse]
-'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune]
+'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune] [--force]
 
 DESCRIPTION
 -----------
@@ -72,6 +72,10 @@
 --quiet::
 	Suppress all progress reports.
 
+--force::
+	Force `git gc` to run even if there may be another `git gc`
+	instance running on this repository.
+
 Configuration
 -------------
 
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index 8497aa4..f837334 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -9,7 +9,7 @@
 SYNOPSIS
 --------
 [verse]
-'git grep' [-a | --text] [-I] [-i | --ignore-case] [-w | --word-regexp]
+'git grep' [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | --word-regexp]
 	   [-v | --invert-match] [-h|-H] [--full-name]
 	   [-E | --extended-regexp] [-G | --basic-regexp]
 	   [-P | --perl-regexp]
@@ -80,6 +80,13 @@
 --text::
 	Process binary files as if they were text.
 
+--textconv::
+	Honor textconv filter settings.
+
+--no-textconv::
+	Do not honor textconv filter settings.
+	This is the default.
+
 -i::
 --ignore-case::
 	Ignore case differences between the patterns and the
diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.txt
index e3bcdb5..e8c13f6 100644
--- a/Documentation/git-http-backend.txt
+++ b/Documentation/git-http-backend.txt
@@ -263,14 +263,6 @@
 All CGI environment variables are available to each of the hooks
 invoked by the 'git-receive-pack'.
 
-Author
-------
-Written by Shawn O. Pearce <spearce@spearce.org>.
-
-Documentation
---------------
-Documentation by Shawn O. Pearce <spearce@spearce.org>.
-
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index ac2694d..1f7bc67 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -15,9 +15,9 @@
 -----------
 Shows the commit logs.
 
-The command takes options applicable to the 'git rev-list'
+The command takes options applicable to the `git rev-list`
 command to control what is shown and how, and options applicable to
-the 'git diff-*' commands to control how the changes
+the `git diff-*` commands to control how the changes
 each commit introduces are shown.
 
 
@@ -42,28 +42,27 @@
 
 --use-mailmap::
 	Use mailmap file to map author and committer names and email
-	to canonical real names and email addresses. See
+	addresses to canonical real names and email addresses. See
 	linkgit:git-shortlog[1].
 
 --full-diff::
-	Without this flag, "git log -p <path>..." shows commits that
+	Without this flag, `git log -p <path>...` shows commits that
 	touch the specified paths, and diffs about the same specified
 	paths.  With this, the full diff is shown for commits that touch
 	the specified paths; this means that "<path>..." limits only
 	commits, and doesn't limit diff for those commits.
 +
 Note that this affects all diff-based output types, e.g. those
-produced by --stat etc.
+produced by `--stat`, etc.
 
 --log-size::
-	Before the log message print out its size in bytes. Intended
-	mainly for porcelain tools consumption. If Git is unable to
-	produce a valid value size is set to zero.
-	Note that only message is considered, if also a diff is shown
-	its size is not included.
+	Include a line ``log size <number>'' in the output for each commit,
+	where <number> is the length of that commit's message in bytes.
+	Intended to speed up tools that read log messages from `git log`
+	output by allowing them to allocate space in advance.
 
--L <start>,<end>:<file>, -L :<regex>:<file>::
-
+-L <start>,<end>:<file>::
+-L :<regex>:<file>::
 	Trace the evolution of the line range given by "<start>,<end>"
 	(or the funcname regex <regex>) within the <file>.  You may
 	not give any pathspec limiters.  This is currently limited to
@@ -71,8 +70,6 @@
 	give zero or one positive revision arguments.
 	You can specify this option more than once.
 +
-<start> and <end> can take one of these forms:
-
 include::line-range-format.txt[]
 
 <revision range>::
@@ -81,16 +78,16 @@
 	whole history leading to the current commit).  `origin..HEAD`
 	specifies all the commits reachable from the current commit
 	(i.e. `HEAD`), but not from `origin`. For a complete list of
-	ways to spell <revision range>, see the "Specifying Ranges"
+	ways to spell <revision range>, see the 'Specifying Ranges'
 	section of linkgit:gitrevisions[7].
 
 [\--] <path>...::
 	Show only commits that are enough to explain how the files
-	that match the specified paths came to be.  See "History
-	Simplification" below for details and other simplification
+	that match the specified paths came to be.  See 'History
+	Simplification' below for details and other simplification
 	modes.
 +
-Paths may need to be prefixed with "\-- " to separate them from
+Paths may need to be prefixed with ``\-- '' to separate them from
 options or the revision range, when confusion arises.
 
 include::rev-list-options.txt[]
@@ -114,12 +111,12 @@
 `git log v2.6.12.. include/scsi drivers/scsi`::
 
 	Show all commits since version 'v2.6.12' that changed any file
-	in the include/scsi or drivers/scsi subdirectories
+	in the `include/scsi` or `drivers/scsi` subdirectories
 
 `git log --since="2 weeks ago" -- gitk`::
 
 	Show the changes during the last two weeks to the file 'gitk'.
-	The "--" is necessary to avoid confusion with the *branch* named
+	The ``--'' is necessary to avoid confusion with the *branch* named
 	'gitk'
 
 `git log --name-status release..test`::
@@ -130,7 +127,7 @@
 
 `git log --follow builtin/rev-list.c`::
 
-	Shows the commits that changed builtin/rev-list.c, including
+	Shows the commits that changed `builtin/rev-list.c`, including
 	those commits that occurred before the file was given its
 	present name.
 
@@ -148,17 +145,18 @@
 `git log -p -m --first-parent`::
 
 	Shows the history including change diffs, but only from the
-	"main branch" perspective, skipping commits that come from merged
+	``main branch'' perspective, skipping commits that come from merged
 	branches, and showing full diffs of changes introduced by the merges.
 	This makes sense only when following a strict policy of merging all
 	topic branches when staying on a single integration branch.
 
 `git log -L '/int main/',/^}/:main.c`::
 
-	Shows how the function `main()` in the file 'main.c' evolved
+	Shows how the function `main()` in the file `main.c` evolved
 	over time.
 
 `git log -3`::
+
 	Limits the number of commits to show to 3.
 
 DISCUSSION
@@ -173,12 +171,12 @@
 for settings related to diff generation.
 
 format.pretty::
-	Default for the `--format` option.  (See "PRETTY FORMATS" above.)
-	Defaults to "medium".
+	Default for the `--format` option.  (See 'Pretty Formats' above.)
+	Defaults to `medium`.
 
 i18n.logOutputEncoding::
-	Encoding to use when displaying logs.  (See "Discussion", above.)
-	Defaults to the value of `i18n.commitEncoding` if set, UTF-8
+	Encoding to use when displaying logs.  (See 'Discussion' above.)
+	Defaults to the value of `i18n.commitEncoding` if set, and UTF-8
 	otherwise.
 
 log.date::
@@ -187,7 +185,7 @@
 	dates like `Sat May 8 19:35:34 2010 -0500`.
 
 log.showroot::
-	If `false`, 'git log' and related commands will not treat the
+	If `false`, `git log` and related commands will not treat the
 	initial commit as a big creation event.  Any root commits in
 	`git log -p` output would be shown without a diff attached.
 	The default is `true`.
@@ -198,7 +196,7 @@
 notes.displayRef::
 	Which refs, in addition to the default set by `core.notesRef`
 	or 'GIT_NOTES_REF', to read notes from when showing commit
-	messages with the 'log' family of commands.  See
+	messages with the `log` family of commands.  See
 	linkgit:git-notes[1].
 +
 May be an unabbreviated ref name or a glob and may be specified
diff --git a/Documentation/git-lost-found.txt b/Documentation/git-lost-found.txt
deleted file mode 100644
index d549328..0000000
--- a/Documentation/git-lost-found.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-git-lost-found(1)
-=================
-
-NAME
-----
-git-lost-found - Recover lost refs that luckily have not yet been pruned
-
-SYNOPSIS
---------
-[verse]
-'git lost-found'
-
-DESCRIPTION
------------
-
-*NOTE*: this command is deprecated.  Use linkgit:git-fsck[1] with
-the option '--lost-found' instead.
-
-Finds dangling commits and tags from the object database, and
-creates refs to them in the .git/lost-found/ directory.  Commits and
-tags that dereference to commits are stored in .git/lost-found/commit,
-and other objects are stored in .git/lost-found/other.
-
-
-OUTPUT
-------
-Prints to standard output the object names and one-line descriptions
-of any commits or tags found.
-
-EXAMPLE
--------
-
-Suppose you run 'git tag -f' and mistype the tag to overwrite.
-The ref to your tag is overwritten, but until you run 'git
-prune', the tag itself is still there.
-
-------------
-$ git lost-found
-[1ef2b196d909eed523d4f3c9bf54b78cdd6843c6] GIT 0.99.9c
-...
-------------
-
-Also you can use gitk to browse how any tags found relate to each
-other.
-
-------------
-$ gitk $(cd .git/lost-found/commit && echo ??*)
-------------
-
-After making sure you know which the object is the tag you are looking
-for, you can reconnect it to your regular `refs` hierarchy by using
-the `update-ref` command.
-
-------------
-$ git cat-file -t 1ef2b196
-tag
-$ git cat-file tag 1ef2b196
-object fa41bbce8e38c67a218415de6cfa510c7e50032a
-type commit
-tag v0.99.9c
-tagger Junio C Hamano <junkio@cox.net> 1131059594 -0800
-
-GIT 0.99.9c
-
-This contains the following changes from the "master" branch, since
-...
-$ git update-ref refs/tags/not-lost-anymore 1ef2b196
-$ git rev-parse not-lost-anymore
-1ef2b196d909eed523d4f3c9bf54b78cdd6843c6
-------------
-
-GIT
----
-Part of the linkgit:git[1] suite
diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt
index 87842e3..808426f 100644
--- a/Documentation/git-merge-base.txt
+++ b/Documentation/git-merge-base.txt
@@ -13,6 +13,7 @@
 'git merge-base' [-a|--all] --octopus <commit>...
 'git merge-base' --is-ancestor <commit> <commit>
 'git merge-base' --independent <commit>...
+'git merge-base' --fork-point <ref> [<commit>]
 
 DESCRIPTION
 -----------
@@ -24,8 +25,8 @@
 ancestor', i.e. a 'merge base'.  Note that there can be more than one
 merge base for a pair of commits.
 
-OPERATION MODE
---------------
+OPERATION MODES
+---------------
 
 As the most common special case, specifying only two commits on the
 command line means computing the merge base between the given two commits.
@@ -56,6 +57,14 @@
 	and exit with status 0 if true, or with status 1 if not.
 	Errors are signaled by a non-zero status that is not 1.
 
+--fork-point::
+	Find the point at which a branch (or any history that leads
+	to <commit>) forked from another branch (or any reference)
+	<ref>. This does not just look for the common ancestor of
+	the two commits, but also takes into account the reflog of
+	<ref> to see if the history leading to <commit> forked from
+	an earlier incarnation of the branch <ref> (see discussion
+	on this mode below).
 
 OPTIONS
 -------
@@ -137,6 +146,31 @@
 
 instead.
 
+Discussion on fork-point mode
+-----------------------------
+
+After working on the `topic` branch created with `git checkout -b
+topic origin/master`, the history of remote-tracking branch
+`origin/master` may have been rewound and rebuilt, leading to a
+history of this shape:
+
+			 o---B1
+			/
+	---o---o---B2--o---o---o---B (origin/master)
+		\
+		 B3
+		  \
+		   Derived (topic)
+
+where `origin/master` used to point at commits B3, B2, B1 and now it
+points at B, and your `topic` branch was started on top of it back
+when `origin/master` was at B3. This mode uses the reflog of
+`origin/master` to find B3 as the fork point, so that the `topic`
+can be rebased on top of the updated `origin/master` by:
+
+    $ fork_point=$(git merge-base --fork-point origin/master topic)
+    $ git rebase --onto origin/master $fork_point topic
+
 
 See also
 --------
diff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt
index d7db2a3..d2fc12e 100644
--- a/Documentation/git-merge-file.txt
+++ b/Documentation/git-merge-file.txt
@@ -11,7 +11,7 @@
 [verse]
 'git merge-file' [-L <current-name> [-L <base-name> [-L <other-name>]]]
 	[--ours|--theirs|--union] [-p|--stdout] [-q|--quiet] [--marker-size=<n>]
-	<current-file> <base-file> <other-file>
+	[--[no-]diff3] <current-file> <base-file> <other-file>
 
 
 DESCRIPTION
@@ -66,6 +66,9 @@
 -q::
 	Quiet; do not warn about conflicts.
 
+--diff3::
+	Show conflicts in "diff3" style.
+
 --ours::
 --theirs::
 --union::
diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt
index c5f84b6..58731c1 100644
--- a/Documentation/git-merge-tree.txt
+++ b/Documentation/git-merge-tree.txt
@@ -13,7 +13,7 @@
 
 DESCRIPTION
 -----------
-Reads three treeish, and output trivial merge results and
+Reads three tree-ish, and output trivial merge results and
 conflicting stages to the standard output.  This is similar to
 what three-way 'git read-tree -m' does, but instead of storing the
 results in the index, the command outputs the entries to the
diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt
index e93fcb4..e453132 100644
--- a/Documentation/git-mv.txt
+++ b/Documentation/git-mv.txt
@@ -13,7 +13,7 @@
 
 DESCRIPTION
 -----------
-This script is used to move or rename a file, directory or symlink.
+Move or rename a file, directory or symlink.
 
  git mv [-v] [-f] [-n] [-k] <source> <destination>
  git mv [-v] [-f] [-n] [-k] <source> ... <destination directory>
@@ -44,6 +44,26 @@
 --verbose::
 	Report the names of files as they are moved.
 
+SUBMODULES
+----------
+Moving a submodule using a gitfile (which means they were cloned
+with a Git version 1.7.8 or newer) will update the gitfile and
+core.worktree setting to make the submodule work in the new location.
+It also will attempt to update the submodule.<name>.path setting in
+the linkgit:gitmodules[5] file and stage that file (unless -n is used).
+
+BUGS
+----
+Each time a superproject update moves a populated submodule (e.g. when
+switching between commits before and after the move) a stale submodule
+checkout will remain in the old location and an empty directory will
+appear in the new location. To populate the submodule again in the new
+location the user will have to run "git submodule update"
+afterwards. Removing the old directory is only safe when it uses a
+gitfile, as otherwise the history of the submodule will be deleted
+too. Both steps will be obsolete when recursive submodule update has
+been implemented.
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index 15b00e0..ca28fb8 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -10,7 +10,7 @@
 --------
 [verse]
 'git name-rev' [--tags] [--refs=<pattern>]
-	       ( --all | --stdin | <committish>... )
+	       ( --all | --stdin | <commit-ish>... )
 
 DESCRIPTION
 -----------
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index 46ef046..84bb0fe 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -375,16 +375,6 @@
 If not set in the environment, the list of notes to copy depends
 on the `notes.rewrite.<command>` and `notes.rewriteRef` settings.
 
-
-Author
-------
-Written by Johannes Schindelin <johannes.schindelin@gmx.de> and
-Johan Herland <johan@herland.net>
-
-Documentation
--------------
-Documentation by Johannes Schindelin and Johan Herland
-
 GIT
 ---
 Part of the linkgit:git[7] suite
diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt
index 8cba16d..6ab5f94 100644
--- a/Documentation/git-p4.txt
+++ b/Documentation/git-p4.txt
@@ -168,7 +168,8 @@
 --git-dir <dir>::
 	Set the 'GIT_DIR' environment variable.  See linkgit:git[1].
 
---verbose, -v::
+-v::
+--verbose::
 	Provide more progress information.
 
 Sync options
@@ -279,7 +280,8 @@
 	Export tags from Git as p4 labels. Tags found in Git are applied
 	to the perforce working directory.
 
---dry-run, -n::
+-n::
+--dry-run::
 	Show just what commits would be submitted to p4; do not change
 	state in Git or p4.
 
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index d94edcd..cdab9ed 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -51,8 +51,7 @@
 	<base-name> to determine the name of the created file.
 	When this option is used, the two files are written in
 	<base-name>-<SHA-1>.{pack,idx} files.  <SHA-1> is a hash
-	of the sorted object names to make the resulting filename
-	based on the pack content, and written to the standard
+	based on the pack content and is written to the standard
 	output of the command.
 
 --stdout::
diff --git a/Documentation/git-peek-remote.txt b/Documentation/git-peek-remote.txt
deleted file mode 100644
index 87ea3fb..0000000
--- a/Documentation/git-peek-remote.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-git-peek-remote(1)
-==================
-
-NAME
-----
-git-peek-remote - List the references in a remote repository
-
-
-SYNOPSIS
---------
-[verse]
-'git peek-remote' [--upload-pack=<git-upload-pack>] [<host>:]<directory>
-
-DESCRIPTION
------------
-This command is deprecated; use 'git ls-remote' instead.
-
-OPTIONS
--------
---upload-pack=<git-upload-pack>::
-	Use this to specify the path to 'git-upload-pack' on the
-	remote side, if it is not found on your $PATH. Some
-	installations of sshd ignores the user's environment
-	setup scripts for login shells (e.g. .bash_profile) and
-	your privately installed git may not be found on the system
-	default $PATH.  Another workaround suggested is to set
-	up your $PATH in ".bashrc", but this flag is for people
-	who do not want to pay the overhead for non-interactive
-	shells, but prefer having a lean .bashrc file (they set most of
-	the things up in .bash_profile).
-
-<host>::
-	A remote host that houses the repository.  When this
-	part is specified, 'git-upload-pack' is invoked via
-	ssh.
-
-<directory>::
-	The repository to sync from.
-
-
-GIT
----
-Part of the linkgit:git[1] suite
diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt
index bf82410..058ac0d 100644
--- a/Documentation/git-prune.txt
+++ b/Documentation/git-prune.txt
@@ -24,6 +24,8 @@
 In addition, it
 prunes the unpacked objects that are also found in packs by
 running 'git prune-packed'.
+It also removes entries from .git/shallow that are not reachable by
+any ref.
 
 Note that unreachable, packed objects will remain.  If this is
 not desired, see linkgit:git-repack[1].
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 6ef8d59..200eb22 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -42,6 +42,8 @@
 	  A---B---C master on origin
 	 /
     D---E---F---G master
+	^
+	origin/master in your repository
 ------------
 
 Then "`git pull`" will fetch and replay the changes from the remote
@@ -51,7 +53,7 @@
 and a log message from the user describing the changes.
 
 ------------
-	  A---B---C remotes/origin/master
+	  A---B---C origin/master
 	 /         \
     D---E---F---G---H master
 ------------
@@ -97,17 +99,23 @@
 Options related to merging
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-include::merge-options.txt[]
-
 :git-pull: 1
 
+include::merge-options.txt[]
+
 -r::
---rebase::
-	Rebase the current branch on top of the upstream branch after
-	fetching.  If there is a remote-tracking branch corresponding to
-	the upstream branch and the upstream branch was rebased since last
-	fetched, the rebase uses that information to avoid rebasing
-	non-local changes.
+--rebase[=false|true|preserve]::
+	When true, rebase the current branch on top of the upstream
+	branch after fetching. If there is a remote-tracking branch
+	corresponding to the upstream branch and the upstream branch
+	was rebased since last fetched, the rebase uses that information
+	to avoid rebasing non-local changes.
++
+When preserve, also rebase the current branch on top of the upstream
+branch, but pass `--preserve-merges` along to `git rebase` so that
+locally created merge commits will not be flattened.
++
+When false, merge the current branch into the upstream branch.
 +
 See `pull.rebase`, `branch.<name>.rebase` and `branch.autosetuprebase` in
 linkgit:git-config[1] if you want to make `git pull` always use
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index f7dfe48..2b7f4f9 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -11,6 +11,7 @@
 [verse]
 'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
 	   [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream]
+	   [--force-with-lease[=<refname>[:<expect>]]]
 	   [--no-verify] [<repository> [<refspec>...]]
 
 DESCRIPTION
@@ -55,8 +56,13 @@
 +
 The <dst> tells which ref on the remote side is updated with this
 push. Arbitrary expressions cannot be used here, an actual ref must
-be named. If `:`<dst> is omitted, the same ref as <src> will be
-updated.
+be named.
+If `git push [<repository>]` without any `<refspec>` argument is set to
+update some ref at the destination with `<src>` with
+`remote.<repository>.push` configuration variable, `:<dst>` part can
+be omitted---such a push will update a ref that `<src>` normally updates
+without any `<refspec>` on the command line.  Otherwise, missing
+`:<dst>` means to update the same ref as the `<src>`.
 +
 The object referenced by <src> is used to update the <dst> reference
 on the remote side.  By default this is only allowed if <dst> is not
@@ -120,7 +126,7 @@
 --follow-tags::
 	Push all the refs that would be pushed without this option,
 	and also push annotated tags in `refs/tags` that are missing
-	from the remote but are pointing at committish that are
+	from the remote but are pointing at commit-ish that are
 	reachable from the refs being pushed.
 
 --receive-pack=<git-receive-pack>::
@@ -130,21 +136,75 @@
 	repository over ssh, and you do not have the program in
 	a directory on the default $PATH.
 
+--[no-]force-with-lease::
+--force-with-lease=<refname>::
+--force-with-lease=<refname>:<expect>::
+	Usually, "git push" refuses to update a remote ref that is
+	not an ancestor of the local ref used to overwrite it.
++
+This option bypasses the check, but instead requires that the
+current value of the ref to be the expected value.  "git push"
+fails otherwise.
++
+Imagine that you have to rebase what you have already published.
+You will have to bypass the "must fast-forward" rule in order to
+replace the history you originally published with the rebased history.
+If somebody else built on top of your original history while you are
+rebasing, the tip of the branch at the remote may advance with her
+commit, and blindly pushing with `--force` will lose her work.
++
+This option allows you to say that you expect the history you are
+updating is what you rebased and want to replace. If the remote ref
+still points at the commit you specified, you can be sure that no
+other people did anything to the ref (it is like taking a "lease" on
+the ref without explicitly locking it, and you update the ref while
+making sure that your earlier "lease" is still valid).
++
+`--force-with-lease` alone, without specifying the details, will protect
+all remote refs that are going to be updated by requiring their
+current value to be the same as the remote-tracking branch we have
+for them, unless specified with a `--force-with-lease=<refname>:<expect>`
+option that explicitly states what the expected value is.
++
+`--force-with-lease=<refname>`, without specifying the expected value, will
+protect the named ref (alone), if it is going to be updated, by
+requiring its current value to be the same as the remote-tracking
+branch we have for it.
++
+`--force-with-lease=<refname>:<expect>` will protect the named ref (alone),
+if it is going to be updated, by requiring its current value to be
+the same as the specified value <expect> (which is allowed to be
+different from the remote-tracking branch we have for the refname,
+or we do not even have to have such a remote-tracking branch when
+this form is used).
++
+Note that all forms other than `--force-with-lease=<refname>:<expect>`
+that specifies the expected current value of the ref explicitly are
+still experimental and their semantics may change as we gain experience
+with this feature.
++
+"--no-force-with-lease" will cancel all the previous --force-with-lease on the
+command line.
+
 -f::
 --force::
 	Usually, the command refuses to update a remote ref that is
 	not an ancestor of the local ref used to overwrite it.
-	This flag disables the check.  This can cause the
-	remote repository to lose commits; use it with care.
-	Note that `--force` applies to all the refs that are pushed,
-	hence using it with `push.default` set to `matching` or with
-	multiple push destinations configured with `remote.*.push`
-	may overwrite refs other than the current branch (including
-	local refs that are strictly behind their remote counterpart).
-	To force a push to only one branch, use a `+` in front of the
-	refspec to push	(e.g `git push origin +master` to force a push
-	to the `master`	branch). See the `<refspec>...` section above
-	for details.
+	Also, when `--force-with-lease` option is used, the command refuses
+	to update a remote ref whose current value does not match
+	what is expected.
++
+This flag disables these checks, and can cause the remote repository
+to lose commits; use it with care.
++
+Note that `--force` applies to all the refs that are pushed, hence
+using it with `push.default` set to `matching` or with multiple push
+destinations configured with `remote.*.push` may overwrite refs
+other than the current branch (including local refs that are
+strictly behind their remote counterpart).  To force a push to only
+one branch, use a `+` in front of the refspec to push (e.g `git push
+origin +master` to force a push to the `master` branch). See the
+`<refspec>...` section above for details.
 
 --repo=<repository>::
 	This option is only relevant if no <repository> argument is
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 6b2e1c8..2889be6 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -322,7 +322,17 @@
 reverting a topic branch merge, as this option recreates the topic branch with
 fresh commits so it can be remerged successfully without needing to "revert
 the reversion" (see the
-link:howto/revert-a-faulty-merge.txt[revert-a-faulty-merge How-To] for details).
+link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for details).
+
+--fork-point::
+--no-fork-point::
+	Use 'git merge-base --fork-point' to find a better common ancestor
+	between `upstream` and `branch` when calculating which commits have
+	have been introduced by `branch` (see linkgit:git-merge-base[1]).
++
+If no non-option arguments are given on the command line, then the default is
+`--fork-point @{u}` otherwise the `upstream` argument is interpreted literally
+unless the `--fork-point` option is specified.
 
 --ignore-whitespace::
 --whitespace=<option>::
@@ -416,7 +426,7 @@
 You may find this helpful after reverting a topic branch merge, as this option
 recreates the topic branch with fresh commits so it can be remerged
 successfully without needing to "revert the reversion" (see the
-link:howto/revert-a-faulty-merge.txt[revert-a-faulty-merge How-To] for details).
+link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for details).
 
 include::merge-strategies.txt[]
 
diff --git a/Documentation/git-remote-ext.txt b/Documentation/git-remote-ext.txt
index 8cfc748..cd0bb77 100644
--- a/Documentation/git-remote-ext.txt
+++ b/Documentation/git-remote-ext.txt
@@ -116,11 +116,6 @@
 	determined by the helper using environment variables (see
 	above).
 
-Documentation
---------------
-Documentation by Ilari Liusvaara, Jonathan Nieder and the Git list
-<git@vger.kernel.org>
-
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-remote-fd.txt b/Documentation/git-remote-fd.txt
index 933c2ad..bcd3766 100644
--- a/Documentation/git-remote-fd.txt
+++ b/Documentation/git-remote-fd.txt
@@ -50,10 +50,6 @@
 `git push fd::7,8/bar master`::
 	Same as above.
 
-Documentation
---------------
-Documentation by Ilari Liusvaara and the Git list <git@vger.kernel.org>
-
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 9c3e3bf..2507c8b 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -13,7 +13,7 @@
 'git remote add' [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=<fetch|push>] <name> <url>
 'git remote rename' <old> <new>
 'git remote remove' <name>
-'git remote set-head' <name> (-a | -d | <branch>)
+'git remote set-head' <name> (-a | --auto | -d | --delete | <branch>)
 'git remote set-branches' [--add] <name> <branch>...
 'git remote set-url' [--push] <name> <newurl> [<oldurl>]
 'git remote set-url --add' [--push] <name> <newurl>
@@ -101,9 +101,9 @@
 `master`, then `origin` may be specified wherever you would normally
 specify `origin/master`.
 +
-With `-d`, the symbolic ref `refs/remotes/<name>/HEAD` is deleted.
+With `-d` or `--delete`, the symbolic ref `refs/remotes/<name>/HEAD` is deleted.
 +
-With `-a`, the remote is queried to determine its `HEAD`, then the
+With `-a` or `--auto`, the remote is queried to determine its `HEAD`, then the
 symbolic-ref `refs/remotes/<name>/HEAD` is set to the same branch. e.g., if the remote
 `HEAD` is pointed at `next`, "`git remote set-head origin -a`" will set
 the symbolic-ref `refs/remotes/origin/HEAD` to `refs/remotes/origin/next`. This will
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 4c1aff6..509cf73 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -14,7 +14,7 @@
 DESCRIPTION
 -----------
 
-This script is used to combine all objects that do not currently
+This command is used to combine all objects that do not currently
 reside in a "pack", into a pack.  It can also be used to re-organize
 existing packs into a single, more efficient pack.
 
diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt
index e0b4057..0a02f70 100644
--- a/Documentation/git-replace.txt
+++ b/Documentation/git-replace.txt
@@ -10,7 +10,7 @@
 [verse]
 'git replace' [-f] <object> <replacement>
 'git replace' -d <object>...
-'git replace' -l [<pattern>]
+'git replace' [--format=<format>] [-l [<pattern>]]
 
 DESCRIPTION
 -----------
@@ -20,8 +20,14 @@
 replaced. The content of the 'replace' reference is the SHA-1 of the
 replacement object.
 
+The replaced object and the replacement object must be of the same type.
+This restriction can be bypassed using `-f`.
+
 Unless `-f` is given, the 'replace' reference must not yet exist.
 
+There is no other restriction on the replaced and replacement objects.
+Merge commits can be replaced by non-merge commits and vice versa.
+
 Replacement references will be used by default by all Git commands
 except those doing reachability traversal (prune, pack transfer and
 fsck).
@@ -49,18 +55,51 @@
 OPTIONS
 -------
 -f::
+--force::
 	If an existing replace ref for the same object exists, it will
 	be overwritten (instead of failing).
 
 -d::
+--delete::
 	Delete existing replace refs for the given objects.
 
 -l <pattern>::
+--list <pattern>::
 	List replace refs for objects that match the given pattern (or
 	all if no pattern is given).
 	Typing "git replace" without arguments, also lists all replace
 	refs.
 
+--format=<format>::
+	When listing, use the specified <format>, which can be one of
+	'short', 'medium' and 'long'. When omitted, the format
+	defaults to 'short'.
+
+FORMATS
+-------
+
+The following format are available:
+
+* 'short':
+	<replaced sha1>
+* 'medium':
+	<replaced sha1> -> <replacement sha1>
+* 'long':
+	<replaced sha1> (<replaced type>) -> <replacement sha1> (<replacement type>)
+
+CREATING REPLACEMENT OBJECTS
+----------------------------
+
+linkgit:git-filter-branch[1], linkgit:git-hash-object[1] and
+linkgit:git-rebase[1], among other git commands, can be used to create
+replacement objects from existing objects.
+
+If you want to replace many blobs, trees or commits that are part of a
+string of commits, you may just want to create a replacement string of
+commits and then only replace the commit at the tip of the target
+string of commits with the commit at the tip of the replacement string
+of commits.
+
 BUGS
 ----
 Comparing blobs or trees that have been replaced with those that
@@ -69,12 +108,13 @@
 commit instead of the replaced commit.
 
 There may be other problems when using 'git rev-list' related to
-pending objects. And of course things may break if an object of one
-type is replaced by an object of another type (for example a blob
-replaced by a commit).
+pending objects.
 
 SEE ALSO
 --------
+linkgit:git-hash-object[1]
+linkgit:git-filter-branch[1]
+linkgit:git-rebase[1]
 linkgit:git-tag[1]
 linkgit:git-branch[1]
 linkgit:git[1]
diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt
deleted file mode 100644
index 9ec115b..0000000
--- a/Documentation/git-repo-config.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-git-repo-config(1)
-==================
-
-NAME
-----
-git-repo-config - Get and set repository or global options
-
-
-SYNOPSIS
---------
-[verse]
-'git repo-config' ...
-
-
-DESCRIPTION
------------
-
-This is a synonym for linkgit:git-config[1].  Please refer to the
-documentation of that command.
-
-GIT
----
-Part of the linkgit:git[1] suite
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 2b126c0..0d2cdcd 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -24,9 +24,23 @@
 
 OPTIONS
 -------
+
+Operation Modes
+~~~~~~~~~~~~~~~
+
+Each of these options must appear first on the command line.
+
 --parseopt::
 	Use 'git rev-parse' in option parsing mode (see PARSEOPT section below).
 
+--sq-quote::
+	Use 'git rev-parse' in shell quoting mode (see SQ-QUOTE
+	section below). In contrast to the `--sq` option below, this
+	mode does only quoting. Nothing else is done to command input.
+
+Options for --parseopt
+~~~~~~~~~~~~~~~~~~~~~~
+
 --keep-dashdash::
 	Only meaningful in `--parseopt` mode. Tells the option parser to echo
 	out the first `--` met instead of skipping it.
@@ -36,10 +50,12 @@
 	the first non-option argument.  This can be used to parse sub-commands
 	that take options themselves.
 
---sq-quote::
-	Use 'git rev-parse' in shell quoting mode (see SQ-QUOTE
-	section below). In contrast to the `--sq` option below, this
-	mode does only quoting. Nothing else is done to command input.
+--stuck-long::
+	Only meaningful in `--parseopt` mode. Output the options in their
+	long form if available, and with their arguments stuck.
+
+Options for Filtering
+~~~~~~~~~~~~~~~~~~~~~
 
 --revs-only::
 	Do not output flags and parameters not meant for
@@ -55,6 +71,9 @@
 --no-flags::
 	Do not output flag parameters.
 
+Options for Output
+~~~~~~~~~~~~~~~~~~
+
 --default <arg>::
 	If there is no parameter given by the user, use `<arg>`
 	instead.
@@ -110,6 +129,17 @@
 	strip '{caret}' prefix from the object names that already have
 	one.
 
+--abbrev-ref[=(strict|loose)]::
+	A non-ambiguous short name of the objects name.
+	The option core.warnAmbiguousRefs is used to select the strict
+	abbreviation mode.
+
+--short::
+--short=number::
+	Instead of outputting the full SHA-1 values of object names try to
+	abbreviate them to a shorter unique name. When no length is specified
+	7 is used. The minimum length is 4.
+
 --symbolic::
 	Usually the object names are output in SHA-1 form (with
 	possible '{caret}' prefix); this option makes them output in a
@@ -123,16 +153,8 @@
 	unfortunately named tag "master"), and show them as full
 	refnames (e.g. "refs/heads/master").
 
---abbrev-ref[=(strict|loose)]::
-	A non-ambiguous short name of the objects name.
-	The option core.warnAmbiguousRefs is used to select the strict
-	abbreviation mode.
-
---disambiguate=<prefix>::
-	Show every object whose name begins with the given prefix.
-	The <prefix> must be at least 4 hexadecimal digits long to
-	avoid listing each and every object in the repository by
-	mistake.
+Options for Objects
+~~~~~~~~~~~~~~~~~~~
 
 --all::
 	Show all refs found in `refs/`.
@@ -155,18 +177,34 @@
 	character (`?`, `*`, or `[`), it is turned into a prefix
 	match by appending `/*`.
 
---show-toplevel::
-	Show the absolute path of the top-level directory.
+--exclude=<glob-pattern>::
+	Do not include refs matching '<glob-pattern>' that the next `--all`,
+	`--branches`, `--tags`, `--remotes`, or `--glob` would otherwise
+	consider. Repetitions of this option accumulate exclusion patterns
+	up to the next `--all`, `--branches`, `--tags`, `--remotes`, or
+	`--glob` option (other options or arguments do not clear
+	accumlated patterns).
++
+The patterns given should not begin with `refs/heads`, `refs/tags`, or
+`refs/remotes` when applied to `--branches`, `--tags`, or `--remotes`,
+respectively, and they must begin with `refs/` when applied to `--glob`
+or `--all`. If a trailing '/{asterisk}' is intended, it must be given
+explicitly.
 
---show-prefix::
-	When the command is invoked from a subdirectory, show the
-	path of the current directory relative to the top-level
-	directory.
+--disambiguate=<prefix>::
+	Show every object whose name begins with the given prefix.
+	The <prefix> must be at least 4 hexadecimal digits long to
+	avoid listing each and every object in the repository by
+	mistake.
 
---show-cdup::
-	When the command is invoked from a subdirectory, show the
-	path of the top-level directory relative to the current
-	directory (typically a sequence of "../", or an empty string).
+Options for Files
+~~~~~~~~~~~~~~~~~
+
+--local-env-vars::
+	List the GIT_* environment variables that are local to the
+	repository (e.g. GIT_DIR or GIT_WORK_TREE, but not GIT_EDITOR).
+	Only the names of the variables are listed, not their value,
+	even if they are set.
 
 --git-dir::
 	Show `$GIT_DIR` if defined. Otherwise show the path to
@@ -188,17 +226,27 @@
 --is-bare-repository::
 	When the repository is bare print "true", otherwise "false".
 
---local-env-vars::
-	List the GIT_* environment variables that are local to the
-	repository (e.g. GIT_DIR or GIT_WORK_TREE, but not GIT_EDITOR).
-	Only the names of the variables are listed, not their value,
-	even if they are set.
+--resolve-git-dir <path>::
+	Check if <path> is a valid repository or a gitfile that
+	points at a valid repository, and print the location of the
+	repository.  If <path> is a gitfile then the resolved path
+	to the real repository is printed.
 
---short::
---short=number::
-	Instead of outputting the full SHA-1 values of object names try to
-	abbreviate them to a shorter unique name. When no length is specified
-	7 is used. The minimum length is 4.
+--show-cdup::
+	When the command is invoked from a subdirectory, show the
+	path of the top-level directory relative to the current
+	directory (typically a sequence of "../", or an empty string).
+
+--show-prefix::
+	When the command is invoked from a subdirectory, show the
+	path of the current directory relative to the top-level
+	directory.
+
+--show-toplevel::
+	Show the absolute path of the top-level directory.
+
+Other Options
+~~~~~~~~~~~~~
 
 --since=datestring::
 --after=datestring::
@@ -213,12 +261,6 @@
 <args>...::
 	Flags and parameters to be parsed.
 
---resolve-git-dir <path>::
-	Check if <path> is a valid repository or a gitfile that
-	points at a valid repository, and print the location of the
-	repository.  If <path> is a gitfile then the resolved path
-	to the real repository is printed.
-
 
 include::revisions.txt[]
 
@@ -261,7 +303,9 @@
 	`<flags>` are of `*`, `=`, `?` or `!`.
 	* Use `=` if the option takes an argument.
 
-	* Use `?` to mean that the option is optional (though its use is discouraged).
+	* Use `?` to mean that the option takes an optional argument. You
+	  probably want to use the `--stuck-long` mode to be able to
+	  unambiguously parse the optional argument.
 
 	* Use `*` to mean that this option should not be listed in the usage
 	  generated for the `-h` argument. It's shown for `--help-all` as
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index f79c9d8..2de67a5 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -59,7 +59,7 @@
 changes introduced by commits that are not ancestors of the previously
 reverted merge.  This may or may not be what you want.
 +
-See the link:howto/revert-a-faulty-merge.txt[revert-a-faulty-merge How-To] for
+See the link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for
 more details.
 
 --no-edit::
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index 1d876c2..f1efc11 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -134,14 +134,16 @@
 git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
 ----------------
 
-Submodules
-~~~~~~~~~~
+SUBMODULES
+----------
 Only submodules using a gitfile (which means they were cloned
 with a Git version 1.7.8 or newer) will be removed from the work
 tree, as their repository lives inside the .git directory of the
 superproject. If a submodule (or one of those nested inside it)
 still uses a .git directory, `git rm` will fail - no matter if forced
-or not - to protect the submodule's history.
+or not - to protect the submodule's history. If it exists the
+submodule.<name> section in the linkgit:gitmodules[5] file will also
+be removed and that file will be staged (unless --cached or -n are used).
 
 A submodule is considered up-to-date when the HEAD is the same as
 recorded in the index, no tracked files are modified and no untracked
@@ -168,6 +170,15 @@
 	(i.e. you are listing the files explicitly), it
 	does not remove `subdir/git-foo.sh`.
 
+BUGS
+----
+Each time a superproject update removes a populated submodule
+(e.g. when switching between commits before and after the removal) a
+stale submodule checkout will remain in the old location. Removing the
+old directory is only safe when it uses a gitfile, as otherwise the
+history of the submodule will be deleted too. This step will be
+obsolete when recursive submodule update has been implemented.
+
 SEE ALSO
 --------
 linkgit:git-add[1]
diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt
index 5d709d0..4f67c4c 100644
--- a/Documentation/git-sh-setup.txt
+++ b/Documentation/git-sh-setup.txt
@@ -41,9 +41,11 @@
 	die with the usage message.
 
 set_reflog_action::
-	set the message that will be recorded to describe the
-	end-user action in the reflog, when the script updates a
-	ref.
+	Set GIT_REFLOG_ACTION environment to a given string (typically
+	the name of the program) unless it is already set.  Whenever
+	the script runs a `git` command that updates refs, a reflog
+	entry is created using the value of this string to leave the
+	record of what command updated the ref.
 
 git_editor::
 	runs an editor of user's choice (GIT_EDITOR, core.editor, VISUAL or
diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt
index b0a309b..ffd1b03 100644
--- a/Documentation/git-show-ref.txt
+++ b/Documentation/git-show-ref.txt
@@ -175,6 +175,7 @@
 
 SEE ALSO
 --------
+linkgit:git-for-each-ref[1],
 linkgit:git-ls-remote[1],
 linkgit:git-update-ref[1],
 linkgit:gitrepository-layout[5]
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 9046df9..a4acaa0 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -210,7 +210,13 @@
 If `status.submodulesummary` is set to a non zero number or true (identical
 to -1 or an unlimited number), the submodule summary will be enabled for
 the long format and a summary of commits for modified submodules will be
-shown (see --summary-limit option of linkgit:git-submodule[1]).
+shown (see --summary-limit option of linkgit:git-submodule[1]). Please note
+that the summary output from the status command will be suppressed for all
+submodules when `diff.ignoreSubmodules` is set to 'all' or only for those
+submodules where `submodule.<name>.ignore=all`. To also view the summary for
+ignored submodules you can either use the --ignore-submodules=dirty command
+line option or the 'git submodule summary' command, which shows a similar
+output but does not honor these settings.
 
 SEE ALSO
 --------
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 4dd3bcb..30c5ee2 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -79,8 +79,21 @@
 	trailing slash, so be sure you include one in the
 	argument if that is what you want.  If --branches/-b is
 	specified, the prefix must include a trailing slash.
-	Setting a prefix is useful if you wish to track multiple
-	projects that share a common repository.
+	Setting a prefix (with a trailing slash) is strongly
+	encouraged in any case, as your SVN-tracking refs will
+	then be located at "refs/remotes/$prefix/*", which is
+	compatible with Git's own remote-tracking ref layout
+	(refs/remotes/$remote/*). Setting a prefix is also useful
+	if you wish to track multiple projects that share a common
+	repository.
++
+NOTE: In Git v2.0, the default prefix will CHANGE from "" (no prefix)
+to "origin/". This is done to put SVN-tracking refs at
+"refs/remotes/origin/*" instead of "refs/remotes/*", and make them
+more compatible with how Git's own remote-tracking refs are organized
+(i.e. refs/remotes/$remote/*). You can enjoy the same benefits today,
+by using the --prefix option.
+
 --ignore-paths=<regex>;;
 	When passed to 'init' or 'clone' this regular expression will
 	be preserved as a config key.  See 'fetch' for a description
@@ -104,19 +117,22 @@
 'fetch'::
 	Fetch unfetched revisions from the Subversion remote we are
 	tracking.  The name of the [svn-remote "..."] section in the
-	.git/config file may be specified as an optional command-line
-	argument.
+	$GIT_DIR/config file may be specified as an optional
+	command-line argument.
++
+This automatically updates the rev_map if needed (see
+'$GIT_DIR/svn/\*\*/.rev_map.*' in the FILES section below for details).
 
 --localtime;;
-	Store Git commit times in the local timezone instead of UTC.  This
+	Store Git commit times in the local time zone instead of UTC.  This
 	makes 'git log' (even without --date=local) show the same times
-	that `svn log` would in the local timezone.
+	that `svn log` would in the local time zone.
 +
 This doesn't interfere with interoperating with the Subversion
 repository you cloned from, but if you wish for your local Git
 repository to be able to interoperate with someone else's local Git
 repository, either don't use this option or you should both use it in
-the same local timezone.
+the same local time zone.
 
 --parent;;
 	Fetch only from the SVN parent of the current HEAD.
@@ -159,11 +175,11 @@
 	precedence over '--include-paths'.
 
 --log-window-size=<n>;;
-    Fetch <n> log entries per request when scanning Subversion history.
-    The default is 100. For very large Subversion repositories, larger
-    values may be needed for 'clone'/'fetch' to complete in reasonable
-    time. But overly large values may lead to higher memory usage and
-    request timeouts.
+	Fetch <n> log entries per request when scanning Subversion history.
+	The default is 100. For very large Subversion repositories, larger
+	values may be needed for 'clone'/'fetch' to complete in reasonable
+	time. But overly large values may lead to higher memory usage and
+	request timeouts.
 
 'clone'::
 	Runs 'init' and 'fetch'.  It will automatically create a
@@ -201,6 +217,9 @@
 +
 Like 'git rebase'; this requires that the working tree be clean
 and have no uncommitted changes.
++
+This automatically updates the rev_map if needed (see
+'$GIT_DIR/svn/\*\*/.rev_map.*' in the FILES section below for details).
 
 -l;;
 --local;;
@@ -256,7 +275,7 @@
 	For each patch, one may answer "yes" (accept this patch), "no" (discard this
 	patch), "all" (accept all patches), or "quit".
 	+
-       'git svn dcommit' returns immediately if answer is "no" or "quit", without
+	'git svn dcommit' returns immediately if answer is "no" or "quit", without
 	committing anything to SVN.
 
 'branch'::
@@ -347,12 +366,12 @@
 Any other arguments are passed directly to 'git log'
 
 'blame'::
-       Show what revision and author last modified each line of a file. The
-       output of this mode is format-compatible with the output of
-       `svn blame' by default. Like the SVN blame command,
-       local uncommitted changes in the working tree are ignored;
-       the version of the file in the HEAD revision is annotated. Unknown
-       arguments are passed directly to 'git blame'.
+	Show what revision and author last modified each line of a file. The
+	output of this mode is format-compatible with the output of
+	`svn blame' by default. Like the SVN blame command,
+	local uncommitted changes in the working tree are ignored;
+	the version of the file in the HEAD revision is annotated. Unknown
+	arguments are passed directly to 'git blame'.
 +
 --git-format;;
 	Produce output in the same format as 'git blame', but with
@@ -435,8 +454,8 @@
 	specific revision.
 
 'gc'::
-	Compress $GIT_DIR/svn/<refname>/unhandled.log files in .git/svn
-	and remove $GIT_DIR/svn/<refname>index files in .git/svn.
+	Compress $GIT_DIR/svn/<refname>/unhandled.log files and remove
+	$GIT_DIR/svn/<refname>/index files.
 
 'reset'::
 	Undoes the effects of 'fetch' back to the specified revision.
@@ -449,9 +468,10 @@
 	file cannot be ignored forever (with --ignore-paths) the only
 	way to repair the repo is to use 'reset'.
 +
-Only the rev_map and refs/remotes/git-svn are changed.  Follow 'reset'
-with a 'fetch' and then 'git reset' or 'git rebase' to move local
-branches onto the new tree.
+Only the rev_map and refs/remotes/git-svn are changed (see
+'$GIT_DIR/svn/\*\*/.rev_map.*' in the FILES section below for details).
+Follow 'reset' with a 'fetch' and then 'git reset' or 'git rebase' to
+move local branches onto the new tree.
 
 -r <n>;;
 --revision=<n>;;
@@ -684,7 +704,7 @@
 +
 This option can only be used for one-shot imports as 'git svn'
 will not be able to fetch again without metadata. Additionally,
-if you lose your .git/svn/**/.rev_map.* files, 'git svn' will not
+if you lose your '$GIT_DIR/svn/\*\*/.rev_map.*' files, 'git svn' will not
 be able to rebuild them.
 +
 The 'git svn log' command will not work on repositories using
@@ -804,16 +824,16 @@
 
 ------------------------------------------------------------------------
 # Clone a repo with standard SVN directory layout (like git clone):
-	git svn clone http://svn.example.com/project --stdlayout
+	git svn clone http://svn.example.com/project --stdlayout --prefix svn/
 # Or, if the repo uses a non-standard directory layout:
-	git svn clone http://svn.example.com/project -T tr -b branch -t tag
+	git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/
 # View all branches and tags you have cloned:
 	git branch -r
 # Create a new branch in SVN
-    git svn branch waldo
+	git svn branch waldo
 # Reset your master to trunk (or any other branch, replacing 'trunk'
 # with the appropriate name):
-	git reset --hard remotes/trunk
+	git reset --hard svn/trunk
 # You may only dcommit to one branch/tag/trunk at a time.  The usage
 # of dcommit/rebase/show-ignore should be the same as above.
 ------------------------------------------------------------------------
@@ -827,7 +847,7 @@
 
 ------------------------------------------------------------------------
 # Do the initial import on a server
-	ssh server "cd /pub && git svn clone http://svn.example.com/project
+	ssh server "cd /pub && git svn clone http://svn.example.com/project [options...]"
 # Clone locally - make sure the refs/remotes/ space matches the server
 	mkdir project
 	cd project
@@ -840,8 +860,9 @@
 	git config --remove-section remote.origin
 # Create a local branch from one of the branches just fetched
 	git checkout -b master FETCH_HEAD
-# Initialize 'git svn' locally (be sure to use the same URL and -T/-b/-t options as were used on server)
-	git svn init http://svn.example.com/project
+# Initialize 'git svn' locally (be sure to use the same URL and
+# --stdlayout/-T/-b/-t/--prefix options as were used on server)
+	git svn init http://svn.example.com/project [options...]
 # Pull the latest changes from Subversion
 	git svn rebase
 ------------------------------------------------------------------------
@@ -973,12 +994,22 @@
 branches and tags is required, the options '--trunk' / '--branches' /
 '--tags' must be used.
 
+When using the options for describing the repository layout (--trunk,
+--tags, --branches, --stdlayout), please also specify the --prefix
+option (e.g. '--prefix=origin/') to cause your SVN-tracking refs to be
+placed at refs/remotes/origin/* rather than the default refs/remotes/*.
+The former is more compatible with the layout of Git's "regular"
+remote-tracking refs (refs/remotes/$remote/*), and may potentially
+prevent similarly named SVN branches and Git remotes from clobbering
+each other. In Git v2.0 the default prefix used (i.e. when no --prefix
+is given) will change from "" (no prefix) to "origin/".
+
 When using multiple --branches or --tags, 'git svn' does not automatically
 handle name collisions (for example, if two branches from different paths have
 the same name, or if a branch and a tag have the same name).  In these cases,
 use 'init' to set up your Git repository then, before your first 'fetch', edit
-the .git/config file so that the branches and tags are associated with
-different name spaces.  For example:
+the $GIT_DIR/config file so that the branches and tags are associated
+with different name spaces.  For example:
 
 	branches = stable/*:refs/remotes/svn/stable/*
 	branches = debug/*:refs/remotes/svn/debug/*
@@ -1006,7 +1037,7 @@
 -------------
 
 'git svn' stores [svn-remote] configuration information in the
-repository .git/config file.  It is similar the core Git
+repository $GIT_DIR/config file.  It is similar the core Git
 [remote] sections except 'fetch' keys do not accept glob
 arguments; but they are instead handled by the 'branches'
 and 'tags' keys.  Since some SVN repositories are oddly
@@ -1035,8 +1066,8 @@
 [svn-remote "huge-project"]
 	url = http://server.org/svn
 	fetch = trunk/src:refs/remotes/trunk
-	branches = branches/{red,green}/src:refs/remotes/branches/*
-	tags = tags/{1.0,2.0}/src:refs/remotes/tags/*
+	branches = branches/{red,green}/src:refs/remotes/project-a/branches/*
+	tags = tags/{1.0,2.0}/src:refs/remotes/project-a/tags/*
 ------------------------------------------------------------------------
 
 Multiple fetch, branches, and tags keys are supported:
@@ -1060,8 +1091,21 @@
 
 Note that git-svn keeps track of the highest revision in which a branch
 or tag has appeared. If the subset of branches or tags is changed after
-fetching, then .git/svn/.metadata must be manually edited to remove (or
-reset) branches-maxRev and/or tags-maxRev as appropriate.
+fetching, then $GIT_DIR/svn/.metadata must be manually edited to remove
+(or reset) branches-maxRev and/or tags-maxRev as appropriate.
+
+FILES
+-----
+$GIT_DIR/svn/\*\*/.rev_map.*::
+	Mapping between Subversion revision numbers and Git commit
+	names.  In a repository where the noMetadata option is not set,
+	this can be rebuilt from the git-svn-id: lines that are at the
+	end of every commit (see the 'svn.noMetadata' section above for
+	details).
++
+'git svn fetch' and 'git svn rebase' automatically update the rev_map
+if it is missing or not up to date.  'git svn reset' automatically
+rewinds it.
 
 SEE ALSO
 --------
diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt
deleted file mode 100644
index f7362dc..0000000
--- a/Documentation/git-tar-tree.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-git-tar-tree(1)
-===============
-
-NAME
-----
-git-tar-tree - Create a tar archive of the files in the named tree object
-
-
-SYNOPSIS
---------
-[verse]
-'git tar-tree' [--remote=<repo>] <tree-ish> [ <base> ]
-
-DESCRIPTION
------------
-THIS COMMAND IS DEPRECATED.  Use 'git archive' with `--format=tar`
-option instead (and move the <base> argument to `--prefix=base/`).
-
-Creates a tar archive containing the tree structure for the named tree.
-When <base> is specified it is added as a leading path to the files in the
-generated tar archive.
-
-'git tar-tree' behaves differently when given a tree ID versus when given
-a commit ID or tag ID.  In the first case the current time is used as
-modification time of each file in the archive.  In the latter case the
-commit time as recorded in the referenced commit object is used instead.
-Additionally the commit ID is stored in a global extended pax header.
-It can be extracted using 'git get-tar-commit-id'.
-
-OPTIONS
--------
-
-<tree-ish>::
-	The tree or commit to produce tar archive for.  If it is
-	the object name of a commit object.
-
-<base>::
-	Leading path to the files in the resulting tar archive.
-
---remote=<repo>::
-	Instead of making a tar archive from local repository,
-	retrieve a tar archive from a remote repository.
-
-CONFIGURATION
--------------
-
-tar.umask::
-	This variable can be used to restrict the permission bits of
-	tar archive entries.  The default is 0002, which turns off the
-	world write bit.  The special value "user" indicates that the
-	archiving user's umask will be used instead.  See umask(2) for
-	details.
-
-EXAMPLES
---------
-`git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)`::
-
-	Create a tar archive that contains the contents of the
-	latest commit on the current branch, and extracts it in
-	`/var/tmp/junk` directory.
-
-`git tar-tree v1.4.0 git-1.4.0 | gzip >git-1.4.0.tar.gz`::
-
-	Create a tarball for v1.4.0 release.
-
-`git tar-tree v1.4.0^{tree} git-1.4.0 | gzip >git-1.4.0.tar.gz`::
-
-	Create a tarball for v1.4.0 release, but without a
-	global extended pax header.
-
-`git tar-tree --remote=example.com:git.git v1.4.0 >git-1.4.0.tar`::
-
-	Get a tarball v1.4.0 from example.com.
-
-`git tar-tree HEAD:Documentation/ git-docs > git-1.4.0-docs.tar`::
-
-	Put everything in the current head's Documentation/ directory
-	into 'git-1.4.0-docs.tar', with the prefix 'git-docs/'.
-
-GIT
----
-Part of the linkgit:git[1] suite
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index 0df13ff..0a0a551 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -8,7 +8,7 @@
 SYNOPSIS
 --------
 [verse]
-'git update-ref' [-m <reason>] (-d <ref> [<oldvalue>] | [--no-deref] <ref> <newvalue> [<oldvalue>])
+'git update-ref' [-m <reason>] (-d <ref> [<oldvalue>] | [--no-deref] <ref> <newvalue> [<oldvalue>] | --stdin [-z])
 
 DESCRIPTION
 -----------
@@ -58,6 +58,58 @@
 With `-d` flag, it deletes the named <ref> after verifying it
 still contains <oldvalue>.
 
+With `--stdin`, update-ref reads instructions from standard input and
+performs all modifications together.  Specify commands of the form:
+
+	update SP <ref> SP <newvalue> [SP <oldvalue>] LF
+	create SP <ref> SP <newvalue> LF
+	delete SP <ref> [SP <oldvalue>] LF
+	verify SP <ref> [SP <oldvalue>] LF
+	option SP <opt> LF
+
+Quote fields containing whitespace as if they were strings in C source
+code.  Alternatively, use `-z` to specify commands without quoting:
+
+	update SP <ref> NUL <newvalue> NUL [<oldvalue>] NUL
+	create SP <ref> NUL <newvalue> NUL
+	delete SP <ref> NUL [<oldvalue>] NUL
+	verify SP <ref> NUL [<oldvalue>] NUL
+	option SP <opt> NUL
+
+Lines of any other format or a repeated <ref> produce an error.
+Command meanings are:
+
+update::
+	Set <ref> to <newvalue> after verifying <oldvalue>, if given.
+	Specify a zero <newvalue> to ensure the ref does not exist
+	after the update and/or a zero <oldvalue> to make sure the
+	ref does not exist before the update.
+
+create::
+	Create <ref> with <newvalue> after verifying it does not
+	exist.  The given <newvalue> may not be zero.
+
+delete::
+	Delete <ref> after verifying it exists with <oldvalue>, if
+	given.  If given, <oldvalue> may not be zero.
+
+verify::
+	Verify <ref> against <oldvalue> but do not change it.  If
+	<oldvalue> zero or missing, the ref must not exist.
+
+option::
+	Modify behavior of the next command naming a <ref>.
+	The only valid option is `no-deref` to avoid dereferencing
+	a symbolic ref.
+
+Use 40 "0" or the empty string to specify a zero value, except that
+with `-z` an empty <oldvalue> is considered missing.
+
+If all <ref>s can be locked with matching <oldvalue>s
+simultaneously, all modifications are performed.  Otherwise, no
+modifications are performed.  Note that while each individual
+<ref> is updated or deleted atomically, a concurrent reader may
+still see a subset of the modifications.
 
 Logging Updates
 ---------------
diff --git a/Documentation/git-web--browse.txt b/Documentation/git-web--browse.txt
index 5aec4ec..2de575f 100644
--- a/Documentation/git-web--browse.txt
+++ b/Documentation/git-web--browse.txt
@@ -35,6 +35,7 @@
 * open (this is the default under Mac OS X GUI)
 * start (this is the default under MinGW)
 * cygstart (this is the default under Cygwin)
+* xdg-open
 
 Custom commands may also be specified.
 
diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt
index c600b61..8b63ceb 100644
--- a/Documentation/git-whatchanged.txt
+++ b/Documentation/git-whatchanged.txt
@@ -13,43 +13,17 @@
 
 DESCRIPTION
 -----------
-Shows commit logs and diff output each commit introduces.  The
-command internally invokes 'git rev-list' piped to
-'git diff-tree', and takes command line options for both of
-these commands.
 
-This manual page describes only the most frequently used options.
+Shows commit logs and diff output each commit introduces.
 
+New users are encouraged to use linkgit:git-log[1] instead.  The
+`whatchanged` command is essentially the same as linkgit:git-log[1]
+but defaults to show the raw format diff output and to skip merges.
 
-OPTIONS
--------
--p::
-	Show textual diffs, instead of the Git internal diff
-	output format that is useful only to tell the changed
-	paths and their nature of changes.
+The command is kept primarily for historical reasons; fingers of
+many people who learned Git long before `git log` was invented by
+reading Linux kernel mailing list are trained to type it.
 
--<n>::
-	Limit output to <n> commits.
-
-<since>..<until>::
-	Limit output to between the two named commits (bottom
-	exclusive, top inclusive).
-
--r::
-	Show Git internal diff output, but for the whole tree,
-	not just the top level.
-
--m::
-	By default, differences for merge commits are not shown.
-	With this flag, show differences to that commit from all
-	of its parents.
-+
-However, it is not very useful in general, although it
-*is* useful on a file-by-file basis.
-
-include::pretty-options.txt[]
-
-include::pretty-formats.txt[]
 
 Examples
 --------
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 8f7a460..274d816 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -9,7 +9,7 @@
 SYNOPSIS
 --------
 [verse]
-'git' [--version] [--help] [-c <name>=<value>]
+'git' [--version] [--help] [-C <path>] [-c <name>=<value>]
     [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
     [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
     [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
@@ -43,6 +43,14 @@
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
+* link:v1.8.5.3/git.html[documentation for release 1.8.5.3]
+
+* release notes for
+  link:RelNotes/1.8.5.3.txt[1.8.5.3],
+  link:RelNotes/1.8.5.2.txt[1.8.5.2],
+  link:RelNotes/1.8.5.1.txt[1.8.5.1],
+  link:RelNotes/1.8.5.txt[1.8.5].
+
 * link:v1.8.4.5/git.html[documentation for release 1.8.4.5]
 
 * release notes for
@@ -400,6 +408,20 @@
 because `git --help ...` is converted internally into `git
 help ...`.
 
+-C <path>::
+	Run as if git was started in '<path>' instead of the current working
+	directory.  When multiple `-C` options are given, each subsequent
+	non-absolute `-C <path>` is interpreted relative to the preceding `-C
+	<path>`.
++
+This option affects options that expect path name like `--git-dir` and
+`--work-tree` in that their interpretations of the path names would be
+made relative to the working directory caused by the `-C` option. For
+example the following invocations are equivalent:
+
+    git --git-dir=a.git --work-tree=b -C c status
+    git --git-dir=c/a.git --work-tree=c/b status
+
 -c <name>=<value>::
 	Pass a configuration parameter to the command. The value
 	given will override values from configuration files.
@@ -462,10 +484,25 @@
 	linkgit:git-replace[1] for more information.
 
 --literal-pathspecs::
-	Treat pathspecs literally, rather than as glob patterns. This is
-	equivalent to setting the `GIT_LITERAL_PATHSPECS` environment
+	Treat pathspecs literally (i.e. no globbing, no pathspec magic).
+	This is equivalent to setting the `GIT_LITERAL_PATHSPECS` environment
 	variable to `1`.
 
+--glob-pathspecs::
+	Add "glob" magic to all pathspec. This is equivalent to setting
+	the `GIT_GLOB_PATHSPECS` environment variable to `1`. Disabling
+	globbing on individual pathspecs can be done using pathspec
+	magic ":(literal)"
+
+--noglob-pathspecs::
+	Add "literal" magic to all pathspec. This is equivalent to setting
+	the `GIT_NOGLOB_PATHSPECS` environment variable to `1`. Enabling
+	globbing on individual pathspecs can be done using pathspec
+	magic ":(glob)"
+
+--icase-pathspecs::
+	Add "icase" magic to all pathspec. This is equivalent to setting
+	the `GIT_ICASE_PATHSPECS` environment variable to `1`.
 
 GIT COMMANDS
 ------------
@@ -771,6 +808,15 @@
 +
 For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1
 parameter, <path>.
++
+For each path 'GIT_EXTERNAL_DIFF' is called, two environment variables,
+'GIT_DIFF_PATH_COUNTER' and 'GIT_DIFF_PATH_TOTAL' are set.
+
+'GIT_DIFF_PATH_COUNTER'::
+	A 1-based counter incremented by one for every path.
+
+'GIT_DIFF_PATH_TOTAL'::
+	The total number of paths.
 
 other
 ~~~~~
@@ -828,7 +874,7 @@
 'GIT_FLUSH'::
 	If this environment variable is set to "1", then commands such
 	as 'git blame' (in incremental mode), 'git rev-list', 'git log',
-	'git check-attr', 'git check-ignore', and 'git whatchanged' will
+	'git check-attr' and 'git check-ignore' will
 	force a flush of the output stream after each record have been
 	flushed. If this
 	variable is set to "0", the output of these commands will be done
@@ -872,6 +918,28 @@
 	literal paths to Git (e.g., paths previously given to you by
 	`git ls-tree`, `--raw` diff output, etc).
 
+GIT_GLOB_PATHSPECS::
+	Setting this variable to `1` will cause Git to treat all
+	pathspecs as glob patterns (aka "glob" magic).
+
+GIT_NOGLOB_PATHSPECS::
+	Setting this variable to `1` will cause Git to treat all
+	pathspecs as literal (aka "literal" magic).
+
+GIT_ICASE_PATHSPECS::
+	Setting this variable to `1` will cause Git to treat all
+	pathspecs as case-insensitive.
+
+'GIT_REFLOG_ACTION'::
+	When a ref is updated, reflog entries are created to keep
+	track of the reason why the ref was updated (which is
+	typically the name of the high-level command that updated
+	the ref), in addition to the old and new values of the ref.
+	A scripted Porcelain command can use set_reflog_action
+	helper function in `git-sh-setup` to set its name to this
+	variable when it is invoked as the top level command by the
+	end user, to be recorded in the body of the reflog.
+
 
 Discussion[[Discussion]]
 ------------------------
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index b322a26..643c1ba 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -930,9 +930,12 @@
 DEFINING MACRO ATTRIBUTES
 -------------------------
 
-Custom macro attributes can be defined only in the `.gitattributes`
-file at the toplevel (i.e. not in any subdirectory).  The built-in
-macro attribute "binary" is equivalent to:
+Custom macro attributes can be defined only in top-level gitattributes
+files (`$GIT_DIR/info/attributes`, the `.gitattributes` file at the
+top level of the working tree, or the global or system-wide
+gitattributes files), not in `.gitattributes` files in working tree
+subdirectories.  The built-in macro attribute "binary" is equivalent
+to:
 
 ------------
 [attr]binary -diff -merge -text
diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt
index 9ac5088..3f33ca5 100644
--- a/Documentation/gitcli.txt
+++ b/Documentation/gitcli.txt
@@ -59,6 +59,10 @@
 see `hello.c` in your working tree with the former, but with the latter
 you will.
 
+ * Just as the filesystem '.' (period) refers to the current directory,
+   using a '.' as a repository name in Git (a dot-repository) is a relative
+   path and means your current repository.
+
 Here are the rules regarding the "flags" that you should follow when you are
 scripting Git:
 
@@ -68,23 +72,23 @@
  * splitting short options to separate words (prefer `git foo -a -b`
    to `git foo -ab`, the latter may not even work).
 
- * when a command line option takes an argument, use the 'sticked' form.  In
+ * when a command line option takes an argument, use the 'stuck' form.  In
    other words, write `git foo -oArg` instead of `git foo -o Arg` for short
    options, and `git foo --long-opt=Arg` instead of `git foo --long-opt Arg`
    for long options.  An option that takes optional option-argument must be
-   written in the 'sticked' form.
+   written in the 'stuck' form.
 
  * when you give a revision parameter to a command, make sure the parameter is
    not ambiguous with a name of a file in the work tree.  E.g. do not write
    `git log -1 HEAD` but write `git log -1 HEAD --`; the former will not work
    if you happen to have a file called `HEAD` in the work tree.
 
- * many commands allow a long option "--option" to be abbreviated
+ * many commands allow a long option `--option` to be abbreviated
    only to their unique prefix (e.g. if there is no other option
-   whose name begins with "opt", you may be able to spell "--opt" to
-   invoke the "--option" flag), but you should fully spell them out
+   whose name begins with `opt`, you may be able to spell `--opt` to
+   invoke the `--option` flag), but you should fully spell them out
    when writing your scripts; later versions of Git may introduce a
-   new option whose name shares the same prefix, e.g. "--optimize",
+   new option whose name shares the same prefix, e.g. `--optimize`,
    to make a short prefix that used to be unique no longer unique.
 
 
@@ -106,7 +110,7 @@
 +
 ---------------------------------------------
 $ git describe -h
-usage: git describe [options] <committish>*
+usage: git describe [options] <commit-ish>*
    or: git describe [options] --dirty
 
     --contains            find the tag that comes after the commit
@@ -145,7 +149,7 @@
 with a caution.  For example, `git commit --amen` behaves as if you
 typed `git commit --amend`, but that is true only until a later version
 of Git introduces another option that shares the same prefix,
-e.g `git commit --amenity" option.
+e.g. `git commit --amenity` option.
 
 
 Separating argument from the option
@@ -161,7 +165,7 @@
 ----------------------------
 
 However, this is *NOT* allowed for switches with an optional value, where the
-'sticked' form must be used:
+'stuck' form must be used:
 ----------------------------
 $ git describe --abbrev HEAD     # correct
 $ git describe --abbrev=10 HEAD  # correct
diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt
index f538a87..058a352 100644
--- a/Documentation/gitcore-tutorial.txt
+++ b/Documentation/gitcore-tutorial.txt
@@ -534,42 +534,9 @@
 
 In fact, together with the 'git rev-list' program (which generates a
 list of revisions), 'git diff-tree' ends up being a veritable fount of
-changes. A trivial (but very useful) script called 'git whatchanged' is
-included with Git which does exactly this, and shows a log of recent
-activities.
-
-To see the whole history of our pitiful little git-tutorial project, you
-can do
-
-----------------
-$ git log
-----------------
-
-which shows just the log messages, or if we want to see the log together
-with the associated patches use the more complex (and much more
-powerful)
-
-----------------
-$ git whatchanged -p
-----------------
-
-and you will see exactly what has changed in the repository over its
-short history.
-
-[NOTE]
-When using the above two commands, the initial commit will be shown.
-If this is a problem because it is huge, you can hide it by setting
-the log.showroot configuration variable to false. Having this, you
-can still show it for each command just adding the `--root` option,
-which is a flag for 'git diff-tree' accepted by both commands.
-
-With that, you should now be having some inkling of what Git does, and
-can explore on your own.
-
-[NOTE]
-Most likely, you are not directly using the core
-Git Plumbing commands, but using Porcelain such as 'git add', `git-rm'
-and `git-commit'.
+changes.  You can emulate `git log`, `git log -p`, etc. with a trivial
+script that pipes the output of `git rev-list` to `git diff-tree --stdin`,
+which was exactly how early versions of `git log` were implemented.
 
 
 Tagging a version
diff --git a/Documentation/gitcvs-migration.txt b/Documentation/gitcvs-migration.txt
index 5ab5b07..5ea94cb 100644
--- a/Documentation/gitcvs-migration.txt
+++ b/Documentation/gitcvs-migration.txt
@@ -157,7 +157,7 @@
 repository to a mailing list.  See linkgit:githooks[5].
 
 You can enforce finer grained permissions using update hooks.  See
-link:howto/update-hook-example.txt[Controlling access to branches using
+link:howto/update-hook-example.html[Controlling access to branches using
 update hooks].
 
 Providing CVS Access to a Git Repository
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index f971960..b08d34d 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -7,7 +7,7 @@
 
 SYNOPSIS
 --------
-$GIT_DIR/info/exclude, .gitignore
+$HOME/.config/git/ignore, $GIT_DIR/info/exclude, .gitignore
 
 DESCRIPTION
 -----------
@@ -79,8 +79,10 @@
 
  - An optional prefix "`!`" which negates the pattern; any
    matching file excluded by a previous pattern will become
-   included again.  If a negated pattern matches, this will
-   override lower precedence patterns sources.
+   included again. It is not possible to re-include a file if a parent
+   directory of that file is excluded. Git doesn't list excluded
+   directories for performance reasons, so any patterns on contained
+   files have no effect, no matter where they are defined.
    Put a backslash ("`\`") in front of the first "`!`" for patterns
    that begin with a literal "`!`", for example, "`\!important!.txt`".
 
@@ -182,6 +184,19 @@
 The second .gitignore prevents Git from ignoring
 `arch/foo/kernel/vmlinux.lds.S`.
 
+Example to exclude everything except a specific directory `foo/bar`
+(note the `/*` - without the slash, the wildcard would also exclude
+everything within `foo/bar`):
+
+--------------------------------------------------------------
+    $ cat .gitignore
+    # exclude everything except directory foo/bar
+    /*
+    !/foo
+    /foo/*
+    !/foo/bar
+--------------------------------------------------------------
+
 SEE ALSO
 --------
 linkgit:git-rm[1],
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index c17e760..1e9e38a 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -8,7 +8,7 @@
 SYNOPSIS
 --------
 [verse]
-'gitk' [<option>...] [<revs>] [--] [<path>...]
+'gitk' [<options>] [<revision range>] [\--] [<path>...]
 
 DESCRIPTION
 -----------
@@ -16,21 +16,38 @@
 visualizing the commit graph, showing information related to each commit, and
 the files in the trees of each revision.
 
-Historically, gitk was the first repository browser. It's written in tcl/tk
-and started off in a separate repository but was later merged into the main
-Git repository.
-
 OPTIONS
 -------
-To control which revisions to show, the command takes options applicable to
-the 'git rev-list' command (see linkgit:git-rev-list[1]).
-This manual page describes only the most
-frequently used options.
 
--n <number>::
---max-count=<number>::
+To control which revisions to show, gitk supports most options
+applicable to the 'git rev-list' command.  It also supports a few
+options applicable to the 'git diff-*' commands to control how the
+changes each commit introduces are shown.  Finally, it supports some
+gitk-specific options.
 
-	Limits the number of commits to show.
+gitk generally only understands options with arguments in the
+'sticked' form (see linkgit:gitcli[7]) due to limitations in the
+command line parser.
+
+rev-list options and arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This manual page describes only the most frequently used options.  See
+linkgit:git-rev-list[1] for a complete list.
+
+--all::
+
+	Show all refs (branches, tags, etc.).
+
+--branches[=<pattern>]::
+--tags[=<pattern>]::
+--remotes[=<pattern>]::
+
+	Pretend as if all the branches (tags, remote branches, resp.)
+	are listed on the command line as '<commit>'. If '<pattern>'
+	is given, limit refs to ones matching given shell glob. If
+	pattern lacks '?', '{asterisk}', or '[', '/{asterisk}' at the
+	end is implied.
 
 --since=<date>::
 
@@ -40,9 +57,9 @@
 
 	Show commits older than a specific date.
 
---all::
+--date-order::
 
-	Show all branches.
+	Sort commits by date when possible.
 
 --merge::
 
@@ -51,19 +68,53 @@
 	that modify the conflicted files and do not exist on all the heads
 	being merged.
 
---argscmd=<command>::
-	Command to be run each time gitk has to determine the list of
-	<revs> to show.  The command is expected to print on its standard
-	output a list of additional revs to be shown, one per line.
-	Use this instead of explicitly specifying <revs> if the set of
-	commits to show may vary between refreshes.
+--left-right::
 
---select-commit=<ref>::
+	Mark which side of a symmetric diff a commit is reachable
+	from.  Commits from the left side are prefixed with a `<`
+	symbol and those from the right with a `>` symbol.
 
-	Automatically select the specified commit after loading the graph.
-	Default behavior is equivalent to specifying '--select-commit=HEAD'.
+--full-history::
 
-<revs>::
+	When filtering history with '<path>...', does not prune some
+	history.  (See "History simplification" in linkgit:git-log[1]
+	for a more detailed explanation.)
+
+--simplify-merges::
+
+	Additional option to '--full-history' to remove some needless
+	merges from the resulting history, as there are no selected
+	commits contributing to this merge.  (See "History
+	simplification" in linkgit:git-log[1] for a more detailed
+	explanation.)
+
+--ancestry-path::
+
+	When given a range of commits to display
+	(e.g. 'commit1..commit2' or 'commit2 {caret}commit1'), only
+	display commits that exist directly on the ancestry chain
+	between the 'commit1' and 'commit2', i.e. commits that are
+	both descendants of 'commit1', and ancestors of 'commit2'.
+	(See "History simplification" in linkgit:git-log[1] for a more
+	detailed explanation.)
+
+-L<start>,<end>:<file>::
+-L:<regex>:<file>::
+
+	Trace the evolution of the line range given by "<start>,<end>"
+	(or the funcname regex <regex>) within the <file>.  You may
+	not give any pathspec limiters.  This is currently limited to
+	a walk starting from a single revision, i.e., you may only
+	give zero or one positive revision arguments.
+	You can specify this option more than once.
++
+*Note:* gitk (unlike linkgit:git-log[1]) currently only understands
+this option if you specify it "glued together" with its argument.  Do
+*not* put a space after `-L`.
++
+include::line-range-format.txt[]
+
+<revision range>::
 
 	Limit the revisions to show. This can be either a single revision
 	meaning show from the given revision and back, or it can be a range in
@@ -78,6 +129,23 @@
 	avoid ambiguity with respect to revision names use "--" to separate the paths
 	from any preceding options.
 
+gitk-specific options
+~~~~~~~~~~~~~~~~~~~~~
+
+--argscmd=<command>::
+
+	Command to be run each time gitk has to determine the revision
+	range to show.  The command is expected to print on its
+	standard output a list of additional revisions to be shown,
+	one per line.  Use this instead of explicitly specifying a
+	'<revision range>' if the set of commits to show may vary
+	between refreshes.
+
+--select-commit=<ref>::
+
+	Select the specified commit after loading the graph.
+	Default behavior is equivalent to specifying '--select-commit=HEAD'.
+
 Examples
 --------
 gitk v2.6.12.. include/scsi drivers/scsi::
@@ -101,6 +169,13 @@
 Gitk creates the .gitk file in your $HOME directory to store preferences
 such as display options, font, and colors.
 
+History
+-------
+Gitk was the first graphical repository browser. It's written in
+tcl/tk and started off in a separate repository but was later merged
+into the main Git repository.
+
+
 SEE ALSO
 --------
 'qgit(1)'::
diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
index 6a1ca4a..347a9f7 100644
--- a/Documentation/gitmodules.txt
+++ b/Documentation/gitmodules.txt
@@ -35,6 +35,8 @@
 	linkgit:git-clone[1] or (if it begins with ./ or ../) a location
 	relative to the superproject's origin repository.
 
+In addition, there are a number of optional keys:
+
 submodule.<name>.update::
 	Defines what to do when the submodule is updated by the superproject.
 	If 'checkout' (the default), the new commit specified in the
@@ -75,7 +77,8 @@
 	the superproject, the setting there will override the one found in
 	.gitmodules.
 	Both settings can be overridden on the command line by using the
-	"--ignore-submodule" option.
+	"--ignore-submodule" option. The 'git submodule' commands are not
+	affected by this setting.
 
 
 EXAMPLES
diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt
index 0827f69..c2908db 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -120,6 +120,11 @@
 When choosing between 'push' and 'export', Git prefers 'push'.
 Other frontends may have some other order of preference.
 
+'no-private-update'::
+	When using the 'refspec' capability, git normally updates the
+	private ref on successful push. This update is disabled when
+	the remote-helper declares the capability 'no-private-update'.
+
 
 Capabilities for Fetching
 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -143,6 +148,10 @@
 +
 Supported commands: 'list', 'import'.
 
+'check-connectivity'::
+	Can guarantee that when a clone is requested, the received
+	pack is self contained and is connected.
+
 If a helper advertises 'connect', Git will use it if possible and
 fall back to another capability if the helper requests so when
 connecting (see the 'connect' command under COMMANDS).
@@ -176,6 +185,12 @@
 advertised with this capability must cover all refs reported by
 the list command.  If no 'refspec' capability is advertised,
 there is an implied `refspec *:*`.
++
+When writing remote-helpers for decentralized version control
+systems, it is advised to keep a local copy of the repository to
+interact with, and to let the private namespace refs point to this
+local repository, while the refs/remotes namespace is used to track
+the remote repository.
 
 'bidi-import'::
 	This modifies the 'import' capability.
@@ -270,6 +285,9 @@
 GIT_DIR/objects/pack which is keeping a pack until refs can be
 suitably updated.
 +
+If option 'check-connectivity' is requested, the helper must output
+'connectivity-ok' if the clone is self-contained and connected.
++
 Supported if the helper has the "fetch" capability.
 
 'push' +<src>:<dst>::
@@ -416,6 +434,16 @@
 	must not rely on this option being set before
 	connect request occurs.
 
+'option check-connectivity' \{'true'|'false'\}::
+	Request the helper to check connectivity of a clone.
+
+'option cloning \{'true'|'false'\}::
+	Notify the helper this is a clone request (i.e. the current
+	repository is guaranteed empty).
+
+'option update-shallow \{'true'|'false'\}::
+	Allow to extend .git/shallow if the new refs require it.
+
 SEE ALSO
 --------
 linkgit:git-remote[1]
diff --git a/Documentation/gitweb.conf.txt b/Documentation/gitweb.conf.txt
index 305db63..db4154f 100644
--- a/Documentation/gitweb.conf.txt
+++ b/Documentation/gitweb.conf.txt
@@ -822,18 +822,18 @@
 Project specific override is not supported.
 
 javascript-timezone::
-	Enable and configure the ability to change a common timezone for dates
+	Enable and configure the ability to change a common time zone for dates
 	in gitweb output via JavaScript.  Dates in gitweb output include
 	authordate and committerdate in "commit", "commitdiff" and "log"
 	views, and taggerdate in "tag" view.  Enabled by default.
 +
-The value is a list of three values: a default timezone (for if the client
-hasn't selected some other timezone and saved it in a cookie), a name of cookie
-where to store selected timezone, and a CSS class used to mark up
+The value is a list of three values: a default time zone (for if the client
+hasn't selected some other time zone and saved it in a cookie), a name of cookie
+where to store selected time zone, and a CSS class used to mark up
 dates for manipulation.  If you want to turn this feature off, set "default"
 to empty list: `[]`.
 +
-Typical gitweb config files will only change starting (default) timezone,
+Typical gitweb config files will only change starting (default) time zone,
 and leave other elements at their default values:
 +
 ---------------------------------------------------------------------------
@@ -843,12 +843,49 @@
 The example configuration presented here is guaranteed to be backwards
 and forward compatible.
 +
-Timezone values can be "local" (for local timezone that browser uses), "utc"
+Time zone values can be "local" (for local time zone that browser uses), "utc"
 (what gitweb uses when JavaScript or this feature is disabled), or numerical
-timezones in the form of "+/-HHMM", such as "+0200".
+time zones in the form of "+/-HHMM", such as "+0200".
 +
 Project specific override is not supported.
 
+extra-branch-refs::
+	List of additional directories under "refs" which are going to
+	be used as branch refs. For example if you have a gerrit setup
+	where all branches under refs/heads/ are official,
+	push-after-review ones and branches under refs/sandbox/,
+	refs/wip and refs/other are user ones where permissions are
+	much wider, then you might want to set this variable as
+	follows:
++
+--------------------------------------------------------------------------------
+$feature{'extra-branch-refs'}{'default'} =
+	['sandbox', 'wip', 'other'];
+--------------------------------------------------------------------------------
++
+This feature can be configured on per-repository basis after setting
+$feature{'extra-branch-refs'}{'override'} to true, via repository's
+`gitweb.extraBranchRefs` configuration variable, which contains a
+space separated list of refs. An example:
++
+--------------------------------------------------------------------------------
+[gitweb]
+	extraBranchRefs = sandbox wip other
+--------------------------------------------------------------------------------
++
+The gitweb.extraBranchRefs is actually a multi-valued configuration
+variable, so following example is also correct and the result is the
+same as of the snippet above:
++
+--------------------------------------------------------------------------------
+[gitweb]
+	extraBranchRefs = sandbox
+	extraBranchRefs = wip other
+--------------------------------------------------------------------------------
++
+It is an error to specify a ref that does not pass "git check-ref-format"
+scrutiny. Duplicated values are filtered.
+
 
 EXAMPLES
 --------
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index dba5062..378306f 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -82,6 +82,18 @@
 	to the top <<def_directory,directory>> of the stored
 	revision.
 
+[[def_commit-ish]]commit-ish (also committish)::
+	A <<def_commit_object,commit object>> or an
+	<<def_object,object>> that can be recursively dereferenced to
+	a commit object.
+	The following are all commit-ishes:
+	a commit object,
+	a <<def_tag_object,tag object>> that points to a commit
+	object,
+	a tag object that points to a tag object that points to a
+	commit object,
+	etc.
+
 [[def_core_git]]core Git::
 	Fundamental data structures and utilities of Git. Exposes only limited
 	source code management tools.
@@ -311,24 +323,68 @@
 A pathspec that begins with a colon `:` has special meaning.  In the
 short form, the leading colon `:` is followed by zero or more "magic
 signature" letters (which optionally is terminated by another colon `:`),
-and the remainder is the pattern to match against the path. The optional
-colon that terminates the "magic signature" can be omitted if the pattern
-begins with a character that cannot be a "magic signature" and is not a
-colon.
+and the remainder is the pattern to match against the path.
+The "magic signature" consists of ASCII symbols that are neither
+alphanumeric, glob, regex special charaters nor colon.
+The optional colon that terminates the "magic signature" can be
+omitted if the pattern begins with a character that does not belong to
+"magic signature" symbol set and is not a colon.
 +
 In the long form, the leading colon `:` is followed by a open
 parenthesis `(`, a comma-separated list of zero or more "magic words",
 and a close parentheses `)`, and the remainder is the pattern to match
 against the path.
 +
-The "magic signature" consists of an ASCII symbol that is not
-alphanumeric. Currently only the slash `/` is recognized as a
-"magic signature": it makes the pattern match from the root of
-the working tree, even when you are running the command from
-inside a subdirectory.
-+
 A pathspec with only a colon means "there is no pathspec". This form
 should not be combined with other pathspec.
++
+--
+top;;
+	The magic word `top` (magic signature: `/`) makes the pattern
+	match from the root of the working tree, even when you are
+	running the command from inside a subdirectory.
+
+literal;;
+	Wildcards in the pattern such as `*` or `?` are treated
+	as literal characters.
+
+icase;;
+	Case insensitive match.
+
+glob;;
+	Git treats the pattern as a shell glob suitable for
+	consumption by fnmatch(3) with the FNM_PATHNAME flag:
+	wildcards in the pattern will not match a / in the pathname.
+	For example, "Documentation/{asterisk}.html" matches
+	"Documentation/git.html" but not "Documentation/ppc/ppc.html"
+	or "tools/perf/Documentation/perf.html".
++
+Two consecutive asterisks ("`**`") in patterns matched against
+full pathname may have special meaning:
+
+ - A leading "`**`" followed by a slash means match in all
+   directories. For example, "`**/foo`" matches file or directory
+   "`foo`" anywhere, the same as pattern "`foo`". "`**/foo/bar`"
+   matches file or directory "`bar`" anywhere that is directly
+   under directory "`foo`".
+
+ - A trailing "`/**`" matches everything inside. For example,
+   "`abc/**`" matches all files inside directory "abc", relative
+   to the location of the `.gitignore` file, with infinite depth.
+
+ - A slash followed by two consecutive asterisks then a slash
+   matches zero or more directories. For example, "`a/**/b`"
+   matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on.
+
+ - Other consecutive asterisks are considered invalid.
++
+Glob magic is incompatible with literal magic.
+
+exclude;;
+	After a path matches any non-exclude pathspec, it will be run
+	through all exclude pathspec (magic signature: `!`). If it
+	matches, the path is ignored.
+--
 
 [[def_parent]]parent::
 	A <<def_commit_object,commit object>> contains a (possibly empty) list
@@ -383,10 +439,20 @@
 	to the result.
 
 [[def_ref]]ref::
-	A 40-byte hex representation of a <<def_SHA1,SHA-1>> or a name that
-	denotes a particular <<def_object,object>>. They may be stored in
-	a file under `$GIT_DIR/refs/` directory, or
-	in the `$GIT_DIR/packed-refs` file.
+	A name that begins with `refs/` (e.g. `refs/heads/master`)
+	that points to an <<def_object_name,object name>> or another
+	ref (the latter is called a <<def_symref,symbolic ref>>).
+	For convenience, a ref can sometimes be abbreviated when used
+	as an argument to a Git command; see linkgit:gitrevisions[7]
+	for details.
+	Refs are stored in the <<def_repository,repository>>.
++
+The ref namespace is hierarchical.
+Different subhierarchies are used for different purposes (e.g. the
+`refs/heads/` hierarchy is used to represent local branches).
++
+There are a few special-purpose refs that do not begin with `refs/`.
+The most notable example is `HEAD`.
 
 [[def_reflog]]reflog::
 	A reflog shows the local "history" of a ref.  In other words,
@@ -486,10 +552,19 @@
 	with refs to the associated blob and/or tree objects. A
 	<<def_tree,tree>> is equivalent to a <<def_directory,directory>>.
 
-[[def_tree-ish]]tree-ish::
-	A <<def_ref,ref>> pointing to either a <<def_commit_object,commit
-	object>>, a <<def_tree_object,tree object>>, or a <<def_tag_object,tag
-	object>> pointing to a tag or commit or tree object.
+[[def_tree-ish]]tree-ish (also treeish)::
+	A <<def_tree_object,tree object>> or an <<def_object,object>>
+	that can be recursively dereferenced to a tree object.
+	Dereferencing a <<def_commit_object,commit object>> yields the
+	tree object corresponding to the <<def_revision,revision>>'s
+	top <<def_directory,directory>>.
+	The following are all tree-ishes:
+	a <<def_commit-ish,commit-ish>>,
+	a tree object,
+	a <<def_tag_object,tag object>> that points to a tree object,
+	a tag object that points to a tag object that points to a tree
+	object,
+	etc.
 
 [[def_unmerged_index]]unmerged index::
 	An <<def_index,index>> which contains unmerged
diff --git a/Documentation/howto/recover-corrupted-object-harder.txt b/Documentation/howto/recover-corrupted-object-harder.txt
new file mode 100644
index 0000000..6f33dac
--- /dev/null
+++ b/Documentation/howto/recover-corrupted-object-harder.txt
@@ -0,0 +1,242 @@
+Date: Wed, 16 Oct 2013 04:34:01 -0400
+From: Jeff King <peff@peff.net>
+Subject: pack corruption post-mortem
+Abstract: Recovering a corrupted object when no good copy is available.
+Content-type: text/asciidoc
+
+How to recover an object from scratch
+=====================================
+
+I was recently presented with a repository with a corrupted packfile,
+and was asked if the data was recoverable. This post-mortem describes
+the steps I took to investigate and fix the problem. I thought others
+might find the process interesting, and it might help somebody in the
+same situation.
+
+********************************
+Note: In this case, no good copy of the repository was available. For
+the much easier case where you can get the corrupted object from
+elsewhere, see link:recover-corrupted-blob-object.html[this howto].
+********************************
+
+I started with an fsck, which found a problem with exactly one object
+(I've used $pack and $obj below to keep the output readable, and also
+because I'll refer to them later):
+
+-----------
+    $ git fsck
+    error: $pack SHA1 checksum mismatch
+    error: index CRC mismatch for object $obj from $pack at offset 51653873
+    error: inflate: data stream error (incorrect data check)
+    error: cannot unpack $obj from $pack at offset 51653873
+-----------
+
+The pack checksum failing means a byte is munged somewhere, and it is
+presumably in the object mentioned (since both the index checksum and
+zlib were failing).
+
+Reading the zlib source code, I found that "incorrect data check" means
+that the adler-32 checksum at the end of the zlib data did not match the
+inflated data. So stepping the data through zlib would not help, as it
+did not fail until the very end, when we realize the crc does not match.
+The problematic bytes could be anywhere in the object data.
+
+The first thing I did was pull the broken data out of the packfile. I
+needed to know how big the object was, which I found out with:
+
+------------
+    $ git show-index <$idx | cut -d' ' -f1 | sort -n | grep -A1 51653873
+    51653873
+    51664736
+------------
+
+Show-index gives us the list of objects and their offsets. We throw away
+everything but the offsets, and then sort them so that our interesting
+offset (which we got from the fsck output above) is followed immediately
+by the offset of the next object. Now we know that the object data is
+10863 bytes long, and we can grab it with:
+
+------------
+  dd if=$pack of=object bs=1 skip=51653873 count=10863
+------------
+
+I inspected a hexdump of the data, looking for any obvious bogosity
+(e.g., a 4K run of zeroes would be a good sign of filesystem
+corruption). But everything looked pretty reasonable.
+
+Note that the "object" file isn't fit for feeding straight to zlib; it
+has the git packed object header, which is variable-length. We want to
+strip that off so we can start playing with the zlib data directly. You
+can either work your way through it manually (the format is described in
+link:../technical/pack-format.html[Documentation/technical/pack-format.txt]),
+or you can walk through it in a debugger. I did the latter, creating a
+valid pack like:
+
+------------
+    # pack magic and version
+    printf 'PACK\0\0\0\2' >tmp.pack
+    # pack has one object
+    printf '\0\0\0\1' >>tmp.pack
+    # now add our object data
+    cat object >>tmp.pack
+    # and then append the pack trailer
+    /path/to/git.git/test-sha1 -b <tmp.pack >trailer
+    cat trailer >>tmp.pack
+------------
+
+and then running "git index-pack tmp.pack" in the debugger (stop at
+unpack_raw_entry). Doing this, I found that there were 3 bytes of header
+(and the header itself had a sane type and size). So I stripped those
+off with:
+
+------------
+    dd if=object of=zlib bs=1 skip=3
+------------
+
+I ran the result through zlib's inflate using a custom C program. And
+while it did report the error, I did get the right number of output
+bytes (i.e., it matched git's size header that we decoded above). But
+feeding the result back to "git hash-object" didn't produce the same
+sha1. So there were some wrong bytes, but I didn't know which. The file
+happened to be C source code, so I hoped I could notice something
+obviously wrong with it, but I didn't. I even got it to compile!
+
+I also tried comparing it to other versions of the same path in the
+repository, hoping that there would be some part of the diff that didn't
+make sense. Unfortunately, this happened to be the only revision of this
+particular file in the repository, so I had nothing to compare against.
+
+So I took a different approach. Working under the guess that the
+corruption was limited to a single byte, I wrote a program to munge each
+byte individually, and try inflating the result. Since the object was
+only 10K compressed, that worked out to about 2.5M attempts, which took
+a few minutes.
+
+The program I used is here:
+
+----------------------------------------------
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <zlib.h>
+
+static int try_zlib(unsigned char *buf, int len)
+{
+	/* make this absurdly large so we don't have to loop */
+	static unsigned char out[1024*1024];
+	z_stream z;
+	int ret;
+
+	memset(&z, 0, sizeof(z));
+	inflateInit(&z);
+
+	z.next_in = buf;
+	z.avail_in = len;
+	z.next_out = out;
+	z.avail_out = sizeof(out);
+
+	ret = inflate(&z, 0);
+	inflateEnd(&z);
+	return ret >= 0;
+}
+
+/* eye candy */
+static int counter = 0;
+static void progress(int sig)
+{
+	fprintf(stderr, "\r%d", counter);
+	alarm(1);
+}
+
+int main(void)
+{
+	/* oversized so we can read the whole buffer in */
+	unsigned char buf[1024*1024];
+	int len;
+	unsigned i, j;
+
+	signal(SIGALRM, progress);
+	alarm(1);
+
+	len = read(0, buf, sizeof(buf));
+	for (i = 0; i < len; i++) {
+		unsigned char c = buf[i];
+		for (j = 0; j <= 0xff; j++) {
+			buf[i] = j;
+
+			counter++;
+			if (try_zlib(buf, len))
+				printf("i=%d, j=%x\n", i, j);
+		}
+		buf[i] = c;
+	}
+
+	alarm(0);
+	fprintf(stderr, "\n");
+	return 0;
+}
+----------------------------------------------
+
+I compiled and ran with:
+
+-------
+  gcc -Wall -Werror -O3 munge.c -o munge -lz
+  ./munge <zlib
+-------
+
+
+There were a few false positives early on (if you write "no data" in the
+zlib header, zlib thinks it's just fine :) ). But I got a hit about
+halfway through:
+
+-------
+  i=5642, j=c7
+-------
+
+I let it run to completion, and got a few more hits at the end (where it
+was munging the crc to match our broken data). So there was a good
+chance this middle hit was the source of the problem.
+
+I confirmed by tweaking the byte in a hex editor, zlib inflating the
+result (no errors!), and then piping the output into "git hash-object",
+which reported the sha1 of the broken object. Success!
+
+I fixed the packfile itself with:
+
+-------
+  chmod +w $pack
+  printf '\xc7' | dd of=$pack bs=1 seek=51659518 conv=notrunc
+  chmod -w $pack
+-------
+
+The `\xc7` comes from the replacement byte our "munge" program found.
+The offset 51659518 is derived by taking the original object offset
+(51653873), adding the replacement offset found by "munge" (5642), and
+then adding back in the 3 bytes of git header we stripped.
+
+After that, "git fsck" ran clean.
+
+As for the corruption itself, I was lucky that it was indeed a single
+byte. In fact, it turned out to be a single bit. The byte 0xc7 was
+corrupted to 0xc5. So presumably it was caused by faulty hardware, or a
+cosmic ray.
+
+And the aborted attempt to look at the inflated output to see what was
+wrong? I could have looked forever and never found it. Here's the diff
+between what the corrupted data inflates to, versus the real data:
+
+--------------
+  -       cp = strtok (arg, "+");
+  +       cp = strtok (arg, ".");
+--------------
+
+It tweaked one byte and still ended up as valid, readable C that just
+happened to do something totally different! One takeaway is that on a
+less unlucky day, looking at the zlib output might have actually been
+helpful, as most random changes would actually break the C code.
+
+But more importantly, git's hashing and checksumming noticed a problem
+that easily could have gone undetected in another system. The result
+still compiled, but would have caused an interesting bug (that would
+have been blamed on some random commit).
diff --git a/Documentation/howto/revert-a-faulty-merge.txt b/Documentation/howto/revert-a-faulty-merge.txt
index 075418e..acf3e47 100644
--- a/Documentation/howto/revert-a-faulty-merge.txt
+++ b/Documentation/howto/revert-a-faulty-merge.txt
@@ -37,7 +37,7 @@
 merge that brings these premature changes into the mainline, x are changes
 unrelated to what the side branch did and already made on the mainline,
 and W is the "revert of the merge M" (doesn't W look M upside down?).
-IOW, "diff W^..W" is similar to "diff -R M^..M".
+IOW, `"diff W^..W"` is similar to `"diff -R M^..M"`.
 
 Such a "revert" of a merge can be made with:
 
@@ -121,9 +121,9 @@
        ---A---B                   A'--B'--C'
 
 where Y is the revert of W, A' and B' are rerolled A and B, and there may
-also be a further fix-up C' on the side branch.  "diff Y^..Y" is similar
-to "diff -R W^..W" (which in turn means it is similar to "diff M^..M"),
-and "diff A'^..C'" by definition would be similar but different from that,
+also be a further fix-up C' on the side branch.  `"diff Y^..Y"` is similar
+to `"diff -R W^..W"` (which in turn means it is similar to `"diff M^..M"`),
+and `"diff A'^..C'"` by definition would be similar but different from that,
 because it is a rerolled series of the earlier change.  There will be a
 lot of overlapping changes that result in conflicts.  So do not do "revert
 of revert" blindly without thinking..
diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt
index 0d5419e..85f69db 100644
--- a/Documentation/howto/revert-branch-rebase.txt
+++ b/Documentation/howto/revert-branch-rebase.txt
@@ -154,7 +154,7 @@
 Packing 0 objects
 Unpacking 0 objects
 
-* committish: e3a693c...	refs/heads/master from .
+* commit-ish: e3a693c...	refs/heads/master from .
 Trying to merge e3a693c... into 8c1f5f0... using 10d781b...
 Committed merge 7fb9b7262a1d1e0a47bbfdcbbcf50ce0635d3f8f
  cache.h        |    8 ++++----
diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt
index c803649..6de4f3c 100644
--- a/Documentation/howto/setup-git-server-over-http.txt
+++ b/Documentation/howto/setup-git-server-over-http.txt
@@ -85,8 +85,8 @@
     $ git --bare init
 
 
-Change the ownership to your web-server's credentials. Use "grep ^User
-httpd.conf" and "grep ^Group httpd.conf" to find out:
+Change the ownership to your web-server's credentials. Use `"grep ^User
+httpd.conf"` and `"grep ^Group httpd.conf"` to find out:
 
     $ chown -R www.www .
 
diff --git a/Documentation/line-range-format.txt b/Documentation/line-range-format.txt
index 3e7ce72..d7f2603 100644
--- a/Documentation/line-range-format.txt
+++ b/Documentation/line-range-format.txt
@@ -1,3 +1,5 @@
+<start> and <end> can take one of these forms:
+
 - number
 +
 If <start> or <end> is a number, it specifies an
@@ -7,7 +9,10 @@
 - /regex/
 +
 This form will use the first line matching the given
-POSIX regex.  If <end> is a regex, it will search
+POSIX regex. If <start> is a regex, it will search from the end of
+the previous `-L` range, if any, otherwise from the start of file.
+If <start> is ``^/regex/'', it will search from the start of file.
+If <end> is a regex, it will search
 starting at the line given by <start>.
 +
 
@@ -15,11 +20,10 @@
 +
 This is only valid for <end> and will specify a number
 of lines before or after the line given by <start>.
-+
 
-- :regex
 +
-If the option's argument is of the form :regex, it denotes the range
+If ``:<regex>'' is given in place of <start> and <end>, it denotes the range
 from the first funcname line that matches <regex>, up to the next
-funcname line.
-+
+funcname line. ``:<regex>'' searches from the end of the previous `-L` range,
+if any, otherwise from the start of file.
+``^:<regex>'' searches from the start of file.
diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index afba8d4..e134315 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -14,9 +14,12 @@
 	further edit the auto-generated merge message, so that the user
 	can explain and justify the merge. The `--no-edit` option can be
 	used to accept the auto-generated message (this is generally
-	discouraged). The `--edit` (or `-e`) option is still useful if you are
-	giving a draft message with the `-m` option from the command line
-	and want to edit it in the editor.
+	discouraged).
+ifndef::git-pull[]
+The `--edit` (or `-e`) option is still useful if you are
+giving a draft message with the `-m` option from the command line
+and want to edit it in the editor.
+endif::git-pull[]
 +
 Older scripts may depend on the historical behaviour of not allowing the
 user to edit the merge log message. They will see an editor opened when
diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt
index 49a9a7d..fb6e593 100644
--- a/Documentation/merge-strategies.txt
+++ b/Documentation/merge-strategies.txt
@@ -113,3 +113,11 @@
 	match the tree structure of A, instead of reading the trees at
 	the same level. This adjustment is also done to the common
 	ancestor tree.
+
+With the strategies that use 3-way merge (including the default, 'recursive'),
+if a change is made on both branches, but later reverted on one of the
+branches, that change will be present in the merged result; some people find
+this behavior confusing.  It occurs because only the heads and the merge base
+are considered when performing a merge, not the individual commits.  The merge
+algorithm therefore considers the reverted change as no change at all, and
+substitutes the changed version instead.
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 5bdfb42..03533af 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -18,33 +18,27 @@
 -<number>::
 -n <number>::
 --max-count=<number>::
-
 	Limit the number of commits to output.
 
 --skip=<number>::
-
 	Skip 'number' commits before starting to show the commit output.
 
 --since=<date>::
 --after=<date>::
-
 	Show commits more recent than a specific date.
 
 --until=<date>::
 --before=<date>::
-
 	Show commits older than a specific date.
 
 ifdef::git-rev-list[]
 --max-age=<timestamp>::
 --min-age=<timestamp>::
-
 	Limit the commits output to specified time range.
 endif::git-rev-list[]
 
 --author=<pattern>::
 --committer=<pattern>::
-
 	Limit the commits output to ones with author/committer
 	header lines that match the specified pattern (regular
 	expression).  With more than one `--author=<pattern>`,
@@ -52,7 +46,6 @@
 	chosen (similarly for multiple `--committer=<pattern>`).
 
 --grep-reflog=<pattern>::
-
 	Limit the commits output to ones with reflog entries that
 	match the specified pattern (regular expression). With
 	more than one `--grep-reflog`, commits whose reflog message
@@ -60,7 +53,6 @@
 	error to use this option unless `--walk-reflogs` is in use.
 
 --grep=<pattern>::
-
 	Limit the commits output to ones with log message that
 	matches the specified pattern (regular expression).  With
 	more than one `--grep=<pattern>`, commits whose message
@@ -71,46 +63,39 @@
 if it is part of the log message.
 
 --all-match::
-	Limit the commits output to ones that match all given --grep,
+	Limit the commits output to ones that match all given `--grep`,
 	instead of ones that match at least one.
 
 -i::
 --regexp-ignore-case::
-
-	Match the regexp limiting patterns without regard to letters case.
+	Match the regular expression limiting patterns without regard to letter
+	case.
 
 --basic-regexp::
-
 	Consider the limiting patterns to be basic regular expressions;
 	this is the default.
 
 -E::
 --extended-regexp::
-
 	Consider the limiting patterns to be extended regular expressions
 	instead of the default basic regular expressions.
 
 -F::
 --fixed-strings::
-
 	Consider the limiting patterns to be fixed strings (don't interpret
 	pattern as a regular expression).
 
 --perl-regexp::
-
-	Consider the limiting patterns to be Perl-compatible regexp.
+	Consider the limiting patterns to be Perl-compatible regular expressions.
 	Requires libpcre to be compiled in.
 
 --remove-empty::
-
 	Stop when a given path disappears from the tree.
 
 --merges::
-
 	Print only merge commits. This is exactly the same as `--min-parents=2`.
 
 --no-merges::
-
 	Do not print commits with more than one parent. This is
 	exactly the same as `--max-parents=1`.
 
@@ -118,7 +103,6 @@
 --max-parents=<number>::
 --no-min-parents::
 --no-max-parents::
-
 	Show only commits which have at least (or at most) that many parent
 	commits. In particular, `--max-parents=1` is the same as `--no-merges`,
 	`--min-parents=2` is the same as `--merges`.  `--max-parents=0`
@@ -138,31 +122,26 @@
 	brought in to your history by such a merge.
 
 --not::
-
 	Reverses the meaning of the '{caret}' prefix (or lack thereof)
-	for all following revision specifiers, up to the next '--not'.
+	for all following revision specifiers, up to the next `--not`.
 
 --all::
-
 	Pretend as if all the refs in `refs/` are listed on the
 	command line as '<commit>'.
 
 --branches[=<pattern>]::
-
 	Pretend as if all the refs in `refs/heads` are listed
 	on the command line as '<commit>'. If '<pattern>' is given, limit
 	branches to ones matching given shell glob. If pattern lacks '?',
 	'{asterisk}', or '[', '/{asterisk}' at the end is implied.
 
 --tags[=<pattern>]::
-
 	Pretend as if all the refs in `refs/tags` are listed
 	on the command line as '<commit>'. If '<pattern>' is given, limit
 	tags to ones matching given shell glob. If pattern lacks '?', '{asterisk}',
 	or '[', '/{asterisk}' at the end is implied.
 
 --remotes[=<pattern>]::
-
 	Pretend as if all the refs in `refs/remotes` are listed
 	on the command line as '<commit>'. If '<pattern>' is given, limit
 	remote-tracking branches to ones matching given shell glob.
@@ -174,14 +153,27 @@
 	is automatically prepended if missing. If pattern lacks '?', '{asterisk}',
 	or '[', '/{asterisk}' at the end is implied.
 
---ignore-missing::
+--exclude=<glob-pattern>::
 
+	Do not include refs matching '<glob-pattern>' that the next `--all`,
+	`--branches`, `--tags`, `--remotes`, or `--glob` would otherwise
+	consider. Repetitions of this option accumulate exclusion patterns
+	up to the next `--all`, `--branches`, `--tags`, `--remotes`, or
+	`--glob` option (other options or arguments do not clear
+	accumlated patterns).
++
+The patterns given should not begin with `refs/heads`, `refs/tags`, or
+`refs/remotes` when applied to `--branches`, `--tags`, or `--remotes`,
+respectively, and they must begin with `refs/` when applied to `--glob`
+or `--all`. If a trailing '/{asterisk}' is intended, it must be given
+explicitly.
+
+--ignore-missing::
 	Upon seeing an invalid object name in the input, pretend as if
 	the bad input was not given.
 
 ifndef::git-rev-list[]
 --bisect::
-
 	Pretend as if the bad bisection ref `refs/bisect/bad`
 	was listed and as if it was followed by `--not` and the good
 	bisection refs `refs/bisect/good-*` on the command
@@ -189,7 +181,6 @@
 endif::git-rev-list[]
 
 --stdin::
-
 	In addition to the '<commit>' listed on the command
 	line, read them from the standard input. If a '--' separator is
 	seen, stop reading commits and start reading paths to limit the
@@ -197,36 +188,32 @@
 
 ifdef::git-rev-list[]
 --quiet::
-
 	Don't print anything to standard output.  This form
 	is primarily meant to allow the caller to
 	test the exit status to see if a range of objects is fully
 	connected (or not).  It is faster than redirecting stdout
-	to /dev/null as the output does not have to be formatted.
+	to `/dev/null` as the output does not have to be formatted.
 endif::git-rev-list[]
 
 --cherry-mark::
-
 	Like `--cherry-pick` (see below) but mark equivalent commits
 	with `=` rather than omitting them, and inequivalent ones with `+`.
 
 --cherry-pick::
-
 	Omit any commit that introduces the same change as
-	another commit on the "other side" when the set of
+	another commit on the ``other side'' when the set of
 	commits are limited with symmetric difference.
 +
 For example, if you have two branches, `A` and `B`, a usual way
 to list all commits on only one side of them is with
 `--left-right` (see the example below in the description of
-the `--left-right` option).  It however shows the commits that were cherry-picked
-from the other branch (for example, "3rd on b" may be cherry-picked
-from branch A).  With this option, such pairs of commits are
+the `--left-right` option). However, it shows the commits that were
+cherry-picked from the other branch (for example, ``3rd on b'' may be
+cherry-picked from branch A). With this option, such pairs of commits are
 excluded from the output.
 
 --left-only::
 --right-only::
-
 	List only commits on the respective side of a symmetric range,
 	i.e. only those which would be marked `<` resp. `>` by
 	`--left-right`.
@@ -238,7 +225,6 @@
 list.
 
 --cherry::
-
 	A synonym for `--right-only --cherry-mark --no-merges`; useful to
 	limit the output to the commits on our side and mark those that
 	have been applied to the other side of a forked history with
@@ -247,30 +233,27 @@
 
 -g::
 --walk-reflogs::
-
 	Instead of walking the commit ancestry chain, walk
 	reflog entries from the most recent one to older ones.
 	When this option is used you cannot specify commits to
 	exclude (that is, '{caret}commit', 'commit1..commit2',
 	nor 'commit1\...commit2' notations cannot be used).
 +
-With '\--pretty' format other than oneline (for obvious reasons),
+With `--pretty` format other than `oneline` (for obvious reasons),
 this causes the output to have two extra lines of information
 taken from the reflog.  By default, 'commit@\{Nth}' notation is
 used in the output.  When the starting commit is specified as
 'commit@\{now}', output also uses 'commit@\{timestamp}' notation
-instead.  Under '\--pretty=oneline', the commit message is
+instead.  Under `--pretty=oneline`, the commit message is
 prefixed with this information on the same line.
-This option cannot be combined with '\--reverse'.
+This option cannot be combined with `--reverse`.
 See also linkgit:git-reflog[1].
 
 --merge::
-
 	After a failed merge, show refs that touch files having a
 	conflict and don't exist on all heads to merge.
 
 --boundary::
-
 	Output excluded boundary commits. Boundary commits are
 	prefixed with `-`.
 
@@ -287,11 +270,9 @@
 The following options select the commits to be shown:
 
 <paths>::
-
 	Commits modifying the given <paths> are selected.
 
 --simplify-by-decoration::
-
 	Commits that are referred by some branch or tag are selected.
 
 Note that extra commits can be shown to give a meaningful history.
@@ -299,33 +280,27 @@
 The following options affect the way the simplification is performed:
 
 Default mode::
-
 	Simplifies the history to the simplest history explaining the
 	final state of the tree. Simplest because it prunes some side
 	branches if the end result is the same (i.e. merging branches
 	with the same content)
 
 --full-history::
-
 	Same as the default mode, but does not prune some history.
 
 --dense::
-
 	Only the selected commits are shown, plus some to have a
 	meaningful history.
 
 --sparse::
-
 	All commits in the simplified history are shown.
 
 --simplify-merges::
-
-	Additional option to '--full-history' to remove some needless
+	Additional option to `--full-history` to remove some needless
 	merges from the resulting history, as there are no selected
 	commits contributing to this merge.
 
 --ancestry-path::
-
 	When given a range of commits to display (e.g. 'commit1..commit2'
 	or 'commit2 {caret}commit1'), only display commits that exist
 	directly on the ancestry chain between the 'commit1' and
@@ -352,36 +327,35 @@
 each merge.  The commits are:
 
 * `I` is the initial commit, in which `foo` exists with contents
-  "asdf", and a file `quux` exists with contents "quux".  Initial
+  ``asdf'', and a file `quux` exists with contents ``quux''. Initial
   commits are compared to an empty tree, so `I` is !TREESAME.
 
-* In `A`, `foo` contains just "foo".
+* In `A`, `foo` contains just ``foo''.
 
 * `B` contains the same change as `A`.  Its merge `M` is trivial and
   hence TREESAME to all parents.
 
-* `C` does not change `foo`, but its merge `N` changes it to "foobar",
+* `C` does not change `foo`, but its merge `N` changes it to ``foobar'',
   so it is not TREESAME to any parent.
 
-* `D` sets `foo` to "baz".  Its merge `O` combines the strings from
-  `N` and `D` to "foobarbaz"; i.e., it is not TREESAME to any parent.
+* `D` sets `foo` to ``baz''. Its merge `O` combines the strings from
+  `N` and `D` to ``foobarbaz''; i.e., it is not TREESAME to any parent.
 
-* `E` changes `quux` to "xyzzy", and its merge `P` combines the
-  strings to "quux xyzzy".  `P` is TREESAME to `O`, but not to `E`.
+* `E` changes `quux` to ``xyzzy'', and its merge `P` combines the
+  strings to ``quux xyzzy''. `P` is TREESAME to `O`, but not to `E`.
 
 * `X` is an independent root commit that added a new file `side`, and `Y`
   modified it. `Y` is TREESAME to `X`. Its merge `Q` added `side` to `P`, and
   `Q` is TREESAME to `P`, but not to `Y`.
 
-'rev-list' walks backwards through history, including or excluding
-commits based on whether '\--full-history' and/or parent rewriting
-(via '\--parents' or '\--children') are used.  The following settings
+`rev-list` walks backwards through history, including or excluding
+commits based on whether `--full-history` and/or parent rewriting
+(via `--parents` or `--children`) are used. The following settings
 are available.
 
 Default mode::
-
 	Commits are included if they are not TREESAME to any parent
-	(though this can be changed, see '\--sparse' below).  If the
+	(though this can be changed, see `--sparse` below).  If the
 	commit was a merge, and it was TREESAME to one parent, follow
 	only that parent.  (Even if there are several TREESAME
 	parents, follow only one of them.)  Otherwise, follow all
@@ -400,12 +374,11 @@
 considered via `N`, but is TREESAME.  Root commits are compared to an
 empty tree, so `I` is !TREESAME.
 +
-Parent/child relations are only visible with --parents, but that does
+Parent/child relations are only visible with `--parents`, but that does
 not affect the commits selected in default mode, so we have shown the
 parent lines.
 
 --full-history without parent rewriting::
-
 	This mode differs from the default in one point: always follow
 	all parents of a merge, even if it is TREESAME to one of them.
 	Even if more than one side of the merge has commits that are
@@ -425,9 +398,8 @@
 them disconnected.
 
 --full-history with parent rewriting::
-
 	Ordinary commits are only included if they are !TREESAME
-	(though this can be changed, see '\--sparse' below).
+	(though this can be changed, see `--sparse` below).
 +
 Merges are always included.  However, their parent list is rewritten:
 Along each parent, prune away commits that are not included
@@ -441,7 +413,7 @@
 	  `-------------'
 -----------------------------------------------------------------------
 +
-Compare to '\--full-history' without rewriting above.  Note that `E`
+Compare to `--full-history` without rewriting above.  Note that `E`
 was pruned away because it is TREESAME, but the parent list of P was
 rewritten to contain `E`'s parent `I`.  The same happened for `C` and
 `N`, and `X`, `Y` and `Q`.
@@ -450,22 +422,19 @@
 affects inclusion:
 
 --dense::
-
 	Commits that are walked are included if they are not TREESAME
 	to any parent.
 
 --sparse::
-
 	All commits that are walked are included.
 +
-Note that without '\--full-history', this still simplifies merges: if
+Note that without `--full-history`, this still simplifies merges: if
 one of the parents is TREESAME, we follow only that one, so the other
 sides of the merge are never walked.
 
 --simplify-merges::
-
 	First, build a history graph in the same way that
-	'\--full-history' with parent rewriting does (see above).
+	`--full-history` with parent rewriting does (see above).
 +
 Then simplify each commit `C` to its replacement `C'` in the final
 history according to the following rules:
@@ -484,7 +453,7 @@
 --
 +
 The effect of this is best shown by way of comparing to
-'\--full-history' with parent rewriting.  The example turns into:
+`--full-history` with parent rewriting.  The example turns into:
 +
 -----------------------------------------------------------------------
 	  .-A---M---N---O
@@ -494,7 +463,7 @@
 	  `---------'
 -----------------------------------------------------------------------
 +
-Note the major differences in `N`, `P` and `Q` over '--full-history':
+Note the major differences in `N`, `P`, and `Q` over `--full-history`:
 +
 --
 * `N`'s parent list had `I` removed, because it is an ancestor of the
@@ -511,11 +480,10 @@
 Finally, there is a fifth simplification mode available:
 
 --ancestry-path::
-
 	Limit the displayed commits to those directly on the ancestry
-	chain between the "from" and "to" commits in the given commit
-	range. I.e. only display commits that are ancestor of the "to"
-	commit, and descendants of the "from" commit.
+	chain between the ``from'' and ``to'' commits in the given commit
+	range. I.e. only display commits that are ancestor of the ``to''
+	commit and descendants of the ``from'' commit.
 +
 As an example use case, consider the following commit history:
 +
@@ -530,14 +498,14 @@
 A regular 'D..M' computes the set of commits that are ancestors of `M`,
 but excludes the ones that are ancestors of `D`. This is useful to see
 what happened to the history leading to `M` since `D`, in the sense
-that "what does `M` have that did not exist in `D`". The result in this
+that ``what does `M` have that did not exist in `D`''. The result in this
 example would be all the commits, except `A` and `B` (and `D` itself,
 of course).
 +
 When we want to find out what commits in `M` are contaminated with the
 bug introduced by `D` and need fixing, however, we might want to view
 only the subset of 'D..M' that are actually descendants of `D`, i.e.
-excluding `C` and `K`. This is exactly what the '--ancestry-path'
+excluding `C` and `K`. This is exactly what the `--ancestry-path`
 option does. Applied to the 'D..M' range, it results in:
 +
 -----------------------------------------------------------------------
@@ -548,7 +516,7 @@
 				L--M
 -----------------------------------------------------------------------
 
-The '\--simplify-by-decoration' option allows you to view only the
+The `--simplify-by-decoration` option allows you to view only the
 big picture of the topology of the history, by omitting commits
 that are not referenced by tags.  Commits are marked as !TREESAME
 (in other words, kept after history simplification rules described
@@ -561,50 +529,47 @@
 ~~~~~~~~~~~~~~~~~
 
 --bisect::
-
-Limit output to the one commit object which is roughly halfway between
-included and excluded commits. Note that the bad bisection ref
-`refs/bisect/bad` is added to the included commits (if it
-exists) and the good bisection refs `refs/bisect/good-*` are
-added to the excluded commits (if they exist). Thus, supposing there
-are no refs in `refs/bisect/`, if
-
+	Limit output to the one commit object which is roughly halfway between
+	included and excluded commits. Note that the bad bisection ref
+	`refs/bisect/bad` is added to the included commits (if it
+	exists) and the good bisection refs `refs/bisect/good-*` are
+	added to the excluded commits (if they exist). Thus, supposing there
+	are no refs in `refs/bisect/`, if
++
 -----------------------------------------------------------------------
 	$ git rev-list --bisect foo ^bar ^baz
 -----------------------------------------------------------------------
-
++
 outputs 'midpoint', the output of the two commands
-
++
 -----------------------------------------------------------------------
 	$ git rev-list foo ^midpoint
 	$ git rev-list midpoint ^bar ^baz
 -----------------------------------------------------------------------
-
++
 would be of roughly the same length.  Finding the change which
 introduces a regression is thus reduced to a binary search: repeatedly
 generate and test new 'midpoint's until the commit chain is of length
 one.
 
 --bisect-vars::
-
-This calculates the same as `--bisect`, except that refs in
-`refs/bisect/` are not used, and except that this outputs
-text ready to be eval'ed by the shell. These lines will assign the
-name of the midpoint revision to the variable `bisect_rev`, and the
-expected number of commits to be tested after `bisect_rev` is tested
-to `bisect_nr`, the expected number of commits to be tested if
-`bisect_rev` turns out to be good to `bisect_good`, the expected
-number of commits to be tested if `bisect_rev` turns out to be bad to
-`bisect_bad`, and the number of commits we are bisecting right now to
-`bisect_all`.
+	This calculates the same as `--bisect`, except that refs in
+	`refs/bisect/` are not used, and except that this outputs
+	text ready to be eval'ed by the shell. These lines will assign the
+	name of the midpoint revision to the variable `bisect_rev`, and the
+	expected number of commits to be tested after `bisect_rev` is tested
+	to `bisect_nr`, the expected number of commits to be tested if
+	`bisect_rev` turns out to be good to `bisect_good`, the expected
+	number of commits to be tested if `bisect_rev` turns out to be bad to
+	`bisect_bad`, and the number of commits we are bisecting right now to
+	`bisect_all`.
 
 --bisect-all::
-
-This outputs all the commit objects between the included and excluded
-commits, ordered by their distance to the included and excluded
-commits. Refs in `refs/bisect/` are not used. The farthest
-from them is displayed first. (This is the only one displayed by
-`--bisect`.)
+	This outputs all the commit objects between the included and excluded
+	commits, ordered by their distance to the included and excluded
+	commits. Refs in `refs/bisect/` are not used. The farthest
+	from them is displayed first. (This is the only one displayed by
+	`--bisect`.)
 +
 This is useful because it makes it easy to choose a good commit to
 test when you want to avoid to test some of them for some reason (they
@@ -654,9 +619,8 @@
 together.
 
 --reverse::
-
 	Output the commits in reverse order.
-	Cannot be combined with '\--walk-reflogs'.
+	Cannot be combined with `--walk-reflogs`.
 
 Object Traversal
 ~~~~~~~~~~~~~~~~
@@ -664,37 +628,32 @@
 These options are mostly targeted for packing of Git repositories.
 
 --objects::
-
 	Print the object IDs of any object referenced by the listed
-	commits.  '--objects foo ^bar' thus means "send me
+	commits.  `--objects foo ^bar` thus means ``send me
 	all object IDs which I need to download if I have the commit
-	object 'bar', but not 'foo'".
+	object _bar_ but not _foo_''.
 
 --objects-edge::
-
-	Similar to '--objects', but also print the IDs of excluded
-	commits prefixed with a "-" character.  This is used by
-	linkgit:git-pack-objects[1] to build "thin" pack, which records
+	Similar to `--objects`, but also print the IDs of excluded
+	commits prefixed with a ``-'' character.  This is used by
+	linkgit:git-pack-objects[1] to build ``thin'' pack, which records
 	objects in deltified form based on objects contained in these
 	excluded commits to reduce network traffic.
 
 --unpacked::
-
-	Only useful with '--objects'; print the object IDs that are not
+	Only useful with `--objects`; print the object IDs that are not
 	in packs.
 
 --no-walk[=(sorted|unsorted)]::
-
 	Only show the given commits, but do not traverse their ancestors.
 	This has no effect if a range is specified. If the argument
-	"unsorted" is given, the commits are show in the order they were
-	given on the command line. Otherwise (if "sorted" or no argument
-	was given), the commits are show in reverse chronological order
+	`unsorted` is given, the commits are shown in the order they were
+	given on the command line. Otherwise (if `sorted` or no argument
+	was given), the commits are shown in reverse chronological order
 	by commit time.
 
 --do-walk::
-
-	Overrides a previous --no-walk.
+	Overrides a previous `--no-walk`.
 
 Commit Formatting
 ~~~~~~~~~~~~~~~~~
@@ -708,46 +667,41 @@
 include::pretty-options.txt[]
 
 --relative-date::
-
 	Synonym for `--date=relative`.
 
 --date=(relative|local|default|iso|rfc|short|raw)::
-
 	Only takes effect for dates shown in human-readable format, such
-	as when using "--pretty". `log.date` config variable sets a default
-	value for log command's --date option.
+	as when using `--pretty`. `log.date` config variable sets a default
+	value for the log command's `--date` option.
 +
 `--date=relative` shows dates relative to the current time,
-e.g. "2 hours ago".
+e.g. ``2 hours ago''.
 +
-`--date=local` shows timestamps in user's local timezone.
+`--date=local` shows timestamps in user's local time zone.
 +
 `--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.
 +
 `--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
-format, often found in E-mail messages.
+format, often found in email messages.
 +
-`--date=short` shows only date but not time, in `YYYY-MM-DD` format.
+`--date=short` shows only the date, but not the time, in `YYYY-MM-DD` format.
 +
 `--date=raw` shows the date in the internal raw Git format `%s %z` format.
 +
-`--date=default` shows timestamps in the original timezone
+`--date=default` shows timestamps in the original time zone
 (either committer's or author's).
 
 ifdef::git-rev-list[]
 --header::
-
 	Print the contents of the commit in raw-format; each record is
 	separated with a NUL character.
 endif::git-rev-list[]
 
 --parents::
-
 	Print also the parents of the commit (in the form "commit parent...").
 	Also enables parent rewriting, see 'History Simplification' below.
 
 --children::
-
 	Print also the children of the commit (in the form "commit child...").
 	Also enables parent rewriting, see 'History Simplification' below.
 
@@ -757,7 +711,6 @@
 endif::git-rev-list[]
 
 --left-right::
-
 	Mark which side of a symmetric diff a commit is reachable from.
 	Commits from the left side are prefixed with `<` and those from
 	the right with `>`.  If combined with `--boundary`, those
@@ -787,7 +740,6 @@
 -----------------------------------------------------------------------
 
 --graph::
-
 	Draw a text-based graphical representation of the commit history
 	on the left hand side of the output.  This may cause extra lines
 	to be printed in between commits, in order for the graph history
@@ -795,31 +747,29 @@
 +
 This enables parent rewriting, see 'History Simplification' below.
 +
-This implies the '--topo-order' option by default, but the
-'--date-order' option may also be specified.
+This implies the `--topo-order` option by default, but the
+`--date-order` option may also be specified.
 
 ifdef::git-rev-list[]
 --count::
 	Print a number stating how many commits would have been
 	listed, and suppress all other output.  When used together
-	with '--left-right', instead print the counts for left and
+	with `--left-right`, instead print the counts for left and
 	right commits, separated by a tab. When used together with
-	'--cherry-mark', omit patch equivalent commits from these
+	`--cherry-mark`, omit patch equivalent commits from these
 	counts and print the count for equivalent commits separated
 	by a tab.
 endif::git-rev-list[]
 
-
 ifndef::git-rev-list[]
 Diff Formatting
 ~~~~~~~~~~~~~~~
 
-Below are listed options that control the formatting of diff output.
+Listed below are options that control the formatting of diff output.
 Some of them are specific to linkgit:git-rev-list[1], however other diff
 options may be given. See linkgit:git-diff-files[1] for more options.
 
 -c::
-
 	With this option, diff output for a merge commit
 	shows the differences from each of the parents to the merge result
 	simultaneously instead of showing pairwise diff between a parent
@@ -827,26 +777,22 @@
 	which were modified from all parents.
 
 --cc::
-
-	This flag implies the '-c' option and further compresses the
+	This flag implies the `-c` option and further compresses the
 	patch output by omitting uninteresting hunks whose contents in
 	the parents have only two variants and the merge result picks
 	one of them without modification.
 
 -m::
-
 	This flag makes the merge commits show the full diff like
 	regular commits; for each merge parent, a separate log entry
 	and diff is generated. An exception is that only diff against
-	the first parent is shown when '--first-parent' option is given;
+	the first parent is shown when `--first-parent` option is given;
 	in that case, the output represents the changes the merge
 	brought _into_ the then-current branch.
 
 -r::
-
 	Show recursive diffs.
 
 -t::
-
-	Show the tree objects in the diff output. This implies '-r'.
+	Show the tree objects in the diff output. This implies `-r`.
 endif::git-rev-list[]
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index d477b3f..5a286d0 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -58,6 +58,9 @@
 While the ref name encoding is unspecified, UTF-8 is preferred as
 some output processing may assume ref names in UTF-8.
 
+'@'::
+  '@' alone is a shortcut for 'HEAD'.
+
 '<refname>@\{<date>\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}'::
   A ref followed by the suffix '@' with a date specification
   enclosed in a brace
@@ -85,7 +88,7 @@
   branch 'blabla' then '@\{1\}' means the same as 'blabla@\{1\}'.
 
 '@\{-<n>\}', e.g. '@\{-1\}'::
-  The construct '@\{-<n>\}' means the <n>th branch checked out
+  The construct '@\{-<n>\}' means the <n>th branch/commit checked out
   before the current one.
 
 '<branchname>@\{upstream\}', e.g. 'master@\{upstream\}', '@\{u\}'::
@@ -111,16 +114,23 @@
 
 '<rev>{caret}\{<type>\}', e.g. 'v0.99.8{caret}\{commit\}'::
   A suffix '{caret}' followed by an object type name enclosed in
-  brace pair means the object
-  could be a tag, and dereference the tag recursively until an
-  object of that type is found or the object cannot be
-  dereferenced anymore (in which case, barf).  '<rev>{caret}0'
+  brace pair means dereference the object at '<rev>' recursively until
+  an object of type '<type>' is found or the object cannot be
+  dereferenced anymore (in which case, barf).
+  For example, if '<rev>' is a commit-ish, '<rev>{caret}\{commit\}'
+  describes the corresponding commit object.
+  Similarly, if '<rev>' is a tree-ish, '<rev>{caret}\{tree\}'
+  describes the corresponding tree object.
+  '<rev>{caret}0'
   is a short-hand for '<rev>{caret}\{commit\}'.
 +
 'rev{caret}\{object\}' can be used to make sure 'rev' names an
 object that exists, without requiring 'rev' to be a tag, and
 without dereferencing 'rev'; because a tag is already an object,
 it does not have to be dereferenced even once to get to an object.
++
+'rev{caret}\{tag\}' can be used to ensure that 'rev' identifies an
+existing tag object.
 
 '<rev>{caret}\{\}', e.g. 'v0.99.8{caret}\{\}'::
   A suffix '{caret}' followed by an empty brace pair
diff --git a/Documentation/technical/api-builtin.txt b/Documentation/technical/api-builtin.txt
index f3c1357..e3d6e7a 100644
--- a/Documentation/technical/api-builtin.txt
+++ b/Documentation/technical/api-builtin.txt
@@ -14,8 +14,8 @@
 
 . Add the external declaration for the function to `builtin.h`.
 
-. Add the command to `commands[]` table in `handle_internal_command()`,
-  defined in `git.c`.  The entry should look like:
+. Add the command to the `commands[]` table defined in `git.c`.
+  The entry should look like:
 
 	{ "foo", cmd_foo, <options> },
 +
diff --git a/Documentation/technical/api-diff.txt b/Documentation/technical/api-diff.txt
index 2d2ebc0..8b001de 100644
--- a/Documentation/technical/api-diff.txt
+++ b/Documentation/technical/api-diff.txt
@@ -28,7 +28,8 @@
 
 * Call `diff_setup_done()`; this inspects the options set up so far for
   internal consistency and make necessary tweaking to it (e.g. if
-  textual patch output was asked, recursive behaviour is turned on).
+  textual patch output was asked, recursive behaviour is turned on);
+  the callback set_default in diff_options can be used to tweak this more.
 
 * As you find different pairs of files, call `diff_change()` to feed
   modified files, `diff_addremove()` to feed created or deleted files,
@@ -115,6 +116,13 @@
 	operation, but some do not have anything to do with the diffcore
 	library.
 
+`touched_flags`::
+	Records whether a flag has been changed due to user request
+	(rather than just set/unset by default).
+
+`set_default`::
+	Callback which allows tweaking the options in diff_setup_done().
+
 BINARY, TEXT;;
 	Affects the way how a file that is seemingly binary is treated.
 
diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt
index 0be2b51..be50cf4 100644
--- a/Documentation/technical/api-parse-options.txt
+++ b/Documentation/technical/api-parse-options.txt
@@ -29,9 +29,9 @@
 
 The parse-options API allows:
 
-* 'sticked' and 'separate form' of options with arguments.
-  `-oArg` is sticked, `-o Arg` is separate form.
-  `--option=Arg` is sticked, `--option Arg` is separate form.
+* 'stuck' and 'separate form' of options with arguments.
+  `-oArg` is stuck, `-o Arg` is separate form.
+  `--option=Arg` is stuck, `--option Arg` is separate form.
 
 * Long options may be 'abbreviated', as long as the abbreviation
   is unambiguous.
diff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt
index aa1c50f..02adfd4 100644
--- a/Documentation/technical/api-ref-iteration.txt
+++ b/Documentation/technical/api-ref-iteration.txt
@@ -50,10 +50,10 @@
 this:
 
 	const char *path = "path/to/submodule"
-	if (!add_submodule_odb(path))
+	if (add_submodule_odb(path))
 		die("Error submodule '%s' not populated.", path);
 
-`add_submodule_odb()` will return an non-zero value on success. If you
+`add_submodule_odb()` will return zero on success. If you
 do not do this you will get an error for each ref that it does not point
 to a valid object.
 
diff --git a/Documentation/technical/api-remote.txt b/Documentation/technical/api-remote.txt
index 4be8776..5d245aa 100644
--- a/Documentation/technical/api-remote.txt
+++ b/Documentation/technical/api-remote.txt
@@ -58,16 +58,16 @@
 struct refspec
 --------------
 
-A struct refspec holds the parsed interpretation of a refspec. If it
-will force updates (starts with a '+'), force is true. If it is a
-pattern (sides end with '*') pattern is true. src and dest are the two
-sides (if a pattern, only the part outside of the wildcards); if there
-is only one side, it is src, and dst is NULL; if sides exist but are
-empty (i.e., the refspec either starts or ends with ':'), the
-corresponding side is "".
+A struct refspec holds the parsed interpretation of a refspec.  If it
+will force updates (starts with a '+'), force is true.  If it is a
+pattern (sides end with '*') pattern is true.  src and dest are the
+two sides (including '*' characters if present); if there is only one
+side, it is src, and dst is NULL; if sides exist but are empty (i.e.,
+the refspec either starts or ends with ':'), the corresponding side is
+"".
 
-This parsing can be done to an array of strings to give an array of
-struct refpsecs with parse_ref_spec().
+An array of strings can be parsed into an array of struct refspecs
+using parse_fetch_refspec() or parse_push_refspec().
 
 remote_find_tracking(), given a remote and a struct refspec with
 either src or dst filled out, will fill out the other such that the
diff --git a/Documentation/technical/api-setup.txt b/Documentation/technical/api-setup.txt
index 4f63a04..540e455 100644
--- a/Documentation/technical/api-setup.txt
+++ b/Documentation/technical/api-setup.txt
@@ -8,6 +8,42 @@
 * is_inside_git_dir()
 * is_inside_work_tree()
 * setup_work_tree()
-* get_pathspec()
 
 (Dscho)
+
+Pathspec
+--------
+
+See glossary-context.txt for the syntax of pathspec. In memory, a
+pathspec set is represented by "struct pathspec" and is prepared by
+parse_pathspec(). This function takes several arguments:
+
+- magic_mask specifies what features that are NOT supported by the
+  following code. If a user attempts to use such a feature,
+  parse_pathspec() can reject it early.
+
+- flags specifies other things that the caller wants parse_pathspec to
+  perform.
+
+- prefix and args come from cmd_* functions
+
+get_pathspec() is obsolete and should never be used in new code.
+
+parse_pathspec() helps catch unsupported features and reject them
+politely. At a lower level, different pathspec-related functions may
+not support the same set of features. Such pathspec-sensitive
+functions are guarded with GUARD_PATHSPEC(), which will die in an
+unfriendly way when an unsupported feature is requested.
+
+The command designers are supposed to make sure that GUARD_PATHSPEC()
+never dies. They have to make sure all unsupported features are caught
+by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC()
+should give the designers all pathspec-sensitive codepaths and what
+features they support.
+
+A similar process is applied when a new pathspec magic is added. The
+designer lifts the GUARD_PATHSPEC restriction in the functions that
+support the new magic. At the same time (s)he has to make sure this
+new feature will be caught at parse_pathspec() in commands that cannot
+handle the new magic in some cases. grepping parse_pathspec() should
+help.
diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt
new file mode 100644
index 0000000..544373b
--- /dev/null
+++ b/Documentation/technical/http-protocol.txt
@@ -0,0 +1,506 @@
+HTTP transfer protocols
+=======================
+
+Git supports two HTTP based transfer protocols.  A "dumb" protocol
+which requires only a standard HTTP server on the server end of the
+connection, and a "smart" protocol which requires a Git aware CGI
+(or server module).  This document describes both protocols.
+
+As a design feature smart clients can automatically upgrade "dumb"
+protocol URLs to smart URLs.  This permits all users to have the
+same published URL, and the peers automatically select the most
+efficient transport available to them.
+
+
+URL Format
+----------
+
+URLs for Git repositories accessed by HTTP use the standard HTTP
+URL syntax documented by RFC 1738, so they are of the form:
+
+  http://<host>:<port>/<path>?<searchpart>
+
+Within this documentation the placeholder `$GIT_URL` will stand for
+the http:// repository URL entered by the end-user.
+
+Servers SHOULD handle all requests to locations matching `$GIT_URL`, as
+both the "smart" and "dumb" HTTP protocols used by Git operate
+by appending additional path components onto the end of the user
+supplied `$GIT_URL` string.
+
+An example of a dumb client requesting for a loose object:
+
+  $GIT_URL:     http://example.com:8080/git/repo.git
+  URL request:  http://example.com:8080/git/repo.git/objects/d0/49f6c27a2244e12041955e262a404c7faba355
+
+An example of a smart request to a catch-all gateway:
+
+  $GIT_URL:     http://example.com/daemon.cgi?svc=git&q=
+  URL request:  http://example.com/daemon.cgi?svc=git&q=/info/refs&service=git-receive-pack
+
+An example of a request to a submodule:
+
+  $GIT_URL:     http://example.com/git/repo.git/path/submodule.git
+  URL request:  http://example.com/git/repo.git/path/submodule.git/info/refs
+
+Clients MUST strip a trailing `/`, if present, from the user supplied
+`$GIT_URL` string to prevent empty path tokens (`//`) from appearing
+in any URL sent to a server.  Compatible clients MUST expand
+`$GIT_URL/info/refs` as `foo/info/refs` and not `foo//info/refs`.
+
+
+Authentication
+--------------
+
+Standard HTTP authentication is used if authentication is required
+to access a repository, and MAY be configured and enforced by the
+HTTP server software.
+
+Because Git repositories are accessed by standard path components
+server administrators MAY use directory based permissions within
+their HTTP server to control repository access.
+
+Clients SHOULD support Basic authentication as described by RFC 2616.
+Servers SHOULD support Basic authentication by relying upon the
+HTTP server placed in front of the Git server software.
+
+Servers SHOULD NOT require HTTP cookies for the purposes of
+authentication or access control.
+
+Clients and servers MAY support other common forms of HTTP based
+authentication, such as Digest authentication.
+
+
+SSL
+---
+
+Clients and servers SHOULD support SSL, particularly to protect
+passwords when relying on Basic HTTP authentication.
+
+
+Session State
+-------------
+
+The Git over HTTP protocol (much like HTTP itself) is stateless
+from the perspective of the HTTP server side.  All state MUST be
+retained and managed by the client process.  This permits simple
+round-robin load-balancing on the server side, without needing to
+worry about state management.
+
+Clients MUST NOT require state management on the server side in
+order to function correctly.
+
+Servers MUST NOT require HTTP cookies in order to function correctly.
+Clients MAY store and forward HTTP cookies during request processing
+as described by RFC 2616 (HTTP/1.1).  Servers SHOULD ignore any
+cookies sent by a client.
+
+
+General Request Processing
+--------------------------
+
+Except where noted, all standard HTTP behavior SHOULD be assumed
+by both client and server.  This includes (but is not necessarily
+limited to):
+
+If there is no repository at `$GIT_URL`, or the resource pointed to by a
+location matching `$GIT_URL` does not exist, the server MUST NOT respond
+with `200 OK` response.  A server SHOULD respond with
+`404 Not Found`, `410 Gone`, or any other suitable HTTP status code
+which does not imply the resource exists as requested.
+
+If there is a repository at `$GIT_URL`, but access is not currently
+permitted, the server MUST respond with the `403 Forbidden` HTTP
+status code.
+
+Servers SHOULD support both HTTP 1.0 and HTTP 1.1.
+Servers SHOULD support chunked encoding for both request and response
+bodies.
+
+Clients SHOULD support both HTTP 1.0 and HTTP 1.1.
+Clients SHOULD support chunked encoding for both request and response
+bodies.
+
+Servers MAY return ETag and/or Last-Modified headers.
+
+Clients MAY revalidate cached entities by including If-Modified-Since
+and/or If-None-Match request headers.
+
+Servers MAY return `304 Not Modified` if the relevant headers appear
+in the request and the entity has not changed.  Clients MUST treat
+`304 Not Modified` identical to `200 OK` by reusing the cached entity.
+
+Clients MAY reuse a cached entity without revalidation if the
+Cache-Control and/or Expires header permits caching.  Clients and
+servers MUST follow RFC 2616 for cache controls.
+
+
+Discovering References
+----------------------
+
+All HTTP clients MUST begin either a fetch or a push exchange by
+discovering the references available on the remote repository.
+
+Dumb Clients
+~~~~~~~~~~~~
+
+HTTP clients that only support the "dumb" protocol MUST discover
+references by making a request for the special info/refs file of
+the repository.
+
+Dumb HTTP clients MUST make a `GET` request to `$GIT_URL/info/refs`,
+without any search/query parameters.
+
+   C: GET $GIT_URL/info/refs HTTP/1.0
+
+   S: 200 OK
+   S:
+   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31	refs/heads/maint
+   S: d049f6c27a2244e12041955e262a404c7faba355	refs/heads/master
+   S: 2cb58b79488a98d2721cea644875a8dd0026b115	refs/tags/v1.0
+   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c	refs/tags/v1.0^{}
+
+The Content-Type of the returned info/refs entity SHOULD be
+`text/plain; charset=utf-8`, but MAY be any content type.
+Clients MUST NOT attempt to validate the returned Content-Type.
+Dumb servers MUST NOT return a return type starting with
+`application/x-git-`.
+
+Cache-Control headers MAY be returned to disable caching of the
+returned entity.
+
+When examining the response clients SHOULD only examine the HTTP
+status code.  Valid responses are `200 OK`, or `304 Not Modified`.
+
+The returned content is a UNIX formatted text file describing
+each ref and its known value.  The file SHOULD be sorted by name
+according to the C locale ordering.  The file SHOULD NOT include
+the default ref named `HEAD`.
+
+  info_refs   =  *( ref_record )
+  ref_record  =  any_ref / peeled_ref
+
+  any_ref     =  obj-id HTAB refname LF
+  peeled_ref  =  obj-id HTAB refname LF
+		 obj-id HTAB refname "^{}" LF
+
+Smart Clients
+~~~~~~~~~~~~~
+
+HTTP clients that support the "smart" protocol (or both the
+"smart" and "dumb" protocols) MUST discover references by making
+a parameterized request for the info/refs file of the repository.
+
+The request MUST contain exactly one query parameter,
+`service=$servicename`, where `$servicename` MUST be the service
+name the client wishes to contact to complete the operation.
+The request MUST NOT contain additional query parameters.
+
+   C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0
+
+dumb server reply:
+
+   S: 200 OK
+   S:
+   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31	refs/heads/maint
+   S: d049f6c27a2244e12041955e262a404c7faba355	refs/heads/master
+   S: 2cb58b79488a98d2721cea644875a8dd0026b115	refs/tags/v1.0
+   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c	refs/tags/v1.0^{}
+
+smart server reply:
+
+   S: 200 OK
+   S: Content-Type: application/x-git-upload-pack-advertisement
+   S: Cache-Control: no-cache
+   S:
+   S: 001e# service=git-upload-pack\n
+   S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0multi_ack\n
+   S: 0042d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n
+   S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n
+   S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n
+
+Dumb Server Response
+^^^^^^^^^^^^^^^^^^^^
+Dumb servers MUST respond with the dumb server reply format.
+
+See the prior section under dumb clients for a more detailed
+description of the dumb server response.
+
+Smart Server Response
+^^^^^^^^^^^^^^^^^^^^^
+If the server does not recognize the requested service name, or the
+requested service name has been disabled by the server administrator,
+the server MUST respond with the `403 Forbidden` HTTP status code.
+
+Otherwise, smart servers MUST respond with the smart server reply
+format for the requested service name.
+
+Cache-Control headers SHOULD be used to disable caching of the
+returned entity.
+
+The Content-Type MUST be `application/x-$servicename-advertisement`.
+Clients SHOULD fall back to the dumb protocol if another content
+type is returned.  When falling back to the dumb protocol clients
+SHOULD NOT make an additional request to `$GIT_URL/info/refs`, but
+instead SHOULD use the response already in hand.  Clients MUST NOT
+continue if they do not support the dumb protocol.
+
+Clients MUST validate the status code is either `200 OK` or
+`304 Not Modified`.
+
+Clients MUST validate the first five bytes of the response entity
+matches the regex `^[0-9a-f]{4}#`.  If this test fails, clients
+MUST NOT continue.
+
+Clients MUST parse the entire response as a sequence of pkt-line
+records.
+
+Clients MUST verify the first pkt-line is `# service=$servicename`.
+Servers MUST set $servicename to be the request parameter value.
+Servers SHOULD include an LF at the end of this line.
+Clients MUST ignore an LF at the end of the line.
+
+Servers MUST terminate the response with the magic `0000` end
+pkt-line marker.
+
+The returned response is a pkt-line stream describing each ref and
+its known value.  The stream SHOULD be sorted by name according to
+the C locale ordering.  The stream SHOULD include the default ref
+named `HEAD` as the first ref.  The stream MUST include capability
+declarations behind a NUL on the first ref.
+
+  smart_reply     =  PKT-LINE("# service=$servicename" LF)
+		     ref_list
+		     "0000"
+  ref_list        =  empty_list / non_empty_list
+
+  empty_list      =  PKT-LINE(zero-id SP "capabilities^{}" NUL cap-list LF)
+
+  non_empty_list  =  PKT-LINE(obj-id SP name NUL cap_list LF)
+		     *ref_record
+
+  cap-list        =  capability *(SP capability)
+  capability      =  1*(LC_ALPHA / DIGIT / "-" / "_")
+  LC_ALPHA        =  %x61-7A
+
+  ref_record      =  any_ref / peeled_ref
+  any_ref         =  PKT-LINE(obj-id SP name LF)
+  peeled_ref      =  PKT-LINE(obj-id SP name LF)
+		     PKT-LINE(obj-id SP name "^{}" LF
+
+
+Smart Service git-upload-pack
+------------------------------
+This service reads from the repository pointed to by `$GIT_URL`.
+
+Clients MUST first perform ref discovery with
+`$GIT_URL/info/refs?service=git-upload-pack`.
+
+   C: POST $GIT_URL/git-upload-pack HTTP/1.0
+   C: Content-Type: application/x-git-upload-pack-request
+   C:
+   C: 0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n
+   C: 0032have 441b40d833fdfa93eb2908e52742248faf0ee993\n
+   C: 0000
+
+   S: 200 OK
+   S: Content-Type: application/x-git-upload-pack-result
+   S: Cache-Control: no-cache
+   S:
+   S: ....ACK %s, continue
+   S: ....NAK
+
+Clients MUST NOT reuse or revalidate a cached response.
+Servers MUST include sufficient Cache-Control headers
+to prevent caching of the response.
+
+Servers SHOULD support all capabilities defined here.
+
+Clients MUST send at least one "want" command in the request body.
+Clients MUST NOT reference an id in a "want" command which did not
+appear in the response obtained through ref discovery unless the
+server advertises capability `allow-tip-sha1-in-want`.
+
+  compute_request   =  want_list
+		       have_list
+		       request_end
+  request_end       =  "0000" / "done"
+
+  want_list         =  PKT-LINE(want NUL cap_list LF)
+		       *(want_pkt)
+  want_pkt          =  PKT-LINE(want LF)
+  want              =  "want" SP id
+  cap_list          =  *(SP capability) SP
+
+  have_list         =  *PKT-LINE("have" SP id LF)
+
+TODO: Document this further.
+
+The Negotiation Algorithm
+~~~~~~~~~~~~~~~~~~~~~~~~~
+The computation to select the minimal pack proceeds as follows
+(C = client, S = server):
+
+'init step:'
+
+C: Use ref discovery to obtain the advertised refs.
+
+C: Place any object seen into set `advertised`.
+
+C: Build an empty set, `common`, to hold the objects that are later
+   determined to be on both ends.
+
+C: Build a set, `want`, of the objects from `advertised` the client
+   wants to fetch, based on what it saw during ref discovery.
+
+C: Start a queue, `c_pending`, ordered by commit time (popping newest
+   first).  Add all client refs.  When a commit is popped from
+   the queue its parents SHOULD be automatically inserted back.
+   Commits MUST only enter the queue once.
+
+'one compute step:'
+
+C: Send one `$GIT_URL/git-upload-pack` request:
+
+   C: 0032want <want #1>...............................
+   C: 0032want <want #2>...............................
+   ....
+   C: 0032have <common #1>.............................
+   C: 0032have <common #2>.............................
+   ....
+   C: 0032have <have #1>...............................
+   C: 0032have <have #2>...............................
+   ....
+   C: 0000
+
+The stream is organized into "commands", with each command
+appearing by itself in a pkt-line.  Within a command line
+the text leading up to the first space is the command name,
+and the remainder of the line to the first LF is the value.
+Command lines are terminated with an LF as the last byte of
+the pkt-line value.
+
+Commands MUST appear in the following order, if they appear
+at all in the request stream:
+
+* "want"
+* "have"
+
+The stream is terminated by a pkt-line flush (`0000`).
+
+A single "want" or "have" command MUST have one hex formatted
+SHA-1 as its value.  Multiple SHA-1s MUST be sent by sending
+multiple commands.
+
+The `have` list is created by popping the first 32 commits
+from `c_pending`.  Less can be supplied if `c_pending` empties.
+
+If the client has sent 256 "have" commits and has not yet
+received one of those back from `s_common`, or the client has
+emptied `c_pending` it SHOULD include a "done" command to let
+the server know it won't proceed:
+
+   C: 0009done
+
+S: Parse the git-upload-pack request:
+
+Verify all objects in `want` are directly reachable from refs.
+
+The server MAY walk backwards through history or through
+the reflog to permit slightly stale requests.
+
+If no "want" objects are received, send an error:
+TODO: Define error if no "want" lines are requested.
+
+If any "want" object is not reachable, send an error:
+TODO: Define error if an invalid "want" is requested.
+
+Create an empty list, `s_common`.
+
+If "have" was sent:
+
+Loop through the objects in the order supplied by the client.
+
+For each object, if the server has the object reachable from
+a ref, add it to `s_common`.  If a commit is added to `s_common`,
+do not add any ancestors, even if they also appear in `have`.
+
+S: Send the git-upload-pack response:
+
+If the server has found a closed set of objects to pack or the
+request ends with "done", it replies with the pack.
+TODO: Document the pack based response
+
+   S: PACK...
+
+The returned stream is the side-band-64k protocol supported
+by the git-upload-pack service, and the pack is embedded into
+stream 1.  Progress messages from the server side MAY appear
+in stream 2.
+
+Here a "closed set of objects" is defined to have at least
+one path from every "want" to at least one "common" object.
+
+If the server needs more information, it replies with a
+status continue response:
+TODO: Document the non-pack response
+
+C: Parse the upload-pack response:
+   TODO: Document parsing response
+
+'Do another compute step.'
+
+
+Smart Service git-receive-pack
+------------------------------
+This service reads from the repository pointed to by `$GIT_URL`.
+
+Clients MUST first perform ref discovery with
+`$GIT_URL/info/refs?service=git-receive-pack`.
+
+   C: POST $GIT_URL/git-receive-pack HTTP/1.0
+   C: Content-Type: application/x-git-receive-pack-request
+   C:
+   C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\0 report-status
+   C: 0000
+   C: PACK....
+
+   S: 200 OK
+   S: Content-Type: application/x-git-receive-pack-result
+   S: Cache-Control: no-cache
+   S:
+   S: ....
+
+Clients MUST NOT reuse or revalidate a cached response.
+Servers MUST include sufficient Cache-Control headers
+to prevent caching of the response.
+
+Servers SHOULD support all capabilities defined here.
+
+Clients MUST send at least one command in the request body.
+Within the command portion of the request body clients SHOULD send
+the id obtained through ref discovery as old_id.
+
+  update_request  =  command_list
+		     "PACK" <binary data>
+
+  command_list    =  PKT-LINE(command NUL cap_list LF)
+		     *(command_pkt)
+  command_pkt     =  PKT-LINE(command LF)
+  cap_list        =  *(SP capability) SP
+
+  command         =  create / delete / update
+  create          =  zero-id SP new_id SP name
+  delete          =  old_id SP zero-id SP name
+  update          =  old_id SP new_id SP name
+
+TODO: Document this further.
+
+
+References
+----------
+
+link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]
+link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]
+link:technical/pack-protocol.html
+link:technical/protocol-capabilities.html
diff --git a/Documentation/technical/pack-heuristics.txt b/Documentation/technical/pack-heuristics.txt
index 8b7ae1c..95a07db 100644
--- a/Documentation/technical/pack-heuristics.txt
+++ b/Documentation/technical/pack-heuristics.txt
@@ -1,5 +1,5 @@
-        Concerning Git's Packing Heuristics
-        ===================================
+Concerning Git's Packing Heuristics
+===================================
 
         Oh, here's a really stupid question:
 
@@ -366,12 +366,6 @@
 
     <linus> Yes, we always write out most recent first
 
-For the other record:
-
-    <pasky> njs`: http://pastebin.com/547965
-
-The 'net never forgets, so that should be good until the end of time.
-
     <njs`> And, yeah, I got the part about deeper-in-history stuff
         having worse IO characteristics, one sort of doesn't care.
 
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index b898e97..c73b62f 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -161,6 +161,7 @@
 
 ----
   advertised-refs  =  (no-refs / list-of-refs)
+		      *shallow
 		      flush-pkt
 
   no-refs          =  PKT-LINE(zero-id SP "capabilities^{}"
@@ -174,6 +175,8 @@
   other-tip        =  obj-id SP refname LF
   other-peeled     =  obj-id SP refname "^{}" LF
 
+  shallow          =  PKT-LINE("shallow" SP obj-id)
+
   capability-list  =  capability *(SP capability)
   capability       =  1*(LC_ALPHA / DIGIT / "-" / "_")
   LC_ALPHA         =  %x61-7A
@@ -461,7 +464,9 @@
 references.
 
 ----
-  update-request    =  command-list [pack-file]
+  update-request    =  *shallow command-list [pack-file]
+
+  shallow           =  PKT-LINE("shallow" SP obj-id)
 
   command-list      =  PKT-LINE(command NUL capability-list LF)
 		       *PKT-LINE(command LF)
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index fd8ffa5..e3e7924 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -72,14 +72,29 @@
 thin-pack
 ---------
 
-This capability means that the server can send a 'thin' pack, a pack
-which does not contain base objects; if those base objects are available
-on client side. Client requests 'thin-pack' capability when it
-understands how to "thicken" it by adding required delta bases making
-it self-contained.
+A thin pack is one with deltas which reference base objects not
+contained within the pack (but are known to exist at the receiving
+end). This can reduce the network traffic significantly, but it
+requires the receiving end to know how to "thicken" these packs by
+adding the missing bases to the pack.
 
-Client MUST NOT request 'thin-pack' capability if it cannot turn a thin
-pack into a self-contained pack.
+The upload-pack server advertises 'thin-pack' when it can generate
+and send a thin pack. A client requests the 'thin-pack' capability
+when it understands how to "thicken" it, notifying the server that
+it can receive such a pack. A client MUST NOT request the
+'thin-pack' capability if it cannot turn a thin pack into a
+self-contained pack.
+
+Receive-pack, on the other hand, is assumed by default to be able to
+handle thin packs, but can ask the client not to use the feature by
+advertising the 'no-thin' capability. A client MUST NOT send a thin
+pack if the server advertises the 'no-thin' capability.
+
+The reasons for this asymmetry are historical. The receive-pack
+program did not exist until after the invention of thin packs, so
+historically the reference implementation of receive-pack always
+understood thin packs. Adding 'no-thin' later allowed receive-pack
+to disable the feature in a backwards-compatible manner.
 
 
 side-band, side-band-64k
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index fe723e4..248dcab 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -1,6 +1,5 @@
-Git User's Manual (for version 1.5.3 or newer)
-______________________________________________
-
+Git User Manual
+===============
 
 Git is a fast distributed revision control system.
 
@@ -220,7 +219,7 @@
 
 The best way to see how this works is using the linkgit:gitk[1]
 command; running gitk now on a Git repository and looking for merge
-commits will help understand how the Git organizes history.
+commits will help understand how Git organizes history.
 
 In the following, we say that commit X is "reachable" from commit Y
 if commit X is an ancestor of commit Y.  Equivalently, you could say
@@ -269,27 +268,23 @@
 a summary of the commands:
 
 `git branch`::
-	list all branches
+	list all branches.
 `git branch <branch>`::
 	create a new branch named `<branch>`, referencing the same
-	point in history as the current branch
+	point in history as the current branch.
 `git branch <branch> <start-point>`::
 	create a new branch named `<branch>`, referencing
 	`<start-point>`, which may be specified any way you like,
-	including using a branch name or a tag name
+	including using a branch name or a tag name.
 `git branch -d <branch>`::
-	delete the branch `<branch>`; if the branch you are deleting
-	points to a commit which is not reachable from the current
-	branch, this command will fail with a warning.
+	delete the branch `<branch>`; if the branch is not fully
+	merged in its upstream branch or contained in the current branch,
+	this command will fail with a warning.
 `git branch -D <branch>`::
-	even if the branch points to a commit not reachable
-	from the current branch, you may know that that commit
-	is still reachable from some other branch or tag.  In that
-	case it is safe to use this command to force Git to delete
-	the branch.
+	delete the branch `<branch>` irrespective of its merged status.
 `git checkout <branch>`::
 	make the current branch `<branch>`, updating the working
-	directory to reflect the version referenced by `<branch>`
+	directory to reflect the version referenced by `<branch>`.
 `git checkout -b <new> <start-point>`::
 	create a new branch `<new>` referencing `<start-point>`, and
 	check it out.
@@ -313,10 +308,17 @@
 
 ------------------------------------------------
 $ git checkout v2.6.17
-Note: moving to "v2.6.17" which isn't a local branch
-If you want to create a new branch from this checkout, you may do so
-(now or later) by using -b with the checkout command again. Example:
-  git checkout -b <new_branch_name>
+Note: checking out 'v2.6.17'.
+
+You are in 'detached HEAD' state. You can look around, make experimental
+changes and commit them, and you can discard any commits you make in this
+state without impacting any branches by performing another checkout.
+
+If you want to create a new branch to retain commits you create, you may
+do so (now or later) by using -b with the checkout command again. Example:
+
+  git checkout -b new_branch_name
+
 HEAD is now at 427abfa... Linux v2.6.17
 ------------------------------------------------
 
@@ -327,7 +329,7 @@
 $ cat .git/HEAD
 427abfa28afedffadfca9dd8b067eb6d36bac53f
 $ git branch
-* (no branch)
+* (detached from v2.6.17)
   master
 ------------------------------------------------
 
@@ -787,7 +789,7 @@
 -------------------------------------------------
 
 Or you could recall that the `...` operator selects all commits
-contained reachable from either one reference or the other but not
+reachable from either one reference or the other but not
 both; so
 
 -------------------------------------------------
@@ -814,7 +816,7 @@
 $ gitk e05db0fd..
 -------------------------------------------------
 
-Or you can use linkgit:git-name-rev[1], which will give the commit a
+or you can use linkgit:git-name-rev[1], which will give the commit a
 name based on any tag it finds pointing to one of the commit's
 descendants:
 
@@ -858,8 +860,8 @@
 
 As yet another alternative, the linkgit:git-show-branch[1] command lists
 the commits reachable from its arguments with a display on the left-hand
-side that indicates which arguments that commit is reachable from.  So,
-you can run something like
+side that indicates which arguments that commit is reachable from.
+So, if you run something like
 
 -------------------------------------------------
 $ git show-branch e05db0fd v1.5.0-rc0 v1.5.0-rc1 v1.5.0-rc2
@@ -871,15 +873,15 @@
 ...
 -------------------------------------------------
 
-then search for a line that looks like
+then a line like
 
 -------------------------------------------------
 + ++ [e05db0fd] Fix warnings in sha1_file.c - use C99 printf format if
 available
 -------------------------------------------------
 
-Which shows that e05db0fd is reachable from itself, from v1.5.0-rc1, and
-from v1.5.0-rc2, but not from v1.5.0-rc0.
+shows that e05db0fd is reachable from itself, from v1.5.0-rc1,
+and from v1.5.0-rc2, and not from v1.5.0-rc0.
 
 [[showing-commits-unique-to-a-branch]]
 Showing commits unique to a given branch
@@ -1074,19 +1076,13 @@
 
 Modifying the index is easy:
 
-To update the index with the new contents of a modified file, use
+To update the index with the contents of a new or modified file, use
 
 -------------------------------------------------
 $ git add path/to/file
 -------------------------------------------------
 
-To add the contents of a new file to the index, use
-
--------------------------------------------------
-$ git add path/to/file
--------------------------------------------------
-
-To remove a file from the index and from the working tree,
+To remove a file from the index and from the working tree, use
 
 -------------------------------------------------
 $ git rm path/to/file
@@ -1787,7 +1783,7 @@
 $ git merge branch
 -------------------------------------------------
 
-are roughly equivalent.  The former is actually very commonly used.
+are roughly equivalent.
 
 [[submitting-patches]]
 Submitting patches to a project
@@ -1977,7 +1973,7 @@
 -------------------------------------------------
 
 (See also
-link:howto/setup-git-server-over-http.txt[setup-git-server-over-http]
+link:howto/setup-git-server-over-http.html[setup-git-server-over-http]
 for a slightly more sophisticated setup using WebDAV which also
 allows pushing over HTTP.)
 
@@ -2249,11 +2245,11 @@
 $ ... patch ... test  ... commit [ ... patch ... test ... commit ]*
 -------------------------------------------------
 
-When you are happy with the state of this change, you can pull it into the
+When you are happy with the state of this change, you can merge it into the
 "test" branch in preparation to make it public:
 
 -------------------------------------------------
-$ git checkout test && git pull . speed-up-spinlocks
+$ git checkout test && git merge speed-up-spinlocks
 -------------------------------------------------
 
 It is unlikely that you would have any conflicts here ... but you might if you
@@ -2265,7 +2261,7 @@
 means that the patches can be moved into the `release` tree in any order.
 
 -------------------------------------------------
-$ git checkout release && git pull . speed-up-spinlocks
+$ git checkout release && git merge speed-up-spinlocks
 -------------------------------------------------
 
 After a while, you will have a number of branches, and despite the
@@ -3191,23 +3187,21 @@
 You can save space and make Git faster by moving these loose objects in
 to a "pack file", which stores a group of objects in an efficient
 compressed format; the details of how pack files are formatted can be
-found in link:technical/pack-format.txt[technical/pack-format.txt].
+found in link:technical/pack-format.html[pack format].
 
 To put the loose objects into a pack, just run git repack:
 
 ------------------------------------------------
 $ git repack
-Generating pack...
-Done counting 6020 objects.
-Deltifying 6020 objects.
- 100% (6020/6020) done
-Writing 6020 objects.
- 100% (6020/6020) done
-Total 6020, written 6020 (delta 4070), reused 0 (delta 0)
-Pack pack-3e54ad29d5b2e05838c75df582c65257b8d08e1c created.
+Counting objects: 6020, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (6020/6020), done.
+Writing objects: 100% (6020/6020), done.
+Total 6020 (delta 4070), reused 0 (delta 0)
 ------------------------------------------------
 
-You can then run
+This creates a single "pack file" in .git/objects/pack/
+containing all currently unpacked objects.  You can then run
 
 ------------------------------------------------
 $ git prune
@@ -3305,17 +3299,11 @@
 $ git prune
 ------------------------------------------------
 
-and they'll be gone. But you should only run `git prune` on a quiescent
+and they'll be gone. (You should only run `git prune` on a quiescent
 repository--it's kind of like doing a filesystem fsck recovery: you
 don't want to do that while the filesystem is mounted.
-
-(The same is true of `git fsck` itself, btw, but since
-`git fsck` never actually *changes* the repository, it just reports
-on what it found, `git fsck` itself is never 'dangerous' to run.
-Running it while somebody is actually changing the repository can cause
-confusing and scary messages, but it won't actually do anything bad. In
-contrast, running `git prune` while somebody is actively changing the
-repository is a *BAD* idea).
+`git prune` is designed not to cause any harm in such cases of concurrent
+accesses to a repository but you might receive confusing or scary messages.)
 
 [[recovering-from-repository-corruption]]
 Recovering from repository corruption
@@ -3538,7 +3526,7 @@
 manually check them out; earlier versions won't recognize the submodules at
 all.
 
-To see how submodule support works, create (for example) four example
+To see how submodule support works, create four example
 repositories that can be used later as a submodule:
 
 -------------------------------------------------
@@ -3640,7 +3628,7 @@
 
 -------------------------------------------------
 $ git branch
-* (no branch)
+* (detached from d266b98)
   master
 -------------------------------------------------
 
@@ -3910,7 +3898,7 @@
 previous states represented by other commits.
 
 In other words, while a "tree" represents a particular directory state
-of a working directory, a "commit" represents that state in "time",
+of a working directory, a "commit" represents that state in time,
 and explains how we got there.
 
 You create a commit object by giving it the tree that describes the
@@ -3930,8 +3918,7 @@
 result to the file pointed at by `.git/HEAD`, so that we can always see
 what the last committed state was.
 
-Here is an ASCII art by Jon Loeliger that illustrates how
-various pieces fit together.
+Here is a picture that illustrates how various pieces fit together:
 
 ------------
 
@@ -4010,27 +3997,26 @@
 Merging multiple trees
 ----------------------
 
-Git helps you do a three-way merge, which you can expand to n-way by
-repeating the merge procedure arbitrary times until you finally
-"commit" the state.  The normal situation is that you'd only do one
-three-way merge (two parents), and commit it, but if you like to, you
-can do multiple parents in one go.
+Git can help you perform a three-way merge, which can in turn be
+used for a many-way merge by repeating the merge procedure several
+times.  The usual situation is that you only do one three-way merge
+(reconciling two lines of history) and commit the result, but if
+you like to, you can merge several branches in one go.
 
-To do a three-way merge, you need the two sets of "commit" objects
-that you want to merge, use those to find the closest common parent (a
-third "commit" object), and then use those commit objects to find the
-state of the directory ("tree" object) at these points.
+To perform a three-way merge, you start with the two commits you
+want to merge, find their closest common parent (a third commit),
+and compare the trees corresponding to these three commits.
 
-To get the "base" for the merge, you first look up the common parent
-of two commits with
+To get the "base" for the merge, look up the common parent of two
+commits:
 
 -------------------------------------------------
 $ git merge-base <commit1> <commit2>
 -------------------------------------------------
 
-which will return you the commit they are both based on.  You should
-now look up the "tree" objects of those commits, which you can easily
-do with (for example)
+This prints the name of a commit they are both based on. You should
+now look up the tree objects of those commits, which you can easily
+do with
 
 -------------------------------------------------
 $ git cat-file commit <commitname> | head -1
@@ -4152,8 +4138,6 @@
 that is used to name the object is the hash of the original data
 plus this header, so `sha1sum` 'file' does not match the object name
 for 'file'.
-(Historical note: in the dawn of the age of Git the hash
-was the SHA-1 of the 'compressed' object.)
 
 As a result, the general consistency of an object can always be tested
 independently of the contents or the type of the object: all objects can
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 919a1d4..e66a5ab 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.8.4.5
+DEF_VER=v1.9-rc0
 
 LF='
 '
diff --git a/Makefile b/Makefile
index 4026211..dddaf4f 100644
--- a/Makefile
+++ b/Makefile
@@ -452,7 +452,6 @@
 SCRIPT_SH += git-bisect.sh
 SCRIPT_SH += git-difftool--helper.sh
 SCRIPT_SH += git-filter-branch.sh
-SCRIPT_SH += git-lost-found.sh
 SCRIPT_SH += git-merge-octopus.sh
 SCRIPT_SH += git-merge-one-file.sh
 SCRIPT_SH += git-merge-resolve.sh
@@ -461,7 +460,6 @@
 SCRIPT_SH += git-quiltimport.sh
 SCRIPT_SH += git-rebase.sh
 SCRIPT_SH += git-remote-testgit.sh
-SCRIPT_SH += git-repack.sh
 SCRIPT_SH += git-request-pull.sh
 SCRIPT_SH += git-stash.sh
 SCRIPT_SH += git-submodule.sh
@@ -485,11 +483,9 @@
 SCRIPT_PERL += git-send-email.perl
 SCRIPT_PERL += git-svn.perl
 
-SCRIPT_PYTHON += git-remote-testpy.py
 SCRIPT_PYTHON += git-p4.py
 
 NO_INSTALL += git-remote-testgit
-NO_INSTALL += git-remote-testpy
 
 # Generated files for scripts
 SCRIPT_SH_GEN = $(patsubst %.sh,%,$(SCRIPT_SH))
@@ -577,6 +573,7 @@
 TEST_PROGRAMS_NEED_X += test-string-list
 TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
+TEST_PROGRAMS_NEED_X += test-urlmatch-normalization
 TEST_PROGRAMS_NEED_X += test-wildmatch
 
 TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
@@ -589,11 +586,8 @@
 BUILT_INS += git-cherry-pick$X
 BUILT_INS += git-format-patch$X
 BUILT_INS += git-fsck-objects$X
-BUILT_INS += git-get-tar-commit-id$X
 BUILT_INS += git-init$X
 BUILT_INS += git-merge-subtree$X
-BUILT_INS += git-peek-remote$X
-BUILT_INS += git-repo-config$X
 BUILT_INS += git-show$X
 BUILT_INS += git-stage$X
 BUILT_INS += git-status$X
@@ -733,6 +727,7 @@
 LIB_H += tree.h
 LIB_H += unpack-trees.h
 LIB_H += url.h
+LIB_H += urlmatch.h
 LIB_H += userdiff.h
 LIB_H += utf8.h
 LIB_H += varint.h
@@ -883,6 +878,7 @@
 LIB_OBJS += tree-walk.o
 LIB_OBJS += unpack-trees.o
 LIB_OBJS += url.o
+LIB_OBJS += urlmatch.o
 LIB_OBJS += usage.o
 LIB_OBJS += userdiff.o
 LIB_OBJS += utf8.o
@@ -932,6 +928,7 @@
 BUILTIN_OBJS += builtin/for-each-ref.o
 BUILTIN_OBJS += builtin/fsck.o
 BUILTIN_OBJS += builtin/gc.o
+BUILTIN_OBJS += builtin/get-tar-commit-id.o
 BUILTIN_OBJS += builtin/grep.o
 BUILTIN_OBJS += builtin/hash-object.o
 BUILTIN_OBJS += builtin/help.o
@@ -968,6 +965,7 @@
 BUILTIN_OBJS += builtin/remote.o
 BUILTIN_OBJS += builtin/remote-ext.o
 BUILTIN_OBJS += builtin/remote-fd.o
+BUILTIN_OBJS += builtin/repack.o
 BUILTIN_OBJS += builtin/replace.o
 BUILTIN_OBJS += builtin/rerere.o
 BUILTIN_OBJS += builtin/reset.o
@@ -982,7 +980,6 @@
 BUILTIN_OBJS += builtin/stripspace.o
 BUILTIN_OBJS += builtin/symbolic-ref.o
 BUILTIN_OBJS += builtin/tag.o
-BUILTIN_OBJS += builtin/tar-tree.o
 BUILTIN_OBJS += builtin/unpack-file.o
 BUILTIN_OBJS += builtin/unpack-objects.o
 BUILTIN_OBJS += builtin/update-index.o
@@ -1179,6 +1176,9 @@
 else
 	LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto
 endif
+ifdef APPLE_COMMON_CRYPTO
+	LIB_4_CRYPTO += -framework Security -framework CoreFoundation
+endif
 endif
 ifdef NEEDS_LIBICONV
 	ifdef ICONVDIR
@@ -1584,6 +1584,7 @@
 PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
 TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
 DIFF_SQ = $(subst ','\'',$(DIFF))
+PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA))
 
 LIBS = $(GITLIBS) $(EXTLIBS)
 
@@ -1659,9 +1660,6 @@
 ifndef NO_PERL
 	$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' localedir='$(localedir_SQ)' all
 endif
-ifndef NO_PYTHON
-	$(QUIET_SUBDIR0)git_remote_helpers $(QUIET_SUBDIR1) PYTHON_PATH='$(PYTHON_PATH_SQ)' prefix='$(prefix_SQ)' all
-endif
 	$(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)'
 
 please_set_SHELL_PATH_to_a_more_modern_shell:
@@ -1775,7 +1773,7 @@
 
 git.res: git.rc GIT-VERSION-FILE
 	$(QUIET_RC)$(RC) \
-	  $(join -DMAJOR= -DMINOR= -DPATCH=, $(wordlist 1,3,$(subst -, ,$(subst ., ,$(GIT_VERSION))))) \
+	  $(join -DMAJOR= -DMINOR=, $(wordlist 1,2,$(subst -, ,$(subst ., ,$(GIT_VERSION))))) \
 	  -DGIT_VERSION="\\\"$(GIT_VERSION)\\\"" $< -o $@
 
 ifndef NO_PERL
@@ -1791,9 +1789,12 @@
 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)
 
-$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl GIT-VERSION-FILE
+PERL_DEFINES = $(PERL_PATH_SQ):$(PERLLIB_EXTRA_SQ)
+$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl perl/perl.mak GIT-PERL-DEFINES GIT-VERSION-FILE
 	$(QUIET_GEN)$(RM) $@ $@+ && \
 	INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
+	INSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \
+	INSTLIBDIR="$$INSTLIBDIR$${INSTLIBDIR_EXTRA:+:$$INSTLIBDIR_EXTRA}" && \
 	sed -e '1{' \
 	    -e '	s|#!.*perl|#!$(PERL_PATH_SQ)|' \
 	    -e '	h' \
@@ -1806,6 +1807,13 @@
 	chmod +x $@+ && \
 	mv $@+ $@
 
+GIT-PERL-DEFINES: FORCE
+	@FLAGS='$(PERL_DEFINES)'; \
+	    if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \
+		echo >&2 "    * new perl-specific parameters"; \
+		echo "$$FLAGS" >$@; \
+	    fi
+
 
 .PHONY: gitweb
 gitweb:
@@ -1829,12 +1837,7 @@
 $(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS
 $(SCRIPT_PYTHON_GEN): % : %.py
 	$(QUIET_GEN)$(RM) $@ $@+ && \
-	INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C git_remote_helpers -s \
-		--no-print-directory prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' \
-		instlibdir` && \
 	sed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \
-	    -e 's|\(os\.getenv("GITPYTHONLIB"\)[^)]*)|\1,"@@INSTLIBDIR@@")|' \
-	    -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
 	    $< >$@+ && \
 	chmod +x $@+ && \
 	mv $@+ $@
@@ -2022,6 +2025,9 @@
 gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \
 	-DGIT_LOCALE_PATH='"$(localedir_SQ)"'
 
+http-push.sp http.sp http-walker.sp remote-curl.sp: SPARSE_FLAGS += \
+	-DCURL_DISABLE_TYPECHECK
+
 ifdef NO_EXPAT
 http-walker.sp http-walker.s http-walker.o: EXTRA_CPPFLAGS = -DNO_EXPAT
 endif
@@ -2044,10 +2050,10 @@
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO)
 
-git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o GIT-LDFLAGS $(GITLIBS)
+git-http-fetch$X: http.o http-walker.o http-fetch.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(CURL_LIBCURL)
-git-http-push$X: revision.o http.o http-push.o GIT-LDFLAGS $(GITLIBS)
+git-http-push$X: http.o http-push.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
 
@@ -2341,9 +2347,6 @@
 	$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
 	$(MAKE) -C gitweb install
 endif
-ifndef NO_PYTHON
-	$(MAKE) -C git_remote_helpers prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
-endif
 ifndef NO_TCLTK
 	$(MAKE) -C gitk-git install
 	$(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install
@@ -2491,9 +2494,6 @@
 	$(MAKE) -C gitweb clean
 	$(MAKE) -C perl clean
 endif
-ifndef NO_PYTHON
-	$(MAKE) -C git_remote_helpers clean
-endif
 	$(MAKE) -C templates/ clean
 	$(MAKE) -C t/ clean
 ifndef NO_TCLTK
@@ -2501,7 +2501,8 @@
 	$(MAKE) -C git-gui clean
 endif
 	$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS
-	$(RM) GIT-USER-AGENT GIT-PREFIX GIT-SCRIPT-DEFINES GIT-PYTHON-VARS
+	$(RM) GIT-USER-AGENT GIT-PREFIX
+	$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PYTHON-VARS
 
 .PHONY: all install profile-clean clean strip
 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/RelNotes b/RelNotes
index cb02f31..c300119 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.8.4.5.txt
\ No newline at end of file
+Documentation/RelNotes/1.9.txt
\ No newline at end of file
diff --git a/abspath.c b/abspath.c
index 64adbe2..ca33558 100644
--- a/abspath.c
+++ b/abspath.c
@@ -110,7 +110,7 @@
 				else
 					goto error_out;
 			}
-			if (len && !is_dir_sep(buf[len-1]))
+			if (len && !is_dir_sep(buf[len - 1]))
 				buf[len++] = '/';
 			strcpy(buf + len, last_elem);
 			free(last_elem);
@@ -143,7 +143,7 @@
 error_out:
 	free(last_elem);
 	if (*cwd && chdir(cwd))
-		die_errno ("Could not change back to '%s'", cwd);
+		die_errno("Could not change back to '%s'", cwd);
 
 	return retval;
 }
@@ -201,7 +201,7 @@
 		if (!cwd)
 			die_errno("Cannot determine the current working directory");
 		len = strlen(cwd);
-		fmt = (len > 0 && is_dir_sep(cwd[len-1])) ? "%s%s" : "%s/%s";
+		fmt = (len > 0 && is_dir_sep(cwd[len - 1])) ? "%s%s" : "%s/%s";
 		if (snprintf(buf, PATH_MAX, fmt, cwd, path) >= PATH_MAX)
 			die("Too long path: %.*s", 60, path);
 	}
@@ -215,23 +215,25 @@
  */
 const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
 {
-	static char path[PATH_MAX];
+	static struct strbuf path = STRBUF_INIT;
 #ifndef GIT_WINDOWS_NATIVE
 	if (!pfx_len || is_absolute_path(arg))
 		return arg;
-	memcpy(path, pfx, pfx_len);
-	strcpy(path + pfx_len, arg);
+	strbuf_reset(&path);
+	strbuf_add(&path, pfx, pfx_len);
+	strbuf_addstr(&path, arg);
 #else
 	char *p;
 	/* don't add prefix to absolute paths, but still replace '\' by '/' */
+	strbuf_reset(&path);
 	if (is_absolute_path(arg))
 		pfx_len = 0;
 	else if (pfx_len)
-		memcpy(path, pfx, pfx_len);
-	strcpy(path + pfx_len, arg);
-	for (p = path + pfx_len; *p; p++)
+		strbuf_add(&path, pfx, pfx_len);
+	strbuf_addstr(&path, arg);
+	for (p = path.buf + pfx_len; *p; p++)
 		if (*p == '\\')
 			*p = '/';
 #endif
-	return path;
+	return path.buf;
 }
diff --git a/alias.c b/alias.c
index eb9f08b..5efc3d6 100644
--- a/alias.c
+++ b/alias.c
@@ -5,7 +5,7 @@
 
 static int alias_lookup_cb(const char *k, const char *v, void *cb)
 {
-	if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) {
+	if (starts_with(k, "alias.") && !strcmp(k + 6, alias_key)) {
 		if (!v)
 			return config_error_nonbool(k);
 		alias_val = xstrdup(v);
@@ -34,7 +34,7 @@
 	int src, dst, count = 0, size = 16;
 	char quoted = 0;
 
-	*argv = xmalloc(sizeof(char *) * size);
+	*argv = xmalloc(sizeof(**argv) * size);
 
 	/* split alias_string */
 	(*argv)[count++] = cmdline;
@@ -45,7 +45,7 @@
 			while (cmdline[++src]
 					&& isspace(cmdline[src]))
 				; /* skip */
-			ALLOC_GROW(*argv, count+1, size);
+			ALLOC_GROW(*argv, count + 1, size);
 			(*argv)[count++] = cmdline + dst;
 		} else if (!quoted && (c == '\'' || c == '"')) {
 			quoted = c;
@@ -76,12 +76,13 @@
 		return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
 	}
 
-	ALLOC_GROW(*argv, count+1, size);
+	ALLOC_GROW(*argv, count + 1, size);
 	(*argv)[count] = NULL;
 
 	return count;
 }
 
-const char *split_cmdline_strerror(int split_cmdline_errno) {
-	return split_cmdline_errors[-split_cmdline_errno-1];
+const char *split_cmdline_strerror(int split_cmdline_errno)
+{
+	return split_cmdline_errors[-split_cmdline_errno - 1];
 }
diff --git a/alloc.c b/alloc.c
index aeae55c..f3ee745 100644
--- a/alloc.c
+++ b/alloc.c
@@ -58,7 +58,7 @@
 }
 
 #define REPORT(name)	\
-    report(#name, name##_allocs, name##_allocs*sizeof(struct name) >> 10)
+    report(#name, name##_allocs, name##_allocs * sizeof(struct name) >> 10)
 
 void alloc_report(void)
 {
diff --git a/archive.c b/archive.c
index d254fa5..346f3b2 100644
--- a/archive.c
+++ b/archive.c
@@ -151,7 +151,6 @@
 	struct archiver_context context;
 	struct unpack_trees_options opts;
 	struct tree_desc t;
-	struct pathspec pathspec;
 	int err;
 
 	if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
@@ -186,10 +185,8 @@
 		git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
 	}
 
-	init_pathspec(&pathspec, args->pathspec);
-	err = read_tree_recursive(args->tree, "", 0, 0, &pathspec,
+	err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
 				  write_archive_entry, &context);
-	free_pathspec(&pathspec);
 	if (err == READ_TREE_RECURSIVE)
 		err = 0;
 	return err;
@@ -222,7 +219,7 @@
 	struct pathspec pathspec;
 	int ret;
 
-	init_pathspec(&pathspec, paths);
+	parse_pathspec(&pathspec, 0, 0, "", paths);
 	ret = read_tree_recursive(tree, "", 0, 0, &pathspec, reject_entry, NULL);
 	free_pathspec(&pathspec);
 	return ret != 0;
@@ -231,11 +228,18 @@
 static void parse_pathspec_arg(const char **pathspec,
 		struct archiver_args *ar_args)
 {
-	ar_args->pathspec = pathspec = get_pathspec("", pathspec);
+	/*
+	 * must be consistent with parse_pathspec in path_exists()
+	 * Also if pathspec patterns are dependent, we're in big
+	 * trouble as we test each one separately
+	 */
+	parse_pathspec(&ar_args->pathspec, 0,
+		       PATHSPEC_PREFER_FULL,
+		       "", pathspec);
 	if (pathspec) {
 		while (*pathspec) {
 			if (**pathspec && !path_exists(ar_args->tree, *pathspec))
-				die("path not found: %s", *pathspec);
+				die(_("pathspec '%s' did not match any files"), *pathspec);
 			pathspec++;
 		}
 	}
@@ -436,7 +440,7 @@
 	 * prefix is non-empty (k.e., we don't match .tar.gz with no actual
 	 * filename).
 	 */
-	if (prefixlen < 2 || filename[prefixlen-1] != '.')
+	if (prefixlen < 2 || filename[prefixlen - 1] != '.')
 		return 0;
 	return !strcmp(filename + prefixlen, ext);
 }
diff --git a/archive.h b/archive.h
index 895afcd..4a791e1 100644
--- a/archive.h
+++ b/archive.h
@@ -1,6 +1,8 @@
 #ifndef ARCHIVE_H
 #define ARCHIVE_H
 
+#include "pathspec.h"
+
 struct archiver_args {
 	const char *base;
 	size_t baselen;
@@ -8,7 +10,7 @@
 	const unsigned char *commit_sha1;
 	const struct commit *commit;
 	time_t time;
-	const char **pathspec;
+	struct pathspec pathspec;
 	unsigned int verbose : 1;
 	unsigned int worktree_attributes : 1;
 	unsigned int convert : 1;
diff --git a/attr.c b/attr.c
index 0e774c6..8d13d70 100644
--- a/attr.c
+++ b/attr.c
@@ -211,7 +211,7 @@
 	name = cp;
 	namelen = strcspn(name, blank);
 	if (strlen(ATTRIBUTE_MACRO_PREFIX) < namelen &&
-	    !prefixcmp(name, ATTRIBUTE_MACRO_PREFIX)) {
+	    starts_with(name, ATTRIBUTE_MACRO_PREFIX)) {
 		if (!macro_ok) {
 			fprintf(stderr, "%s not allowed: %s:%d\n",
 				name, src, lineno);
diff --git a/base85.c b/base85.c
index 781b575..5ca601e 100644
--- a/base85.c
+++ b/base85.c
@@ -41,7 +41,7 @@
 {
 	prep_base85();
 
-	say2("decode 85 <%.*s>", len/4*5, buffer);
+	say2("decode 85 <%.*s>", len / 4 * 5, buffer);
 	while (len) {
 		unsigned acc = 0;
 		int de, cnt = 4;
diff --git a/bisect.c b/bisect.c
index 1e46a4f..37200b4 100644
--- a/bisect.c
+++ b/bisect.c
@@ -406,9 +406,9 @@
 	if (!strcmp(refname, "bad")) {
 		current_bad_sha1 = xmalloc(20);
 		hashcpy(current_bad_sha1, sha1);
-	} else if (!prefixcmp(refname, "good-")) {
+	} else if (starts_with(refname, "good-")) {
 		sha1_array_append(&good_revs, sha1);
-	} else if (!prefixcmp(refname, "skip-")) {
+	} else if (starts_with(refname, "skip-")) {
 		sha1_array_append(&skipped_revs, sha1);
 	}
 
diff --git a/block-sha1/sha1.c b/block-sha1/sha1.c
index a8d4bf9..e1a1eb6 100644
--- a/block-sha1/sha1.c
+++ b/block-sha1/sha1.c
@@ -274,10 +274,10 @@
 	padlen[1] = htonl((uint32_t)(ctx->size << 3));
 
 	i = ctx->size & 63;
-	blk_SHA1_Update(ctx, pad, 1+ (63 & (55 - i)));
+	blk_SHA1_Update(ctx, pad, 1 + (63 & (55 - i)));
 	blk_SHA1_Update(ctx, padlen, 8);
 
 	/* Output hash */
 	for (i = 0; i < 5; i++)
-		put_be32(hashout + i*4, ctx->H[i]);
+		put_be32(hashout + i * 4, ctx->H[i]);
 }
diff --git a/branch.c b/branch.c
index 2d15c19..723a36b 100644
--- a/branch.c
+++ b/branch.c
@@ -50,7 +50,7 @@
 void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
 {
 	const char *shortname = remote + 11;
-	int remote_is_branch = !prefixcmp(remote, "refs/heads/");
+	int remote_is_branch = starts_with(remote, "refs/heads/");
 	struct strbuf key = STRBUF_INIT;
 	int rebasing = should_setup_rebase(origin);
 
@@ -272,7 +272,7 @@
 		break;
 	case 1:
 		/* Unique completion -- good, only if it is a real branch */
-		if (prefixcmp(real_ref, "refs/heads/") &&
+		if (!starts_with(real_ref, "refs/heads/") &&
 		    validate_remote_tracking_branch(real_ref)) {
 			if (explicit_tracking)
 				die(_(upstream_not_branch), start_name);
@@ -290,7 +290,7 @@
 	hashcpy(sha1, commit->object.sha1);
 
 	if (!dont_change_ref) {
-		lock = lock_any_ref_for_update(ref.buf, NULL, 0);
+		lock = lock_any_ref_for_update(ref.buf, NULL, 0, NULL);
 		if (!lock)
 			die_errno(_("Failed to lock ref for update"));
 	}
@@ -306,7 +306,7 @@
 			 start_name);
 
 	if (real_ref && track)
-		setup_tracking(ref.buf+11, real_ref, track, quiet);
+		setup_tracking(ref.buf + 11, real_ref, track, quiet);
 
 	if (!dont_change_ref)
 		if (write_ref_sha1(lock, sha1, msg) < 0)
diff --git a/builtin.h b/builtin.h
index 8afa2de..c47c110 100644
--- a/builtin.h
+++ b/builtin.h
@@ -27,6 +27,8 @@
 
 extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, int sha1_valid, char **buf, unsigned long *buf_size);
 
+extern int is_builtin(const char *s);
+
 extern int cmd_add(int argc, const char **argv, const char *prefix);
 extern int cmd_annotate(int argc, const char **argv, const char *prefix);
 extern int cmd_apply(int argc, const char **argv, const char *prefix);
@@ -102,7 +104,7 @@
 extern int cmd_remote(int argc, const char **argv, const char *prefix);
 extern int cmd_remote_ext(int argc, const char **argv, const char *prefix);
 extern int cmd_remote_fd(int argc, const char **argv, const char *prefix);
-extern int cmd_repo_config(int argc, const char **argv, const char *prefix);
+extern int cmd_repack(int argc, const char **argv, const char *prefix);
 extern int cmd_rerere(int argc, const char **argv, const char *prefix);
 extern int cmd_reset(int argc, const char **argv, const char *prefix);
 extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
diff --git a/builtin/add.c b/builtin/add.c
index 8266a9c..2a2722f 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -166,14 +166,16 @@
 	}
 }
 
-static void update_files_in_cache(const char *prefix, const char **pathspec,
+static void update_files_in_cache(const char *prefix,
+				  const struct pathspec *pathspec,
 				  struct update_callback_data *data)
 {
 	struct rev_info rev;
 
 	init_revisions(&rev, prefix);
 	setup_revisions(0, NULL, &rev, NULL);
-	init_pathspec(&rev.prune_data, pathspec);
+	if (pathspec)
+		copy_pathspec(&rev.prune_data, pathspec);
 	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
 	rev.diffopt.format_callback = update_callback;
 	rev.diffopt.format_callback_data = data;
@@ -181,7 +183,8 @@
 	run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
 }
 
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
+int add_files_to_cache(const char *prefix,
+		       const struct pathspec *pathspec, int flags)
 {
 	struct update_callback_data data;
 
@@ -192,23 +195,21 @@
 }
 
 #define WARN_IMPLICIT_DOT (1u << 0)
-static char *prune_directory(struct dir_struct *dir, const char **pathspec,
+static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
 			     int prefix, unsigned flag)
 {
 	char *seen;
-	int i, specs;
+	int i;
 	struct dir_entry **src, **dst;
 
-	for (specs = 0; pathspec[specs];  specs++)
-		/* nothing */;
-	seen = xcalloc(specs, 1);
+	seen = xcalloc(pathspec->nr, 1);
 
 	src = dst = dir->entries;
 	i = dir->nr;
 	while (--i >= 0) {
 		struct dir_entry *entry = *src++;
-		if (match_pathspec(pathspec, entry->name, entry->len,
-				   prefix, seen))
+		if (match_pathspec_depth(pathspec, entry->name, entry->len,
+					 prefix, seen))
 			*dst++ = entry;
 		else if (flag & WARN_IMPLICIT_DOT)
 			/*
@@ -222,72 +223,33 @@
 			warn_pathless_add();
 	}
 	dir->nr = dst - dir->entries;
-	add_pathspec_matches_against_index(pathspec, seen, specs);
+	add_pathspec_matches_against_index(pathspec, seen);
 	return seen;
 }
 
-/*
- * Checks the index to see whether any path in pathspec refers to
- * something inside a submodule.  If so, dies with an error message.
- */
-static void treat_gitlinks(const char **pathspec)
-{
-	int i;
-
-	if (!pathspec || !*pathspec)
-		return;
-
-	for (i = 0; pathspec[i]; i++)
-		pathspec[i] = check_path_for_gitlink(pathspec[i]);
-}
-
-static void refresh(int verbose, const char **pathspec)
+static void refresh(int verbose, const struct pathspec *pathspec)
 {
 	char *seen;
-	int i, specs;
+	int i;
 
-	for (specs = 0; pathspec[specs];  specs++)
-		/* nothing */;
-	seen = xcalloc(specs, 1);
+	seen = xcalloc(pathspec->nr, 1);
 	refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
 		      pathspec, seen, _("Unstaged changes after refreshing the index:"));
-	for (i = 0; i < specs; i++) {
+	for (i = 0; i < pathspec->nr; i++) {
 		if (!seen[i])
-			die(_("pathspec '%s' did not match any files"), pathspec[i]);
+			die(_("pathspec '%s' did not match any files"),
+			    pathspec->items[i].match);
 	}
         free(seen);
 }
 
-/*
- * Normalizes argv relative to prefix, via get_pathspec(), and then
- * runs die_if_path_beyond_symlink() on each path in the normalized
- * list.
- */
-static const char **validate_pathspec(const char **argv, const char *prefix)
-{
-	const char **pathspec = get_pathspec(prefix, argv);
-
-	if (pathspec) {
-		const char **p;
-		for (p = pathspec; *p; p++) {
-			die_if_path_beyond_symlink(*p, prefix);
-		}
-	}
-
-	return pathspec;
-}
-
 int run_add_interactive(const char *revision, const char *patch_mode,
-			const char **pathspec)
+			const struct pathspec *pathspec)
 {
-	int status, ac, pc = 0;
+	int status, ac, i;
 	const char **args;
 
-	if (pathspec)
-		while (pathspec[pc])
-			pc++;
-
-	args = xcalloc(sizeof(const char *), (pc + 5));
+	args = xcalloc(sizeof(const char *), (pathspec->nr + 6));
 	ac = 0;
 	args[ac++] = "add--interactive";
 	if (patch_mode)
@@ -295,11 +257,9 @@
 	if (revision)
 		args[ac++] = revision;
 	args[ac++] = "--";
-	if (pc) {
-		memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
-		ac += pc;
-	}
-	args[ac] = NULL;
+	for (i = 0; i < pathspec->nr; i++)
+		/* pass original pathspec, to be re-parsed */
+		args[ac++] = pathspec->items[i].original;
 
 	status = run_command_v_opt(args, RUN_GIT_CMD);
 	free(args);
@@ -308,17 +268,17 @@
 
 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 {
-	const char **pathspec = NULL;
+	struct pathspec pathspec;
 
-	if (argc) {
-		pathspec = validate_pathspec(argv, prefix);
-		if (!pathspec)
-			return -1;
-	}
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_FULL |
+		       PATHSPEC_SYMLINK_LEADING_PATH |
+		       PATHSPEC_PREFIX_ORIGIN,
+		       prefix, argv);
 
 	return run_add_interactive(NULL,
 				   patch ? "--patch" : NULL,
-				   pathspec);
+				   &pathspec);
 }
 
 static int edit_patch(int argc, const char **argv, const char *prefix)
@@ -336,7 +296,7 @@
 	git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 
 	if (read_cache() < 0)
-		die (_("Could not read the index"));
+		die(_("Could not read the index"));
 
 	init_revisions(&rev, prefix);
 	rev.diffopt.context = 7;
@@ -347,11 +307,11 @@
 	DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
 	out = open(file, O_CREAT | O_WRONLY, 0666);
 	if (out < 0)
-		die (_("Could not open '%s' for writing."), file);
+		die(_("Could not open '%s' for writing."), file);
 	rev.diffopt.file = xfdopen(out, "w");
 	rev.diffopt.close_file = 1;
 	if (run_diff_files(&rev, 0))
-		die (_("Could not write patch"));
+		die(_("Could not write patch"));
 
 	launch_editor(file, NULL, NULL);
 
@@ -364,7 +324,7 @@
 	child.git_cmd = 1;
 	child.argv = apply_argv;
 	if (run_command(&child))
-		die (_("Could not apply '%s'"), file);
+		die(_("Could not apply '%s'"), file);
 
 	unlink(file);
 	free(file);
@@ -446,7 +406,7 @@
 {
 	int exit_status = 0;
 	int newfd;
-	const char **pathspec;
+	struct pathspec pathspec;
 	struct dir_struct dir;
 	int flags;
 	int add_new_files;
@@ -527,14 +487,23 @@
 		fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
 		return 0;
 	}
-	pathspec = validate_pathspec(argv, prefix);
 
 	if (read_cache() < 0)
 		die(_("index file corrupt"));
-	treat_gitlinks(pathspec);
+
+	/*
+	 * Check the "pathspec '%s' did not match any files" block
+	 * below before enabling new magic.
+	 */
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_FULL |
+		       PATHSPEC_SYMLINK_LEADING_PATH |
+		       PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
+		       prefix, argv);
 
 	if (add_new_files) {
 		int baselen;
+		struct pathspec empty_pathspec;
 
 		/* Set up the default git porcelain excludes */
 		memset(&dir, 0, sizeof(dir));
@@ -543,35 +512,52 @@
 			setup_standard_excludes(&dir);
 		}
 
+		memset(&empty_pathspec, 0, sizeof(empty_pathspec));
 		/* This picks up the paths that are not tracked */
-		baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec);
-		if (pathspec)
-			seen = prune_directory(&dir, pathspec, baselen,
+		baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec);
+		if (pathspec.nr)
+			seen = prune_directory(&dir, &pathspec, baselen,
 					implicit_dot ? WARN_IMPLICIT_DOT : 0);
 	}
 
 	if (refresh_only) {
-		refresh(verbose, pathspec);
+		refresh(verbose, &pathspec);
 		goto finish;
 	}
 	if (implicit_dot && prefix)
 		refresh_cache(REFRESH_QUIET);
 
-	if (pathspec) {
+	if (pathspec.nr) {
 		int i;
 
 		if (!seen)
-			seen = find_pathspecs_matching_against_index(pathspec);
-		for (i = 0; pathspec[i]; i++) {
-			if (!seen[i] && pathspec[i][0]
-			    && !file_exists(pathspec[i])) {
+			seen = find_pathspecs_matching_against_index(&pathspec);
+
+		/*
+		 * file_exists() assumes exact match
+		 */
+		GUARD_PATHSPEC(&pathspec,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB |
+			       PATHSPEC_ICASE |
+			       PATHSPEC_EXCLUDE);
+
+		for (i = 0; i < pathspec.nr; i++) {
+			const char *path = pathspec.items[i].match;
+			if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
+				continue;
+			if (!seen[i] && path[0] &&
+			    ((pathspec.items[i].magic &
+			      (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
+			     !file_exists(path))) {
 				if (ignore_missing) {
 					int dtype = DT_UNKNOWN;
-					if (is_excluded(&dir, pathspec[i], &dtype))
-						dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
+					if (is_excluded(&dir, path, &dtype))
+						dir_add_ignored(&dir, path, pathspec.items[i].len);
 				} else
 					die(_("pathspec '%s' did not match any files"),
-					    pathspec[i]);
+					    pathspec.items[i].original);
 			}
 		}
 		free(seen);
@@ -587,10 +573,11 @@
 		 */
 		update_data.implicit_dot = prefix;
 		update_data.implicit_dot_len = strlen(prefix);
-		pathspec = NULL;
+		free_pathspec(&pathspec);
+		memset(&pathspec, 0, sizeof(pathspec));
 	}
 	update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
-	update_files_in_cache(prefix, pathspec, &update_data);
+	update_files_in_cache(prefix, &pathspec, &update_data);
 
 	exit_status |= !!update_data.add_errors;
 	if (add_new_files)
@@ -598,7 +585,7 @@
 
 	unplug_bulk_checkin();
 
- finish:
+finish:
 	if (active_cache_changed) {
 		if (write_cache(newfd, active_cache, active_nr) ||
 		    commit_locked_index(&lock_file))
diff --git a/builtin/apply.c b/builtin/apply.c
index 50912c9..b0d0986 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -1409,10 +1409,10 @@
 		case '\\':
 			continue;
 		case '@':
-			ret = size < 3 || prefixcmp(line, "@@ ");
+			ret = size < 3 || !starts_with(line, "@@ ");
 			break;
 		case 'd':
-			ret = size < 5 || prefixcmp(line, "diff ");
+			ret = size < 5 || !starts_with(line, "diff ");
 			break;
 		default:
 			ret = -1;
@@ -1798,11 +1798,11 @@
 
 	*status_p = 0;
 
-	if (!prefixcmp(buffer, "delta ")) {
+	if (starts_with(buffer, "delta ")) {
 		patch_method = BINARY_DELTA_DEFLATED;
 		origlen = strtoul(buffer + 6, NULL, 10);
 	}
-	else if (!prefixcmp(buffer, "literal ")) {
+	else if (starts_with(buffer, "literal ")) {
 		patch_method = BINARY_LITERAL_DEFLATED;
 		origlen = strtoul(buffer + 8, NULL, 10);
 	}
@@ -3627,12 +3627,12 @@
 	    hunk->oldpos == 1 && hunk->oldlines == 1 &&
 	    /* does preimage begin with the heading? */
 	    (preimage = memchr(hunk->patch, '\n', hunk->size)) != NULL &&
-	    !prefixcmp(++preimage, heading) &&
+	    starts_with(++preimage, heading) &&
 	    /* does it record full SHA-1? */
 	    !get_sha1_hex(preimage + sizeof(heading) - 1, sha1) &&
 	    preimage[sizeof(heading) + 40 - 1] == '\n' &&
 	    /* does the abbreviated name on the index line agree with it? */
-	    !prefixcmp(preimage + sizeof(heading) - 1, p->old_sha1_prefix))
+	    starts_with(preimage + sizeof(heading) - 1, p->old_sha1_prefix))
 		return 0; /* it all looks fine */
 
 	/* we may have full object name on the index line */
@@ -4363,23 +4363,23 @@
 		{ OPTION_CALLBACK, 'p', NULL, NULL, N_("num"),
 			N_("remove <num> leading slashes from traditional diff paths"),
 			0, option_parse_p },
-		OPT_BOOLEAN(0, "no-add", &no_add,
+		OPT_BOOL(0, "no-add", &no_add,
 			N_("ignore additions made by the patch")),
-		OPT_BOOLEAN(0, "stat", &diffstat,
+		OPT_BOOL(0, "stat", &diffstat,
 			N_("instead of applying the patch, output diffstat for the input")),
 		OPT_NOOP_NOARG(0, "allow-binary-replacement"),
 		OPT_NOOP_NOARG(0, "binary"),
-		OPT_BOOLEAN(0, "numstat", &numstat,
+		OPT_BOOL(0, "numstat", &numstat,
 			N_("show number of added and deleted lines in decimal notation")),
-		OPT_BOOLEAN(0, "summary", &summary,
+		OPT_BOOL(0, "summary", &summary,
 			N_("instead of applying the patch, output a summary for the input")),
-		OPT_BOOLEAN(0, "check", &check,
+		OPT_BOOL(0, "check", &check,
 			N_("instead of applying the patch, see if the patch is applicable")),
-		OPT_BOOLEAN(0, "index", &check_index,
+		OPT_BOOL(0, "index", &check_index,
 			N_("make sure the patch is applicable to the current index")),
-		OPT_BOOLEAN(0, "cached", &cached,
+		OPT_BOOL(0, "cached", &cached,
 			N_("apply a patch without touching the working tree")),
-		OPT_BOOLEAN(0, "apply", &force_apply,
+		OPT_BOOL(0, "apply", &force_apply,
 			N_("also apply the patch (use with --stat/--summary/--check)")),
 		OPT_BOOL('3', "3way", &threeway,
 			 N_( "attempt three-way merge if a patch does not apply")),
@@ -4399,13 +4399,13 @@
 		{ OPTION_CALLBACK, 0, "ignore-whitespace", NULL, NULL,
 			N_("ignore changes in whitespace when finding context"),
 			PARSE_OPT_NOARG, option_parse_space_change },
-		OPT_BOOLEAN('R', "reverse", &apply_in_reverse,
+		OPT_BOOL('R', "reverse", &apply_in_reverse,
 			N_("apply the patch in reverse")),
-		OPT_BOOLEAN(0, "unidiff-zero", &unidiff_zero,
+		OPT_BOOL(0, "unidiff-zero", &unidiff_zero,
 			N_("don't expect at least one line of context")),
-		OPT_BOOLEAN(0, "reject", &apply_with_reject,
+		OPT_BOOL(0, "reject", &apply_with_reject,
 			N_("leave the rejected hunks in corresponding *.rej files")),
-		OPT_BOOLEAN(0, "allow-overlap", &allow_overlap,
+		OPT_BOOL(0, "allow-overlap", &allow_overlap,
 			N_("allow overlapping hunks")),
 		OPT__VERBOSE(&apply_verbosely, N_("be verbose")),
 		OPT_BIT(0, "inaccurate-eof", &options,
diff --git a/builtin/archive.c b/builtin/archive.c
index 49178f1..a1e3b94 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -57,9 +57,9 @@
 	if (!buf)
 		die(_("git archive: expected ACK/NAK, got EOF"));
 	if (strcmp(buf, "ACK")) {
-		if (!prefixcmp(buf, "NACK "))
+		if (starts_with(buf, "NACK "))
 			die(_("git archive: NACK %s"), buf + 5);
-		if (!prefixcmp(buf, "ERR "))
+		if (starts_with(buf, "ERR "))
 			die(_("remote error: %s"), buf + 4);
 		die(_("git archive: protocol error"));
 	}
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index e3884e3..33242290 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -13,10 +13,10 @@
 	int next_all = 0;
 	int no_checkout = 0;
 	struct option options[] = {
-		OPT_BOOLEAN(0, "next-all", &next_all,
-			    N_("perform 'git bisect next'")),
-		OPT_BOOLEAN(0, "no-checkout", &no_checkout,
-			    N_("update BISECT_HEAD instead of checking out the current commit")),
+		OPT_BOOL(0, "next-all", &next_all,
+			 N_("perform 'git bisect next'")),
+		OPT_BOOL(0, "no-checkout", &no_checkout,
+			 N_("update BISECT_HEAD instead of checking out the current commit")),
 		OPT_END()
 	};
 
diff --git a/builtin/blame.c b/builtin/blame.c
index 079dcd3..e44a6bb 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -22,6 +22,7 @@
 #include "utf8.h"
 #include "userdiff.h"
 #include "line-range.h"
+#include "line-log.h"
 
 static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
 
@@ -408,7 +409,9 @@
 	paths[0] = origin->path;
 	paths[1] = NULL;
 
-	diff_tree_setup_paths(paths, &diff_opts);
+	parse_pathspec(&diff_opts.pathspec,
+		       PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
+		       PATHSPEC_LITERAL_PATH, "", paths);
 	diff_setup_done(&diff_opts);
 
 	if (is_null_sha1(origin->commit->object.sha1))
@@ -458,7 +461,7 @@
 		}
 	}
 	diff_flush(&diff_opts);
-	diff_tree_release_paths(&diff_opts);
+	free_pathspec(&diff_opts.pathspec);
 	if (porigin) {
 		/*
 		 * Create a freestanding copy that is not part of
@@ -486,15 +489,12 @@
 	struct origin *porigin = NULL;
 	struct diff_options diff_opts;
 	int i;
-	const char *paths[2];
 
 	diff_setup(&diff_opts);
 	DIFF_OPT_SET(&diff_opts, RECURSIVE);
 	diff_opts.detect_rename = DIFF_DETECT_RENAME;
 	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 	diff_opts.single_follow = origin->path;
-	paths[0] = NULL;
-	diff_tree_setup_paths(paths, &diff_opts);
 	diff_setup_done(&diff_opts);
 
 	if (is_null_sha1(origin->commit->object.sha1))
@@ -516,7 +516,7 @@
 		}
 	}
 	diff_flush(&diff_opts);
-	diff_tree_release_paths(&diff_opts);
+	free_pathspec(&diff_opts.pathspec);
 	return porigin;
 }
 
@@ -1064,7 +1064,6 @@
 			       int opt)
 {
 	struct diff_options diff_opts;
-	const char *paths[1];
 	int i, j;
 	int retval;
 	struct blame_list *blame_list;
@@ -1078,8 +1077,6 @@
 	DIFF_OPT_SET(&diff_opts, RECURSIVE);
 	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 
-	paths[0] = NULL;
-	diff_tree_setup_paths(paths, &diff_opts);
 	diff_setup_done(&diff_opts);
 
 	/* Try "find copies harder" on new path if requested;
@@ -1162,7 +1159,7 @@
 	}
 	reset_scanned_flag(sb);
 	diff_flush(&diff_opts);
-	diff_tree_release_paths(&diff_opts);
+	free_pathspec(&diff_opts.pathspec);
 	return retval;
 }
 
@@ -1554,8 +1551,7 @@
 		 */
 		origin_incref(suspect);
 		commit = suspect->commit;
-		if (!commit->object.parsed)
-			parse_commit(commit);
+		parse_commit(commit);
 		if (reverse ||
 		    (!(commit->object.flags & UNINTERESTING) &&
 		     !(revs->max_age != -1 && commit->date < revs->max_age)))
@@ -1807,17 +1803,17 @@
 static int read_ancestry(const char *graft_file)
 {
 	FILE *fp = fopen(graft_file, "r");
-	char buf[1024];
+	struct strbuf buf = STRBUF_INIT;
 	if (!fp)
 		return -1;
-	while (fgets(buf, sizeof(buf), fp)) {
+	while (!strbuf_getwholeline(&buf, fp, '\n')) {
 		/* The format is just "Commit Parent1 Parent2 ...\n" */
-		int len = strlen(buf);
-		struct commit_graft *graft = read_graft_line(buf, len);
+		struct commit_graft *graft = read_graft_line(buf.buf, buf.len);
 		if (graft)
 			register_commit_graft(graft, 0);
 	}
 	fclose(fp);
+	strbuf_release(&buf);
 	return 0;
 }
 
@@ -1937,18 +1933,6 @@
 	return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
 }
 
-/*
- * Parsing of -L option
- */
-static void prepare_blame_range(struct scoreboard *sb,
-				const char *bottomtop,
-				long lno,
-				long *bottom, long *top)
-{
-	if (parse_range_arg(bottomtop, nth_line_cb, sb, lno, bottom, top, sb->path))
-		usage(blame_usage);
-}
-
 static int git_blame_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "blame.showroot")) {
@@ -2245,38 +2229,27 @@
 	return 0;
 }
 
-static int blame_bottomtop_callback(const struct option *option, const char *arg, int unset)
-{
-	const char **bottomtop = option->value;
-	if (!arg)
-		return -1;
-	if (*bottomtop)
-		die("More than one '-L n,m' option given");
-	*bottomtop = arg;
-	return 0;
-}
-
 int cmd_blame(int argc, const char **argv, const char *prefix)
 {
 	struct rev_info revs;
 	const char *path;
 	struct scoreboard sb;
 	struct origin *o;
-	struct blame_entry *ent;
-	long dashdash_pos, bottom, top, lno;
+	struct blame_entry *ent = NULL;
+	long dashdash_pos, lno;
 	const char *final_commit_name = NULL;
 	enum object_type type;
 
-	static const char *bottomtop = NULL;
+	static struct string_list range_list;
 	static int output_option = 0, opt = 0;
 	static int show_stats = 0;
 	static const char *revs_file = NULL;
 	static const char *contents_from = NULL;
 	static const struct option options[] = {
-		OPT_BOOLEAN(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")),
-		OPT_BOOLEAN('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")),
-		OPT_BOOLEAN(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")),
-		OPT_BOOLEAN(0, "show-stats", &show_stats, N_("Show work cost statistics")),
+		OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")),
+		OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")),
+		OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")),
+		OPT_BOOL(0, "show-stats", &show_stats, N_("Show work cost statistics")),
 		OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE),
 		OPT_BIT('f', "show-name", &output_option, N_("Show original filename (Default: auto)"), OUTPUT_SHOW_NAME),
 		OPT_BIT('n', "show-number", &output_option, N_("Show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER),
@@ -2293,13 +2266,16 @@
 		OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
 		{ OPTION_CALLBACK, 'C', NULL, &opt, N_("score"), N_("Find line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback },
 		{ OPTION_CALLBACK, 'M', NULL, &opt, N_("score"), N_("Find line movements within and across files"), PARSE_OPT_OPTARG, blame_move_callback },
-		OPT_CALLBACK('L', NULL, &bottomtop, N_("n,m"), N_("Process only line range n,m, counting from 1"), blame_bottomtop_callback),
+		OPT_STRING_LIST('L', NULL, &range_list, N_("n,m"), N_("Process only line range n,m, counting from 1")),
 		OPT__ABBREV(&abbrev),
 		OPT_END()
 	};
 
 	struct parse_opt_ctx_t ctx;
 	int cmd_is_annotate = !strcmp(argv[0], "annotate");
+	struct range_set ranges;
+	unsigned int range_i;
+	long anchor;
 
 	git_config(git_blame_config, NULL);
 	init_revisions(&revs, NULL);
@@ -2492,22 +2468,48 @@
 	num_read_blob++;
 	lno = prepare_lines(&sb);
 
-	bottom = top = 0;
-	if (bottomtop)
-		prepare_blame_range(&sb, bottomtop, lno, &bottom, &top);
-	if (bottom < 1)
-		bottom = 1;
-	if (top < 1)
-		top = lno;
-	bottom--;
-	if (lno < top || lno < bottom)
-		die("file %s has only %lu lines", path, lno);
+	if (lno && !range_list.nr)
+		string_list_append(&range_list, xstrdup("1"));
 
-	ent = xcalloc(1, sizeof(*ent));
-	ent->lno = bottom;
-	ent->num_lines = top - bottom;
-	ent->suspect = o;
-	ent->s_lno = bottom;
+	anchor = 1;
+	range_set_init(&ranges, range_list.nr);
+	for (range_i = 0; range_i < range_list.nr; ++range_i) {
+		long bottom, top;
+		if (parse_range_arg(range_list.items[range_i].string,
+				    nth_line_cb, &sb, lno, anchor,
+				    &bottom, &top, sb.path))
+			usage(blame_usage);
+		if (lno < top || ((lno || bottom) && lno < bottom))
+			die("file %s has only %lu lines", path, lno);
+		if (bottom < 1)
+			bottom = 1;
+		if (top < 1)
+			top = lno;
+		bottom--;
+		range_set_append_unsafe(&ranges, bottom, top);
+		anchor = top + 1;
+	}
+	sort_and_merge_range_set(&ranges);
+
+	for (range_i = ranges.nr; range_i > 0; --range_i) {
+		const struct range *r = &ranges.ranges[range_i - 1];
+		long bottom = r->start;
+		long top = r->end;
+		struct blame_entry *next = ent;
+		ent = xcalloc(1, sizeof(*ent));
+		ent->lno = bottom;
+		ent->num_lines = top - bottom;
+		ent->suspect = o;
+		ent->s_lno = bottom;
+		ent->next = next;
+		if (next)
+			next->prev = ent;
+		origin_incref(o);
+	}
+	origin_decref(o);
+
+	range_set_release(&ranges);
+	string_list_clear(&range_list, 0);
 
 	sb.ent = ent;
 	sb.path = path;
diff --git a/builtin/branch.c b/builtin/branch.c
index 0836890..b4d7716 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -81,13 +81,13 @@
 
 static int git_branch_config(const char *var, const char *value, void *cb)
 {
-	if (!prefixcmp(var, "column."))
+	if (starts_with(var, "column."))
 		return git_column_config(var, value, "branch", &colopts);
 	if (!strcmp(var, "color.branch")) {
 		branch_use_color = git_config_colorbool(var, value);
 		return 0;
 	}
-	if (!prefixcmp(var, "color.branch.")) {
+	if (starts_with(var, "color.branch.")) {
 		int slot = parse_branch_color_slot(var, 13);
 		if (slot < 0)
 			return 0;
@@ -423,19 +423,20 @@
 	char *ref = NULL;
 	struct branch *branch = branch_get(branch_name);
 	struct strbuf fancy = STRBUF_INIT;
+	int upstream_is_gone = 0;
+	int added_decoration = 1;
 
-	if (!stat_tracking_info(branch, &ours, &theirs)) {
-		if (branch && branch->merge && branch->merge[0]->dst &&
-		    show_upstream_ref) {
-			ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
-			if (want_color(branch_use_color))
-				strbuf_addf(stat, "[%s%s%s] ",
-						branch_get_color(BRANCH_COLOR_UPSTREAM),
-						ref, branch_get_color(BRANCH_COLOR_RESET));
-			else
-				strbuf_addf(stat, "[%s] ", ref);
-		}
+	switch (stat_tracking_info(branch, &ours, &theirs)) {
+	case 0:
+		/* no base */
 		return;
+	case -1:
+		/* with "gone" base */
+		upstream_is_gone = 1;
+		break;
+	default:
+		/* with base */
+		break;
 	}
 
 	if (show_upstream_ref) {
@@ -448,19 +449,29 @@
 			strbuf_addstr(&fancy, ref);
 	}
 
-	if (!ours) {
-		if (ref)
+	if (upstream_is_gone) {
+		if (show_upstream_ref)
+			strbuf_addf(stat, _("[%s: gone]"), fancy.buf);
+		else
+			added_decoration = 0;
+	} else if (!ours && !theirs) {
+		if (show_upstream_ref)
+			strbuf_addf(stat, _("[%s]"), fancy.buf);
+		else
+			added_decoration = 0;
+	} else if (!ours) {
+		if (show_upstream_ref)
 			strbuf_addf(stat, _("[%s: behind %d]"), fancy.buf, theirs);
 		else
 			strbuf_addf(stat, _("[behind %d]"), theirs);
 
 	} else if (!theirs) {
-		if (ref)
+		if (show_upstream_ref)
 			strbuf_addf(stat, _("[%s: ahead %d]"), fancy.buf, ours);
 		else
 			strbuf_addf(stat, _("[ahead %d]"), ours);
 	} else {
-		if (ref)
+		if (show_upstream_ref)
 			strbuf_addf(stat, _("[%s: ahead %d, behind %d]"),
 				    fancy.buf, ours, theirs);
 		else
@@ -468,7 +479,8 @@
 				    ours, theirs);
 	}
 	strbuf_release(&fancy);
-	strbuf_addch(stat, ' ');
+	if (added_decoration)
+		strbuf_addch(stat, ' ');
 	free(ref);
 }
 
@@ -490,7 +502,7 @@
 	const char *sub = _(" **** invalid ref ****");
 	struct commit *commit = item->commit;
 
-	if (commit && !parse_commit(commit)) {
+	if (!parse_commit(commit)) {
 		pp_commit_easy(CMIT_FMT_ONELINE, commit, &subject);
 		sub = subject.buf;
 	}
@@ -797,7 +809,7 @@
 		OPT_SET_INT( 0, "set-upstream",  &track, N_("change upstream info"),
 			BRANCH_TRACK_OVERRIDE),
 		OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"),
-		OPT_BOOLEAN(0, "unset-upstream", &unset_upstream, "Unset the upstream info"),
+		OPT_BOOL(0, "unset-upstream", &unset_upstream, "Unset the upstream info"),
 		OPT__COLOR(&branch_use_color, N_("use colored output")),
 		OPT_SET_INT('r', "remotes",     &kinds, N_("act on remote-tracking branches"),
 			REF_REMOTE_BRANCH),
@@ -822,10 +834,10 @@
 		OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2),
 		OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1),
 		OPT_BIT('M', NULL, &rename, N_("move/rename a branch, even if target exists"), 2),
-		OPT_BOOLEAN(0, "list", &list, N_("list branch names")),
-		OPT_BOOLEAN('l', "create-reflog", &reflog, N_("create the branch's reflog")),
-		OPT_BOOLEAN(0, "edit-description", &edit_description,
-			    N_("edit the description for the branch")),
+		OPT_BOOL(0, "list", &list, N_("list branch names")),
+		OPT_BOOL('l', "create-reflog", &reflog, N_("create the branch's reflog")),
+		OPT_BOOL(0, "edit-description", &edit_description,
+			 N_("edit the description for the branch")),
 		OPT__FORCE(&force_create, N_("force creation (when already exists)")),
 		{
 			OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
@@ -856,7 +868,7 @@
 	if (!strcmp(head, "HEAD")) {
 		detached = 1;
 	} else {
-		if (prefixcmp(head, "refs/heads/"))
+		if (!starts_with(head, "refs/heads/"))
 			die(_("HEAD not found below refs/heads!"));
 		head += 11;
 	}
@@ -872,7 +884,8 @@
 	if (with_commit || merge_filter != NO_FILTER)
 		list = 1;
 
-	if (!!delete + !!rename + !!force_create + !!list + !!new_upstream + !!unset_upstream > 1)
+	if (!!delete + !!rename + !!force_create + !!new_upstream +
+	    list + unset_upstream > 1)
 		usage_with_options(builtin_branch_usage, options);
 
 	if (abbrev == -1)
@@ -968,9 +981,8 @@
 			die(_("no such branch '%s'"), argv[0]);
 		}
 
-		if (!branch_has_merge_config(branch)) {
+		if (!branch_has_merge_config(branch))
 			die(_("Branch '%s' has no upstream information"), branch->name);
-		}
 
 		strbuf_addf(&buf, "branch.%s.remote", branch->name);
 		git_config_set_multivar(buf.buf, NULL, NULL, 1);
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 4253460..d5a93e0 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -45,6 +45,14 @@
 	case 'e':
 		return !has_sha1_file(sha1);
 
+	case 'c':
+		if (!obj_context.path[0])
+			die("git cat-file --textconv %s: <object> must be <sha1:path>",
+			    obj_name);
+
+		if (textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size))
+			break;
+
 	case 'p':
 		type = sha1_object_info(sha1, NULL);
 		if (type < 0)
@@ -67,16 +75,6 @@
 		/* otherwise just spit out the data */
 		break;
 
-	case 'c':
-		if (!obj_context.path[0])
-			die("git cat-file --textconv %s: <object> must be <sha1:path>",
-			    obj_name);
-
-		if (!textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size))
-			die("git cat-file --textconv: unable to run textconv on %s",
-			    obj_name);
-		break;
-
 	case 0:
 		if (type_from_string(exp_type) == OBJ_BLOB) {
 			unsigned char blob_sha1[20];
@@ -119,6 +117,8 @@
 	enum object_type type;
 	unsigned long size;
 	unsigned long disk_size;
+	const char *rest;
+	unsigned char delta_base_sha1[20];
 
 	/*
 	 * If mark_query is true, we do not expand anything, but rather
@@ -127,6 +127,13 @@
 	int mark_query;
 
 	/*
+	 * Whether to split the input on whitespace before feeding it to
+	 * get_sha1; this is decided during the mark_query phase based on
+	 * whether we have a %(rest) token in our format.
+	 */
+	int split_on_whitespace;
+
+	/*
 	 * After a mark_query run, this object_info is set up to be
 	 * passed to sha1_object_info_extended. It will point to the data
 	 * elements above, so you can retrieve the response from there.
@@ -163,6 +170,16 @@
 			data->info.disk_sizep = &data->disk_size;
 		else
 			strbuf_addf(sb, "%lu", data->disk_size);
+	} else if (is_atom("rest", atom, len)) {
+		if (data->mark_query)
+			data->split_on_whitespace = 1;
+		else if (data->rest)
+			strbuf_addstr(sb, data->rest);
+	} else if (is_atom("deltabase", atom, len)) {
+		if (data->mark_query)
+			data->info.delta_base_sha1 = data->delta_base_sha1;
+		else
+			strbuf_addstr(sb, sha1_to_hex(data->delta_base_sha1));
 	} else
 		die("unknown format element: %.*s", len, atom);
 }
@@ -182,25 +199,28 @@
 	return end - start + 1;
 }
 
-static void print_object_or_die(int fd, const unsigned char *sha1,
-				enum object_type type, unsigned long size)
+static void print_object_or_die(int fd, struct expand_data *data)
 {
-	if (type == OBJ_BLOB) {
+	const unsigned char *sha1 = data->sha1;
+
+	assert(data->info.typep);
+
+	if (data->type == OBJ_BLOB) {
 		if (stream_blob_to_fd(fd, sha1, NULL, 0) < 0)
 			die("unable to stream %s to stdout", sha1_to_hex(sha1));
 	}
 	else {
-		enum object_type rtype;
-		unsigned long rsize;
+		enum object_type type;
+		unsigned long size;
 		void *contents;
 
-		contents = read_sha1_file(sha1, &rtype, &rsize);
+		contents = read_sha1_file(sha1, &type, &size);
 		if (!contents)
 			die("object %s disappeared", sha1_to_hex(sha1));
-		if (rtype != type)
+		if (type != data->type)
 			die("object %s changed type!?", sha1_to_hex(sha1));
-		if (rsize != size)
-			die("object %s change size!?", sha1_to_hex(sha1));
+		if (data->info.sizep && size != data->size)
+			die("object %s changed size!?", sha1_to_hex(sha1));
 
 		write_or_die(fd, contents, size);
 		free(contents);
@@ -227,7 +247,7 @@
 		return 0;
 	}
 
-	if (sha1_object_info_extended(data->sha1, &data->info) < 0) {
+	if (sha1_object_info_extended(data->sha1, &data->info, LOOKUP_REPLACE_OBJECT) < 0) {
 		printf("%s missing\n", obj_name);
 		fflush(stdout);
 		return 0;
@@ -239,7 +259,7 @@
 	strbuf_release(&buf);
 
 	if (opt->print_contents) {
-		print_object_or_die(1, data->sha1, data->type, data->size);
+		print_object_or_die(1, data);
 		write_or_die(1, "\n", 1);
 	}
 	return 0;
@@ -264,6 +284,13 @@
 	data.mark_query = 0;
 
 	/*
+	 * If we are printing out the object, then always fill in the type,
+	 * since we will want to decide whether or not to stream.
+	 */
+	if (opt->print_contents)
+		data.info.typep = &data.type;
+
+	/*
 	 * We are going to call get_sha1 on a potentially very large number of
 	 * objects. In most large cases, these will be actual object sha1s. The
 	 * cost to double-check that each one is not also a ref (just so we can
@@ -273,7 +300,23 @@
 	warn_on_object_refname_ambiguity = 0;
 
 	while (strbuf_getline(&buf, stdin, '\n') != EOF) {
-		int error = batch_one_object(buf.buf, opt, &data);
+		int error;
+
+		if (data.split_on_whitespace) {
+			/*
+			 * Split at first whitespace, tying off the beginning
+			 * of the string and saving the remainder (or NULL) in
+			 * data.rest.
+			 */
+			char *p = strpbrk(buf.buf, " \t");
+			if (p) {
+				while (*p && strchr(" \t", *p))
+					*p++ = '\0';
+			}
+			data.rest = p;
+		}
+
+		error = batch_one_object(buf.buf, opt, &data);
 		if (error)
 			return error;
 	}
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 075d01d..e9af7b2 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -13,14 +13,14 @@
 NULL
 };
 
-static int null_term_line;
+static int nul_term_line;
 
 static const struct option check_attr_options[] = {
-	OPT_BOOLEAN('a', "all", &all_attrs, N_("report all attributes set on file")),
-	OPT_BOOLEAN(0,  "cached", &cached_attrs, N_("use .gitattributes only from the index")),
-	OPT_BOOLEAN(0 , "stdin", &stdin_paths, N_("read file names from stdin")),
-	OPT_BOOLEAN('z', NULL, &null_term_line,
-		N_("input paths are terminated by a null character")),
+	OPT_BOOL('a', "all", &all_attrs, N_("report all attributes set on file")),
+	OPT_BOOL(0,  "cached", &cached_attrs, N_("use .gitattributes only from the index")),
+	OPT_BOOL(0 , "stdin", &stdin_paths, N_("read file names from stdin")),
+	OPT_BOOL('z', NULL, &nul_term_line,
+		 N_("terminate input and output records by a NUL character")),
 	OPT_END()
 };
 
@@ -38,8 +38,16 @@
 		else if (ATTR_UNSET(value))
 			value = "unspecified";
 
-		quote_c_style(file, NULL, stdout, 0);
-		printf(": %s: %s\n", git_attr_name(check[j].attr), value);
+		if (nul_term_line) {
+			printf("%s%c" /* path */
+			       "%s%c" /* attrname */
+			       "%s%c" /* attrvalue */,
+			       file, 0, git_attr_name(check[j].attr), 0, value, 0);
+		} else {
+			quote_c_style(file, NULL, stdout, 0);
+			printf(": %s: %s\n", git_attr_name(check[j].attr), value);
+		}
+
 	}
 }
 
@@ -65,7 +73,7 @@
 	struct git_attr_check *check)
 {
 	struct strbuf buf, nbuf;
-	int line_termination = null_term_line ? 0 : '\n';
+	int line_termination = nul_term_line ? 0 : '\n';
 
 	strbuf_init(&buf, 0);
 	strbuf_init(&nbuf, 0);
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index 4a8fc70..594463a 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -5,25 +5,27 @@
 #include "pathspec.h"
 #include "parse-options.h"
 
-static int quiet, verbose, stdin_paths, show_non_matching;
+static int quiet, verbose, stdin_paths, show_non_matching, no_index;
 static const char * const check_ignore_usage[] = {
 "git check-ignore [options] pathname...",
 "git check-ignore [options] --stdin < <list-of-paths>",
 NULL
 };
 
-static int null_term_line;
+static int nul_term_line;
 
 static const struct option check_ignore_options[] = {
 	OPT__QUIET(&quiet, N_("suppress progress reporting")),
 	OPT__VERBOSE(&verbose, N_("be verbose")),
 	OPT_GROUP(""),
-	OPT_BOOLEAN(0, "stdin", &stdin_paths,
-		    N_("read file names from stdin")),
-	OPT_BOOLEAN('z', NULL, &null_term_line,
-		    N_("input paths are terminated by a null character")),
-	OPT_BOOLEAN('n', "non-matching", &show_non_matching,
-		    N_("show non-matching input paths")),
+	OPT_BOOL(0, "stdin", &stdin_paths,
+		 N_("read file names from stdin")),
+	OPT_BOOL('z', NULL, &nul_term_line,
+		 N_("terminate input and output records by a NUL character")),
+	OPT_BOOL('n', "non-matching", &show_non_matching,
+		 N_("show non-matching input paths")),
+	OPT_BOOL(0, "no-index", &no_index,
+		 N_("ignore index when checking")),
 	OPT_END()
 };
 
@@ -31,7 +33,7 @@
 {
 	char *bang  = (exclude && exclude->flags & EXC_FLAG_NEGATIVE)  ? "!" : "";
 	char *slash = (exclude && exclude->flags & EXC_FLAG_MUSTBEDIR) ? "/" : "";
-	if (!null_term_line) {
+	if (!nul_term_line) {
 		if (!verbose) {
 			write_name_quoted(path, stdout, '\n');
 		} else {
@@ -64,37 +66,45 @@
 }
 
 static int check_ignore(struct dir_struct *dir,
-			const char *prefix, const char **pathspec)
+			const char *prefix, int argc, const char **argv)
 {
-	const char *path, *full_path;
+	const char *full_path;
 	char *seen;
 	int num_ignored = 0, dtype = DT_UNKNOWN, i;
 	struct exclude *exclude;
+	struct pathspec pathspec;
 
-	if (!pathspec || !*pathspec) {
+	if (!argc) {
 		if (!quiet)
 			fprintf(stderr, "no pathspec given.\n");
 		return 0;
 	}
 
 	/*
+	 * check-ignore just needs paths. Magic beyond :/ is really
+	 * irrelevant.
+	 */
+	parse_pathspec(&pathspec,
+		       PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
+		       PATHSPEC_SYMLINK_LEADING_PATH |
+		       PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE |
+		       PATHSPEC_KEEP_ORDER,
+		       prefix, argv);
+
+	/*
 	 * look for pathspecs matching entries in the index, since these
 	 * should not be ignored, in order to be consistent with
 	 * 'git status', 'git add' etc.
 	 */
-	seen = find_pathspecs_matching_against_index(pathspec);
-	for (i = 0; pathspec[i]; i++) {
-		path = pathspec[i];
-		full_path = prefix_path(prefix, prefix
-					? strlen(prefix) : 0, path);
-		full_path = check_path_for_gitlink(full_path);
-		die_if_path_beyond_symlink(full_path, prefix);
+	seen = find_pathspecs_matching_against_index(&pathspec);
+	for (i = 0; i < pathspec.nr; i++) {
+		full_path = pathspec.items[i].match;
 		exclude = NULL;
 		if (!seen[i]) {
 			exclude = last_exclude_matching(dir, full_path, &dtype);
 		}
 		if (!quiet && (exclude || show_non_matching))
-			output_exclude(path, exclude);
+			output_exclude(pathspec.items[i].original, exclude);
 		if (exclude)
 			num_ignored++;
 	}
@@ -107,7 +117,7 @@
 {
 	struct strbuf buf, nbuf;
 	char *pathspec[2] = { NULL, NULL };
-	int line_termination = null_term_line ? 0 : '\n';
+	int line_termination = nul_term_line ? 0 : '\n';
 	int num_ignored = 0;
 
 	strbuf_init(&buf, 0);
@@ -120,7 +130,8 @@
 			strbuf_swap(&buf, &nbuf);
 		}
 		pathspec[0] = buf.buf;
-		num_ignored += check_ignore(dir, prefix, (const char **)pathspec);
+		num_ignored += check_ignore(dir, prefix,
+					    1, (const char **)pathspec);
 		maybe_flush_or_die(stdout, "check-ignore to stdout");
 	}
 	strbuf_release(&buf);
@@ -142,7 +153,7 @@
 		if (argc > 0)
 			die(_("cannot specify pathnames with --stdin"));
 	} else {
-		if (null_term_line)
+		if (nul_term_line)
 			die(_("-z only makes sense with --stdin"));
 		if (argc == 0)
 			die(_("no path specified"));
@@ -157,7 +168,7 @@
 		die(_("--non-matching is only valid with --verbose"));
 
 	/* read_cache() is only necessary so we can watch out for submodules. */
-	if (read_cache() < 0)
+	if (!no_index && read_cache() < 0)
 		die(_("index file corrupt"));
 
 	memset(&dir, 0, sizeof(dir));
@@ -166,7 +177,7 @@
 	if (stdin_paths) {
 		num_ignored = check_ignore_stdin_paths(&dir, prefix);
 	} else {
-		num_ignored = check_ignore(&dir, prefix, argv);
+		num_ignored = check_ignore(&dir, prefix, argc, argv);
 		maybe_flush_or_die(stdout, "ignore to stdout");
 	}
 
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index b1feda7..61e75eb 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -14,7 +14,7 @@
 static int line_termination = '\n';
 static int checkout_stage; /* default to checkout stage0 */
 static int to_tempfile;
-static char topath[4][PATH_MAX + 1];
+static char topath[4][TEMPORARY_FILENAME_LENGTH + 1];
 
 static struct checkout state;
 
@@ -183,12 +183,12 @@
 	int prefix_length;
 	int force = 0, quiet = 0, not_new = 0;
 	struct option builtin_checkout_index_options[] = {
-		OPT_BOOLEAN('a', "all", &all,
+		OPT_BOOL('a', "all", &all,
 			N_("check out all files in the index")),
 		OPT__FORCE(&force, N_("force overwrite of existing files")),
 		OPT__QUIET(&quiet,
 			N_("no warning for existing files and files not in index")),
-		OPT_BOOLEAN('n', "no-create", &not_new,
+		OPT_BOOL('n', "no-create", &not_new,
 			N_("don't checkout new files")),
 		{ OPTION_CALLBACK, 'u', "index", &newfd, NULL,
 			N_("update stat information in the index file"),
@@ -196,9 +196,9 @@
 		{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
 			N_("paths are separated with NUL character"),
 			PARSE_OPT_NOARG, option_parse_z },
-		OPT_BOOLEAN(0, "stdin", &read_from_stdin,
+		OPT_BOOL(0, "stdin", &read_from_stdin,
 			N_("read list of paths from the standard input")),
-		OPT_BOOLEAN(0, "temp", &to_tempfile,
+		OPT_BOOL(0, "temp", &to_tempfile,
 			N_("write the content to temporary files")),
 		OPT_CALLBACK(0, "prefix", NULL, N_("string"),
 			N_("when creating files, prepend <string>"),
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 22cc7fc..5df3837 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -46,7 +46,7 @@
 
 	int branch_exists;
 	const char *prefix;
-	const char **pathspec;
+	struct pathspec pathspec;
 	struct tree *source_tree;
 };
 
@@ -83,12 +83,9 @@
 	return 0;
 }
 
-static int read_tree_some(struct tree *tree, const char **pathspec)
+static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)
 {
-	struct pathspec ps;
-	init_pathspec(&ps, pathspec);
-	read_tree_recursive(tree, "", 0, 0, &ps, update_some, NULL);
-	free_pathspec(&ps);
+	read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL);
 
 	/* update the index with the given tree's info
 	 * for all args, expanding wildcards, and exit
@@ -228,8 +225,6 @@
 	int flag;
 	struct commit *head;
 	int errs = 0;
-	int stage = opts->writeout_stage;
-	int merge = opts->merge;
 	int newfd;
 	struct lock_file *lock_file;
 
@@ -257,20 +252,18 @@
 
 	if (opts->patch_mode)
 		return run_add_interactive(revision, "--patch=checkout",
-					   opts->pathspec);
+					   &opts->pathspec);
 
 	lock_file = xcalloc(1, sizeof(struct lock_file));
 
 	newfd = hold_locked_index(lock_file, 1);
-	if (read_cache_preload(opts->pathspec) < 0)
+	if (read_cache_preload(&opts->pathspec) < 0)
 		return error(_("corrupt index file"));
 
 	if (opts->source_tree)
-		read_tree_some(opts->source_tree, opts->pathspec);
+		read_tree_some(opts->source_tree, &opts->pathspec);
 
-	for (pos = 0; opts->pathspec[pos]; pos++)
-		;
-	ps_matched = xcalloc(1, pos);
+	ps_matched = xcalloc(1, opts->pathspec.nr);
 
 	/*
 	 * Make sure all pathspecs participated in locating the paths
@@ -304,12 +297,12 @@
 		 * match_pathspec() for _all_ entries when
 		 * opts->source_tree != NULL.
 		 */
-		if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce),
+		if (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce),
 				   0, ps_matched))
 			ce->ce_flags |= CE_MATCHED;
 	}
 
-	if (report_path_error(ps_matched, opts->pathspec, opts->prefix)) {
+	if (report_path_error(ps_matched, &opts->pathspec, opts->prefix)) {
 		free(ps_matched);
 		return 1;
 	}
@@ -327,8 +320,8 @@
 				continue;
 			if (opts->force) {
 				warning(_("path '%s' is unmerged"), ce->name);
-			} else if (stage) {
-				errs |= check_stage(stage, ce, pos);
+			} else if (opts->writeout_stage) {
+				errs |= check_stage(opts->writeout_stage, ce, pos);
 			} else if (opts->merge) {
 				errs |= check_stages((1<<2) | (1<<3), ce, pos);
 			} else {
@@ -352,9 +345,9 @@
 				errs |= checkout_entry(ce, &state, NULL);
 				continue;
 			}
-			if (stage)
-				errs |= checkout_stage(stage, ce, pos, &state);
-			else if (merge)
+			if (opts->writeout_stage)
+				errs |= checkout_stage(opts->writeout_stage, ce, pos, &state);
+			else if (opts->merge)
 				errs |= checkout_merged(pos, &state);
 			pos = skip_same_name(ce, pos) - 1;
 		}
@@ -387,8 +380,8 @@
 static void describe_detached_head(const char *msg, struct commit *commit)
 {
 	struct strbuf sb = STRBUF_INIT;
-	parse_commit(commit);
-	pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb);
+	if (!parse_commit(commit))
+		pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb);
 	fprintf(stderr, "%s %s... %s\n", msg,
 		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
 	strbuf_release(&sb);
@@ -684,12 +677,12 @@
 
 static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
 {
-	parse_commit(commit);
 	strbuf_addstr(sb, "  ");
 	strbuf_addstr(sb,
 		find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
 	strbuf_addch(sb, ' ');
-	pp_commit_easy(CMIT_FMT_ONELINE, commit, sb);
+	if (!parse_commit(commit))
+		pp_commit_easy(CMIT_FMT_ONELINE, commit, sb);
 	strbuf_addch(sb, '\n');
 }
 
@@ -788,7 +781,7 @@
 	if (!(flag & REF_ISSYMREF))
 		old.path = NULL;
 
-	if (old.path && !prefixcmp(old.path, "refs/heads/"))
+	if (old.path && starts_with(old.path, "refs/heads/"))
 		old.name = old.path + strlen("refs/heads/");
 
 	if (!new->name) {
@@ -796,7 +789,7 @@
 		new->commit = old.commit;
 		if (!new->commit)
 			die(_("You are on a branch yet to be born"));
-		parse_commit(new->commit);
+		parse_commit_or_die(new->commit);
 	}
 
 	ret = merge_working_tree(opts, &old, new, &writeout_error);
@@ -823,7 +816,7 @@
 		return 0;
 	}
 
-	if (!prefixcmp(var, "submodule."))
+	if (starts_with(var, "submodule."))
 		return parse_submodule_config_option(var, value);
 
 	return git_xmerge_config(var, value, NULL);
@@ -1002,7 +995,7 @@
 		/* not a commit */
 		*source_tree = parse_tree_indirect(rev);
 	} else {
-		parse_commit(new->commit);
+		parse_commit_or_die(new->commit);
 		*source_tree = new->commit->tree;
 	}
 
@@ -1045,7 +1038,7 @@
 static int checkout_branch(struct checkout_opts *opts,
 			   struct branch_info *new)
 {
-	if (opts->pathspec)
+	if (opts->pathspec.nr)
 		die(_("paths cannot be used with switching branches"));
 
 	if (opts->patch_mode)
@@ -1099,8 +1092,8 @@
 			   N_("create and checkout a new branch")),
 		OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"),
 			   N_("create/reset and checkout a branch")),
-		OPT_BOOLEAN('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
-		OPT_BOOLEAN(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")),
+		OPT_BOOL('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
+		OPT_BOOL(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")),
 		OPT_SET_INT('t', "track",  &opts.track, N_("set upstream info for new branch"),
 			BRANCH_TRACK_EXPLICIT),
 		OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new branch"), N_("new unparented branch")),
@@ -1109,16 +1102,15 @@
 		OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),
 			    3),
 		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)")),
-		OPT_BOOLEAN('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
-		OPT_BOOLEAN(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
+		OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
+		OPT_BOOL(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
 		OPT_STRING(0, "conflict", &conflict_style, N_("style"),
 			   N_("conflict style (merge or diff3)")),
-		OPT_BOOLEAN('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
+		OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
 		OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree,
 			 N_("do not limit pathspecs to sparse entries only")),
-		{ OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
-		  N_("second guess 'git checkout no-such-branch'"),
-		  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
+		OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch,
+				N_("second guess 'git checkout no-such-branch'")),
 		OPT_END(),
 	};
 
@@ -1159,9 +1151,9 @@
 		const char *argv0 = argv[0];
 		if (!argc || !strcmp(argv0, "--"))
 			die (_("--track needs a branch name"));
-		if (!prefixcmp(argv0, "refs/"))
+		if (starts_with(argv0, "refs/"))
 			argv0 += 5;
-		if (!prefixcmp(argv0, "remotes/"))
+		if (starts_with(argv0, "remotes/"))
 			argv0 += 8;
 		argv0 = strchr(argv0, '/');
 		if (!argv0 || !argv0[1])
@@ -1197,9 +1189,11 @@
 	}
 
 	if (argc) {
-		opts.pathspec = get_pathspec(prefix, argv);
+		parse_pathspec(&opts.pathspec, 0,
+			       opts.patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
+			       prefix, argv);
 
-		if (!opts.pathspec)
+		if (!opts.pathspec.nr)
 			die(_("invalid path specification"));
 
 		/*
@@ -1231,7 +1225,7 @@
 		strbuf_release(&buf);
 	}
 
-	if (opts.patch_mode || opts.pathspec)
+	if (opts.patch_mode || opts.pathspec.nr)
 		return checkout_paths(&opts, new.name);
 	else
 		return checkout_branch(&opts, &new);
diff --git a/builtin/clean.c b/builtin/clean.c
index 3c85e15..2f26297 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -15,6 +15,7 @@
 #include "quote.h"
 #include "column.h"
 #include "color.h"
+#include "pathspec.h"
 
 static int force = -1; /* unset */
 static int interactive;
@@ -99,7 +100,7 @@
 
 static int git_clean_config(const char *var, const char *value, void *cb)
 {
-	if (!prefixcmp(var, "column."))
+	if (starts_with(var, "column."))
 		return git_column_config(var, value, "clean", &colopts);
 
 	/* honors the color.interactive* config variables which also
@@ -108,7 +109,7 @@
 		clean_use_color = git_config_colorbool(var, value);
 		return 0;
 	}
-	if (!prefixcmp(var, "color.interactive.")) {
+	if (starts_with(var, "color.interactive.")) {
 		int slot = parse_clean_color_slot(var +
 						  strlen("color.interactive."));
 		if (slot < 0)
@@ -863,24 +864,23 @@
 	int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
 	struct strbuf abs_path = STRBUF_INIT;
 	struct dir_struct dir;
-	static const char **pathspec;
+	struct pathspec pathspec;
 	struct strbuf buf = STRBUF_INIT;
 	struct string_list exclude_list = STRING_LIST_INIT_NODUP;
 	struct exclude_list *el;
 	struct string_list_item *item;
 	const char *qname;
-	char *seen = NULL;
 	struct option options[] = {
 		OPT__QUIET(&quiet, N_("do not print names of files removed")),
 		OPT__DRY_RUN(&dry_run, N_("dry run")),
 		OPT__FORCE(&force, N_("force")),
 		OPT_BOOL('i', "interactive", &interactive, N_("interactive cleaning")),
-		OPT_BOOLEAN('d', NULL, &remove_directories,
+		OPT_BOOL('d', NULL, &remove_directories,
 				N_("remove whole directories")),
 		{ OPTION_CALLBACK, 'e', "exclude", &exclude_list, N_("pattern"),
 		  N_("add <pattern> to ignore rules"), PARSE_OPT_NONEG, exclude_cb },
-		OPT_BOOLEAN('x', NULL, &ignored, N_("remove ignored files, too")),
-		OPT_BOOLEAN('X', NULL, &ignored_only,
+		OPT_BOOL('x', NULL, &ignored, N_("remove ignored files, too")),
+		OPT_BOOL('X', NULL, &ignored_only,
 				N_("remove only ignored files")),
 		OPT_END()
 	};
@@ -925,12 +925,11 @@
 	for (i = 0; i < exclude_list.nr; i++)
 		add_exclude(exclude_list.items[i].string, "", 0, el, -(i+1));
 
-	pathspec = get_pathspec(prefix, argv);
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_CWD,
+		       prefix, argv);
 
-	fill_directory(&dir, pathspec);
-
-	if (pathspec)
-		seen = xmalloc(argc > 0 ? argc : 1);
+	fill_directory(&dir, &pathspec);
 
 	for (i = 0; i < dir.nr; i++) {
 		struct dir_entry *ent = dir.entries[i];
@@ -961,11 +960,9 @@
 		if (lstat(ent->name, &st))
 			die_errno("Cannot lstat '%s'", ent->name);
 
-		if (pathspec) {
-			memset(seen, 0, argc > 0 ? argc : 1);
-			matches = match_pathspec(pathspec, ent->name, len,
-						 0, seen);
-		}
+		if (pathspec.nr)
+			matches = match_pathspec_depth(&pathspec, ent->name,
+						       len, 0, NULL);
 
 		if (S_ISDIR(st.st_mode)) {
 			if (remove_directories || (matches == MATCHED_EXACTLY)) {
@@ -973,7 +970,7 @@
 				string_list_append(&del_list, rel);
 			}
 		} else {
-			if (pathspec && !matches)
+			if (pathspec.nr && !matches)
 				continue;
 			rel = relative_path(ent->name, prefix, &buf);
 			string_list_append(&del_list, rel);
@@ -1019,7 +1016,6 @@
 		}
 		strbuf_reset(&abs_path);
 	}
-	free(seen);
 
 	strbuf_release(&abs_path);
 	strbuf_release(&buf);
diff --git a/builtin/clone.c b/builtin/clone.c
index 552f340..43e772c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -62,23 +62,22 @@
 	OPT__VERBOSITY(&option_verbosity),
 	OPT_BOOL(0, "progress", &option_progress,
 		 N_("force progress reporting")),
-	OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
-		    N_("don't create a checkout")),
-	OPT_BOOLEAN(0, "bare", &option_bare, N_("create a bare repository")),
-	{ OPTION_BOOLEAN, 0, "naked", &option_bare, NULL,
-		N_("create a bare repository"),
-		PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
-	OPT_BOOLEAN(0, "mirror", &option_mirror,
-		    N_("create a mirror repository (implies bare)")),
+	OPT_BOOL('n', "no-checkout", &option_no_checkout,
+		 N_("don't create a checkout")),
+	OPT_BOOL(0, "bare", &option_bare, N_("create a bare repository")),
+	OPT_HIDDEN_BOOL(0, "naked", &option_bare,
+			N_("create a bare repository")),
+	OPT_BOOL(0, "mirror", &option_mirror,
+		 N_("create a mirror repository (implies bare)")),
 	OPT_BOOL('l', "local", &option_local,
 		N_("to clone from a local repository")),
-	OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks,
+	OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks,
 		    N_("don't use local hardlinks, always copy")),
-	OPT_BOOLEAN('s', "shared", &option_shared,
+	OPT_BOOL('s', "shared", &option_shared,
 		    N_("setup as shared repository")),
-	OPT_BOOLEAN(0, "recursive", &option_recursive,
+	OPT_BOOL(0, "recursive", &option_recursive,
 		    N_("initialize submodules in the clone")),
-	OPT_BOOLEAN(0, "recurse-submodules", &option_recursive,
+	OPT_BOOL(0, "recurse-submodules", &option_recursive,
 		    N_("initialize submodules in the clone")),
 	OPT_STRING(0, "template", &option_template, N_("template-directory"),
 		   N_("directory from which templates will be used")),
@@ -253,6 +252,12 @@
 		die(_("reference repository '%s' is not a local repository."),
 		    item->string);
 
+	if (!access(mkpath("%s/shallow", ref_git), F_OK))
+		die(_("reference repository '%s' is shallow"), item->string);
+
+	if (!access(mkpath("%s/info/grafts", ref_git), F_OK))
+		die(_("reference repository '%s' is grafted"), item->string);
+
 	strbuf_addf(&alternate, "%s/objects", ref_git);
 	add_to_alternates_file(alternate.buf);
 	strbuf_release(&alternate);
@@ -509,9 +514,9 @@
 {
 	const struct ref *ref;
 	for (ref = refs; ref; ref = ref->next) {
-		if (prefixcmp(ref->name, "refs/tags/"))
+		if (!starts_with(ref->name, "refs/tags/"))
 			continue;
-		if (!suffixcmp(ref->name, "^{}"))
+		if (ends_with(ref->name, "^{}"))
 			continue;
 		if (!has_sha1_file(ref->old_sha1))
 			continue;
@@ -557,7 +562,7 @@
 							      0, &rm, transport))
 			die(_("remote did not send all necessary objects"));
 		if (transport->progress)
-			fprintf(stderr, _("done\n"));
+			fprintf(stderr, _("done.\n"));
 	}
 
 	if (refs) {
@@ -579,7 +584,7 @@
 static void update_head(const struct ref *our, const struct ref *remote,
 			const char *msg)
 {
-	if (our && !prefixcmp(our->name, "refs/heads/")) {
+	if (our && starts_with(our->name, "refs/heads/")) {
 		/* Local default branch link */
 		create_symref("HEAD", our->name, NULL);
 		if (!option_bare) {
@@ -626,7 +631,7 @@
 		if (advice_detached_head)
 			detach_advice(sha1_to_hex(sha1));
 	} else {
-		if (prefixcmp(head, "refs/heads/"))
+		if (!starts_with(head, "refs/heads/"))
 			die(_("HEAD not found below refs/heads!"));
 	}
 	free(head);
@@ -792,11 +797,22 @@
 	else
 		repo = repo_name;
 	is_local = option_local != 0 && path && !is_bundle;
-	if (is_local && option_depth)
-		warning(_("--depth is ignored in local clones; use file:// instead."));
+	if (is_local) {
+		if (option_depth)
+			warning(_("--depth is ignored in local clones; use file:// instead."));
+		if (!access(mkpath("%s/shallow", path), F_OK)) {
+			if (option_local > 0)
+				warning(_("source repository is shallow, ignoring --local"));
+			is_local = 0;
+		}
+	}
 	if (option_local > 0 && !is_local)
 		warning(_("--local is ignored"));
 
+	/* no need to be strict, transport_set_option() will validate it again */
+	if (option_depth && atoi(option_depth) < 1)
+		die(_("depth %s is not a positive number"), option_depth);
+
 	if (argc == 2)
 		dir = xstrdup(argv[1]);
 	else
@@ -884,6 +900,7 @@
 
 	remote = remote_get(option_origin);
 	transport = transport_get(remote, remote->url[0]);
+	transport->cloning = 1;
 
 	if (!transport->get_refs_list || (!is_local && !transport->fetch))
 		die(_("Don't know how to clone %s"), transport->url);
diff --git a/builtin/column.c b/builtin/column.c
index e125a55..7581852 100644
--- a/builtin/column.c
+++ b/builtin/column.c
@@ -34,7 +34,7 @@
 	};
 
 	/* This one is special and must be the first one */
-	if (argc > 1 && !prefixcmp(argv[1], "--command=")) {
+	if (argc > 1 && starts_with(argv[1], "--command=")) {
 		command = argv[1] + 10;
 		git_config(column_config, (void *)command);
 	} else
diff --git a/builtin/commit.c b/builtin/commit.c
index a48a7fe..3767478 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -164,6 +164,15 @@
 		s->whence = whence;
 }
 
+static void status_init_config(struct wt_status *s, config_fn_t fn)
+{
+	wt_status_prepare(s);
+	gitmodules_config();
+	git_config(fn, s);
+	determine_whence(s);
+	s->hints = advice_status_hints; /* must come after git_config() */
+}
+
 static void rollback_index_files(void)
 {
 	switch (commit_style) {
@@ -203,17 +212,15 @@
  * and return the paths that match the given pattern in list.
  */
 static int list_paths(struct string_list *list, const char *with_tree,
-		      const char *prefix, const char **pattern)
+		      const char *prefix, const struct pathspec *pattern)
 {
 	int i;
 	char *m;
 
-	if (!pattern)
+	if (!pattern->nr)
 		return 0;
 
-	for (i = 0; pattern[i]; i++)
-		;
-	m = xcalloc(1, i);
+	m = xcalloc(1, pattern->nr);
 
 	if (with_tree) {
 		char *max_prefix = common_prefix(pattern);
@@ -227,7 +234,7 @@
 
 		if (ce->ce_flags & CE_UPDATE)
 			continue;
-		if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
+		if (!match_pathspec_depth(pattern, ce->name, ce_namelen(ce), 0, m))
 			continue;
 		item = string_list_insert(list, ce->name);
 		if (ce_skip_worktree(ce))
@@ -299,17 +306,17 @@
 {
 	int fd;
 	struct string_list partial;
-	const char **pathspec = NULL;
+	struct pathspec pathspec;
 	char *old_index_env = NULL;
 	int refresh_flags = REFRESH_QUIET;
 
 	if (is_status)
 		refresh_flags |= REFRESH_UNMERGED;
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_FULL,
+		       prefix, argv);
 
-	if (*argv)
-		pathspec = get_pathspec(prefix, argv);
-
-	if (read_cache_preload(pathspec) < 0)
+	if (read_cache_preload(&pathspec) < 0)
 		die(_("index file corrupt"));
 
 	if (interactive) {
@@ -351,9 +358,9 @@
 	 * (A) if all goes well, commit the real index;
 	 * (B) on failure, rollback the real index.
 	 */
-	if (all || (also && pathspec && *pathspec)) {
+	if (all || (also && pathspec.nr)) {
 		fd = hold_locked_index(&index_lock, 1);
-		add_files_to_cache(also ? prefix : NULL, pathspec, 0);
+		add_files_to_cache(also ? prefix : NULL, &pathspec, 0);
 		refresh_cache_or_die(refresh_flags);
 		update_main_cache_tree(WRITE_TREE_SILENT);
 		if (write_cache(fd, active_cache, active_nr) ||
@@ -372,7 +379,7 @@
 	 * and create commit from the_index.
 	 * We still need to refresh the index here.
 	 */
-	if (!only && (!pathspec || !*pathspec)) {
+	if (!only && !pathspec.nr) {
 		fd = hold_locked_index(&index_lock, 1);
 		refresh_cache_or_die(refresh_flags);
 		if (active_cache_changed) {
@@ -417,7 +424,7 @@
 
 	memset(&partial, 0, sizeof(partial));
 	partial.strdup_strings = 1;
-	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec))
+	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, &pathspec))
 		exit(1);
 
 	discard_cache();
@@ -600,6 +607,7 @@
 	const char *hook_arg2 = NULL;
 	int ident_shown = 0;
 	int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
+	int old_display_comment_prefix;
 
 	/* This checks and barfs if author is badly specified */
 	determine_author_info(author_ident);
@@ -697,6 +705,16 @@
 	if (s->fp == NULL)
 		die_errno(_("could not open '%s'"), git_path(commit_editmsg));
 
+	/* Ignore status.displayCommentPrefix: we do need comments in COMMIT_EDITMSG. */
+	old_display_comment_prefix = s->display_comment_prefix;
+	s->display_comment_prefix = 1;
+
+	/*
+	 * Most hints are counter-productive when the commit has
+	 * already started.
+	 */
+	s->hints = 0;
+
 	if (clean_message_contents)
 		stripspace(&sb, 0);
 
@@ -715,7 +733,7 @@
 				eol = nl - sb.buf;
 			else
 				eol = sb.len;
-			if (!prefixcmp(sb.buf + previous, "\nConflicts:\n")) {
+			if (starts_with(sb.buf + previous, "\nConflicts:\n")) {
 				ignore_footer = sb.len - previous;
 				break;
 			}
@@ -822,6 +840,7 @@
 	 */
 	if (!commitable && whence != FROM_MERGE && !allow_empty &&
 	    !(amend && is_a_merge(current_head))) {
+		s->display_comment_prefix = old_display_comment_prefix;
 		run_status(stdout, index_file, prefix, 0, s);
 		if (amend)
 			fputs(_(empty_amend_advice), stderr);
@@ -885,7 +904,7 @@
 			eol = sb->len;
 
 		if (strlen(sign_off_header) <= eol - i &&
-		    !prefixcmp(sb->buf + i, sign_off_header)) {
+		    starts_with(sb->buf + i, sign_off_header)) {
 			i = eol;
 			continue;
 		}
@@ -1097,7 +1116,7 @@
 	if (patch_interactive)
 		interactive = 1;
 
-	if (!!also + !!only + !!all + !!interactive > 1)
+	if (also + only + all + interactive > 1)
 		die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
 	if (argc == 0 && (also || (only && !amend)))
 		die(_("No paths with --include/--only does not make sense."));
@@ -1164,7 +1183,7 @@
 {
 	struct wt_status *s = cb;
 
-	if (!prefixcmp(k, "column."))
+	if (starts_with(k, "column."))
 		return git_column_config(k, v, "status", &s->colopts);
 	if (!strcmp(k, "status.submodulesummary")) {
 		int is_bool;
@@ -1188,7 +1207,11 @@
 		s->use_color = git_config_colorbool(k, v);
 		return 0;
 	}
-	if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
+	if (!strcmp(k, "status.displaycommentprefix")) {
+		s->display_comment_prefix = git_config_bool(k, v);
+		return 0;
+	}
+	if (starts_with(k, "status.color.") || starts_with(k, "color.status.")) {
 		int slot = parse_status_slot(k, 13);
 		if (slot < 0)
 			return 0;
@@ -1234,14 +1257,14 @@
 		OPT_SET_INT(0, "long", &status_format,
 			    N_("show status in long format (default)"),
 			    STATUS_FORMAT_LONG),
-		OPT_BOOLEAN('z', "null", &s.null_termination,
-			    N_("terminate entries with NUL")),
+		OPT_BOOL('z', "null", &s.null_termination,
+			 N_("terminate entries with NUL")),
 		{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
 		  N_("mode"),
 		  N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
 		  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
-		OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
-			    N_("show ignored files")),
+		OPT_BOOL(0, "ignored", &show_ignored_in_status,
+			 N_("show ignored files")),
 		{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
 		  N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
 		  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
@@ -1252,10 +1275,7 @@
 	if (argc == 2 && !strcmp(argv[1], "-h"))
 		usage_with_options(builtin_status_usage, builtin_status_options);
 
-	wt_status_prepare(&s);
-	gitmodules_config();
-	git_config(git_status_config, &s);
-	determine_whence(&s);
+	status_init_config(&s, git_status_config);
 	argc = parse_options(argc, argv, prefix,
 			     builtin_status_options,
 			     builtin_status_usage, 0);
@@ -1265,11 +1285,12 @@
 	handle_untracked_files_arg(&s);
 	if (show_ignored_in_status)
 		s.show_ignored_files = 1;
-	if (*argv)
-		s.pathspec = get_pathspec(prefix, argv);
+	parse_pathspec(&s.pathspec, 0,
+		       PATHSPEC_PREFER_FULL,
+		       prefix, argv);
 
-	read_cache_preload(s.pathspec);
-	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
+	read_cache_preload(&s.pathspec);
+	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &s.pathspec, NULL, NULL);
 
 	fd = hold_locked_index(&index_lock, 0);
 	if (0 <= fd)
@@ -1317,7 +1338,7 @@
 	commit = lookup_commit(sha1);
 	if (!commit)
 		die(_("couldn't look up newly created commit"));
-	if (!commit || parse_commit(commit))
+	if (parse_commit(commit))
 		die(_("could not parse newly created commit"));
 
 	strbuf_addstr(&format, "format:%h] %s");
@@ -1356,7 +1377,7 @@
 
 	head = resolve_ref_unsafe("HEAD", junk_sha1, 0, NULL);
 	printf("[%s%s ",
-		!prefixcmp(head, "refs/heads/") ?
+		starts_with(head, "refs/heads/") ?
 			head + 11 :
 			!strcmp(head, "HEAD") ?
 				_("detached HEAD") :
@@ -1440,24 +1461,24 @@
 		OPT_STRING('C', "reuse-message", &use_message, N_("commit"), N_("reuse message from specified commit")),
 		OPT_STRING(0, "fixup", &fixup_message, N_("commit"), N_("use autosquash formatted message to fixup specified commit")),
 		OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")),
-		OPT_BOOLEAN(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")),
-		OPT_BOOLEAN('s', "signoff", &signoff, N_("add Signed-off-by:")),
+		OPT_BOOL(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")),
+		OPT_BOOL('s', "signoff", &signoff, N_("add Signed-off-by:")),
 		OPT_FILENAME('t', "template", &template_file, N_("use specified template file")),
 		OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
 		OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")),
-		OPT_BOOLEAN(0, "status", &include_status, N_("include status in commit message template")),
+		OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")),
 		{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
 		  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
 		/* end commit message options */
 
 		OPT_GROUP(N_("Commit contents options")),
-		OPT_BOOLEAN('a', "all", &all, N_("commit all changed files")),
-		OPT_BOOLEAN('i', "include", &also, N_("add specified files to index for commit")),
-		OPT_BOOLEAN(0, "interactive", &interactive, N_("interactively add files")),
-		OPT_BOOLEAN('p', "patch", &patch_interactive, N_("interactively add changes")),
-		OPT_BOOLEAN('o', "only", &only, N_("commit only specified files")),
-		OPT_BOOLEAN('n', "no-verify", &no_verify, N_("bypass pre-commit hook")),
-		OPT_BOOLEAN(0, "dry-run", &dry_run, N_("show what would be committed")),
+		OPT_BOOL('a', "all", &all, N_("commit all changed files")),
+		OPT_BOOL('i', "include", &also, N_("add specified files to index for commit")),
+		OPT_BOOL(0, "interactive", &interactive, N_("interactively add files")),
+		OPT_BOOL('p', "patch", &patch_interactive, N_("interactively add changes")),
+		OPT_BOOL('o', "only", &only, N_("commit only specified files")),
+		OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit hook")),
+		OPT_BOOL(0, "dry-run", &dry_run, N_("show what would be committed")),
 		OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
 			    STATUS_FORMAT_SHORT),
 		OPT_BOOL(0, "branch", &s.show_branch, N_("show branch information")),
@@ -1466,19 +1487,17 @@
 		OPT_SET_INT(0, "long", &status_format,
 			    N_("show status in long format (default)"),
 			    STATUS_FORMAT_LONG),
-		OPT_BOOLEAN('z', "null", &s.null_termination,
-			    N_("terminate entries with NUL")),
-		OPT_BOOLEAN(0, "amend", &amend, N_("amend previous commit")),
-		OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
+		OPT_BOOL('z', "null", &s.null_termination,
+			 N_("terminate entries with NUL")),
+		OPT_BOOL(0, "amend", &amend, N_("amend previous commit")),
+		OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
 		{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
 		/* end commit contents options */
 
-		{ OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
-		  N_("ok to record an empty change"),
-		  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
-		{ OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
-		  N_("ok to record a change with an empty message"),
-		  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
+		OPT_HIDDEN_BOOL(0, "allow-empty", &allow_empty,
+				N_("ok to record an empty change")),
+		OPT_HIDDEN_BOOL(0, "allow-empty-message", &allow_empty_message,
+				N_("ok to record a change with an empty message")),
 
 		OPT_END()
 	};
@@ -1486,7 +1505,7 @@
 	struct strbuf sb = STRBUF_INIT;
 	struct strbuf author_ident = STRBUF_INIT;
 	const char *index_file, *reflog_msg;
-	char *nl, *p;
+	char *nl;
 	unsigned char sha1[20];
 	struct ref_lock *ref_lock;
 	struct commit_list *parents = NULL, **pptr = &parents;
@@ -1498,18 +1517,15 @@
 	if (argc == 2 && !strcmp(argv[1], "-h"))
 		usage_with_options(builtin_commit_usage, builtin_commit_options);
 
-	wt_status_prepare(&s);
-	gitmodules_config();
-	git_config(git_commit_config, &s);
+	status_init_config(&s, git_commit_config);
 	status_format = STATUS_FORMAT_NONE; /* Ignore status.short */
-	determine_whence(&s);
 	s.colopts = 0;
 
 	if (get_sha1("HEAD", sha1))
 		current_head = NULL;
 	else {
 		current_head = lookup_commit_or_die(sha1, "HEAD");
-		if (!current_head || parse_commit(current_head))
+		if (parse_commit(current_head))
 			die(_("could not parse HEAD commit"));
 	}
 	argc = parse_and_validate_options(argc, argv, builtin_commit_options,
@@ -1585,11 +1601,8 @@
 	}
 
 	/* Truncate the message just before the diff, if any. */
-	if (verbose) {
-		p = strstr(sb.buf, "\ndiff --git ");
-		if (p != NULL)
-			strbuf_setlen(&sb, p - sb.buf + 1);
-	}
+	if (verbose)
+		wt_status_truncate_message_at_cut_line(&sb);
 
 	if (cleanup_mode != CLEANUP_NONE)
 		stripspace(&sb, cleanup_mode == CLEANUP_ALL);
@@ -1624,7 +1637,7 @@
 					   !current_head
 					   ? NULL
 					   : current_head->object.sha1,
-					   0);
+					   0, NULL);
 
 	nl = strchr(sb.buf, '\n');
 	if (nl)
diff --git a/builtin/config.c b/builtin/config.c
index 4010c43..92ebf23 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -2,6 +2,7 @@
 #include "cache.h"
 #include "color.h"
 #include "parse-options.h"
+#include "urlmatch.h"
 
 static const char *const builtin_config_usage[] = {
 	N_("git config [options]"),
@@ -42,6 +43,7 @@
 #define ACTION_SET_ALL (1<<12)
 #define ACTION_GET_COLOR (1<<13)
 #define ACTION_GET_COLORBOOL (1<<14)
+#define ACTION_GET_URLMATCH (1<<15)
 
 #define TYPE_BOOL (1<<0)
 #define TYPE_INT (1<<1)
@@ -50,15 +52,16 @@
 
 static struct option builtin_config_options[] = {
 	OPT_GROUP(N_("Config file location")),
-	OPT_BOOLEAN(0, "global", &use_global_config, N_("use global config file")),
-	OPT_BOOLEAN(0, "system", &use_system_config, N_("use system config file")),
-	OPT_BOOLEAN(0, "local", &use_local_config, N_("use repository config file")),
+	OPT_BOOL(0, "global", &use_global_config, N_("use global config file")),
+	OPT_BOOL(0, "system", &use_system_config, N_("use system config file")),
+	OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")),
 	OPT_STRING('f', "file", &given_config_file, N_("file"), N_("use given config file")),
 	OPT_STRING(0, "blob", &given_config_blob, N_("blob-id"), N_("read config from given blob object")),
 	OPT_GROUP(N_("Action")),
 	OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
 	OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
 	OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP),
+	OPT_BIT(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH),
 	OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL),
 	OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
 	OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET),
@@ -75,7 +78,7 @@
 	OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
 	OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
 	OPT_GROUP(N_("Other")),
-	OPT_BOOLEAN('z', "null", &end_null, N_("terminate values with NUL byte")),
+	OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
 	OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
 	OPT_END(),
 };
@@ -102,25 +105,13 @@
 	int alloc;
 };
 
-static int collect_config(const char *key_, const char *value_, void *cb)
+static int format_config(struct strbuf *buf, const char *key_, const char *value_)
 {
-	struct strbuf_list *values = cb;
-	struct strbuf *buf;
-	char value[256];
-	const char *vptr = value;
 	int must_free_vptr = 0;
 	int must_print_delim = 0;
+	char value[256];
+	const char *vptr = value;
 
-	if (!use_key_regexp && strcmp(key_, key))
-		return 0;
-	if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
-		return 0;
-	if (regexp != NULL &&
-	    (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
-		return 0;
-
-	ALLOC_GROW(values->items, values->nr + 1, values->alloc);
-	buf = &values->items[values->nr++];
 	strbuf_init(buf, 0);
 
 	if (show_keys) {
@@ -128,7 +119,8 @@
 		must_print_delim = 1;
 	}
 	if (types == TYPE_INT)
-		sprintf(value, "%d", git_config_int(key_, value_?value_:""));
+		sprintf(value, "%"PRId64,
+			git_config_int64(key_, value_ ? value_ : ""));
 	else if (types == TYPE_BOOL)
 		vptr = git_config_bool(key_, value_) ? "true" : "false";
 	else if (types == TYPE_BOOL_OR_INT) {
@@ -156,15 +148,27 @@
 	strbuf_addch(buf, term);
 
 	if (must_free_vptr)
-		/* If vptr must be freed, it's a pointer to a
-		 * dynamically allocated buffer, it's safe to cast to
-		 * const.
-		*/
 		free((char *)vptr);
-
 	return 0;
 }
 
+static int collect_config(const char *key_, const char *value_, void *cb)
+{
+	struct strbuf_list *values = cb;
+
+	if (!use_key_regexp && strcmp(key_, key))
+		return 0;
+	if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
+		return 0;
+	if (regexp != NULL &&
+	    (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
+		return 0;
+
+	ALLOC_GROW(values->items, values->nr + 1, values->alloc);
+
+	return format_config(&values->items[values->nr++], key_, value_);
+}
+
 static int get_value(const char *key_, const char *regex_)
 {
 	int ret = CONFIG_GENERIC_ERROR;
@@ -265,8 +269,8 @@
 	else {
 		normalized = xmalloc(64);
 		if (types == TYPE_INT) {
-			int v = git_config_int(key, value);
-			sprintf(normalized, "%d", v);
+			int64_t v = git_config_int64(key, value);
+			sprintf(normalized, "%"PRId64, v);
 		}
 		else if (types == TYPE_BOOL)
 			sprintf(normalized, "%s",
@@ -364,6 +368,97 @@
 		die("writing config blobs is not supported");
 }
 
+struct urlmatch_current_candidate_value {
+	char value_is_null;
+	struct strbuf value;
+};
+
+static int urlmatch_collect_fn(const char *var, const char *value, void *cb)
+{
+	struct string_list *values = cb;
+	struct string_list_item *item = string_list_insert(values, var);
+	struct urlmatch_current_candidate_value *matched = item->util;
+
+	if (!matched) {
+		matched = xmalloc(sizeof(*matched));
+		strbuf_init(&matched->value, 0);
+		item->util = matched;
+	} else {
+		strbuf_reset(&matched->value);
+	}
+
+	if (value) {
+		strbuf_addstr(&matched->value, value);
+		matched->value_is_null = 0;
+	} else {
+		matched->value_is_null = 1;
+	}
+	return 0;
+}
+
+static char *dup_downcase(const char *string)
+{
+	char *result;
+	size_t len, i;
+
+	len = strlen(string);
+	result = xmalloc(len + 1);
+	for (i = 0; i < len; i++)
+		result[i] = tolower(string[i]);
+	result[i] = '\0';
+	return result;
+}
+
+static int get_urlmatch(const char *var, const char *url)
+{
+	char *section_tail;
+	struct string_list_item *item;
+	struct urlmatch_config config = { STRING_LIST_INIT_DUP };
+	struct string_list values = STRING_LIST_INIT_DUP;
+
+	config.collect_fn = urlmatch_collect_fn;
+	config.cascade_fn = NULL;
+	config.cb = &values;
+
+	if (!url_normalize(url, &config.url))
+		die("%s", config.url.err);
+
+	config.section = dup_downcase(var);
+	section_tail = strchr(config.section, '.');
+	if (section_tail) {
+		*section_tail = '\0';
+		config.key = section_tail + 1;
+		show_keys = 0;
+	} else {
+		config.key = NULL;
+		show_keys = 1;
+	}
+
+	git_config_with_options(urlmatch_config_entry, &config,
+				given_config_file, NULL, respect_includes);
+
+	for_each_string_list_item(item, &values) {
+		struct urlmatch_current_candidate_value *matched = item->util;
+		struct strbuf key = STRBUF_INIT;
+		struct strbuf buf = STRBUF_INIT;
+
+		strbuf_addstr(&key, item->string);
+		format_config(&buf, key.buf,
+			      matched->value_is_null ? NULL : matched->value.buf);
+		fwrite(buf.buf, 1, buf.len, stdout);
+		strbuf_release(&key);
+		strbuf_release(&buf);
+
+		strbuf_release(&matched->value);
+	}
+	string_list_clear(&config.vars, 1);
+	string_list_clear(&values, 1);
+	free(config.url.url);
+
+	free((void *)config.section);
+	return 0;
+}
+
 int cmd_config(int argc, const char **argv, const char *prefix)
 {
 	int nongit = !startup_info->have_repository;
@@ -523,6 +618,10 @@
 		check_argc(argc, 1, 2);
 		return get_value(argv[0], argv[1]);
 	}
+	else if (actions == ACTION_GET_URLMATCH) {
+		check_argc(argc, 2, 2);
+		return get_urlmatch(argv[0], argv[1]);
+	}
 	else if (actions == ACTION_UNSET) {
 		check_blob_write();
 		check_argc(argc, 1, 2);
@@ -572,9 +671,3 @@
 
 	return 0;
 }
-
-int cmd_repo_config(int argc, const char **argv, const char *prefix)
-{
-	fprintf(stderr, "WARNING: git repo-config is deprecated in favor of git config.\n");
-	return cmd_config(argc, argv, prefix);
-}
diff --git a/builtin/describe.c b/builtin/describe.c
index 7d73722..7db43da 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -9,11 +9,11 @@
 #include "hash.h"
 #include "argv-array.h"
 
-#define SEEN		(1u<<0)
+#define SEEN		(1u << 0)
 #define MAX_TAGS	(FLAG_BITS - 1)
 
 static const char * const describe_usage[] = {
-	N_("git describe [options] <committish>*"),
+	N_("git describe [options] <commit-ish>*"),
 	N_("git describe [options] --dirty"),
 	NULL
 };
@@ -36,7 +36,6 @@
 	"diff-index", "--quiet", "HEAD", "--", NULL
 };
 
-
 struct commit_name {
 	struct commit_name *next;
 	unsigned char peeled[20];
@@ -46,6 +45,7 @@
 	unsigned char sha1[20];
 	char *path;
 };
+
 static const char *prio_names[] = {
 	"head", "lightweight", "annotated",
 };
@@ -141,7 +141,7 @@
 
 static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
 {
-	int is_tag = !prefixcmp(path, "refs/tags/");
+	int is_tag = starts_with(path, "refs/tags/");
 	unsigned char peeled[20];
 	int is_annotated, prio;
 
@@ -406,12 +406,12 @@
 {
 	int contains = 0;
 	struct option options[] = {
-		OPT_BOOLEAN(0, "contains",   &contains, N_("find the tag that comes after the commit")),
-		OPT_BOOLEAN(0, "debug",      &debug, N_("debug search strategy on stderr")),
-		OPT_BOOLEAN(0, "all",        &all, N_("use any ref")),
-		OPT_BOOLEAN(0, "tags",       &tags, N_("use any tag, even unannotated")),
-		OPT_BOOLEAN(0, "long",       &longformat, N_("always use long format")),
-		OPT_BOOLEAN(0, "first-parent", &first_parent, N_("only follow first parent")),
+		OPT_BOOL(0, "contains",   &contains, N_("find the tag that comes after the commit")),
+		OPT_BOOL(0, "debug",      &debug, N_("debug search strategy on stderr")),
+		OPT_BOOL(0, "all",        &all, N_("use any ref")),
+		OPT_BOOL(0, "tags",       &tags, N_("use any tag, even unannotated")),
+		OPT_BOOL(0, "long",       &longformat, N_("always use long format")),
+		OPT_BOOL(0, "first-parent", &first_parent, N_("only follow first parent")),
 		OPT__ABBREV(&abbrev),
 		OPT_SET_INT(0, "exact-match", &max_candidates,
 			    N_("only output exact matches"), 0),
@@ -419,11 +419,11 @@
 			    N_("consider <n> most recent tags (default: 10)")),
 		OPT_STRING(0, "match",       &pattern, N_("pattern"),
 			   N_("only consider tags matching <pattern>")),
-		OPT_BOOLEAN(0, "always",     &always,
-			   N_("show abbreviated commit object as fallback")),
+		OPT_BOOL(0, "always",        &always,
+			N_("show abbreviated commit object as fallback")),
 		{OPTION_STRING, 0, "dirty",  &dirty, N_("mark"),
-			   N_("append <mark> on dirty working tree (default: \"-dirty\")"),
-		 PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
+			N_("append <mark> on dirty working tree (default: \"-dirty\")"),
+			PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
 		OPT_END(),
 	};
 
@@ -486,11 +486,10 @@
 		}
 		describe("HEAD", 1);
 	} else if (dirty) {
-		die(_("--dirty is incompatible with committishes"));
+		die(_("--dirty is incompatible with commit-ishes"));
 	} else {
-		while (argc-- > 0) {
+		while (argc-- > 0)
 			describe(*argv++, argc == 0);
-		}
 	}
 	return 0;
 }
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 46085f8..9200069 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -61,7 +61,7 @@
 	    (rev.diffopt.output_format & DIFF_FORMAT_PATCH))
 		rev.combine_merges = rev.dense_combined_merges = 1;
 
-	if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {
+	if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
 		perror("read_cache_preload");
 		return -1;
 	}
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 1c737f7..ce15b23 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -43,7 +43,7 @@
 		usage(diff_cache_usage);
 	if (!cached) {
 		setup_work_tree();
-		if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {
+		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
 			perror("read_cache_preload");
 			return -1;
 		}
diff --git a/builtin/diff.c b/builtin/diff.c
index 9fc273d..0f247d2 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -16,6 +16,9 @@
 #include "submodule.h"
 #include "sha1-array.h"
 
+#define DIFF_NO_INDEX_EXPLICIT 1
+#define DIFF_NO_INDEX_IMPLICIT 2
+
 struct blobinfo {
 	unsigned char sha1[20];
 	const char *name;
@@ -64,15 +67,18 @@
 
 static int builtin_diff_b_f(struct rev_info *revs,
 			    int argc, const char **argv,
-			    struct blobinfo *blob,
-			    const char *path)
+			    struct blobinfo *blob)
 {
 	/* Blob vs file in the working tree*/
 	struct stat st;
+	const char *path;
 
 	if (argc > 1)
 		usage(builtin_diff_usage);
 
+	GUARD_PATHSPEC(&revs->prune_data, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+	path = revs->prune_data.items[0].match;
+
 	if (lstat(path, &st))
 		die_errno(_("failed to stat '%s'"), path);
 	if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
@@ -140,7 +146,7 @@
 		usage(builtin_diff_usage);
 	if (!cached) {
 		setup_work_tree();
-		if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
+		if (read_cache_preload(&revs->diffopt.pathspec) < 0) {
 			perror("read_cache_preload");
 			return -1;
 		}
@@ -169,7 +175,7 @@
 	if (ent1->item->flags & UNINTERESTING)
 		swap = 1;
 	sha1[swap] = ent0->item->sha1;
-	sha1[1-swap] = ent1->item->sha1;
+	sha1[1 - swap] = ent1->item->sha1;
 	diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
 	log_tree_diff_flush(revs);
 	return 0;
@@ -242,7 +248,7 @@
 		revs->combine_merges = revs->dense_combined_merges = 1;
 
 	setup_work_tree();
-	if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
+	if (read_cache_preload(&revs->diffopt.pathspec) < 0) {
 		perror("read_cache_preload");
 		return -1;
 	}
@@ -255,9 +261,8 @@
 	struct rev_info rev;
 	struct object_array ent = OBJECT_ARRAY_INIT;
 	int blobs = 0, paths = 0;
-	const char *path = NULL;
 	struct blobinfo blob[2];
-	int nongit;
+	int nongit = 0, no_index = 0;
 	int result = 0;
 
 	/*
@@ -283,14 +288,59 @@
 	 * Other cases are errors.
 	 */
 
-	prefix = setup_git_directory_gently(&nongit);
-	gitmodules_config();
+	/* Were we asked to do --no-index explicitly? */
+	for (i = 1; i < argc; i++) {
+		if (!strcmp(argv[i], "--")) {
+			i++;
+			break;
+		}
+		if (!strcmp(argv[i], "--no-index"))
+			no_index = DIFF_NO_INDEX_EXPLICIT;
+		if (argv[i][0] != '-')
+			break;
+	}
+
+	if (!no_index)
+		prefix = setup_git_directory_gently(&nongit);
+
+	/*
+	 * Treat git diff with at least one path outside of the
+	 * repo the same as if the command would have been executed
+	 * outside of a git repository.  In this case it behaves
+	 * the same way as "git diff --no-index <a> <b>", which acts
+	 * as a colourful "diff" replacement.
+	 */
+	if (nongit || ((argc == i + 2) &&
+		       (!path_inside_repo(prefix, argv[i]) ||
+			!path_inside_repo(prefix, argv[i + 1]))))
+		no_index = DIFF_NO_INDEX_IMPLICIT;
+
+	if (!no_index)
+		gitmodules_config();
 	git_config(git_diff_ui_config, NULL);
 
 	init_revisions(&rev, prefix);
 
-	/* If this is a no-index diff, just run it and exit there. */
-	diff_no_index(&rev, argc, argv, nongit, prefix);
+	if (no_index && argc != i + 2) {
+		if (no_index == DIFF_NO_INDEX_IMPLICIT) {
+			/*
+			 * There was no --no-index and there were not two
+			 * paths. It is possible that the user intended
+			 * to do an inside-repository operation.
+			 */
+			fprintf(stderr, "Not a git repository\n");
+			fprintf(stderr,
+				"To compare two paths outside a working tree:\n");
+		}
+		/* Give the usage message for non-repository usage and exit. */
+		usagef("git diff %s <path> <path>",
+		       no_index == DIFF_NO_INDEX_EXPLICIT ?
+		       "--no-index" : "[--no-index]");
+
+	}
+	if (no_index)
+		/* If this is a no-index diff, just run it and exit there. */
+		diff_no_index(&rev, argc, argv, prefix);
 
 	/* Otherwise, we are doing the usual "git" diff */
 	rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;
@@ -366,11 +416,8 @@
 			die(_("unhandled object '%s' given."), name);
 		}
 	}
-	if (rev.prune_data.nr) {
-		if (!path)
-			path = rev.prune_data.items[0].match;
+	if (rev.prune_data.nr)
 		paths += rev.prune_data.nr;
-	}
 
 	/*
 	 * Now, do the arguments look reasonable?
@@ -383,7 +430,7 @@
 		case 1:
 			if (paths != 1)
 				usage(builtin_diff_usage);
-			result = builtin_diff_b_f(&rev, argc, argv, blob, path);
+			result = builtin_diff_b_f(&rev, argc, argv, blob);
 			break;
 		case 2:
 			if (paths)
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 8e19058..b8d8a3a 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -30,6 +30,7 @@
 static int use_done_feature;
 static int no_data;
 static int full_tree;
+static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
 
 static int parse_opt_signed_tag_mode(const struct option *opt,
 				     const char *arg, int unset)
@@ -286,7 +287,7 @@
 
 	rev->diffopt.output_format = DIFF_FORMAT_CALLBACK;
 
-	parse_commit(commit);
+	parse_commit_or_die(commit);
 	author = strstr(commit->buffer, "\nauthor ");
 	if (!author)
 		die ("Could not find author in commit %s",
@@ -307,7 +308,7 @@
 	if (commit->parents &&
 	    get_object_mark(&commit->parents->item->object) != 0 &&
 	    !full_tree) {
-		parse_commit(commit->parents->item);
+		parse_commit_or_die(commit->parents->item);
 		diff_tree_sha1(commit->parents->item->tree->object.sha1,
 			       commit->tree->object.sha1, "", &rev->diffopt);
 	}
@@ -475,7 +476,7 @@
 		}
 	}
 
-	if (!prefixcmp(name, "refs/tags/"))
+	if (starts_with(name, "refs/tags/"))
 		name += 10;
 	printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n",
 	       name, tagged_mark,
@@ -484,10 +485,32 @@
 	       (int)message_size, (int)message_size, message ? message : "");
 }
 
-static void get_tags_and_duplicates(struct rev_cmdline_info *info,
-				    struct string_list *extra_refs)
+static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)
 {
-	struct tag *tag;
+	switch (e->item->type) {
+	case OBJ_COMMIT:
+		return (struct commit *)e->item;
+	case OBJ_TAG: {
+		struct tag *tag = (struct tag *)e->item;
+
+		/* handle nested tags */
+		while (tag && tag->object.type == OBJ_TAG) {
+			parse_object(tag->object.sha1);
+			string_list_append(&extra_refs, full_name)->util = tag;
+			tag = (struct tag *)tag->tagged;
+		}
+		if (!tag)
+			die("Tag %s points nowhere?", e->name);
+		return (struct commit *)tag;
+		break;
+	}
+	default:
+		return NULL;
+	}
+}
+
+static void get_tags_and_duplicates(struct rev_cmdline_info *info)
+{
 	int i;
 
 	for (i = 0; i < info->nr; i++) {
@@ -502,60 +525,45 @@
 		if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
 			continue;
 
-		switch (e->item->type) {
-		case OBJ_COMMIT:
-			commit = (struct commit *)e->item;
-			break;
-		case OBJ_TAG:
-			tag = (struct tag *)e->item;
-
-			/* handle nested tags */
-			while (tag && tag->object.type == OBJ_TAG) {
-				parse_object(tag->object.sha1);
-				string_list_append(extra_refs, full_name)->util = tag;
-				tag = (struct tag *)tag->tagged;
-			}
-			if (!tag)
-				die ("Tag %s points nowhere?", e->name);
-			switch(tag->object.type) {
-			case OBJ_COMMIT:
-				commit = (struct commit *)tag;
-				break;
-			case OBJ_BLOB:
-				export_blob(tag->object.sha1);
-				continue;
-			default: /* OBJ_TAG (nested tags) is already handled */
-				warning("Tag points to object of unexpected type %s, skipping.",
-					typename(tag->object.type));
-				continue;
-			}
-			break;
-		default:
+		commit = get_commit(e, full_name);
+		if (!commit) {
 			warning("%s: Unexpected object of type %s, skipping.",
 				e->name,
 				typename(e->item->type));
 			continue;
 		}
 
+		switch(commit->object.type) {
+		case OBJ_COMMIT:
+			break;
+		case OBJ_BLOB:
+			export_blob(commit->object.sha1);
+			continue;
+		default: /* OBJ_TAG (nested tags) is already handled */
+			warning("Tag points to object of unexpected type %s, skipping.",
+				typename(commit->object.type));
+			continue;
+		}
+
 		/*
 		 * This ref will not be updated through a commit, lets make
 		 * sure it gets properly updated eventually.
 		 */
 		if (commit->util || commit->object.flags & SHOWN)
-			string_list_append(extra_refs, full_name)->util = commit;
+			string_list_append(&extra_refs, full_name)->util = commit;
 		if (!commit->util)
 			commit->util = full_name;
 	}
 }
 
-static void handle_tags_and_duplicates(struct string_list *extra_refs)
+static void handle_tags_and_duplicates(void)
 {
 	struct commit *commit;
 	int i;
 
-	for (i = extra_refs->nr - 1; i >= 0; i--) {
-		const char *name = extra_refs->items[i].string;
-		struct object *object = extra_refs->items[i].util;
+	for (i = extra_refs.nr - 1; i >= 0; i--) {
+		const char *name = extra_refs.items[i].string;
+		struct object *object = extra_refs.items[i].util;
 		switch (object->type) {
 		case OBJ_TAG:
 			handle_tag(name, (struct tag *)object);
@@ -657,7 +665,6 @@
 {
 	struct rev_info revs;
 	struct object_array commits = OBJECT_ARRAY_INIT;
-	struct string_list extra_refs = STRING_LIST_INIT_NODUP;
 	struct commit *commit;
 	char *export_filename = NULL, *import_filename = NULL;
 	uint32_t lastimportid;
@@ -674,11 +681,11 @@
 			     N_("Dump marks to this file")),
 		OPT_STRING(0, "import-marks", &import_filename, N_("file"),
 			     N_("Import marks from this file")),
-		OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger,
-			     N_("Fake a tagger when tags lack one")),
-		OPT_BOOLEAN(0, "full-tree", &full_tree,
-			     N_("Output full tree for each commit")),
-		OPT_BOOLEAN(0, "use-done-feature", &use_done_feature,
+		OPT_BOOL(0, "fake-missing-tagger", &fake_missing_tagger,
+			 N_("Fake a tagger when tags lack one")),
+		OPT_BOOL(0, "full-tree", &full_tree,
+			 N_("Output full tree for each commit")),
+		OPT_BOOL(0, "use-done-feature", &use_done_feature,
 			     N_("Use the done feature to terminate the stream")),
 		OPT_BOOL(0, "no-data", &no_data, N_("Skip output of blob data")),
 		OPT_END()
@@ -709,7 +716,7 @@
 	if (import_filename && revs.prune_data.nr)
 		full_tree = 1;
 
-	get_tags_and_duplicates(&revs.cmdline, &extra_refs);
+	get_tags_and_duplicates(&revs.cmdline);
 
 	if (prepare_revision_walk(&revs))
 		die("revision walk setup failed");
@@ -725,7 +732,7 @@
 		}
 	}
 
-	handle_tags_and_duplicates(&extra_refs);
+	handle_tags_and_duplicates();
 
 	if (export_filename && lastimportid != last_idnum)
 		export_marks(export_filename);
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index aba4465..1262b40 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -1,16 +1,26 @@
 #include "builtin.h"
 #include "pkt-line.h"
 #include "fetch-pack.h"
+#include "remote.h"
+#include "connect.h"
+#include "sha1-array.h"
 
 static const char fetch_pack_usage[] =
 "git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] "
 "[--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] "
-"[--no-progress] [-v] [<host>:]<directory> [<refs>...]";
+"[--no-progress] [--diag-url] [-v] [<host>:]<directory> [<refs>...]";
 
 static void add_sought_entry_mem(struct ref ***sought, int *nr, int *alloc,
 				 const char *name, int namelen)
 {
 	struct ref *ref = xcalloc(1, sizeof(*ref) + namelen + 1);
+	unsigned char sha1[20];
+
+	if (namelen > 41 && name[40] == ' ' && !get_sha1_hex(name, sha1)) {
+		hashcpy(ref->old_sha1, sha1);
+		name += 41;
+		namelen -= 41;
+	}
 
 	memcpy(ref->name, name, namelen);
 	ref->name[namelen] = '\0';
@@ -37,6 +47,7 @@
 	char **pack_lockfile_ptr = NULL;
 	struct child_process *conn;
 	struct fetch_pack_args args;
+	struct sha1_array shallow = SHA1_ARRAY_INIT;
 
 	packet_trace_identity("fetch-pack");
 
@@ -46,11 +57,11 @@
 	for (i = 1; i < argc && *argv[i] == '-'; i++) {
 		const char *arg = argv[i];
 
-		if (!prefixcmp(arg, "--upload-pack=")) {
+		if (starts_with(arg, "--upload-pack=")) {
 			args.uploadpack = arg + 14;
 			continue;
 		}
-		if (!prefixcmp(arg, "--exec=")) {
+		if (starts_with(arg, "--exec=")) {
 			args.uploadpack = arg + 7;
 			continue;
 		}
@@ -79,11 +90,15 @@
 			args.stdin_refs = 1;
 			continue;
 		}
+		if (!strcmp("--diag-url", arg)) {
+			args.diag_url = 1;
+			continue;
+		}
 		if (!strcmp("-v", arg)) {
 			args.verbose = 1;
 			continue;
 		}
-		if (!prefixcmp(arg, "--depth=")) {
+		if (starts_with(arg, "--depth=")) {
 			args.depth = strtol(arg + 8, NULL, 0);
 			continue;
 		}
@@ -100,6 +115,18 @@
 			pack_lockfile_ptr = &pack_lockfile;
 			continue;
 		}
+		if (!strcmp("--check-self-contained-and-connected", arg)) {
+			args.check_self_contained_and_connected = 1;
+			continue;
+		}
+		if (!strcmp("--cloning", arg)) {
+			args.cloning = 1;
+			continue;
+		}
+		if (!strcmp("--update-shallow", arg)) {
+			args.update_shallow = 1;
+			continue;
+		}
 		usage(fetch_pack_usage);
 	}
 
@@ -140,18 +167,27 @@
 		fd[0] = 0;
 		fd[1] = 1;
 	} else {
+		int flags = args.verbose ? CONNECT_VERBOSE : 0;
+		if (args.diag_url)
+			flags |= CONNECT_DIAG_URL;
 		conn = git_connect(fd, dest, args.uploadpack,
-				   args.verbose ? CONNECT_VERBOSE : 0);
+				   flags);
+		if (!conn)
+			return args.diag_url ? 0 : 1;
 	}
+	get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow);
 
-	get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL);
-
-	ref = fetch_pack(&args, fd, conn, ref, dest,
-			 sought, nr_sought, pack_lockfile_ptr);
+	ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
+			 &shallow, pack_lockfile_ptr);
 	if (pack_lockfile) {
 		printf("lock %s\n", pack_lockfile);
 		fflush(stdout);
 	}
+	if (args.check_self_contained_and_connected &&
+	    args.self_contained_and_connected) {
+		printf("connectivity-ok\n");
+		fflush(stdout);
+	}
 	close(fd[0]);
 	close(fd[1]);
 	if (finish_connect(conn))
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 5647055..025bc3e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -30,9 +30,13 @@
 	TAGS_SET = 2
 };
 
-static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
+static int fetch_prune_config = -1; /* unspecified */
+static int prune = -1; /* unspecified */
+#define PRUNE_BY_DEFAULT 0 /* do we prune by default? */
+
+static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;
 static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-static int tags = TAGS_DEFAULT, unshallow;
+static int tags = TAGS_DEFAULT, unshallow, update_shallow;
 static const char *depth;
 static const char *upload_pack;
 static struct strbuf default_rla = STRBUF_INIT;
@@ -40,6 +44,7 @@
 static struct transport *gsecondary;
 static const char *submodule_prefix = "";
 static const char *recurse_submodules_default;
+static int shown_url = 0;
 
 static int option_parse_recurse_submodules(const struct option *opt,
 				   const char *arg, int unset)
@@ -55,30 +60,39 @@
 	return 0;
 }
 
+static int git_fetch_config(const char *k, const char *v, void *cb)
+{
+	if (!strcmp(k, "fetch.prune")) {
+		fetch_prune_config = git_config_bool(k, v);
+		return 0;
+	}
+	return 0;
+}
+
 static struct option builtin_fetch_options[] = {
 	OPT__VERBOSITY(&verbosity),
-	OPT_BOOLEAN(0, "all", &all,
-		    N_("fetch from all remotes")),
-	OPT_BOOLEAN('a', "append", &append,
-		    N_("append to .git/FETCH_HEAD instead of overwriting")),
+	OPT_BOOL(0, "all", &all,
+		 N_("fetch from all remotes")),
+	OPT_BOOL('a', "append", &append,
+		 N_("append to .git/FETCH_HEAD instead of overwriting")),
 	OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
 		   N_("path to upload pack on remote end")),
 	OPT__FORCE(&force, N_("force overwrite of local branch")),
-	OPT_BOOLEAN('m', "multiple", &multiple,
-		    N_("fetch from multiple remotes")),
+	OPT_BOOL('m', "multiple", &multiple,
+		 N_("fetch from multiple remotes")),
 	OPT_SET_INT('t', "tags", &tags,
 		    N_("fetch all tags and associated objects"), TAGS_SET),
 	OPT_SET_INT('n', NULL, &tags,
 		    N_("do not fetch all tags (--no-tags)"), TAGS_UNSET),
-	OPT_BOOLEAN('p', "prune", &prune,
-		    N_("prune remote-tracking branches no longer on remote")),
+	OPT_BOOL('p', "prune", &prune,
+		 N_("prune remote-tracking branches no longer on remote")),
 	{ OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"),
 		    N_("control recursive fetching of submodules"),
 		    PARSE_OPT_OPTARG, option_parse_recurse_submodules },
-	OPT_BOOLEAN(0, "dry-run", &dry_run,
-		    N_("dry run")),
-	OPT_BOOLEAN('k', "keep", &keep, N_("keep downloaded pack")),
-	OPT_BOOLEAN('u', "update-head-ok", &update_head_ok,
+	OPT_BOOL(0, "dry-run", &dry_run,
+		 N_("dry run")),
+	OPT_BOOL('k', "keep", &keep, N_("keep downloaded pack")),
+	OPT_BOOL('u', "update-head-ok", &update_head_ok,
 		    N_("allow updating of HEAD ref")),
 	OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
 	OPT_STRING(0, "depth", &depth, N_("depth"),
@@ -91,6 +105,8 @@
 	{ OPTION_STRING, 0, "recurse-submodules-default",
 		   &recurse_submodules_default, NULL,
 		   N_("default mode for recursion"), PARSE_OPT_HIDDEN },
+	OPT_BOOL(0, "update-shallow", &update_shallow,
+		 N_("accept refs that update .git/shallow")),
 	OPT_END()
 };
 
@@ -147,48 +163,156 @@
 	}
 }
 
+static int add_existing(const char *refname, const unsigned char *sha1,
+			int flag, void *cbdata)
+{
+	struct string_list *list = (struct string_list *)cbdata;
+	struct string_list_item *item = string_list_insert(list, refname);
+	item->util = xmalloc(20);
+	hashcpy(item->util, sha1);
+	return 0;
+}
+
+static int will_fetch(struct ref **head, const unsigned char *sha1)
+{
+	struct ref *rm = *head;
+	while (rm) {
+		if (!hashcmp(rm->old_sha1, sha1))
+			return 1;
+		rm = rm->next;
+	}
+	return 0;
+}
+
 static void find_non_local_tags(struct transport *transport,
 			struct ref **head,
-			struct ref ***tail);
+			struct ref ***tail)
+{
+	struct string_list existing_refs = STRING_LIST_INIT_DUP;
+	struct string_list remote_refs = STRING_LIST_INIT_NODUP;
+	const struct ref *ref;
+	struct string_list_item *item = NULL;
+
+	for_each_ref(add_existing, &existing_refs);
+	for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
+		if (!starts_with(ref->name, "refs/tags/"))
+			continue;
+
+		/*
+		 * The peeled ref always follows the matching base
+		 * ref, so if we see a peeled ref that we don't want
+		 * to fetch then we can mark the ref entry in the list
+		 * as one to ignore by setting util to NULL.
+		 */
+		if (ends_with(ref->name, "^{}")) {
+			if (item && !has_sha1_file(ref->old_sha1) &&
+			    !will_fetch(head, ref->old_sha1) &&
+			    !has_sha1_file(item->util) &&
+			    !will_fetch(head, item->util))
+				item->util = NULL;
+			item = NULL;
+			continue;
+		}
+
+		/*
+		 * If item is non-NULL here, then we previously saw a
+		 * ref not followed by a peeled reference, so we need
+		 * to check if it is a lightweight tag that we want to
+		 * fetch.
+		 */
+		if (item && !has_sha1_file(item->util) &&
+		    !will_fetch(head, item->util))
+			item->util = NULL;
+
+		item = NULL;
+
+		/* skip duplicates and refs that we already have */
+		if (string_list_has_string(&remote_refs, ref->name) ||
+		    string_list_has_string(&existing_refs, ref->name))
+			continue;
+
+		item = string_list_insert(&remote_refs, ref->name);
+		item->util = (void *)ref->old_sha1;
+	}
+	string_list_clear(&existing_refs, 1);
+
+	/*
+	 * We may have a final lightweight tag that needs to be
+	 * checked to see if it needs fetching.
+	 */
+	if (item && !has_sha1_file(item->util) &&
+	    !will_fetch(head, item->util))
+		item->util = NULL;
+
+	/*
+	 * For all the tags in the remote_refs string list,
+	 * add them to the list of refs to be fetched
+	 */
+	for_each_string_list_item(item, &remote_refs) {
+		/* Unless we have already decided to ignore this item... */
+		if (item->util)
+		{
+			struct ref *rm = alloc_ref(item->string);
+			rm->peer_ref = alloc_ref(item->string);
+			hashcpy(rm->old_sha1, item->util);
+			**tail = rm;
+			*tail = &rm->next;
+		}
+	}
+
+	string_list_clear(&remote_refs, 0);
+}
 
 static struct ref *get_ref_map(struct transport *transport,
-			       struct refspec *refs, int ref_count, int tags,
-			       int *autotags)
+			       struct refspec *refspecs, int refspec_count,
+			       int tags, int *autotags)
 {
 	int i;
 	struct ref *rm;
 	struct ref *ref_map = NULL;
 	struct ref **tail = &ref_map;
 
+	/* opportunistically-updated references: */
+	struct ref *orefs = NULL, **oref_tail = &orefs;
+
 	const struct ref *remote_refs = transport_get_remote_refs(transport);
 
-	if (ref_count || tags == TAGS_SET) {
-		struct ref **old_tail;
-
-		for (i = 0; i < ref_count; i++) {
-			get_fetch_map(remote_refs, &refs[i], &tail, 0);
-			if (refs[i].dst && refs[i].dst[0])
+	if (refspec_count) {
+		for (i = 0; i < refspec_count; i++) {
+			get_fetch_map(remote_refs, &refspecs[i], &tail, 0);
+			if (refspecs[i].dst && refspecs[i].dst[0])
 				*autotags = 1;
 		}
-		/* Merge everything on the command line, but not --tags */
+		/* Merge everything on the command line (but not --tags) */
 		for (rm = ref_map; rm; rm = rm->next)
 			rm->fetch_head_status = FETCH_HEAD_MERGE;
-		if (tags == TAGS_SET)
-			get_fetch_map(remote_refs, tag_refspec, &tail, 0);
 
 		/*
-		 * For any refs that we happen to be fetching via command-line
-		 * arguments, take the opportunity to update their configured
-		 * counterparts. However, we do not want to mention these
-		 * entries in FETCH_HEAD at all, as they would simply be
-		 * duplicates of existing entries.
+		 * For any refs that we happen to be fetching via
+		 * command-line arguments, the destination ref might
+		 * have been missing or have been different than the
+		 * remote-tracking ref that would be derived from the
+		 * configured refspec.  In these cases, we want to
+		 * take the opportunity to update their configured
+		 * remote-tracking reference.  However, we do not want
+		 * to mention these entries in FETCH_HEAD at all, as
+		 * they would simply be duplicates of existing
+		 * entries, so we set them FETCH_HEAD_IGNORE below.
+		 *
+		 * We compute these entries now, based only on the
+		 * refspecs specified on the command line.  But we add
+		 * them to the list following the refspecs resulting
+		 * from the tags option so that one of the latter,
+		 * which has FETCH_HEAD_NOT_FOR_MERGE, is not removed
+		 * by ref_remove_duplicates() in favor of one of these
+		 * opportunistic entries with FETCH_HEAD_IGNORE.
 		 */
-		old_tail = tail;
 		for (i = 0; i < transport->remote->fetch_refspec_nr; i++)
 			get_fetch_map(ref_map, &transport->remote->fetch[i],
-				      &tail, 1);
-		for (rm = *old_tail; rm; rm = rm->next)
-			rm->fetch_head_status = FETCH_HEAD_IGNORE;
+				      &oref_tail, 1);
+
+		if (tags == TAGS_SET)
+			get_fetch_map(remote_refs, tag_refspec, &tail, 0);
 	} else {
 		/* Use the defaults */
 		struct remote *remote = transport->remote;
@@ -225,11 +349,21 @@
 			tail = &ref_map->next;
 		}
 	}
-	if (tags == TAGS_DEFAULT && *autotags)
-		find_non_local_tags(transport, &ref_map, &tail);
-	ref_remove_duplicates(ref_map);
 
-	return ref_map;
+	if (tags == TAGS_SET)
+		/* also fetch all tags */
+		get_fetch_map(remote_refs, tag_refspec, &tail, 0);
+	else if (tags == TAGS_DEFAULT && *autotags)
+		find_non_local_tags(transport, &ref_map, &tail);
+
+	/* Now append any refs to be updated opportunistically: */
+	*tail = orefs;
+	for (rm = orefs; rm; rm = rm->next) {
+		rm->fetch_head_status = FETCH_HEAD_IGNORE;
+		tail = &rm->next;
+	}
+
+	return ref_remove_duplicates(ref_map);
 }
 
 #define STORE_REF_ERROR_OTHER 1
@@ -249,7 +383,8 @@
 		rla = default_rla.buf;
 	snprintf(msg, sizeof(msg), "%s: %s", rla, action);
 	lock = lock_any_ref_for_update(ref->name,
-				       check_old ? ref->old_sha1 : NULL, 0);
+				       check_old ? ref->old_sha1 : NULL,
+				       0, NULL);
 	if (!lock)
 		return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
 					  STORE_REF_ERROR_OTHER;
@@ -299,7 +434,7 @@
 	}
 
 	if (!is_null_sha1(ref->old_sha1) &&
-	    !prefixcmp(ref->name, "refs/tags/")) {
+	    starts_with(ref->name, "refs/tags/")) {
 		int r;
 		r = s_update_ref("updating tag", ref, 0);
 		strbuf_addf(display, "%c %-*s %-*s -> %s%s",
@@ -322,10 +457,10 @@
 		 * more likely to follow a standard layout.
 		 */
 		const char *name = remote_ref ? remote_ref->name : "";
-		if (!prefixcmp(name, "refs/tags/")) {
+		if (starts_with(name, "refs/tags/")) {
 			msg = "storing tag";
 			what = _("[new tag]");
-		} else if (!prefixcmp(name, "refs/heads/")) {
+		} else if (starts_with(name, "refs/heads/")) {
 			msg = "storing head";
 			what = _("[new branch]");
 		} else {
@@ -391,6 +526,8 @@
 	struct ref **rm = cb_data;
 	struct ref *ref = *rm;
 
+	while (ref && ref->status == REF_STATUS_REJECT_SHALLOW)
+		ref = ref->next;
 	if (!ref)
 		return -1; /* end of the list */
 	*rm = ref->next;
@@ -403,7 +540,7 @@
 {
 	FILE *fp;
 	struct commit *commit;
-	int url_len, i, shown_url = 0, rc = 0;
+	int url_len, i, rc = 0;
 	struct strbuf note = STRBUF_INIT;
 	const char *what, *kind;
 	struct ref *rm;
@@ -437,6 +574,13 @@
 			struct ref *ref = NULL;
 			const char *merge_status_marker = "";
 
+			if (rm->status == REF_STATUS_REJECT_SHALLOW) {
+				if (want_status == FETCH_HEAD_MERGE)
+					warning(_("reject %s because shallow roots are not allowed to be updated"),
+						rm->peer_ref ? rm->peer_ref->name : rm->name);
+				continue;
+			}
+
 			commit = lookup_commit_reference_gently(rm->old_sha1, 1);
 			if (!commit)
 				rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE;
@@ -457,15 +601,15 @@
 				kind = "";
 				what = "";
 			}
-			else if (!prefixcmp(rm->name, "refs/heads/")) {
+			else if (starts_with(rm->name, "refs/heads/")) {
 				kind = "branch";
 				what = rm->name + 11;
 			}
-			else if (!prefixcmp(rm->name, "refs/tags/")) {
+			else if (starts_with(rm->name, "refs/tags/")) {
 				kind = "tag";
 				what = rm->name + 10;
 			}
-			else if (!prefixcmp(rm->name, "refs/remotes/")) {
+			else if (starts_with(rm->name, "refs/remotes/")) {
 				kind = "remote-tracking branch";
 				what = rm->name + 13;
 			}
@@ -576,17 +720,36 @@
 	return ret;
 }
 
-static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
+static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
+		const char *raw_url)
 {
-	int result = 0;
+	int url_len, i, result = 0;
 	struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
+	char *url;
 	const char *dangling_msg = dry_run
 		? _("   (%s will become dangling)")
 		: _("   (%s has become dangling)");
 
+	if (raw_url)
+		url = transport_anonymize_url(raw_url);
+	else
+		url = xstrdup("foreign");
+
+	url_len = strlen(url);
+	for (i = url_len - 1; url[i] == '/' && 0 <= i; i--)
+		;
+
+	url_len = i + 1;
+	if (4 < i && !strncmp(".git", url + i - 3, 4))
+		url_len = i - 3;
+
 	for (ref = stale_refs; ref; ref = ref->next) {
 		if (!dry_run)
 			result |= delete_ref(ref->name, NULL, 0);
+		if (verbosity >= 0 && !shown_url) {
+			fprintf(stderr, _("From %.*s\n"), url_len, url);
+			shown_url = 1;
+		}
 		if (verbosity >= 0) {
 			fprintf(stderr, " x %-*s %-*s -> %s\n",
 				TRANSPORT_SUMMARY(_("[deleted]")),
@@ -594,110 +757,11 @@
 			warn_dangling_symref(stderr, dangling_msg, ref->name);
 		}
 	}
+	free(url);
 	free_refs(stale_refs);
 	return result;
 }
 
-static int add_existing(const char *refname, const unsigned char *sha1,
-			int flag, void *cbdata)
-{
-	struct string_list *list = (struct string_list *)cbdata;
-	struct string_list_item *item = string_list_insert(list, refname);
-	item->util = xmalloc(20);
-	hashcpy(item->util, sha1);
-	return 0;
-}
-
-static int will_fetch(struct ref **head, const unsigned char *sha1)
-{
-	struct ref *rm = *head;
-	while (rm) {
-		if (!hashcmp(rm->old_sha1, sha1))
-			return 1;
-		rm = rm->next;
-	}
-	return 0;
-}
-
-static void find_non_local_tags(struct transport *transport,
-			struct ref **head,
-			struct ref ***tail)
-{
-	struct string_list existing_refs = STRING_LIST_INIT_DUP;
-	struct string_list remote_refs = STRING_LIST_INIT_NODUP;
-	const struct ref *ref;
-	struct string_list_item *item = NULL;
-
-	for_each_ref(add_existing, &existing_refs);
-	for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
-		if (prefixcmp(ref->name, "refs/tags/"))
-			continue;
-
-		/*
-		 * The peeled ref always follows the matching base
-		 * ref, so if we see a peeled ref that we don't want
-		 * to fetch then we can mark the ref entry in the list
-		 * as one to ignore by setting util to NULL.
-		 */
-		if (!suffixcmp(ref->name, "^{}")) {
-			if (item && !has_sha1_file(ref->old_sha1) &&
-			    !will_fetch(head, ref->old_sha1) &&
-			    !has_sha1_file(item->util) &&
-			    !will_fetch(head, item->util))
-				item->util = NULL;
-			item = NULL;
-			continue;
-		}
-
-		/*
-		 * If item is non-NULL here, then we previously saw a
-		 * ref not followed by a peeled reference, so we need
-		 * to check if it is a lightweight tag that we want to
-		 * fetch.
-		 */
-		if (item && !has_sha1_file(item->util) &&
-		    !will_fetch(head, item->util))
-			item->util = NULL;
-
-		item = NULL;
-
-		/* skip duplicates and refs that we already have */
-		if (string_list_has_string(&remote_refs, ref->name) ||
-		    string_list_has_string(&existing_refs, ref->name))
-			continue;
-
-		item = string_list_insert(&remote_refs, ref->name);
-		item->util = (void *)ref->old_sha1;
-	}
-	string_list_clear(&existing_refs, 1);
-
-	/*
-	 * We may have a final lightweight tag that needs to be
-	 * checked to see if it needs fetching.
-	 */
-	if (item && !has_sha1_file(item->util) &&
-	    !will_fetch(head, item->util))
-		item->util = NULL;
-
-	/*
-	 * For all the tags in the remote_refs string list,
-	 * add them to the list of refs to be fetched
-	 */
-	for_each_string_list_item(item, &remote_refs) {
-		/* Unless we have already decided to ignore this item... */
-		if (item->util)
-		{
-			struct ref *rm = alloc_ref(item->string);
-			rm->peer_ref = alloc_ref(item->string);
-			hashcpy(rm->old_sha1, item->util);
-			**tail = rm;
-			*tail = &rm->next;
-		}
-	}
-
-	string_list_clear(&remote_refs, 0);
-}
-
 static void check_not_current_branch(struct ref *ref_map)
 {
 	struct branch *current_branch = branch_get(NULL);
@@ -745,6 +809,8 @@
 		set_option(transport, TRANS_OPT_KEEP, "yes");
 	if (depth)
 		set_option(transport, TRANS_OPT_DEPTH, depth);
+	if (update_shallow)
+		set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
 	return transport;
 }
 
@@ -810,36 +876,26 @@
 
 	if (tags == TAGS_DEFAULT && autotags)
 		transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
+	if (prune) {
+		/*
+		 * We only prune based on refspecs specified
+		 * explicitly (via command line or configuration); we
+		 * don't care whether --tags was specified.
+		 */
+		if (ref_count) {
+			prune_refs(refs, ref_count, ref_map, transport->url);
+		} else {
+			prune_refs(transport->remote->fetch,
+				   transport->remote->fetch_refspec_nr,
+				   ref_map,
+				   transport->url);
+		}
+	}
 	if (fetch_refs(transport, ref_map)) {
 		free_refs(ref_map);
 		retcode = 1;
 		goto cleanup;
 	}
-	if (prune) {
-		/* If --tags was specified, pretend the user gave us the canonical tags refspec */
-		if (tags == TAGS_SET) {
-			const char *tags_str = "refs/tags/*:refs/tags/*";
-			struct refspec *tags_refspec, *refspec;
-
-			/* Copy the refspec and add the tags to it */
-			refspec = xcalloc(ref_count + 1, sizeof(struct refspec));
-			tags_refspec = parse_fetch_refspec(1, &tags_str);
-			memcpy(refspec, refs, ref_count * sizeof(struct refspec));
-			memcpy(&refspec[ref_count], tags_refspec, sizeof(struct refspec));
-			ref_count++;
-
-			prune_refs(refspec, ref_count, ref_map);
-
-			ref_count--;
-			/* The rest of the strings belong to fetch_one */
-			free_refspec(1, tags_refspec);
-			free(refspec);
-		} else if (ref_count) {
-			prune_refs(refs, ref_count, ref_map);
-		} else {
-			prune_refs(transport->remote->fetch, transport->remote->fetch_refspec_nr, ref_map);
-		}
-	}
 	free_refs(ref_map);
 
 	/* if neither --no-tags nor --tags was specified, do automated tag
@@ -875,7 +931,7 @@
 {
 	struct remote_group_data *g = priv;
 
-	if (!prefixcmp(key, "remotes.") &&
+	if (starts_with(key, "remotes.") &&
 			!strcmp(key + 8, g->name)) {
 		/* split list by white space */
 		int space = strcspn(value, " \t\n");
@@ -913,8 +969,8 @@
 {
 	if (dry_run)
 		argv_array_push(argv, "--dry-run");
-	if (prune)
-		argv_array_push(argv, "--prune");
+	if (prune != -1)
+		argv_array_push(argv, prune ? "--prune" : "--no-prune");
 	if (update_head_ok)
 		argv_array_push(argv, "--update-head-ok");
 	if (force)
@@ -981,6 +1037,17 @@
 		    "remote name from which new revisions should be fetched."));
 
 	gtransport = prepare_transport(remote);
+
+	if (prune < 0) {
+		/* no command line request */
+		if (0 <= gtransport->remote->prune)
+			prune = gtransport->remote->prune;
+		else if (0 <= fetch_prune_config)
+			prune = fetch_prune_config;
+		else
+			prune = PRUNE_BY_DEFAULT;
+	}
+
 	if (argc > 0) {
 		int j = 0;
 		refs = xcalloc(argc + 1, sizeof(const char *));
@@ -1030,6 +1097,8 @@
 	for (i = 1; i < argc; i++)
 		strbuf_addf(&default_rla, " %s", argv[i]);
 
+	git_config(git_fetch_config, NULL);
+
 	argc = parse_options(argc, argv, prefix,
 			     builtin_fetch_options, builtin_fetch_usage, 0);
 
@@ -1045,6 +1114,10 @@
 		}
 	}
 
+	/* no need to be strict, transport_set_option() will validate it again */
+	if (depth && atoi(depth) < 1)
+		die(_("depth %s is not a positive number"), depth);
+
 	if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
 		if (recurse_submodules_default) {
 			int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 1c04070..3906eda 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -109,7 +109,7 @@
 	if (len < 43 || line[40] != '\t')
 		return 1;
 
-	if (!prefixcmp(line + 41, "not-for-merge"))
+	if (starts_with(line + 41, "not-for-merge"))
 		return 0;
 
 	if (line[41] != '\t')
@@ -155,16 +155,16 @@
 	if (pulling_head) {
 		origin = src;
 		src_data->head_status |= 1;
-	} else if (!prefixcmp(line, "branch ")) {
+	} else if (starts_with(line, "branch ")) {
 		origin_data->is_local_branch = 1;
 		origin = line + 7;
 		string_list_append(&src_data->branch, origin);
 		src_data->head_status |= 2;
-	} else if (!prefixcmp(line, "tag ")) {
+	} else if (starts_with(line, "tag ")) {
 		origin = line;
 		string_list_append(&src_data->tag, origin + 4);
 		src_data->head_status |= 2;
-	} else if (!prefixcmp(line, "remote-tracking branch ")) {
+	} else if (starts_with(line, "remote-tracking branch ")) {
 		origin = line + strlen("remote-tracking branch ");
 		string_list_append(&src_data->r_branch, origin);
 		src_data->head_status |= 2;
@@ -605,7 +605,7 @@
 		resolve_refdup("HEAD", head_sha1, 1, NULL);
 	if (!current_branch)
 		die("No current branch");
-	if (!prefixcmp(current_branch, "refs/heads/"))
+	if (starts_with(current_branch, "refs/heads/"))
 		current_branch += 11;
 
 	find_merge_parents(&merge_parents, in, head_sha1);
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 7f059c3..51798b4 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -9,6 +9,7 @@
 #include "quote.h"
 #include "parse-options.h"
 #include "remote.h"
+#include "color.h"
 
 /* Quoting styles */
 #define QUOTE_NONE 0
@@ -75,6 +76,8 @@
 	{ "upstream" },
 	{ "symref" },
 	{ "flag" },
+	{ "HEAD" },
+	{ "color" },
 };
 
 /*
@@ -89,7 +92,8 @@
  */
 static const char **used_atom;
 static cmp_type *used_atom_type;
-static int used_atom_cnt, sort_atom_limit, need_tagged, need_symref;
+static int used_atom_cnt, need_tagged, need_symref;
+static int need_color_reset_at_eol;
 
 /*
  * Used to parse format string and sort specifiers
@@ -176,13 +180,21 @@
 static int verify_format(const char *format)
 {
 	const char *cp, *sp;
+	static const char color_reset[] = "color:reset";
+
+	need_color_reset_at_eol = 0;
 	for (cp = format; *cp && (sp = find_next(cp)); ) {
 		const char *ep = strchr(sp, ')');
+		int at;
+
 		if (!ep)
 			return error("malformed format string %s", sp);
 		/* sp points at "%(" and ep points at the closing ")" */
-		parse_atom(sp + 2, ep);
+		at = parse_atom(sp + 2, ep);
 		cp = ep + 1;
+
+		if (!memcmp(used_atom[at], "color:", 6))
+			need_color_reset_at_eol = !!strcmp(used_atom[at], color_reset);
 	}
 	return 0;
 }
@@ -205,6 +217,22 @@
 	return buf;
 }
 
+static int grab_objectname(const char *name, const unsigned char *sha1,
+			    struct atom_value *v)
+{
+	if (!strcmp(name, "objectname")) {
+		char *s = xmalloc(41);
+		strcpy(s, sha1_to_hex(sha1));
+		v->s = s;
+		return 1;
+	}
+	if (!strcmp(name, "objectname:short")) {
+		v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
+		return 1;
+	}
+	return 0;
+}
+
 /* See grab_values */
 static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 {
@@ -225,15 +253,8 @@
 			v->ul = sz;
 			v->s = s;
 		}
-		else if (!strcmp(name, "objectname")) {
-			char *s = xmalloc(41);
-			strcpy(s, sha1_to_hex(obj->sha1));
-			v->s = s;
-		}
-		else if (!strcmp(name, "objectname:short")) {
-			v->s = xstrdup(find_unique_abbrev(obj->sha1,
-							  DEFAULT_ABBREV));
-		}
+		else if (deref)
+			grab_objectname(name, obj->sha1, v);
 	}
 }
 
@@ -432,7 +453,7 @@
 		if (name[wholen] != 0 &&
 		    strcmp(name + wholen, "name") &&
 		    strcmp(name + wholen, "email") &&
-		    prefixcmp(name + wholen, "date"))
+		    !starts_with(name + wholen, "date"))
 			continue;
 		if (!wholine)
 			wholine = find_wholine(who, wholen, buf, sz);
@@ -444,7 +465,7 @@
 			v->s = copy_name(wholine);
 		else if (!strcmp(name + wholen, "email"))
 			v->s = copy_email(wholine);
-		else if (!prefixcmp(name + wholen, "date"))
+		else if (starts_with(name + wholen, "date"))
 			grab_date(wholine, v, name);
 	}
 
@@ -466,7 +487,7 @@
 		if (deref)
 			name++;
 
-		if (!prefixcmp(name, "creatordate"))
+		if (starts_with(name, "creatordate"))
 			grab_date(wholine, v, name);
 		else if (!strcmp(name, "creator"))
 			v->s = copy_line(wholine);
@@ -640,20 +661,20 @@
 		int deref = 0;
 		const char *refname;
 		const char *formatp;
+		struct branch *branch = NULL;
 
 		if (*name == '*') {
 			deref = 1;
 			name++;
 		}
 
-		if (!prefixcmp(name, "refname"))
+		if (starts_with(name, "refname"))
 			refname = ref->refname;
-		else if (!prefixcmp(name, "symref"))
+		else if (starts_with(name, "symref"))
 			refname = ref->symref ? ref->symref : "";
-		else if (!prefixcmp(name, "upstream")) {
-			struct branch *branch;
+		else if (starts_with(name, "upstream")) {
 			/* only local branches may have an upstream */
-			if (prefixcmp(ref->refname, "refs/heads/"))
+			if (!starts_with(ref->refname, "refs/heads/"))
 				continue;
 			branch = branch_get(ref->refname + 11);
 
@@ -661,8 +682,13 @@
 			    !branch->merge[0]->dst)
 				continue;
 			refname = branch->merge[0]->dst;
-		}
-		else if (!strcmp(name, "flag")) {
+		} else if (starts_with(name, "color:")) {
+			char color[COLOR_MAXLEN] = "";
+
+			color_parse(name + 6, "--format", color);
+			v->s = xstrdup(color);
+			continue;
+		} else if (!strcmp(name, "flag")) {
 			char buf[256], *cp = buf;
 			if (ref->flag & REF_ISSYMREF)
 				cp = copy_advance(cp, ",symref");
@@ -675,18 +701,62 @@
 				v->s = xstrdup(buf + 1);
 			}
 			continue;
-		}
-		else
+		} else if (!deref && grab_objectname(name, ref->objectname, v)) {
+			continue;
+		} else if (!strcmp(name, "HEAD")) {
+			const char *head;
+			unsigned char sha1[20];
+
+			head = resolve_ref_unsafe("HEAD", sha1, 1, NULL);
+			if (!strcmp(ref->refname, head))
+				v->s = "*";
+			else
+				v->s = " ";
+			continue;
+		} else
 			continue;
 
 		formatp = strchr(name, ':');
-		/* look for "short" refname format */
 		if (formatp) {
+			int num_ours, num_theirs;
+
 			formatp++;
 			if (!strcmp(formatp, "short"))
 				refname = shorten_unambiguous_ref(refname,
 						      warn_ambiguous_refs);
-			else
+			else if (!strcmp(formatp, "track") &&
+				 starts_with(name, "upstream")) {
+				char buf[40];
+
+				stat_tracking_info(branch, &num_ours, &num_theirs);
+				if (!num_ours && !num_theirs)
+					v->s = "";
+				else if (!num_ours) {
+					sprintf(buf, "[behind %d]", num_theirs);
+					v->s = xstrdup(buf);
+				} else if (!num_theirs) {
+					sprintf(buf, "[ahead %d]", num_ours);
+					v->s = xstrdup(buf);
+				} else {
+					sprintf(buf, "[ahead %d, behind %d]",
+						num_ours, num_theirs);
+					v->s = xstrdup(buf);
+				}
+				continue;
+			} else if (!strcmp(formatp, "trackshort") &&
+				   starts_with(name, "upstream")) {
+				assert(branch);
+				stat_tracking_info(branch, &num_ours, &num_theirs);
+				if (!num_ours && !num_theirs)
+					v->s = "=";
+				else if (!num_ours)
+					v->s = "<";
+				else if (!num_theirs)
+					v->s = ">";
+				else
+					v->s = "<>";
+				continue;
+			} else
 				die("unknown %.*s format %s",
 				    (int)(formatp - name), name, formatp);
 		}
@@ -864,27 +934,30 @@
 	qsort(refs, num_refs, sizeof(struct refinfo *), compare_refs);
 }
 
-static void print_value(struct refinfo *ref, int atom, int quote_style)
+static void print_value(struct atom_value *v, int quote_style)
 {
-	struct atom_value *v;
-	get_value(ref, atom, &v);
+	struct strbuf sb = STRBUF_INIT;
 	switch (quote_style) {
 	case QUOTE_NONE:
 		fputs(v->s, stdout);
 		break;
 	case QUOTE_SHELL:
-		sq_quote_print(stdout, v->s);
+		sq_quote_buf(&sb, v->s);
 		break;
 	case QUOTE_PERL:
-		perl_quote_print(stdout, v->s);
+		perl_quote_buf(&sb, v->s);
 		break;
 	case QUOTE_PYTHON:
-		python_quote_print(stdout, v->s);
+		python_quote_buf(&sb, v->s);
 		break;
 	case QUOTE_TCL:
-		tcl_quote_print(stdout, v->s);
+		tcl_quote_buf(&sb, v->s);
 		break;
 	}
+	if (quote_style != QUOTE_NONE) {
+		fputs(sb.buf, stdout);
+		strbuf_release(&sb);
+	}
 }
 
 static int hex1(char ch)
@@ -930,15 +1003,26 @@
 	const char *cp, *sp, *ep;
 
 	for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
+		struct atom_value *atomv;
+
 		ep = strchr(sp, ')');
 		if (cp < sp)
 			emit(cp, sp);
-		print_value(info, parse_atom(sp + 2, ep), quote_style);
+		get_value(info, parse_atom(sp + 2, ep), &atomv);
+		print_value(atomv, quote_style);
 	}
 	if (*cp) {
 		sp = cp + strlen(cp);
 		emit(cp, sp);
 	}
+	if (need_color_reset_at_eol) {
+		struct atom_value resetv;
+		char color[COLOR_MAXLEN] = "";
+
+		color_parse("reset", "--format", color);
+		resetv.s = color;
+		print_value(&resetv, quote_style);
+	}
 	putchar('\n');
 }
 
@@ -1021,7 +1105,6 @@
 
 	if (!sort)
 		sort = default_sort();
-	sort_atom_limit = used_atom_cnt;
 
 	/* for warn_ambiguous_refs */
 	git_config(git_default_config, NULL);
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 9909b6d..1affdd5 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -16,6 +16,7 @@
 
 #define REACHABLE 0x0001
 #define SEEN      0x0002
+#define HAS_OBJ   0x0004
 
 static int show_root;
 static int show_tags;
@@ -101,7 +102,7 @@
 	if (obj->flags & REACHABLE)
 		return 0;
 	obj->flags |= REACHABLE;
-	if (!obj->parsed) {
+	if (!(obj->flags & HAS_OBJ)) {
 		if (parent && !has_sha1_file(obj->sha1)) {
 			printf("broken link from %7s %s\n",
 				 typename(parent->type), sha1_to_hex(parent->sha1));
@@ -127,16 +128,13 @@
 	struct tree *tree = NULL;
 
 	if (obj->type == OBJ_TREE) {
-		obj->parsed = 0;
 		tree = (struct tree *)obj;
 		if (parse_tree(tree) < 0)
 			return 1; /* error already displayed */
 	}
 	result = fsck_walk(obj, mark_object, obj);
-	if (tree) {
-		free(tree->buffer);
-		tree->buffer = NULL;
-	}
+	if (tree)
+		free_tree_buffer(tree);
 	return result;
 }
 
@@ -178,7 +176,7 @@
 	 * except if it was in a pack-file and we didn't
 	 * do a full fsck
 	 */
-	if (!obj->parsed) {
+	if (!(obj->flags & HAS_OBJ)) {
 		if (has_sha1_pack(obj->sha1))
 			return; /* it is in pack - forget about it */
 		printf("missing %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
@@ -306,8 +304,7 @@
 	if (obj->type == OBJ_TREE) {
 		struct tree *item = (struct tree *) obj;
 
-		free(item->buffer);
-		item->buffer = NULL;
+		free_tree_buffer(item);
 	}
 
 	if (obj->type == OBJ_COMMIT) {
@@ -340,6 +337,7 @@
 		return error("%s: object corrupt or missing",
 			     sha1_to_hex(sha1));
 	}
+	obj->flags |= HAS_OBJ;
 	return fsck_obj(obj);
 }
 
@@ -352,6 +350,7 @@
 		errors_found |= ERROR_OBJECT;
 		return error("%s: object corrupt or missing", sha1_to_hex(sha1));
 	}
+	obj->flags = HAS_OBJ;
 	return fsck_obj(obj);
 }
 
@@ -443,7 +442,7 @@
 			add_sha1_list(sha1, DIRENT_SORT_HINT(de));
 			continue;
 		}
-		if (!prefixcmp(de->d_name, "tmp_obj_"))
+		if (starts_with(de->d_name, "tmp_obj_"))
 			continue;
 		fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
 	}
@@ -485,7 +484,7 @@
 
 static int is_branch(const char *refname)
 {
-	return !strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/");
+	return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
 }
 
 static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
@@ -567,7 +566,7 @@
 	if (!strcmp(head_points_at, "HEAD"))
 		/* detached HEAD */
 		null_is_error = 1;
-	else if (prefixcmp(head_points_at, "refs/heads/"))
+	else if (!starts_with(head_points_at, "refs/heads/"))
 		return error("HEAD points to something strange (%s)",
 			     head_points_at);
 	if (is_null_sha1(head_sha1)) {
@@ -611,15 +610,15 @@
 
 static struct option fsck_opts[] = {
 	OPT__VERBOSE(&verbose, N_("be verbose")),
-	OPT_BOOLEAN(0, "unreachable", &show_unreachable, N_("show unreachable objects")),
+	OPT_BOOL(0, "unreachable", &show_unreachable, N_("show unreachable objects")),
 	OPT_BOOL(0, "dangling", &show_dangling, N_("show dangling objects")),
-	OPT_BOOLEAN(0, "tags", &show_tags, N_("report tags")),
-	OPT_BOOLEAN(0, "root", &show_root, N_("report root nodes")),
-	OPT_BOOLEAN(0, "cache", &keep_cache_objects, N_("make index objects head nodes")),
-	OPT_BOOLEAN(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")),
-	OPT_BOOLEAN(0, "full", &check_full, N_("also consider packs and alternate objects")),
-	OPT_BOOLEAN(0, "strict", &check_strict, N_("enable more strict checking")),
-	OPT_BOOLEAN(0, "lost-found", &write_lost_and_found,
+	OPT_BOOL(0, "tags", &show_tags, N_("report tags")),
+	OPT_BOOL(0, "root", &show_root, N_("report root nodes")),
+	OPT_BOOL(0, "cache", &keep_cache_objects, N_("make index objects head nodes")),
+	OPT_BOOL(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")),
+	OPT_BOOL(0, "full", &check_full, N_("also consider packs and alternate objects")),
+	OPT_BOOL(0, "strict", &check_strict, N_("enable more strict checking")),
+	OPT_BOOL(0, "lost-found", &write_lost_and_found,
 				N_("write dangling objects in .git/lost-found")),
 	OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
 	OPT_END(),
diff --git a/builtin/gc.c b/builtin/gc.c
index 6be6c8d..c19545d 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -14,7 +14,9 @@
 #include "cache.h"
 #include "parse-options.h"
 #include "run-command.h"
+#include "sigchain.h"
 #include "argv-array.h"
+#include "commit.h"
 
 #define FAILED_RUN "failed to run %s"
 
@@ -35,6 +37,21 @@
 static struct argv_array prune = ARGV_ARRAY_INIT;
 static struct argv_array rerere = ARGV_ARRAY_INIT;
 
+static char *pidfile;
+
+static void remove_pidfile(void)
+{
+	if (pidfile)
+		unlink(pidfile);
+}
+
+static void remove_pidfile_on_signal(int signo)
+{
+	remove_pidfile();
+	sigchain_pop(signo);
+	raise(signo);
+}
+
 static int gc_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "gc.packrefs")) {
@@ -167,19 +184,86 @@
 	return 1;
 }
 
+/* return NULL on success, else hostname running the gc */
+static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
+{
+	static struct lock_file lock;
+	static char locking_host[128];
+	char my_host[128];
+	struct strbuf sb = STRBUF_INIT;
+	struct stat st;
+	uintmax_t pid;
+	FILE *fp;
+	int fd, should_exit;
+
+	if (pidfile)
+		/* already locked */
+		return NULL;
+
+	if (gethostname(my_host, sizeof(my_host)))
+		strcpy(my_host, "unknown");
+
+	fd = hold_lock_file_for_update(&lock, git_path("gc.pid"),
+				       LOCK_DIE_ON_ERROR);
+	if (!force) {
+		fp = fopen(git_path("gc.pid"), "r");
+		memset(locking_host, 0, sizeof(locking_host));
+		should_exit =
+			fp != NULL &&
+			!fstat(fileno(fp), &st) &&
+			/*
+			 * 12 hour limit is very generous as gc should
+			 * never take that long. On the other hand we
+			 * don't really need a strict limit here,
+			 * running gc --auto one day late is not a big
+			 * problem. --force can be used in manual gc
+			 * after the user verifies that no gc is
+			 * running.
+			 */
+			time(NULL) - st.st_mtime <= 12 * 3600 &&
+			fscanf(fp, "%"PRIuMAX" %127c", &pid, locking_host) == 2 &&
+			/* be gentle to concurrent "gc" on remote hosts */
+			(strcmp(locking_host, my_host) || !kill(pid, 0) || errno == EPERM);
+		if (fp != NULL)
+			fclose(fp);
+		if (should_exit) {
+			if (fd >= 0)
+				rollback_lock_file(&lock);
+			*ret_pid = pid;
+			return locking_host;
+		}
+	}
+
+	strbuf_addf(&sb, "%"PRIuMAX" %s",
+		    (uintmax_t) getpid(), my_host);
+	write_in_full(fd, sb.buf, sb.len);
+	strbuf_release(&sb);
+	commit_lock_file(&lock);
+
+	pidfile = git_pathdup("gc.pid");
+	sigchain_push_common(remove_pidfile_on_signal);
+	atexit(remove_pidfile);
+
+	return NULL;
+}
+
 int cmd_gc(int argc, const char **argv, const char *prefix)
 {
 	int aggressive = 0;
 	int auto_gc = 0;
 	int quiet = 0;
+	int force = 0;
+	const char *name;
+	pid_t pid;
 
 	struct option builtin_gc_options[] = {
 		OPT__QUIET(&quiet, N_("suppress progress reporting")),
 		{ OPTION_STRING, 0, "prune", &prune_expire, N_("date"),
 			N_("prune unreferenced objects"),
 			PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
-		OPT_BOOLEAN(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
-		OPT_BOOLEAN(0, "auto", &auto_gc, N_("enable auto-gc mode")),
+		OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
+		OPT_BOOL(0, "auto", &auto_gc, N_("enable auto-gc mode")),
+		OPT_BOOL(0, "force", &force, N_("force running gc even if there may be another gc running")),
 		OPT_END()
 	};
 
@@ -225,6 +309,14 @@
 	} else
 		add_repack_all_option();
 
+	name = lock_repo_for_gc(force, &pid);
+	if (name) {
+		if (auto_gc)
+			return 0; /* be quiet on --auto */
+		die(_("gc is already running on machine '%s' pid %"PRIuMAX" (use --force if not)"),
+		    name, (uintmax_t)pid);
+	}
+
 	if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
 		return error(FAILED_RUN, pack_refs_cmd.argv[0]);
 
diff --git a/builtin/get-tar-commit-id.c b/builtin/get-tar-commit-id.c
new file mode 100644
index 0000000..aa72596
--- /dev/null
+++ b/builtin/get-tar-commit-id.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005, 2006 Rene Scharfe
+ */
+#include "cache.h"
+#include "commit.h"
+#include "tar.h"
+#include "builtin.h"
+#include "quote.h"
+
+static const char builtin_get_tar_commit_id_usage[] =
+"git get-tar-commit-id < <tarfile>";
+
+/* ustar header + extended global header content */
+#define RECORDSIZE	(512)
+#define HEADERSIZE (2 * RECORDSIZE)
+
+int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
+{
+	char buffer[HEADERSIZE];
+	struct ustar_header *header = (struct ustar_header *)buffer;
+	char *content = buffer + RECORDSIZE;
+	ssize_t n;
+
+	if (argc != 1)
+		usage(builtin_get_tar_commit_id_usage);
+
+	n = read_in_full(0, buffer, HEADERSIZE);
+	if (n < HEADERSIZE)
+		die("git get-tar-commit-id: read error");
+	if (header->typeflag[0] != 'g')
+		return 1;
+	if (memcmp(content, "52 comment=", 11))
+		return 1;
+
+	n = write_in_full(1, content + 11, 41);
+	if (n < 41)
+		die_errno("git get-tar-commit-id: write error");
+
+	return 0;
+}
diff --git a/builtin/grep.c b/builtin/grep.c
index d3b3b1d..63f8603 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -17,6 +17,7 @@
 #include "grep.h"
 #include "quote.h"
 #include "dir.h"
+#include "pathspec.h"
 
 static char const * const grep_usage[] = {
 	N_("git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"),
@@ -457,10 +458,10 @@
 }
 
 static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
-		       struct object *obj, const char *name)
+		       struct object *obj, const char *name, struct object_context *oc)
 {
 	if (obj->type == OBJ_BLOB)
-		return grep_sha1(opt, obj->sha1, name, 0, NULL);
+		return grep_sha1(opt, obj->sha1, name, 0, oc ? oc->path : NULL);
 	if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
 		struct tree_desc tree;
 		void *data;
@@ -502,7 +503,7 @@
 	for (i = 0; i < nr; i++) {
 		struct object *real_obj;
 		real_obj = deref_tag(list->objects[i].item, NULL, 0);
-		if (grep_object(opt, pathspec, real_obj, list->objects[i].name)) {
+		if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].context)) {
 			hit = 1;
 			if (opt->status_only)
 				break;
@@ -521,7 +522,7 @@
 	if (exc_std)
 		setup_standard_excludes(&dir);
 
-	fill_directory(&dir, pathspec->raw);
+	fill_directory(&dir, pathspec);
 	for (i = 0; i < dir.nr; i++) {
 		const char *name = dir.entries[i]->name;
 		int namelen = strlen(name);
@@ -629,7 +630,6 @@
 	const char *show_in_pager = NULL, *default_pager = "dummy";
 	struct grep_opt opt;
 	struct object_array list = OBJECT_ARRAY_INIT;
-	const char **paths = NULL;
 	struct pathspec pathspec;
 	struct string_list path_list = STRING_LIST_INIT_NODUP;
 	int i;
@@ -638,26 +638,28 @@
 	int pattern_type_arg = GREP_PATTERN_TYPE_UNSPECIFIED;
 
 	struct option options[] = {
-		OPT_BOOLEAN(0, "cached", &cached,
+		OPT_BOOL(0, "cached", &cached,
 			N_("search in index instead of in the work tree")),
 		OPT_NEGBIT(0, "no-index", &use_index,
 			 N_("find in contents not managed by git"), 1),
-		OPT_BOOLEAN(0, "untracked", &untracked,
+		OPT_BOOL(0, "untracked", &untracked,
 			N_("search in both tracked and untracked files")),
 		OPT_SET_INT(0, "exclude-standard", &opt_exclude,
 			    N_("search also in ignored files"), 1),
 		OPT_GROUP(""),
-		OPT_BOOLEAN('v', "invert-match", &opt.invert,
+		OPT_BOOL('v', "invert-match", &opt.invert,
 			N_("show non-matching lines")),
-		OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case,
+		OPT_BOOL('i', "ignore-case", &opt.ignore_case,
 			N_("case insensitive matching")),
-		OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
+		OPT_BOOL('w', "word-regexp", &opt.word_regexp,
 			N_("match patterns only at word boundaries")),
 		OPT_SET_INT('a', "text", &opt.binary,
 			N_("process binary files as text"), GREP_BINARY_TEXT),
 		OPT_SET_INT('I', NULL, &opt.binary,
 			N_("don't match patterns in binary files"),
 			GREP_BINARY_NOMATCH),
+		OPT_BOOL(0, "textconv", &opt.allow_textconv,
+			 N_("process binary files with textconv filters")),
 		{ OPTION_INTEGER, 0, "max-depth", &opt.max_depth, N_("depth"),
 			N_("descend at most <depth> levels"), PARSE_OPT_NONEG,
 			NULL, 1 },
@@ -675,26 +677,26 @@
 			    N_("use Perl-compatible regular expressions"),
 			    GREP_PATTERN_TYPE_PCRE),
 		OPT_GROUP(""),
-		OPT_BOOLEAN('n', "line-number", &opt.linenum, N_("show line numbers")),
+		OPT_BOOL('n', "line-number", &opt.linenum, N_("show line numbers")),
 		OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1),
 		OPT_BIT('H', NULL, &opt.pathname, N_("show filenames"), 1),
 		OPT_NEGBIT(0, "full-name", &opt.relative,
 			N_("show filenames relative to top directory"), 1),
-		OPT_BOOLEAN('l', "files-with-matches", &opt.name_only,
+		OPT_BOOL('l', "files-with-matches", &opt.name_only,
 			N_("show only filenames instead of matching lines")),
-		OPT_BOOLEAN(0, "name-only", &opt.name_only,
+		OPT_BOOL(0, "name-only", &opt.name_only,
 			N_("synonym for --files-with-matches")),
-		OPT_BOOLEAN('L', "files-without-match",
+		OPT_BOOL('L', "files-without-match",
 			&opt.unmatch_name_only,
 			N_("show only the names of files without match")),
-		OPT_BOOLEAN('z', "null", &opt.null_following_name,
+		OPT_BOOL('z', "null", &opt.null_following_name,
 			N_("print NUL after filenames")),
-		OPT_BOOLEAN('c', "count", &opt.count,
+		OPT_BOOL('c', "count", &opt.count,
 			N_("show the number of matches instead of matching lines")),
 		OPT__COLOR(&opt.color, N_("highlight matches")),
-		OPT_BOOLEAN(0, "break", &opt.file_break,
+		OPT_BOOL(0, "break", &opt.file_break,
 			N_("print empty line between matches from different files")),
-		OPT_BOOLEAN(0, "heading", &opt.heading,
+		OPT_BOOL(0, "heading", &opt.heading,
 			N_("show filename only once above matches from same file")),
 		OPT_GROUP(""),
 		OPT_CALLBACK('C', "context", &opt, N_("n"),
@@ -706,9 +708,9 @@
 			N_("show <n> context lines after matches")),
 		OPT_NUMBER_CALLBACK(&opt, N_("shortcut for -C NUM"),
 			context_callback),
-		OPT_BOOLEAN('p', "show-function", &opt.funcname,
+		OPT_BOOL('p', "show-function", &opt.funcname,
 			N_("show a line with the function name before matches")),
-		OPT_BOOLEAN('W', "function-context", &opt.funcbody,
+		OPT_BOOL('W', "function-context", &opt.funcbody,
 			N_("show the surrounding function")),
 		OPT_GROUP(""),
 		OPT_CALLBACK('f', NULL, &opt, N_("file"),
@@ -718,7 +720,7 @@
 		{ OPTION_CALLBACK, 0, "and", &opt, NULL,
 		  N_("combine patterns specified with -e"),
 		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback },
-		OPT_BOOLEAN(0, "or", &dummy, ""),
+		OPT_BOOL(0, "or", &dummy, ""),
 		{ OPTION_CALLBACK, 0, "not", &opt, NULL, "",
 		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback },
 		{ OPTION_CALLBACK, '(', NULL, &opt, NULL, "",
@@ -729,7 +731,7 @@
 		  close_callback },
 		OPT__QUIET(&opt.status_only,
 			   N_("indicate hit with exit status without output")),
-		OPT_BOOLEAN(0, "all-match", &opt.all_match,
+		OPT_BOOL(0, "all-match", &opt.all_match,
 			N_("show only matches from files that match all patterns")),
 		{ OPTION_SET_INT, 0, "debug", &opt.debug, NULL,
 		  N_("show parse tree for grep expression"),
@@ -738,8 +740,8 @@
 		{ OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
 			N_("pager"), N_("show matching files in the pager"),
 			PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager },
-		OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed__ignored,
-			    N_("allow calling of grep(1) (ignored by this build)")),
+		OPT_BOOL(0, "ext-grep", &external_grep_allowed__ignored,
+			 N_("allow calling of grep(1) (ignored by this build)")),
 		{ OPTION_CALLBACK, 0, "help-all", &options, NULL, N_("show usage"),
 		  PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
 		OPT_END()
@@ -817,12 +819,13 @@
 	for (i = 0; i < argc; i++) {
 		const char *arg = argv[i];
 		unsigned char sha1[20];
+		struct object_context oc;
 		/* Is it a rev? */
-		if (!get_sha1(arg, sha1)) {
+		if (!get_sha1_with_context(arg, 0, sha1, &oc)) {
 			struct object *object = parse_object_or_die(sha1, arg);
 			if (!seen_dashdash)
 				verify_non_filename(prefix, arg);
-			add_object_array(object, arg, &list);
+			add_object_array_with_context(object, arg, &list, xmemdupz(&oc, sizeof(struct object_context)));
 			continue;
 		}
 		if (!strcmp(arg, "--")) {
@@ -856,8 +859,10 @@
 			verify_filename(prefix, argv[j], j == i);
 	}
 
-	paths = get_pathspec(prefix, argv + i);
-	init_pathspec(&pathspec, paths);
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_CWD |
+		       (opt.max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0),
+		       prefix, argv + i);
 	pathspec.max_depth = opt.max_depth;
 	pathspec.recursive = 1;
 
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 8d184f1..d7fcf4c 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -70,10 +70,10 @@
 
 static const struct option hash_object_options[] = {
 	OPT_STRING('t', NULL, &type, N_("type"), N_("object type")),
-	OPT_BOOLEAN('w', NULL, &write_object, N_("write the object into the object database")),
-	OPT_BOOLEAN( 0 , "stdin", &hashstdin, N_("read the object from stdin")),
-	OPT_BOOLEAN( 0 , "stdin-paths", &stdin_paths, N_("read file names from stdin")),
-	OPT_BOOLEAN( 0 , "no-filters", &no_filters, N_("store file as is without filters")),
+	OPT_BOOL('w', NULL, &write_object, N_("write the object into the object database")),
+	OPT_COUNTUP( 0 , "stdin", &hashstdin, N_("read the object from stdin")),
+	OPT_BOOL( 0 , "stdin-paths", &stdin_paths, N_("read file names from stdin")),
+	OPT_BOOL( 0 , "no-filters", &no_filters, N_("store file as is without filters")),
 	OPT_STRING( 0 , "path", &vpath, N_("file"), N_("process file as it were from this path")),
 	OPT_END()
 };
diff --git a/builtin/help.c b/builtin/help.c
index f1e236b..1fdefeb 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -100,7 +100,7 @@
 	 */
 	finish_command(&ec_process);
 
-	if (prefixcmp(buffer.buf, "emacsclient")) {
+	if (!starts_with(buffer.buf, "emacsclient")) {
 		strbuf_release(&buffer);
 		return error(_("Failed to parse emacsclient version."));
 	}
@@ -258,7 +258,7 @@
 
 static int git_help_config(const char *var, const char *value, void *cb)
 {
-	if (!prefixcmp(var, "column."))
+	if (starts_with(var, "column."))
 		return git_column_config(var, value, "help", &colopts);
 	if (!strcmp(var, "help.format")) {
 		if (!value)
@@ -278,7 +278,7 @@
 		add_man_viewer(value);
 		return 0;
 	}
-	if (!prefixcmp(var, "man."))
+	if (starts_with(var, "man."))
 		return add_man_viewer_info(var, value);
 
 	return git_default_config(var, value, cb);
@@ -288,6 +288,10 @@
 
 static int is_git_command(const char *s)
 {
+	if (is_builtin(s))
+		return 1;
+
+	load_command_list("git-", &main_cmds, &other_cmds);
 	return is_in_cmdlist(&main_cmds, s) ||
 		is_in_cmdlist(&other_cmds, s);
 }
@@ -306,7 +310,7 @@
 {
 	if (!git_cmd)
 		return "git";
-	else if (!prefixcmp(git_cmd, "git"))
+	else if (starts_with(git_cmd, "git"))
 		return git_cmd;
 	else if (is_git_command(git_cmd))
 		return prepend("git-", git_cmd);
@@ -449,7 +453,6 @@
 	int nongit;
 	const char *alias;
 	enum help_format parsed_help_format;
-	load_command_list("git-", &main_cmds, &other_cmds);
 
 	argc = parse_options(argc, argv, prefix, builtin_help_options,
 			builtin_help_usage, 0);
@@ -458,6 +461,7 @@
 	if (show_all) {
 		git_config(git_help_config, NULL);
 		printf(_("usage: %s%s"), _(git_usage_string), "\n\n");
+		load_command_list("git-", &main_cmds, &other_cmds);
 		list_commands(colopts, &main_cmds, &other_cmds);
 	}
 
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 9c1cfac..2f37a38 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -770,6 +770,7 @@
 			if (obj->type == OBJ_TREE) {
 				struct tree *item = (struct tree *) obj;
 				item->buffer = NULL;
+				obj->parsed = 0;
 			}
 			if (obj->type == OBJ_COMMIT) {
 				struct commit *commit = (struct commit *) obj;
@@ -1533,9 +1534,9 @@
 				stat_only = 1;
 			} else if (!strcmp(arg, "--keep")) {
 				keep_msg = "";
-			} else if (!prefixcmp(arg, "--keep=")) {
+			} else if (starts_with(arg, "--keep=")) {
 				keep_msg = arg + 7;
-			} else if (!prefixcmp(arg, "--threads=")) {
+			} else if (starts_with(arg, "--threads=")) {
 				char *end;
 				nr_threads = strtoul(arg+10, &end, 0);
 				if (!arg[10] || *end || nr_threads < 0)
@@ -1546,7 +1547,7 @@
 						  "ignoring %s"), arg);
 				nr_threads = 1;
 #endif
-			} else if (!prefixcmp(arg, "--pack_header=")) {
+			} else if (starts_with(arg, "--pack_header=")) {
 				struct pack_header *hdr;
 				char *c;
 
@@ -1565,7 +1566,7 @@
 				if (index_name || (i+1) >= argc)
 					usage(index_pack_usage);
 				index_name = argv[++i];
-			} else if (!prefixcmp(arg, "--index-version=")) {
+			} else if (starts_with(arg, "--index-version=")) {
 				char *c;
 				opts.version = strtoul(arg + 16, &c, 10);
 				if (opts.version > 2)
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 78aa387..c7c76bb 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -266,7 +266,7 @@
 		/* allow template config file to override the default */
 		if (log_all_ref_updates == -1)
 		    git_config_set("core.logallrefupdates", "true");
-		if (prefixcmp(git_dir, work_tree) ||
+		if (!starts_with(git_dir, work_tree) ||
 		    strcmp(git_dir + strlen(work_tree), "/.git")) {
 			git_config_set("core.worktree", work_tree);
 		}
@@ -515,13 +515,14 @@
 				saved = shared_repository;
 				shared_repository = 0;
 				switch (safe_create_leading_directories_const(argv[0])) {
-				case -3:
+				case SCLD_OK:
+				case SCLD_PERMS:
+					break;
+				case SCLD_EXISTS:
 					errno = EEXIST;
 					/* fallthru */
-				case -1:
-					die_errno(_("cannot mkdir %s"), argv[0]);
-					break;
 				default:
+					die_errno(_("cannot mkdir %s"), argv[0]);
 					break;
 				}
 				shared_repository = saved;
diff --git a/builtin/log.c b/builtin/log.c
index 2625f98..b97373d 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -111,6 +111,7 @@
 
 	if (default_date_mode)
 		rev->date_mode = parse_date_format(default_date_mode);
+	rev->diffopt.touched_flags = 0;
 }
 
 static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
@@ -121,7 +122,7 @@
 	static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
 
 	const struct option builtin_log_options[] = {
-		OPT_BOOL(0, "quiet", &quiet, N_("suppress diff output")),
+		OPT__QUIET(&quiet, N_("suppress diff output")),
 		OPT_BOOL(0, "source", &source, N_("show source")),
 		OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
 		{ OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
@@ -390,7 +391,7 @@
 		default_show_root = git_config_bool(var, value);
 		return 0;
 	}
-	if (!prefixcmp(var, "color.decorate."))
+	if (starts_with(var, "color.decorate."))
 		return parse_decorate_color_config(var, 15, value);
 	if (!strcmp(var, "log.mailmap")) {
 		use_mailmap_config = git_config_bool(var, value);
@@ -436,10 +437,29 @@
 	strbuf_release(&out);
 }
 
-static int show_blob_object(const unsigned char *sha1, struct rev_info *rev)
+static int show_blob_object(const unsigned char *sha1, struct rev_info *rev, const char *obj_name)
 {
+	unsigned char sha1c[20];
+	struct object_context obj_context;
+	char *buf;
+	unsigned long size;
+
 	fflush(stdout);
-	return stream_blob_to_fd(1, sha1, NULL, 0);
+	if (!DIFF_OPT_TOUCHED(&rev->diffopt, ALLOW_TEXTCONV) ||
+	    !DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
+		return stream_blob_to_fd(1, sha1, NULL, 0);
+
+	if (get_sha1_with_context(obj_name, 0, sha1c, &obj_context))
+		die("Not a valid object name %s", obj_name);
+	if (!obj_context.path[0] ||
+	    !textconv_object(obj_context.path, obj_context.mode, sha1c, 1, &buf, &size))
+		return stream_blob_to_fd(1, sha1, NULL, 0);
+
+	if (!buf)
+		die("git show %s: bad file", obj_name);
+
+	write_or_die(1, buf, size);
+	return 0;
 }
 
 static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
@@ -457,7 +477,7 @@
 		int new_offset = offset + 1;
 		while (new_offset < size && buf[new_offset++] != '\n')
 			; /* do nothing */
-		if (!prefixcmp(buf + offset, "tagger "))
+		if (starts_with(buf + offset, "tagger "))
 			show_tagger(buf + offset + 7,
 				    new_offset - offset - 7, rev);
 		offset = new_offset;
@@ -503,7 +523,7 @@
 	init_grep_defaults();
 	git_config(git_log_config, NULL);
 
-	init_pathspec(&match_all, NULL);
+	memset(&match_all, 0, sizeof(match_all));
 	init_revisions(&rev, prefix);
 	rev.diff = 1;
 	rev.always_show_header = 1;
@@ -525,7 +545,7 @@
 		const char *name = objects[i].name;
 		switch (o->type) {
 		case OBJ_BLOB:
-			ret = show_blob_object(o->sha1, NULL);
+			ret = show_blob_object(o->sha1, &rev, name);
 			break;
 		case OBJ_TAG: {
 			struct tag *t = (struct tag *)o;
@@ -862,7 +882,7 @@
 	ref = rev->cmdline.rev[positive].name;
 	tip_sha1 = rev->cmdline.rev[positive].item->sha1;
 	if (dwim_ref(ref, strlen(ref), branch_sha1, &full_ref) &&
-	    !prefixcmp(full_ref, "refs/heads/") &&
+	    starts_with(full_ref, "refs/heads/") &&
 	    !hashcmp(tip_sha1, branch_sha1))
 		branch = xstrdup(full_ref + strlen("refs/heads/"));
 	free(full_ref);
@@ -1179,13 +1199,13 @@
 		{ OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL,
 			    N_("don't strip/add [PATCH]"),
 			    PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
-		OPT_BOOLEAN(0, "no-binary", &no_binary_diff,
-			    N_("don't output binary diffs")),
-		OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
-			    N_("don't include a patch matching a commit upstream")),
-		{ OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
+		OPT_BOOL(0, "no-binary", &no_binary_diff,
+			 N_("don't output binary diffs")),
+		OPT_BOOL(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
+			 N_("don't include a patch matching a commit upstream")),
+		{ OPTION_SET_INT, 'p', "no-stat", &use_patch_format, NULL,
 		  N_("show patch format instead of default (patch + stat)"),
-		  PARSE_OPT_NONEG | PARSE_OPT_NOARG },
+		  PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1},
 		OPT_GROUP(N_("Messaging")),
 		{ OPTION_CALLBACK, 0, "add-header", NULL, N_("header"),
 			    N_("add email header"), 0, header_callback },
@@ -1210,8 +1230,7 @@
 			    PARSE_OPT_OPTARG, thread_callback },
 		OPT_STRING(0, "signature", &signature, N_("signature"),
 			    N_("add a signature")),
-		OPT_BOOLEAN(0, "quiet", &quiet,
-			    N_("don't print the patch filenames")),
+		OPT__QUIET(&quiet, N_("don't print the patch filenames")),
 		OPT_END()
 	};
 
@@ -1369,7 +1388,7 @@
 			unsigned char sha1[20];
 			const char *ref;
 			ref = resolve_ref_unsafe("HEAD", sha1, 1, NULL);
-			if (ref && !prefixcmp(ref, "refs/heads/"))
+			if (ref && starts_with(ref, "refs/heads/"))
 				branch_name = xstrdup(ref + strlen("refs/heads/"));
 			else
 				branch_name = xstrdup(""); /* no branch */
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 8500446..e1cf6d8 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -13,6 +13,7 @@
 #include "parse-options.h"
 #include "resolve-undo.h"
 #include "string-list.h"
+#include "pathspec.h"
 
 static int abbrev;
 static int show_deleted;
@@ -30,7 +31,7 @@
 static const char *prefix;
 static int max_prefix_len;
 static int prefix_len;
-static const char **pathspec;
+static struct pathspec pathspec;
 static int error_unmatch;
 static char *ps_matched;
 static const char *with_tree;
@@ -63,7 +64,7 @@
 	if (len >= ent->len)
 		die("git ls-files: internal error - directory entry not superset of prefix");
 
-	if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched))
+	if (!match_pathspec_depth(&pathspec, ent->name, ent->len, len, ps_matched))
 		return;
 
 	fputs(tag, stdout);
@@ -138,7 +139,7 @@
 	if (len >= ce_namelen(ce))
 		die("git ls-files: internal error - cache entry not superset of prefix");
 
-	if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched))
+	if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched))
 		return;
 
 	if (tag && *tag && show_valid_bit &&
@@ -194,7 +195,7 @@
 		len = strlen(path);
 		if (len < max_prefix_len)
 			continue; /* outside of the prefix */
-		if (!match_pathspec(pathspec, path, len, max_prefix_len, ps_matched))
+		if (!match_pathspec_depth(&pathspec, path, len, max_prefix_len, ps_matched))
 			continue; /* uninterested */
 		for (i = 0; i < 3; i++) {
 			if (!ui->mode[i])
@@ -221,7 +222,7 @@
 	if (show_others || show_killed) {
 		if (!show_others)
 			dir->flags |= DIR_COLLECT_KILLED_ONLY;
-		fill_directory(dir, pathspec);
+		fill_directory(dir, &pathspec);
 		if (show_others)
 			show_other_files(dir);
 		if (show_killed)
@@ -289,21 +290,6 @@
 	active_nr = last;
 }
 
-static void strip_trailing_slash_from_submodules(void)
-{
-	const char **p;
-
-	for (p = pathspec; *p != NULL; p++) {
-		int len = strlen(*p), pos;
-
-		if (len < 1 || (*p)[len - 1] != '/')
-			continue;
-		pos = cache_name_pos(*p, len - 1);
-		if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode))
-			*p = xstrndup(*p, len - 1);
-	}
-}
-
 /*
  * Read the tree specified with --with-tree option
  * (typically, HEAD) into stage #1 and then
@@ -335,13 +321,12 @@
 	}
 
 	if (prefix) {
-		static const char *(matchbuf[2]);
-		matchbuf[0] = prefix;
-		matchbuf[1] = NULL;
-		init_pathspec(&pathspec, matchbuf);
-		pathspec.items[0].nowildcard_len = pathspec.items[0].len;
+		static const char *(matchbuf[1]);
+		matchbuf[0] = NULL;
+		parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC,
+			       PATHSPEC_PREFER_CWD, prefix, matchbuf);
 	} else
-		init_pathspec(&pathspec, NULL);
+		memset(&pathspec, 0, sizeof(pathspec));
 	if (read_tree(tree, 1, &pathspec))
 		die("unable to read tree entries %s", tree_name);
 
@@ -366,15 +351,16 @@
 	}
 }
 
-int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix)
+int report_path_error(const char *ps_matched,
+		      const struct pathspec *pathspec,
+		      const char *prefix)
 {
 	/*
 	 * Make sure all pathspec matched; otherwise it is an error.
 	 */
 	struct strbuf sb = STRBUF_INIT;
-	const char *name;
 	int num, errors = 0;
-	for (num = 0; pathspec[num]; num++) {
+	for (num = 0; num < pathspec->nr; num++) {
 		int other, found_dup;
 
 		if (ps_matched[num])
@@ -382,13 +368,16 @@
 		/*
 		 * The caller might have fed identical pathspec
 		 * twice.  Do not barf on such a mistake.
+		 * FIXME: parse_pathspec should have eliminated
+		 * duplicate pathspec.
 		 */
 		for (found_dup = other = 0;
-		     !found_dup && pathspec[other];
+		     !found_dup && other < pathspec->nr;
 		     other++) {
 			if (other == num || !ps_matched[other])
 				continue;
-			if (!strcmp(pathspec[other], pathspec[num]))
+			if (!strcmp(pathspec->items[other].original,
+				    pathspec->items[num].original))
 				/*
 				 * Ok, we have a match already.
 				 */
@@ -397,9 +386,8 @@
 		if (found_dup)
 			continue;
 
-		name = quote_path_relative(pathspec[num], prefix, &sb);
 		error("pathspec '%s' did not match any file(s) known to git.",
-		      name);
+		      pathspec->items[num].original);
 		errors++;
 	}
 	strbuf_release(&sb);
@@ -463,24 +451,24 @@
 		{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
 			N_("paths are separated with NUL character"),
 			PARSE_OPT_NOARG, option_parse_z },
-		OPT_BOOLEAN('t', NULL, &show_tag,
+		OPT_BOOL('t', NULL, &show_tag,
 			N_("identify the file status with tags")),
-		OPT_BOOLEAN('v', NULL, &show_valid_bit,
+		OPT_BOOL('v', NULL, &show_valid_bit,
 			N_("use lowercase letters for 'assume unchanged' files")),
-		OPT_BOOLEAN('c', "cached", &show_cached,
+		OPT_BOOL('c', "cached", &show_cached,
 			N_("show cached files in the output (default)")),
-		OPT_BOOLEAN('d', "deleted", &show_deleted,
+		OPT_BOOL('d', "deleted", &show_deleted,
 			N_("show deleted files in the output")),
-		OPT_BOOLEAN('m', "modified", &show_modified,
+		OPT_BOOL('m', "modified", &show_modified,
 			N_("show modified files in the output")),
-		OPT_BOOLEAN('o', "others", &show_others,
+		OPT_BOOL('o', "others", &show_others,
 			N_("show other files in the output")),
 		OPT_BIT('i', "ignored", &dir.flags,
 			N_("show ignored files in the output"),
 			DIR_SHOW_IGNORED),
-		OPT_BOOLEAN('s', "stage", &show_stage,
+		OPT_BOOL('s', "stage", &show_stage,
 			N_("show staged contents' object name in the output")),
-		OPT_BOOLEAN('k', "killed", &show_killed,
+		OPT_BOOL('k', "killed", &show_killed,
 			N_("show files on the filesystem that need to be removed")),
 		OPT_BIT(0, "directory", &dir.flags,
 			N_("show 'other' directories' name only"),
@@ -488,9 +476,9 @@
 		OPT_NEGBIT(0, "empty-directory", &dir.flags,
 			N_("don't show empty directories"),
 			DIR_HIDE_EMPTY_DIRECTORIES),
-		OPT_BOOLEAN('u', "unmerged", &show_unmerged,
+		OPT_BOOL('u', "unmerged", &show_unmerged,
 			N_("show unmerged files in the output")),
-		OPT_BOOLEAN(0, "resolve-undo", &show_resolve_undo,
+		OPT_BOOL(0, "resolve-undo", &show_resolve_undo,
 			    N_("show resolve-undo information")),
 		{ OPTION_CALLBACK, 'x', "exclude", &exclude_list, N_("pattern"),
 			N_("skip files matching pattern"),
@@ -506,12 +494,12 @@
 		{ OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
 			N_("make the output relative to the project top directory"),
 			PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
-		OPT_BOOLEAN(0, "error-unmatch", &error_unmatch,
+		OPT_BOOL(0, "error-unmatch", &error_unmatch,
 			N_("if any <file> is not in the index, treat this as an error")),
 		OPT_STRING(0, "with-tree", &with_tree, N_("tree-ish"),
 			N_("pretend that paths removed since <tree-ish> are still present")),
 		OPT__ABBREV(&abbrev),
-		OPT_BOOLEAN(0, "debug", &debug_mode, N_("show debugging data")),
+		OPT_BOOL(0, "debug", &debug_mode, N_("show debugging data")),
 		OPT_END()
 	};
 
@@ -557,23 +545,18 @@
 	if (require_work_tree && !is_inside_work_tree())
 		setup_work_tree();
 
-	pathspec = get_pathspec(prefix, argv);
-
-	/* be nice with submodule paths ending in a slash */
-	if (pathspec)
-		strip_trailing_slash_from_submodules();
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_CWD |
+		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
+		       prefix, argv);
 
 	/* Find common prefix for all pathspec's */
-	max_prefix = common_prefix(pathspec);
+	max_prefix = common_prefix(&pathspec);
 	max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
 
 	/* Treat unmatching pathspec elements as errors */
-	if (pathspec && error_unmatch) {
-		int num;
-		for (num = 0; pathspec[num]; num++)
-			;
-		ps_matched = xcalloc(1, num);
-	}
+	if (pathspec.nr && error_unmatch)
+		ps_matched = xcalloc(1, pathspec.nr);
 
 	if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)
 		die("ls-files --ignored needs some exclude pattern");
@@ -600,7 +583,7 @@
 
 	if (ps_matched) {
 		int bad;
-		bad = report_path_error(ps_matched, pathspec, prefix);
+		bad = report_path_error(ps_matched, &pathspec, prefix);
 		if (bad)
 			fprintf(stderr, "Did you forget to 'git add'?\n");
 
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 25e83cf..39e5144 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -50,11 +50,11 @@
 		const char *arg = argv[i];
 
 		if (*arg == '-') {
-			if (!prefixcmp(arg, "--upload-pack=")) {
+			if (starts_with(arg, "--upload-pack=")) {
 				uploadpack = arg + 14;
 				continue;
 			}
-			if (!prefixcmp(arg, "--exec=")) {
+			if (starts_with(arg, "--exec=")) {
 				uploadpack = arg + 7;
 				continue;
 			}
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index fb76e38..65ec931 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -10,6 +10,7 @@
 #include "quote.h"
 #include "builtin.h"
 #include "parse-options.h"
+#include "pathspec.h"
 
 static int line_termination = '\n';
 #define LS_RECURSIVE 1
@@ -35,7 +36,7 @@
 	if (ls_options & LS_RECURSIVE)
 		return 1;
 
-	s = pathspec.raw;
+	s = pathspec._raw;
 	if (!s)
 		return 0;
 
@@ -138,9 +139,9 @@
 			LS_NAME_ONLY),
 		OPT_SET_INT(0, "full-name", &chomp_prefix,
 			    N_("use full path names"), 0),
-		OPT_BOOLEAN(0, "full-tree", &full_tree,
-			    N_("list entire tree; not just current directory "
-			       "(implies --full-name)")),
+		OPT_BOOL(0, "full-tree", &full_tree,
+			 N_("list entire tree; not just current directory "
+			    "(implies --full-name)")),
 		OPT__ABBREV(&abbrev),
 		OPT_END()
 	};
@@ -166,7 +167,15 @@
 	if (get_sha1(argv[0], sha1))
 		die("Not a valid object name %s", argv[0]);
 
-	init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
+	/*
+	 * show_recursive() rolls its own matching code and is
+	 * generally ignorant of 'struct pathspec'. The magic mask
+	 * cannot be lifted until it is converted to use
+	 * match_pathspec_depth() or tree_entry_interesting()
+	 */
+	parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE,
+		       PATHSPEC_PREFER_CWD,
+		       prefix, argv + 1);
 	for (i = 0; i < pathspec.nr; i++)
 		pathspec.items[i].nowildcard_len = pathspec.items[i].len;
 	pathspec.has_wildcard = 0;
diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c
index 24a772d..2c3cd8e 100644
--- a/builtin/mailinfo.c
+++ b/builtin/mailinfo.c
@@ -328,11 +328,11 @@
 	}
 
 	/* for inbody stuff */
-	if (!prefixcmp(line->buf, ">From") && isspace(line->buf[5])) {
+	if (starts_with(line->buf, ">From") && isspace(line->buf[5])) {
 		ret = 1; /* Should this return 0? */
 		goto check_header_out;
 	}
-	if (!prefixcmp(line->buf, "[PATCH]") && isspace(line->buf[7])) {
+	if (starts_with(line->buf, "[PATCH]") && isspace(line->buf[7])) {
 		for (i = 0; header[i]; i++) {
 			if (!memcmp("Subject", header[i], 7)) {
 				handle_header(&hdr_data[i], line);
@@ -361,7 +361,7 @@
 	char *cp = line->buf;
 
 	/* Count mbox From headers as headers */
-	if (!prefixcmp(cp, "From ") || !prefixcmp(cp, ">From "))
+	if (starts_with(cp, "From ") || starts_with(cp, ">From "))
 		return 1;
 
 	while ((ch = *cp++)) {
@@ -671,11 +671,11 @@
 	size_t i;
 
 	/* Beginning of a "diff -" header? */
-	if (!prefixcmp(line->buf, "diff -"))
+	if (starts_with(line->buf, "diff -"))
 		return 1;
 
 	/* CVS "Index: " line? */
-	if (!prefixcmp(line->buf, "Index: "))
+	if (starts_with(line->buf, "Index: "))
 		return 1;
 
 	/*
@@ -685,7 +685,7 @@
 	if (line->len < 4)
 		return 0;
 
-	if (!prefixcmp(line->buf, "---")) {
+	if (starts_with(line->buf, "---")) {
 		/* space followed by a filename? */
 		if (line->buf[3] == ' ' && !isspace(line->buf[4]))
 			return 1;
@@ -986,7 +986,7 @@
 
 static int git_mailinfo_config(const char *var, const char *value, void *unused)
 {
-	if (prefixcmp(var, "mailinfo."))
+	if (!starts_with(var, "mailinfo."))
 		return git_default_config(var, value, unused);
 	if (!strcmp(var, "mailinfo.scissors")) {
 		use_scissors = git_config_bool(var, value);
@@ -1020,7 +1020,7 @@
 			metainfo_charset = def_charset;
 		else if (!strcmp(argv[1], "-n"))
 			metainfo_charset = NULL;
-		else if (!prefixcmp(argv[1], "--encoding="))
+		else if (starts_with(argv[1], "--encoding="))
 			metainfo_charset = argv[1] + 11;
 		else if (!strcmp(argv[1], "--scissors"))
 			use_scissors = 1;
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index 0c4cd2f..0ecde8d 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -1,6 +1,9 @@
 #include "builtin.h"
 #include "cache.h"
 #include "commit.h"
+#include "refs.h"
+#include "diff.h"
+#include "revision.h"
 #include "parse-options.h"
 
 static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
@@ -27,6 +30,7 @@
 	N_("git merge-base [-a|--all] --octopus <commit>..."),
 	N_("git merge-base --independent <commit>..."),
 	N_("git merge-base --is-ancestor <commit> <commit>"),
+	N_("git merge-base --fork-point <ref> [<commit>]"),
 	NULL
 };
 
@@ -44,19 +48,36 @@
 	return r;
 }
 
-static int handle_octopus(int count, const char **args, int reduce, int show_all)
+static int handle_independent(int count, const char **args)
 {
 	struct commit_list *revs = NULL;
 	struct commit_list *result;
 	int i;
 
-	if (reduce)
-		show_all = 1;
+	for (i = count - 1; i >= 0; i--)
+		commit_list_insert(get_commit_reference(args[i]), &revs);
+
+	result = reduce_heads(revs);
+	if (!result)
+		return 1;
+
+	while (result) {
+		printf("%s\n", sha1_to_hex(result->item->object.sha1));
+		result = result->next;
+	}
+	return 0;
+}
+
+static int handle_octopus(int count, const char **args, int show_all)
+{
+	struct commit_list *revs = NULL;
+	struct commit_list *result;
+	int i;
 
 	for (i = count - 1; i >= 0; i--)
 		commit_list_insert(get_commit_reference(args[i]), &revs);
 
-	result = reduce ? reduce_heads(revs) : get_octopus_merge_bases(revs);
+	result = reduce_heads(get_octopus_merge_bases(revs));
 
 	if (!result)
 		return 1;
@@ -85,37 +106,151 @@
 		return 1;
 }
 
+struct rev_collect {
+	struct commit **commit;
+	int nr;
+	int alloc;
+	unsigned int initial : 1;
+};
+
+static void add_one_commit(unsigned char *sha1, struct rev_collect *revs)
+{
+	struct commit *commit;
+
+	if (is_null_sha1(sha1))
+		return;
+
+	commit = lookup_commit(sha1);
+	if (!commit ||
+	    (commit->object.flags & TMP_MARK) ||
+	    parse_commit(commit))
+		return;
+
+	ALLOC_GROW(revs->commit, revs->nr + 1, revs->alloc);
+	revs->commit[revs->nr++] = commit;
+	commit->object.flags |= TMP_MARK;
+}
+
+static int collect_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
+				  const char *ident, unsigned long timestamp,
+				  int tz, const char *message, void *cbdata)
+{
+	struct rev_collect *revs = cbdata;
+
+	if (revs->initial) {
+		revs->initial = 0;
+		add_one_commit(osha1, revs);
+	}
+	add_one_commit(nsha1, revs);
+	return 0;
+}
+
+static int handle_fork_point(int argc, const char **argv)
+{
+	unsigned char sha1[20];
+	char *refname;
+	const char *commitname;
+	struct rev_collect revs;
+	struct commit *derived;
+	struct commit_list *bases;
+	int i, ret = 0;
+
+	switch (dwim_ref(argv[0], strlen(argv[0]), sha1, &refname)) {
+	case 0:
+		die("No such ref: '%s'", argv[0]);
+	case 1:
+		break; /* good */
+	default:
+		die("Ambiguous refname: '%s'", argv[0]);
+	}
+
+	commitname = (argc == 2) ? argv[1] : "HEAD";
+	if (get_sha1(commitname, sha1))
+		die("Not a valid object name: '%s'", commitname);
+
+	derived = lookup_commit_reference(sha1);
+	memset(&revs, 0, sizeof(revs));
+	revs.initial = 1;
+	for_each_reflog_ent(refname, collect_one_reflog_ent, &revs);
+
+	for (i = 0; i < revs.nr; i++)
+		revs.commit[i]->object.flags &= ~TMP_MARK;
+
+	bases = get_merge_bases_many(derived, revs.nr, revs.commit, 0);
+
+	/*
+	 * There should be one and only one merge base, when we found
+	 * a common ancestor among reflog entries.
+	 */
+	if (!bases || bases->next) {
+		ret = 1;
+		goto cleanup_return;
+	}
+
+	/* And the found one must be one of the reflog entries */
+	for (i = 0; i < revs.nr; i++)
+		if (&bases->item->object == &revs.commit[i]->object)
+			break; /* found */
+	if (revs.nr <= i) {
+		ret = 1; /* not found */
+		goto cleanup_return;
+	}
+
+	printf("%s\n", sha1_to_hex(bases->item->object.sha1));
+
+cleanup_return:
+	free_commit_list(bases);
+	return ret;
+}
+
 int cmd_merge_base(int argc, const char **argv, const char *prefix)
 {
 	struct commit **rev;
 	int rev_nr = 0;
 	int show_all = 0;
-	int octopus = 0;
-	int reduce = 0;
-	int is_ancestor = 0;
+	int cmdmode = 0;
 
 	struct option options[] = {
-		OPT_BOOLEAN('a', "all", &show_all, N_("output all common ancestors")),
-		OPT_BOOLEAN(0, "octopus", &octopus, N_("find ancestors for a single n-way merge")),
-		OPT_BOOLEAN(0, "independent", &reduce, N_("list revs not reachable from others")),
-		OPT_BOOLEAN(0, "is-ancestor", &is_ancestor,
-			    N_("is the first one ancestor of the other?")),
+		OPT_BOOL('a', "all", &show_all, N_("output all common ancestors")),
+		OPT_CMDMODE(0, "octopus", &cmdmode,
+			    N_("find ancestors for a single n-way merge"), 'o'),
+		OPT_CMDMODE(0, "independent", &cmdmode,
+			    N_("list revs not reachable from others"), 'r'),
+		OPT_CMDMODE(0, "is-ancestor", &cmdmode,
+			    N_("is the first one ancestor of the other?"), 'a'),
+		OPT_CMDMODE(0, "fork-point", &cmdmode,
+			    N_("find where <commit> forked from reflog of <ref>"), 'f'),
 		OPT_END()
 	};
 
 	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0);
-	if (!octopus && !reduce && argc < 2)
-		usage_with_options(merge_base_usage, options);
-	if (is_ancestor && (show_all || octopus || reduce))
-		die("--is-ancestor cannot be used with other options");
-	if (is_ancestor)
-		return handle_is_ancestor(argc, argv);
-	if (reduce && (show_all || octopus))
-		die("--independent cannot be used with other options");
 
-	if (octopus || reduce)
-		return handle_octopus(argc, argv, reduce, show_all);
+	if (cmdmode == 'a') {
+		if (argc < 2)
+			usage_with_options(merge_base_usage, options);
+		if (show_all)
+			die("--is-ancestor cannot be used with --all");
+		return handle_is_ancestor(argc, argv);
+	}
+
+	if (cmdmode == 'r' && show_all)
+		die("--independent cannot be used with --all");
+
+	if (cmdmode == 'o')
+		return handle_octopus(argc, argv, show_all);
+
+	if (cmdmode == 'r')
+		return handle_independent(argc, argv);
+
+	if (cmdmode == 'f') {
+		if (argc < 1 || 2 < argc)
+			usage_with_options(merge_base_usage, options);
+		return handle_fork_point(argc, argv);
+	}
+
+	if (argc < 2)
+		usage_with_options(merge_base_usage, options);
 
 	rev = xmalloc(argc * sizeof(*rev));
 	while (argc-- > 0)
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index c0570f2..844f84f 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -30,7 +30,7 @@
 	int quiet = 0;
 	int prefixlen = 0;
 	struct option options[] = {
-		OPT_BOOLEAN('p', "stdout", &to_stdout, N_("send results to standard output")),
+		OPT_BOOL('p', "stdout", &to_stdout, N_("send results to standard output")),
 		OPT_SET_INT(0, "diff3", &xmp.style, N_("use a diff3 based merge"), XDL_MERGE_DIFF3),
 		OPT_SET_INT(0, "ours", &xmp.favor, N_("for conflicts, use our version"),
 			    XDL_MERGE_FAVOR_OURS),
diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index 3a64f5d..a90f28f 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -29,7 +29,7 @@
 	struct commit *result;
 
 	init_merge_options(&o);
-	if (argv[0] && !suffixcmp(argv[0], "-subtree"))
+	if (argv[0] && ends_with(argv[0], "-subtree"))
 		o.subtree_shift = "";
 
 	if (argc < 4)
@@ -38,7 +38,7 @@
 	for (i = 1; i < argc; ++i) {
 		const char *arg = argv[i];
 
-		if (!prefixcmp(arg, "--")) {
+		if (starts_with(arg, "--")) {
 			if (!arg[2])
 				break;
 			if (parse_merge_opt(&o, arg + 2))
diff --git a/builtin/merge.c b/builtin/merge.c
index 34a6166..e576a7f 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -186,33 +186,26 @@
 	return 0;
 }
 
-static int option_parse_ff_only(const struct option *opt,
-			  const char *arg, int unset)
-{
-	fast_forward = FF_ONLY;
-	return 0;
-}
-
 static struct option builtin_merge_options[] = {
 	{ OPTION_CALLBACK, 'n', NULL, NULL, NULL,
 		N_("do not show a diffstat at the end of the merge"),
 		PARSE_OPT_NOARG, option_parse_n },
-	OPT_BOOLEAN(0, "stat", &show_diffstat,
+	OPT_BOOL(0, "stat", &show_diffstat,
 		N_("show a diffstat at the end of the merge")),
-	OPT_BOOLEAN(0, "summary", &show_diffstat, N_("(synonym to --stat)")),
+	OPT_BOOL(0, "summary", &show_diffstat, N_("(synonym to --stat)")),
 	{ OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"),
 	  N_("add (at most <n>) entries from shortlog to merge commit message"),
 	  PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN },
-	OPT_BOOLEAN(0, "squash", &squash,
+	OPT_BOOL(0, "squash", &squash,
 		N_("create a single commit instead of doing a merge")),
-	OPT_BOOLEAN(0, "commit", &option_commit,
+	OPT_BOOL(0, "commit", &option_commit,
 		N_("perform a commit if the merge succeeds (default)")),
 	OPT_BOOL('e', "edit", &option_edit,
 		N_("edit message before committing")),
 	OPT_SET_INT(0, "ff", &fast_forward, N_("allow fast-forward (default)"), FF_ALLOW),
-	{ OPTION_CALLBACK, 0, "ff-only", NULL, NULL,
+	{ OPTION_SET_INT, 0, "ff-only", &fast_forward, NULL,
 		N_("abort if fast-forward is not possible"),
-		PARSE_OPT_NOARG | PARSE_OPT_NONEG, option_parse_ff_only },
+		PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, FF_ONLY },
 	OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
 	OPT_BOOL(0, "verify-signatures", &verify_signatures,
 		N_("Verify that the named commit has a valid GPG signature")),
@@ -224,12 +217,12 @@
 		N_("merge commit message (for a non-fast-forward merge)"),
 		option_parse_message),
 	OPT__VERBOSITY(&verbosity),
-	OPT_BOOLEAN(0, "abort", &abort_current_merge,
+	OPT_BOOL(0, "abort", &abort_current_merge,
 		N_("abort the current in-progress merge")),
 	OPT_SET_INT(0, "progress", &show_progress, N_("force progress reporting"), 1),
 	{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
 	  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
-	OPT_BOOLEAN(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
+	OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
 	OPT_END()
 };
 
@@ -374,7 +367,7 @@
 			sha1_to_hex(commit->object.sha1));
 		pretty_print_commit(&ctx, commit, &out);
 	}
-	if (write(fd, out.buf, out.len) < 0)
+	if (write_in_full(fd, out.buf, out.len) != out.len)
 		die_errno(_("Writing SQUASH_MSG"));
 	if (close(fd))
 		die_errno(_("Finishing SQUASH_MSG"));
@@ -453,17 +446,17 @@
 		die(_("'%s' does not point to a commit"), remote);
 
 	if (dwim_ref(remote, strlen(remote), branch_head, &found_ref) > 0) {
-		if (!prefixcmp(found_ref, "refs/heads/")) {
+		if (starts_with(found_ref, "refs/heads/")) {
 			strbuf_addf(msg, "%s\t\tbranch '%s' of .\n",
 				    sha1_to_hex(branch_head), remote);
 			goto cleanup;
 		}
-		if (!prefixcmp(found_ref, "refs/tags/")) {
+		if (starts_with(found_ref, "refs/tags/")) {
 			strbuf_addf(msg, "%s\t\ttag '%s' of .\n",
 				    sha1_to_hex(branch_head), remote);
 			goto cleanup;
 		}
-		if (!prefixcmp(found_ref, "refs/remotes/")) {
+		if (starts_with(found_ref, "refs/remotes/")) {
 			strbuf_addf(msg, "%s\t\tremote-tracking branch '%s' of .\n",
 				    sha1_to_hex(branch_head), remote);
 			goto cleanup;
@@ -577,8 +570,8 @@
 {
 	int status;
 
-	if (branch && !prefixcmp(k, "branch.") &&
-		!prefixcmp(k + 7, branch) &&
+	if (branch && starts_with(k, "branch.") &&
+		starts_with(k + 7, branch) &&
 		!strcmp(k + 7 + strlen(branch), ".mergeoptions")) {
 		free(branch_mergeoptions);
 		branch_mergeoptions = xstrdup(v);
@@ -1113,7 +1106,7 @@
 	 * current branch.
 	 */
 	branch = branch_to_free = resolve_refdup("HEAD", head_sha1, 0, &flag);
-	if (branch && !prefixcmp(branch, "refs/heads/"))
+	if (branch && starts_with(branch, "refs/heads/"))
 		branch += 11;
 	if (!branch || is_null_sha1(head_sha1))
 		head_commit = NULL;
@@ -1193,7 +1186,7 @@
 	 * This could be traditional "merge <msg> HEAD <commit>..."  and
 	 * the way we can tell it is to see if the second token is HEAD,
 	 * but some people might have misused the interface and used a
-	 * committish that is the same as HEAD there instead.
+	 * commit-ish that is the same as HEAD there instead.
 	 * Traditional format never would have "-m" so it is an
 	 * additional safety measure to check for it.
 	 */
diff --git a/builtin/mv.c b/builtin/mv.c
index 034fec9..21c46d1 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -9,14 +9,19 @@
 #include "cache-tree.h"
 #include "string-list.h"
 #include "parse-options.h"
+#include "submodule.h"
 
 static const char * const builtin_mv_usage[] = {
 	N_("git mv [options] <source>... <destination>"),
 	NULL
 };
 
-static const char **copy_pathspec(const char *prefix, const char **pathspec,
-				  int count, int base_name)
+#define DUP_BASENAME 1
+#define KEEP_TRAILING_SLASH 2
+
+static const char **internal_copy_pathspec(const char *prefix,
+					   const char **pathspec,
+					   int count, unsigned flags)
 {
 	int i;
 	const char **result = xmalloc((count + 1) * sizeof(const char *));
@@ -25,11 +30,12 @@
 	for (i = 0; i < count; i++) {
 		int length = strlen(result[i]);
 		int to_copy = length;
-		while (to_copy > 0 && is_dir_sep(result[i][to_copy - 1]))
+		while (!(flags & KEEP_TRAILING_SLASH) &&
+		       to_copy > 0 && is_dir_sep(result[i][to_copy - 1]))
 			to_copy--;
-		if (to_copy != length || base_name) {
+		if (to_copy != length || flags & DUP_BASENAME) {
 			char *it = xmemdupz(result[i], to_copy);
-			if (base_name) {
+			if (flags & DUP_BASENAME) {
 				result[i] = xstrdup(basename(it));
 				free(it);
 			} else
@@ -53,23 +59,25 @@
 }
 
 static struct lock_file lock_file;
+#define SUBMODULE_WITH_GITDIR ((const char *)1)
 
 int cmd_mv(int argc, const char **argv, const char *prefix)
 {
-	int i, newfd;
+	int i, newfd, gitmodules_modified = 0;
 	int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
 	struct option builtin_mv_options[] = {
 		OPT__VERBOSE(&verbose, N_("be verbose")),
 		OPT__DRY_RUN(&show_only, N_("dry run")),
 		OPT__FORCE(&force, N_("force move/rename even if target exists")),
-		OPT_BOOLEAN('k', NULL, &ignore_errors, N_("skip move/rename errors")),
+		OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")),
 		OPT_END(),
 	};
-	const char **source, **destination, **dest_path;
+	const char **source, **destination, **dest_path, **submodule_gitfile;
 	enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes;
 	struct stat st;
 	struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
 
+	gitmodules_config();
 	git_config(git_default_config, NULL);
 
 	argc = parse_options(argc, argv, prefix, builtin_mv_options,
@@ -81,17 +89,23 @@
 	if (read_cache() < 0)
 		die(_("index file corrupt"));
 
-	source = copy_pathspec(prefix, argv, argc, 0);
+	source = internal_copy_pathspec(prefix, argv, argc, 0);
 	modes = xcalloc(argc, sizeof(enum update_mode));
-	dest_path = copy_pathspec(prefix, argv + argc, 1, 0);
+	/*
+	 * Keep trailing slash, needed to let
+	 * "git mv file no-such-dir/" error out.
+	 */
+	dest_path = internal_copy_pathspec(prefix, argv + argc, 1,
+					   KEEP_TRAILING_SLASH);
+	submodule_gitfile = xcalloc(argc, sizeof(char *));
 
 	if (dest_path[0][0] == '\0')
 		/* special case: "." was normalized to "" */
-		destination = copy_pathspec(dest_path[0], argv, argc, 1);
+		destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
 	else if (!lstat(dest_path[0], &st) &&
 			S_ISDIR(st.st_mode)) {
 		dest_path[0] = add_slash(dest_path[0]);
-		destination = copy_pathspec(dest_path[0], argv, argc, 1);
+		destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
 	} else {
 		if (argc != 1)
 			die("destination '%s' is not a directory", dest_path[0]);
@@ -117,55 +131,70 @@
 				&& lstat(dst, &st) == 0)
 			bad = _("cannot move directory over file");
 		else if (src_is_dir) {
-			const char *src_w_slash = add_slash(src);
-			int len_w_slash = length + 1;
-			int first, last;
+			int first = cache_name_pos(src, length);
+			if (first >= 0) {
+				struct strbuf submodule_dotgit = STRBUF_INIT;
+				if (!S_ISGITLINK(active_cache[first]->ce_mode))
+					die (_("Huh? Directory %s is in index and no submodule?"), src);
+				if (!is_staging_gitmodules_ok())
+					die (_("Please, stage your changes to .gitmodules or stash them to proceed"));
+				strbuf_addf(&submodule_dotgit, "%s/.git", src);
+				submodule_gitfile[i] = read_gitfile(submodule_dotgit.buf);
+				if (submodule_gitfile[i])
+					submodule_gitfile[i] = xstrdup(submodule_gitfile[i]);
+				else
+					submodule_gitfile[i] = SUBMODULE_WITH_GITDIR;
+				strbuf_release(&submodule_dotgit);
+			} else {
+				const char *src_w_slash = add_slash(src);
+				int last, len_w_slash = length + 1;
 
-			modes[i] = WORKING_DIRECTORY;
+				modes[i] = WORKING_DIRECTORY;
 
-			first = cache_name_pos(src_w_slash, len_w_slash);
-			if (first >= 0)
-				die (_("Huh? %.*s is in index?"),
-						len_w_slash, src_w_slash);
+				first = cache_name_pos(src_w_slash, len_w_slash);
+				if (first >= 0)
+					die (_("Huh? %.*s is in index?"),
+							len_w_slash, src_w_slash);
 
-			first = -1 - first;
-			for (last = first; last < active_nr; last++) {
-				const char *path = active_cache[last]->name;
-				if (strncmp(path, src_w_slash, len_w_slash))
-					break;
-			}
-			free((char *)src_w_slash);
-
-			if (last - first < 1)
-				bad = _("source directory is empty");
-			else {
-				int j, dst_len;
-
-				if (last - first > 0) {
-					source = xrealloc(source,
-							(argc + last - first)
-							* sizeof(char *));
-					destination = xrealloc(destination,
-							(argc + last - first)
-							* sizeof(char *));
-					modes = xrealloc(modes,
-							(argc + last - first)
-							* sizeof(enum update_mode));
+				first = -1 - first;
+				for (last = first; last < active_nr; last++) {
+					const char *path = active_cache[last]->name;
+					if (strncmp(path, src_w_slash, len_w_slash))
+						break;
 				}
+				free((char *)src_w_slash);
 
-				dst = add_slash(dst);
-				dst_len = strlen(dst);
+				if (last - first < 1)
+					bad = _("source directory is empty");
+				else {
+					int j, dst_len;
 
-				for (j = 0; j < last - first; j++) {
-					const char *path =
-						active_cache[first + j]->name;
-					source[argc + j] = path;
-					destination[argc + j] =
-						prefix_path(dst, dst_len,
-							path + length + 1);
-					modes[argc + j] = INDEX;
+					if (last - first > 0) {
+						source = xrealloc(source,
+								(argc + last - first)
+								* sizeof(char *));
+						destination = xrealloc(destination,
+								(argc + last - first)
+								* sizeof(char *));
+						modes = xrealloc(modes,
+								(argc + last - first)
+								* sizeof(enum update_mode));
+					}
+
+					dst = add_slash(dst);
+					dst_len = strlen(dst);
+
+					for (j = 0; j < last - first; j++) {
+						const char *path =
+							active_cache[first + j]->name;
+						source[argc + j] = path;
+						destination[argc + j] =
+							prefix_path(dst, dst_len,
+								path + length + 1);
+						modes[argc + j] = INDEX;
+					}
+					argc += last - first;
 				}
-				argc += last - first;
 			}
 		} else if (cache_name_pos(src, length) < 0)
 			bad = _("not under version control");
@@ -185,6 +214,8 @@
 			}
 		} else if (string_list_has_string(&src_for_dst, dst))
 			bad = _("multiple sources for the same target");
+		else if (is_dir_sep(dst[strlen(dst) - 1]))
+			bad = _("destination directory does not exist");
 		else
 			string_list_insert(&src_for_dst, dst);
 
@@ -210,9 +241,16 @@
 		int pos;
 		if (show_only || verbose)
 			printf(_("Renaming %s to %s\n"), src, dst);
-		if (!show_only && mode != INDEX &&
-				rename(src, dst) < 0 && !ignore_errors)
-			die_errno (_("renaming '%s' failed"), src);
+		if (!show_only && mode != INDEX) {
+			if (rename(src, dst) < 0 && !ignore_errors)
+				die_errno (_("renaming '%s' failed"), src);
+			if (submodule_gitfile[i]) {
+				if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
+					connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
+				if (!update_path_in_gitmodules(src, dst))
+					gitmodules_modified = 1;
+			}
+		}
 
 		if (mode == WORKING_DIRECTORY)
 			continue;
@@ -223,6 +261,9 @@
 			rename_cache_entry_at(pos, dst);
 	}
 
+	if (gitmodules_modified)
+		stage_updated_gitmodules();
+
 	if (active_cache_changed) {
 		if (write_cache(newfd, active_cache, active_nr) ||
 		    commit_locked_index(&lock_file))
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 0aaa19e..0b21d7e 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -27,8 +27,7 @@
 	struct commit_list *parents;
 	int parent_number = 1;
 
-	if (!commit->object.parsed)
-		parse_commit(commit);
+	parse_commit(commit);
 
 	if (commit->date < cutoff)
 		return;
@@ -101,9 +100,9 @@
 {
 	if (shorten_unambiguous)
 		refname = shorten_unambiguous_ref(refname, 0);
-	else if (!prefixcmp(refname, "refs/heads/"))
+	else if (starts_with(refname, "refs/heads/"))
 		refname = refname + 11;
-	else if (!prefixcmp(refname, "refs/"))
+	else if (starts_with(refname, "refs/"))
 		refname = refname + 5;
 	return refname;
 }
@@ -149,7 +148,7 @@
 	int can_abbreviate_output = data->tags_only && data->name_only;
 	int deref = 0;
 
-	if (data->tags_only && prefixcmp(path, "refs/tags/"))
+	if (data->tags_only && !starts_with(path, "refs/tags/"))
 		return 0;
 
 	if (data->ref_filter) {
@@ -310,15 +309,15 @@
 	int all = 0, transform_stdin = 0, allow_undefined = 1, always = 0, peel_tag = 0;
 	struct name_ref_data data = { 0, 0, NULL };
 	struct option opts[] = {
-		OPT_BOOLEAN(0, "name-only", &data.name_only, N_("print only names (no SHA-1)")),
-		OPT_BOOLEAN(0, "tags", &data.tags_only, N_("only use tags to name the commits")),
+		OPT_BOOL(0, "name-only", &data.name_only, N_("print only names (no SHA-1)")),
+		OPT_BOOL(0, "tags", &data.tags_only, N_("only use tags to name the commits")),
 		OPT_STRING(0, "refs", &data.ref_filter, N_("pattern"),
 				   N_("only use refs matching <pattern>")),
 		OPT_GROUP(""),
-		OPT_BOOLEAN(0, "all", &all, N_("list all commits reachable from all refs")),
-		OPT_BOOLEAN(0, "stdin", &transform_stdin, N_("read from stdin")),
-		OPT_BOOLEAN(0, "undefined", &allow_undefined, N_("allow to print `undefined` names")),
-		OPT_BOOLEAN(0, "always",     &always,
+		OPT_BOOL(0, "all", &all, N_("list all commits reachable from all refs")),
+		OPT_BOOL(0, "stdin", &transform_stdin, N_("read from stdin")),
+		OPT_BOOL(0, "undefined", &allow_undefined, N_("allow to print `undefined` names (default)")),
+		OPT_BOOL(0, "always",     &always,
 			   N_("show abbreviated commit object as fallback")),
 		{
 			/* A Hidden OPT_BOOL */
@@ -331,7 +330,7 @@
 
 	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0);
-	if (!!all + !!transform_stdin + !!argc > 1) {
+	if (all + transform_stdin + !!argc > 1) {
 		error("Specify either a list, or --all, not both!");
 		usage_with_options(name_rev_usage, opts);
 	}
diff --git a/builtin/notes.c b/builtin/notes.c
index e4100c4..2b24d05 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -347,7 +347,7 @@
 	init_notes(NULL, NULL, NULL, 0);
 	t = &default_notes_tree;
 
-	if (prefixcmp(t->ref, "refs/notes/"))
+	if (!starts_with(t->ref, "refs/notes/"))
 		die("Refusing to %s notes in %s (outside of refs/notes/)",
 		    subcommand, t->ref);
 	return t;
@@ -483,7 +483,7 @@
 	const char *rewrite_cmd = NULL;
 	struct option options[] = {
 		OPT__FORCE(&force, N_("replace existing notes")),
-		OPT_BOOLEAN(0, "stdin", &from_stdin, N_("read objects from stdin")),
+		OPT_BOOL(0, "stdin", &from_stdin, N_("read objects from stdin")),
 		OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"),
 			   N_("load rewriting config for <command> (implies "
 			      "--stdin)")),
@@ -739,13 +739,13 @@
 			   N_("resolve notes conflicts using the given strategy "
 			      "(manual/ours/theirs/union/cat_sort_uniq)")),
 		OPT_GROUP(N_("Committing unmerged notes")),
-		{ OPTION_BOOLEAN, 0, "commit", &do_commit, NULL,
+		{ OPTION_SET_INT, 0, "commit", &do_commit, NULL,
 			N_("finalize notes merge by committing unmerged notes"),
-			PARSE_OPT_NOARG | PARSE_OPT_NONEG },
+			PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
 		OPT_GROUP(N_("Aborting notes merge resolution")),
-		{ OPTION_BOOLEAN, 0, "abort", &do_abort, NULL,
+		{ OPTION_SET_INT, 0, "abort", &do_abort, NULL,
 			N_("abort notes merge"),
-			PARSE_OPT_NOARG | PARSE_OPT_NONEG },
+			PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
 		OPT_END()
 	};
 
@@ -853,7 +853,7 @@
 		OPT_BIT(0, "ignore-missing", &flag,
 			N_("attempt to remove non-existent note is not an error"),
 			IGNORE_MISSING),
-		OPT_BOOLEAN(0, "stdin", &from_stdin,
+		OPT_BOOL(0, "stdin", &from_stdin,
 			    N_("read object names from the standard input")),
 		OPT_END()
 	};
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index dd117b3..541667f 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -38,17 +38,18 @@
 	void *delta_data;	/* cached delta (uncompressed) */
 	unsigned long delta_size;	/* delta data size (uncompressed) */
 	unsigned long z_delta_size;	/* delta data size (compressed) */
-	unsigned int hash;	/* name hint hash */
 	enum object_type type;
 	enum object_type in_pack_type;	/* could be delta */
+	uint32_t hash;			/* name hint hash */
 	unsigned char in_pack_header_size;
-	unsigned char preferred_base; /* we do not pack this, but is available
-				       * to be used as the base object to delta
-				       * objects against.
-				       */
-	unsigned char no_try_delta;
-	unsigned char tagged; /* near the very tip of refs */
-	unsigned char filled; /* assigned write-order */
+	unsigned preferred_base:1; /*
+				    * we do not pack this, but is available
+				    * to be used as the base object to delta
+				    * objects against.
+				    */
+	unsigned no_try_delta:1;
+	unsigned tagged:1; /* near the very tip of refs */
+	unsigned filled:1; /* assigned write-order */
 };
 
 /*
@@ -736,8 +737,6 @@
 			f = create_tmp_packfile(&pack_tmp_name);
 
 		offset = write_pack_header(f, nr_remaining);
-		if (!offset)
-			die_errno("unable to write pack header");
 		nr_written = 0;
 		for (; i < nr_objects; i++) {
 			struct object_entry *e = write_order[i];
@@ -859,9 +858,9 @@
 	}
 }
 
-static unsigned name_hash(const char *name)
+static uint32_t name_hash(const char *name)
 {
-	unsigned c, hash = 0;
+	uint32_t c, hash = 0;
 
 	if (!name)
 		return 0;
@@ -908,7 +907,7 @@
 	struct packed_git *p, *found_pack = NULL;
 	off_t found_offset = 0;
 	int ix;
-	unsigned hash = name_hash(name);
+	uint32_t hash = name_hash(name);
 
 	ix = nr_objects ? locate_object_entry_hash(sha1) : -1;
 	if (ix >= 0) {
@@ -1809,7 +1808,7 @@
 static void try_to_free_from_threads(size_t size)
 {
 	read_lock();
-	release_pack_memory(size, -1);
+	release_pack_memory(size);
 	read_unlock();
 }
 
@@ -2031,7 +2030,7 @@
 {
 	unsigned char peeled[20];
 
-	if (!prefixcmp(path, "refs/tags/") && /* is a tag? */
+	if (starts_with(path, "refs/tags/") && /* is a tag? */
 	    !peel_ref(path, peeled)        && /* peelable? */
 	    locate_object_entry(peeled))      /* object packed? */
 		add_object_entry(sha1, OBJ_TAG, NULL, 0);
diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c
index fa6ce42..fcf5fb6 100644
--- a/builtin/prune-packed.c
+++ b/builtin/prune-packed.c
@@ -10,58 +10,62 @@
 
 static struct progress *progress;
 
-static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
+static void prune_dir(int i, DIR *dir, struct strbuf *pathname, int opts)
 {
 	struct dirent *de;
 	char hex[40];
+	int top_len = pathname->len;
 
 	sprintf(hex, "%02x", i);
 	while ((de = readdir(dir)) != NULL) {
 		unsigned char sha1[20];
 		if (strlen(de->d_name) != 38)
 			continue;
-		memcpy(hex+2, de->d_name, 38);
+		memcpy(hex + 2, de->d_name, 38);
 		if (get_sha1_hex(hex, sha1))
 			continue;
 		if (!has_sha1_pack(sha1))
 			continue;
-		memcpy(pathname + len, de->d_name, 38);
+
+		strbuf_add(pathname, de->d_name, 38);
 		if (opts & PRUNE_PACKED_DRY_RUN)
-			printf("rm -f %s\n", pathname);
+			printf("rm -f %s\n", pathname->buf);
 		else
-			unlink_or_warn(pathname);
+			unlink_or_warn(pathname->buf);
 		display_progress(progress, i + 1);
+		strbuf_setlen(pathname, top_len);
 	}
 }
 
 void prune_packed_objects(int opts)
 {
 	int i;
-	static char pathname[PATH_MAX];
 	const char *dir = get_object_directory();
-	int len = strlen(dir);
+	struct strbuf pathname = STRBUF_INIT;
+	int top_len;
 
+	strbuf_addstr(&pathname, dir);
 	if (opts & PRUNE_PACKED_VERBOSE)
 		progress = start_progress_delay("Removing duplicate objects",
 			256, 95, 2);
 
-	if (len > PATH_MAX - 42)
-		die("impossible object directory");
-	memcpy(pathname, dir, len);
-	if (len && pathname[len-1] != '/')
-		pathname[len++] = '/';
+	if (pathname.len && pathname.buf[pathname.len - 1] != '/')
+		strbuf_addch(&pathname, '/');
+
+	top_len = pathname.len;
 	for (i = 0; i < 256; i++) {
 		DIR *d;
 
 		display_progress(progress, i + 1);
-		sprintf(pathname + len, "%02x/", i);
-		d = opendir(pathname);
+		strbuf_setlen(&pathname, top_len);
+		strbuf_addf(&pathname, "%02x/", i);
+		d = opendir(pathname.buf);
 		if (!d)
 			continue;
-		prune_dir(i, d, pathname, len + 3, opts);
+		prune_dir(i, d, &pathname, opts);
 		closedir(d);
-		pathname[len + 2] = '\0';
-		rmdir(pathname);
+		strbuf_setlen(&pathname, top_len + 2);
+		rmdir(pathname.buf);
 	}
 	stop_progress(&progress);
 }
diff --git a/builtin/prune.c b/builtin/prune.c
index 6366917..de43b26 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -17,9 +17,8 @@
 static unsigned long expire;
 static int show_progress = -1;
 
-static int prune_tmp_object(const char *path, const char *filename)
+static int prune_tmp_file(const char *fullpath)
 {
-	const char *fullpath = mkpath("%s/%s", path, filename);
 	struct stat st;
 	if (lstat(fullpath, &st))
 		return error("Could not stat '%s'", fullpath);
@@ -32,9 +31,8 @@
 	return 0;
 }
 
-static int prune_object(char *path, const char *filename, const unsigned char *sha1)
+static int prune_object(const char *fullpath, const unsigned char *sha1)
 {
-	const char *fullpath = mkpath("%s/%s", path, filename);
 	struct stat st;
 	if (lstat(fullpath, &st))
 		return error("Could not stat '%s'", fullpath);
@@ -50,9 +48,10 @@
 	return 0;
 }
 
-static int prune_dir(int i, char *path)
+static int prune_dir(int i, struct strbuf *path)
 {
-	DIR *dir = opendir(path);
+	size_t baselen = path->len;
+	DIR *dir = opendir(path->buf);
 	struct dirent *de;
 
 	if (!dir)
@@ -77,28 +76,39 @@
 			if (lookup_object(sha1))
 				continue;
 
-			prune_object(path, de->d_name, sha1);
+			strbuf_addf(path, "/%s", de->d_name);
+			prune_object(path->buf, sha1);
+			strbuf_setlen(path, baselen);
 			continue;
 		}
-		if (!prefixcmp(de->d_name, "tmp_obj_")) {
-			prune_tmp_object(path, de->d_name);
+		if (starts_with(de->d_name, "tmp_obj_")) {
+			strbuf_addf(path, "/%s", de->d_name);
+			prune_tmp_file(path->buf);
+			strbuf_setlen(path, baselen);
 			continue;
 		}
-		fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
+		fprintf(stderr, "bad sha1 file: %s/%s\n", path->buf, de->d_name);
 	}
 	closedir(dir);
 	if (!show_only)
-		rmdir(path);
+		rmdir(path->buf);
 	return 0;
 }
 
 static void prune_object_dir(const char *path)
 {
+	struct strbuf buf = STRBUF_INIT;
+	size_t baselen;
 	int i;
+
+	strbuf_addstr(&buf, path);
+	strbuf_addch(&buf, '/');
+	baselen = buf.len;
+
 	for (i = 0; i < 256; i++) {
-		static char dir[4096];
-		sprintf(dir, "%s/%02x", path, i);
-		prune_dir(i, dir);
+		strbuf_addf(&buf, "%02x", i);
+		prune_dir(i, &buf);
+		strbuf_setlen(&buf, baselen);
 	}
 }
 
@@ -119,8 +129,8 @@
 		return;
 	}
 	while ((de = readdir(dir)) != NULL)
-		if (!prefixcmp(de->d_name, "tmp_"))
-			prune_tmp_object(path, de->d_name);
+		if (starts_with(de->d_name, "tmp_"))
+			prune_tmp_file(mkpath("%s/%s", path, de->d_name));
 	closedir(dir);
 }
 
@@ -170,5 +180,9 @@
 	s = mkpathdup("%s/pack", get_object_directory());
 	remove_temporary_files(s);
 	free(s);
+
+	if (is_repository_shallow())
+		prune_shallow(show_only);
+
 	return 0;
 }
diff --git a/builtin/push.c b/builtin/push.c
index 04f0eaf..0e50ddb 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -15,12 +15,14 @@
 	NULL,
 };
 
-static int thin;
+static int thin = 1;
 static int deleterefs;
 static const char *receivepack;
 static int verbosity;
 static int progress = -1;
 
+static struct push_cas_option cas;
+
 static const char **refspec;
 static int refspec_nr;
 static int refspec_alloc;
@@ -33,35 +35,75 @@
 	refspec[refspec_nr-1] = ref;
 }
 
-static void set_refspecs(const char **refs, int nr)
+static const char *map_refspec(const char *ref,
+			       struct remote *remote, struct ref *local_refs)
 {
+	struct ref *matched = NULL;
+
+	/* Does "ref" uniquely name our ref? */
+	if (count_refspec_match(ref, local_refs, &matched) != 1)
+		return ref;
+
+	if (remote->push) {
+		struct refspec query;
+		memset(&query, 0, sizeof(struct refspec));
+		query.src = matched->name;
+		if (!query_refspecs(remote->push, remote->push_refspec_nr, &query) &&
+		    query.dst) {
+			struct strbuf buf = STRBUF_INIT;
+			strbuf_addf(&buf, "%s%s:%s",
+				    query.force ? "+" : "",
+				    query.src, query.dst);
+			return strbuf_detach(&buf, NULL);
+		}
+	}
+
+	if (push_default == PUSH_DEFAULT_UPSTREAM &&
+	    !prefixcmp(matched->name, "refs/heads/")) {
+		struct branch *branch = branch_get(matched->name + 11);
+		if (branch->merge_nr == 1 && branch->merge[0]->src) {
+			struct strbuf buf = STRBUF_INIT;
+			strbuf_addf(&buf, "%s:%s",
+				    ref, branch->merge[0]->src);
+			return strbuf_detach(&buf, NULL);
+		}
+	}
+
+	return ref;
+}
+
+static void set_refspecs(const char **refs, int nr, const char *repo)
+{
+	struct remote *remote = NULL;
+	struct ref *local_refs = NULL;
 	int i;
+
 	for (i = 0; i < nr; i++) {
 		const char *ref = refs[i];
 		if (!strcmp("tag", ref)) {
-			char *tag;
-			int len;
+			struct strbuf tagref = STRBUF_INIT;
 			if (nr <= ++i)
 				die(_("tag shorthand without <tag>"));
-			len = strlen(refs[i]) + 11;
-			if (deleterefs) {
-				tag = xmalloc(len+1);
-				strcpy(tag, ":refs/tags/");
-			} else {
-				tag = xmalloc(len);
-				strcpy(tag, "refs/tags/");
+			ref = refs[i];
+			if (deleterefs)
+				strbuf_addf(&tagref, ":refs/tags/%s", ref);
+			else
+				strbuf_addf(&tagref, "refs/tags/%s", ref);
+			ref = strbuf_detach(&tagref, NULL);
+		} else if (deleterefs) {
+			struct strbuf delref = STRBUF_INIT;
+			if (strchr(ref, ':'))
+				die(_("--delete only accepts plain target ref names"));
+			strbuf_addf(&delref, ":%s", ref);
+			ref = strbuf_detach(&delref, NULL);
+		} else if (!strchr(ref, ':')) {
+			if (!remote) {
+				/* lazily grab remote and local_refs */
+				remote = remote_get(repo);
+				local_refs = get_local_heads();
 			}
-			strcat(tag, refs[i]);
-			ref = tag;
-		} else if (deleterefs && !strchr(ref, ':')) {
-			char *delref;
-			int len = strlen(ref)+1;
-			delref = xmalloc(len+1);
-			strcpy(delref, ":");
-			strcat(delref, ref);
-			ref = delref;
-		} else if (deleterefs)
-			die(_("--delete only accepts plain target ref names"));
+			ref = map_refspec(ref, remote, local_refs);
+		}
 		add_refspec(ref);
 	}
 }
@@ -172,6 +214,13 @@
    "\n"
    "  git config --global push.default simple\n"
    "\n"
+   "When push.default is set to 'matching', git will push local branches\n"
+   "to the remote branches that already exist with the same name.\n"
+   "\n"
+   "In Git 2.0, Git will default to the more conservative 'simple'\n"
+   "behavior, which only pushes the current branch to the corresponding\n"
+   "remote branch that 'git pull' uses to update the current branch.\n"
+   "\n"
    "See 'git help config' and search for 'push.default' for further information.\n"
    "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n"
    "'current' instead of 'simple' if you sometimes use older versions of Git)");
@@ -313,8 +362,14 @@
 	if (receivepack)
 		transport_set_option(transport,
 				     TRANS_OPT_RECEIVEPACK, receivepack);
-	if (thin)
-		transport_set_option(transport, TRANS_OPT_THIN, "yes");
+	transport_set_option(transport, TRANS_OPT_THIN, thin ? "yes" : NULL);
+
+	if (!is_empty_cas(&cas)) {
+		if (!transport->smart_options)
+			die("underlying transport does not support --%s option",
+			    CAS_OPT_NAME);
+		transport->smart_options->cas = &cas;
+	}
 
 	if (verbosity > 0)
 		fprintf(stderr, _("Pushing to %s\n"), transport->url);
@@ -446,15 +501,19 @@
 		OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
 		OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
 			    (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
-		OPT_BOOLEAN( 0, "delete", &deleterefs, N_("delete refs")),
-		OPT_BOOLEAN( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
+		OPT_BOOL( 0, "delete", &deleterefs, N_("delete refs")),
+		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
 		OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
 		OPT_BIT( 0,  "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
 		OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
+		{ OPTION_CALLBACK,
+		  0, CAS_OPT_NAME, &cas, N_("refname>:<expect"),
+		  N_("require old value of ref to be at this value"),
+		  PARSE_OPT_OPTARG, parseopt_push_cas_option },
 		{ OPTION_CALLBACK, 0, "recurse-submodules", &flags, N_("check"),
 			N_("control recursive pushing of submodules"),
 			PARSE_OPT_OPTARG, option_parse_recurse_submodules },
-		OPT_BOOLEAN( 0 , "thin", &thin, N_("use thin pack")),
+		OPT_BOOL( 0 , "thin", &thin, N_("use thin pack")),
 		OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
 		OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
 		OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
@@ -482,7 +541,7 @@
 
 	if (argc > 0) {
 		repo = argv[0];
-		set_refspecs(argv + 1, argc - 1);
+		set_refspecs(argv + 1, argc - 1, repo);
 	}
 
 	rc = do_push(repo, flags);
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index 0f5d7fe..0d7ef84 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -178,7 +178,7 @@
 
 	if (1 < opts.index_only + opts.update)
 		die("-u and -i at the same time makes no sense");
-	if ((opts.update||opts.index_only) && !opts.merge)
+	if ((opts.update || opts.index_only) && !opts.merge)
 		die("%s is meaningless without -m, --reset, or --prefix",
 		    opts.update ? "-u" : "-i");
 	if ((opts.dir && !opts.update))
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index e3eb5fc..85bba35 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -8,10 +8,12 @@
 #include "commit.h"
 #include "object.h"
 #include "remote.h"
+#include "connect.h"
 #include "transport.h"
 #include "string-list.h"
 #include "sha1-array.h"
 #include "connected.h"
+#include "argv-array.h"
 #include "version.h"
 
 static const char receive_pack_usage[] = "git receive-pack <git-dir>";
@@ -38,9 +40,12 @@
 static int prefer_ofs_delta = 1;
 static int auto_update_server_info;
 static int auto_gc = 1;
+static int fix_thin = 1;
 static const char *head_name;
 static void *head_name_to_free;
 static int sent_capabilities;
+static int shallow_update;
+static const char *alt_shallow_file;
 
 static enum deny_action parse_deny_action(const char *var, const char *value)
 {
@@ -119,6 +124,11 @@
 		return 0;
 	}
 
+	if (strcmp(var, "receive.shallowupdate") == 0) {
+		shallow_update = git_config_bool(var, value);
+		return 0;
+	}
+
 	return git_default_config(var, value, cb);
 }
 
@@ -176,6 +186,8 @@
 	if (!sent_capabilities)
 		show_ref("capabilities^{}", null_sha1);
 
+	advertise_shallow_grafts(1);
+
 	/* EOF */
 	packet_flush(1);
 }
@@ -185,6 +197,7 @@
 	const char *error_string;
 	unsigned int skip_update:1,
 		     did_not_exist:1;
+	int index;
 	unsigned char old_sha1[20];
 	unsigned char new_sha1[20];
 	char ref_name[FLEX_ARRAY]; /* more */
@@ -416,7 +429,46 @@
 		rp_error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
 }
 
-static const char *update(struct command *cmd)
+static int command_singleton_iterator(void *cb_data, unsigned char sha1[20]);
+static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
+{
+	static struct lock_file shallow_lock;
+	struct sha1_array extra = SHA1_ARRAY_INIT;
+	const char *alt_file;
+	uint32_t mask = 1 << (cmd->index % 32);
+	int i;
+
+	trace_printf_key("GIT_TRACE_SHALLOW",
+			 "shallow: update_shallow_ref %s\n", cmd->ref_name);
+	for (i = 0; i < si->shallow->nr; i++)
+		if (si->used_shallow[i] &&
+		    (si->used_shallow[i][cmd->index / 32] & mask) &&
+		    !delayed_reachability_test(si, i))
+			sha1_array_append(&extra, si->shallow->sha1[i]);
+
+	setup_alternate_shallow(&shallow_lock, &alt_file, &extra);
+	if (check_shallow_connected(command_singleton_iterator,
+				    0, cmd, alt_file)) {
+		rollback_lock_file(&shallow_lock);
+		sha1_array_clear(&extra);
+		return -1;
+	}
+
+	commit_lock_file(&shallow_lock);
+
+	/*
+	 * Make sure setup_alternate_shallow() for the next ref does
+	 * not lose these new roots..
+	 */
+	for (i = 0; i < extra.nr; i++)
+		register_shallow(extra.sha1[i]);
+
+	si->shallow_ref[cmd->index] = 0;
+	sha1_array_clear(&extra);
+	return 0;
+}
+
+static const char *update(struct command *cmd, struct shallow_info *si)
 {
 	const char *name = cmd->ref_name;
 	struct strbuf namespaced_name_buf = STRBUF_INIT;
@@ -426,7 +478,7 @@
 	struct ref_lock *lock;
 
 	/* only refs/... are allowed */
-	if (prefixcmp(name, "refs/") || check_refname_format(name + 5, 0)) {
+	if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) {
 		rp_error("refusing to create funny ref '%s' remotely", name);
 		return "funny refname";
 	}
@@ -457,7 +509,7 @@
 	}
 
 	if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
-		if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
+		if (deny_deletes && starts_with(name, "refs/heads/")) {
 			rp_error("denying ref deletion for %s", name);
 			return "deletion prohibited";
 		}
@@ -481,7 +533,7 @@
 
 	if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
 	    !is_null_sha1(old_sha1) &&
-	    !prefixcmp(name, "refs/heads/")) {
+	    starts_with(name, "refs/heads/")) {
 		struct object *old_object, *new_object;
 		struct commit *old_commit, *new_commit;
 
@@ -524,7 +576,12 @@
 		return NULL; /* good */
 	}
 	else {
-		lock = lock_any_ref_for_update(namespaced_name, old_sha1, 0);
+		if (shallow_update && si->shallow_ref[cmd->index] &&
+		    update_shallow_ref(cmd, si))
+			return "shallow error";
+
+		lock = lock_any_ref_for_update(namespaced_name, old_sha1,
+					       0, NULL);
 		if (!lock) {
 			rp_error("failed to lock %s", name);
 			return "failed to lock";
@@ -663,12 +720,16 @@
 	return 0;
 }
 
-static void set_connectivity_errors(struct command *commands)
+static void set_connectivity_errors(struct command *commands,
+				    struct shallow_info *si)
 {
 	struct command *cmd;
 
 	for (cmd = commands; cmd; cmd = cmd->next) {
 		struct command *singleton = cmd;
+		if (shallow_update && si->shallow_ref[cmd->index])
+			/* to be checked in update_shallow_ref() */
+			continue;
 		if (!check_everything_connected(command_singleton_iterator,
 						0, &singleton))
 			continue;
@@ -676,18 +737,26 @@
 	}
 }
 
+struct iterate_data {
+	struct command *cmds;
+	struct shallow_info *si;
+};
+
 static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
 {
-	struct command **cmd_list = cb_data;
+	struct iterate_data *data = cb_data;
+	struct command **cmd_list = &data->cmds;
 	struct command *cmd = *cmd_list;
 
-	while (cmd) {
-		if (!is_null_sha1(cmd->new_sha1)) {
+	for (; cmd; cmd = cmd->next) {
+		if (shallow_update && data->si->shallow_ref[cmd->index])
+			/* to be checked in update_shallow_ref() */
+			continue;
+		if (!is_null_sha1(cmd->new_sha1) && !cmd->skip_update) {
 			hashcpy(sha1, cmd->new_sha1);
 			*cmd_list = cmd->next;
 			return 0;
 		}
-		cmd = cmd->next;
 	}
 	*cmd_list = NULL;
 	return -1; /* end of list */
@@ -707,10 +776,14 @@
 	}
 }
 
-static void execute_commands(struct command *commands, const char *unpacker_error)
+static void execute_commands(struct command *commands,
+			     const char *unpacker_error,
+			     struct shallow_info *si)
 {
+	int checked_connectivity;
 	struct command *cmd;
 	unsigned char sha1[20];
+	struct iterate_data data;
 
 	if (unpacker_error) {
 		for (cmd = commands; cmd; cmd = cmd->next)
@@ -718,10 +791,10 @@
 		return;
 	}
 
-	cmd = commands;
-	if (check_everything_connected(iterate_receive_command_list,
-				       0, &cmd))
-		set_connectivity_errors(commands);
+	data.cmds = commands;
+	data.si = si;
+	if (check_everything_connected(iterate_receive_command_list, 0, &data))
+		set_connectivity_errors(commands, si);
 
 	reject_updates_to_hidden(commands);
 
@@ -738,6 +811,7 @@
 	free(head_name_to_free);
 	head_name = head_name_to_free = resolve_refdup("HEAD", sha1, 0, NULL);
 
+	checked_connectivity = 1;
 	for (cmd = commands; cmd; cmd = cmd->next) {
 		if (cmd->error_string)
 			continue;
@@ -745,11 +819,26 @@
 		if (cmd->skip_update)
 			continue;
 
-		cmd->error_string = update(cmd);
+		cmd->error_string = update(cmd, si);
+		if (shallow_update && !cmd->error_string &&
+		    si->shallow_ref[cmd->index]) {
+			error("BUG: connectivity check has not been run on ref %s",
+			      cmd->ref_name);
+			checked_connectivity = 0;
+		}
+	}
+
+	if (shallow_update) {
+		if (!checked_connectivity)
+			error("BUG: run 'git fsck' for safety.\n"
+			      "If there are errors, try to remove "
+			      "the reported refs above");
+		if (alt_shallow_file && *alt_shallow_file)
+			unlink(alt_shallow_file);
 	}
 }
 
-static struct command *read_head_info(void)
+static struct command *read_head_info(struct sha1_array *shallow)
 {
 	struct command *commands = NULL;
 	struct command **p = &commands;
@@ -763,6 +852,14 @@
 		line = packet_read_line(0, &len);
 		if (!line)
 			break;
+
+		if (len == 48 && starts_with(line, "shallow ")) {
+			if (get_sha1_hex(line + 8, old_sha1))
+				die("protocol error: expected shallow sha, got '%s'", line + 8);
+			sha1_array_append(shallow, old_sha1);
+			continue;
+		}
+
 		if (len < 83 ||
 		    line[40] != ' ' ||
 		    line[81] != ' ' ||
@@ -814,11 +911,14 @@
 
 static const char *pack_lockfile;
 
-static const char *unpack(int err_fd)
+static const char *unpack(int err_fd, struct shallow_info *si)
 {
 	struct pack_header hdr;
+	struct argv_array av = ARGV_ARRAY_INIT;
 	const char *hdr_err;
+	int status;
 	char hdr_arg[38];
+	struct child_process child;
 	int fsck_objects = (receive_fsck_objects >= 0
 			    ? receive_fsck_objects
 			    : transfer_fsck_objects >= 0
@@ -835,71 +935,63 @@
 			"--pack_header=%"PRIu32",%"PRIu32,
 			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
 
+	if (si->nr_ours || si->nr_theirs) {
+		alt_shallow_file = setup_temporary_shallow(si->shallow);
+		argv_array_pushl(&av, "--shallow-file", alt_shallow_file, NULL);
+	}
+
+	memset(&child, 0, sizeof(child));
 	if (ntohl(hdr.hdr_entries) < unpack_limit) {
-		int code, i = 0;
-		struct child_process child;
-		const char *unpacker[5];
-		unpacker[i++] = "unpack-objects";
+		argv_array_pushl(&av, "unpack-objects", hdr_arg, NULL);
 		if (quiet)
-			unpacker[i++] = "-q";
+			argv_array_push(&av, "-q");
 		if (fsck_objects)
-			unpacker[i++] = "--strict";
-		unpacker[i++] = hdr_arg;
-		unpacker[i++] = NULL;
-		memset(&child, 0, sizeof(child));
-		child.argv = unpacker;
+			argv_array_push(&av, "--strict");
+		child.argv = av.argv;
 		child.no_stdout = 1;
 		child.err = err_fd;
 		child.git_cmd = 1;
-		code = run_command(&child);
-		if (!code)
-			return NULL;
-		return "unpack-objects abnormal exit";
+		status = run_command(&child);
+		if (status)
+			return "unpack-objects abnormal exit";
 	} else {
-		const char *keeper[7];
-		int s, status, i = 0;
+		int s;
 		char keep_arg[256];
-		struct child_process ip;
 
 		s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
 		if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
 			strcpy(keep_arg + s, "localhost");
 
-		keeper[i++] = "index-pack";
-		keeper[i++] = "--stdin";
+		argv_array_pushl(&av, "index-pack",
+				 "--stdin", hdr_arg, keep_arg, NULL);
 		if (fsck_objects)
-			keeper[i++] = "--strict";
-		keeper[i++] = "--fix-thin";
-		keeper[i++] = hdr_arg;
-		keeper[i++] = keep_arg;
-		keeper[i++] = NULL;
-		memset(&ip, 0, sizeof(ip));
-		ip.argv = keeper;
-		ip.out = -1;
-		ip.err = err_fd;
-		ip.git_cmd = 1;
-		status = start_command(&ip);
-		if (status) {
+			argv_array_push(&av, "--strict");
+		if (fix_thin)
+			argv_array_push(&av, "--fix-thin");
+		child.argv = av.argv;
+		child.out = -1;
+		child.err = err_fd;
+		child.git_cmd = 1;
+		status = start_command(&child);
+		if (status)
 			return "index-pack fork failed";
-		}
-		pack_lockfile = index_pack_lockfile(ip.out);
-		close(ip.out);
-		status = finish_command(&ip);
-		if (!status) {
-			reprepare_packed_git();
-			return NULL;
-		}
-		return "index-pack abnormal exit";
+		pack_lockfile = index_pack_lockfile(child.out);
+		close(child.out);
+		status = finish_command(&child);
+		if (status)
+			return "index-pack abnormal exit";
+		reprepare_packed_git();
 	}
+	return NULL;
 }
 
-static const char *unpack_with_sideband(void)
+static const char *unpack_with_sideband(struct shallow_info *si)
 {
 	struct async muxer;
 	const char *ret;
 
 	if (!use_sideband)
-		return unpack(0);
+		return unpack(0, si);
 
 	memset(&muxer, 0, sizeof(muxer));
 	muxer.proc = copy_to_sideband;
@@ -907,12 +999,101 @@
 	if (start_async(&muxer))
 		return NULL;
 
-	ret = unpack(muxer.in);
+	ret = unpack(muxer.in, si);
 
 	finish_async(&muxer);
 	return ret;
 }
 
+static void prepare_shallow_update(struct command *commands,
+				   struct shallow_info *si)
+{
+	int i, j, k, bitmap_size = (si->ref->nr + 31) / 32;
+
+	si->used_shallow = xmalloc(sizeof(*si->used_shallow) *
+				   si->shallow->nr);
+	assign_shallow_commits_to_refs(si, si->used_shallow, NULL);
+
+	si->need_reachability_test =
+		xcalloc(si->shallow->nr, sizeof(*si->need_reachability_test));
+	si->reachable =
+		xcalloc(si->shallow->nr, sizeof(*si->reachable));
+	si->shallow_ref = xcalloc(si->ref->nr, sizeof(*si->shallow_ref));
+
+	for (i = 0; i < si->nr_ours; i++)
+		si->need_reachability_test[si->ours[i]] = 1;
+
+	for (i = 0; i < si->shallow->nr; i++) {
+		if (!si->used_shallow[i])
+			continue;
+		for (j = 0; j < bitmap_size; j++) {
+			if (!si->used_shallow[i][j])
+				continue;
+			si->need_reachability_test[i]++;
+			for (k = 0; k < 32; k++)
+				if (si->used_shallow[i][j] & (1 << k))
+					si->shallow_ref[j * 32 + k]++;
+		}
+
+		/*
+		 * true for those associated with some refs and belong
+		 * in "ours" list aka "step 7 not done yet"
+		 */
+		si->need_reachability_test[i] =
+			si->need_reachability_test[i] > 1;
+	}
+
+	/*
+	 * keep hooks happy by forcing a temporary shallow file via
+	 * env variable because we can't add --shallow-file to every
+	 * command. check_everything_connected() will be done with
+	 * true .git/shallow though.
+	 */
+	setenv(GIT_SHALLOW_FILE_ENVIRONMENT, alt_shallow_file, 1);
+}
+
+static void update_shallow_info(struct command *commands,
+				struct shallow_info *si,
+				struct sha1_array *ref)
+{
+	struct command *cmd;
+	int *ref_status;
+	remove_nonexistent_theirs_shallow(si);
+	if (!si->nr_ours && !si->nr_theirs) {
+		shallow_update = 0;
+		return;
+	}
+
+	for (cmd = commands; cmd; cmd = cmd->next) {
+		if (is_null_sha1(cmd->new_sha1))
+			continue;
+		sha1_array_append(ref, cmd->new_sha1);
+		cmd->index = ref->nr - 1;
+	}
+	si->ref = ref;
+
+	if (shallow_update) {
+		prepare_shallow_update(commands, si);
+		return;
+	}
+
+	ref_status = xmalloc(sizeof(*ref_status) * ref->nr);
+	assign_shallow_commits_to_refs(si, NULL, ref_status);
+	for (cmd = commands; cmd; cmd = cmd->next) {
+		if (is_null_sha1(cmd->new_sha1))
+			continue;
+		if (ref_status[cmd->index]) {
+			cmd->error_string = "shallow update not allowed";
+			cmd->skip_update = 1;
+		}
+	}
+	if (alt_shallow_file && *alt_shallow_file) {
+		unlink(alt_shallow_file);
+		alt_shallow_file = NULL;
+	}
+	free(ref_status);
+}
+
 static void report(struct command *commands, const char *unpack_status)
 {
 	struct command *cmd;
@@ -954,6 +1135,9 @@
 	int i;
 	char *dir = NULL;
 	struct command *commands;
+	struct sha1_array shallow = SHA1_ARRAY_INIT;
+	struct sha1_array ref = SHA1_ARRAY_INIT;
+	struct shallow_info si;
 
 	packet_trace_identity("receive-pack");
 
@@ -975,6 +1159,10 @@
 				stateless_rpc = 1;
 				continue;
 			}
+			if (!strcmp(arg, "--reject-thin-pack-for-testing")) {
+				fix_thin = 0;
+				continue;
+			}
 
 			usage(receive_pack_usage);
 		}
@@ -990,9 +1178,6 @@
 	if (!enter_repo(dir, 0))
 		die("'%s' does not appear to be a git repository", dir);
 
-	if (is_repository_shallow())
-		die("attempt to push into a shallow repository");
-
 	git_config(receive_pack_config, NULL);
 
 	if (0 <= transfer_unpack_limit)
@@ -1006,12 +1191,17 @@
 	if (advertise_refs)
 		return 0;
 
-	if ((commands = read_head_info()) != NULL) {
+	if ((commands = read_head_info(&shallow)) != NULL) {
 		const char *unpack_status = NULL;
 
-		if (!delete_only(commands))
-			unpack_status = unpack_with_sideband();
-		execute_commands(commands, unpack_status);
+		prepare_shallow_info(&si, &shallow);
+		if (!si.nr_ours && !si.nr_theirs)
+			shallow_update = 0;
+		if (!delete_only(commands)) {
+			unpack_status = unpack_with_sideband(&si);
+			update_shallow_info(commands, &si, &ref);
+		}
+		execute_commands(commands, unpack_status, &si);
 		if (pack_lockfile)
 			unlink_or_warn(pack_lockfile);
 		if (report_status)
@@ -1027,8 +1217,11 @@
 		}
 		if (auto_update_server_info)
 			update_server_info(0);
+		clear_shallow_info(&si);
 	}
 	if (use_sideband)
 		packet_flush(1);
+	sha1_array_clear(&shallow);
+	sha1_array_clear(&ref);
 	return 0;
 }
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 54184b3..852cff6 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -94,8 +94,7 @@
 			complete = 0;
 		}
 	}
-	free(tree->buffer);
-	tree->buffer = NULL;
+	free_tree_buffer(tree);
 
 	if (complete)
 		tree->object.flags |= SEEN;
@@ -366,7 +365,7 @@
 	 * we take the lock for the ref itself to prevent it from
 	 * getting updated.
 	 */
-	lock = lock_any_ref_for_update(ref, sha1, 0);
+	lock = lock_any_ref_for_update(ref, sha1, 0, NULL);
 	if (!lock)
 		return error("cannot lock ref '%s'", ref);
 	log_file = git_pathdup("logs/%s", ref);
@@ -611,12 +610,12 @@
 		const char *arg = argv[i];
 		if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
 			cb.dry_run = 1;
-		else if (!prefixcmp(arg, "--expire=")) {
+		else if (starts_with(arg, "--expire=")) {
 			if (parse_expiry_date(arg + 9, &cb.expire_total))
 				die(_("'%s' is not a valid timestamp"), arg);
 			explicit_expiry |= EXPIRE_TOTAL;
 		}
-		else if (!prefixcmp(arg, "--expire-unreachable=")) {
+		else if (starts_with(arg, "--expire-unreachable=")) {
 			if (parse_expiry_date(arg + 21, &cb.expire_unreachable))
 				die(_("'%s' is not a valid timestamp"), arg);
 			explicit_expiry |= EXPIRE_UNREACH;
diff --git a/builtin/remote.c b/builtin/remote.c
index 5e54d36..b3ab4cf 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -6,13 +6,14 @@
 #include "strbuf.h"
 #include "run-command.h"
 #include "refs.h"
+#include "argv-array.h"
 
 static const char * const builtin_remote_usage[] = {
 	N_("git remote [-v | --verbose]"),
 	N_("git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>"),
 	N_("git remote rename <old> <new>"),
 	N_("git remote remove <name>"),
-	N_("git remote set-head <name> (-a | -d | <branch>)"),
+	N_("git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"),
 	N_("git remote [-v | --verbose] show [-n] <name>"),
 	N_("git remote prune [-n | --dry-run] <name>"),
 	N_("git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"),
@@ -39,7 +40,7 @@
 };
 
 static const char * const builtin_remote_sethead_usage[] = {
-	N_("git remote set-head <name> (-a | -d | <branch>)"),
+	N_("git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"),
 	NULL
 };
 
@@ -77,17 +78,6 @@
 
 static int verbose;
 
-static int show_all(void);
-static int prune_remote(const char *remote, int dry_run);
-
-static inline int postfixcmp(const char *string, const char *postfix)
-{
-	int len1 = strlen(string), len2 = strlen(postfix);
-	if (len1 < len2)
-		return 1;
-	return strcmp(string + len1 - len2, postfix);
-}
-
 static int fetch_remote(const char *name)
 {
 	const char *argv[] = { "fetch", name, NULL, NULL };
@@ -160,7 +150,7 @@
 	int i;
 
 	struct option options[] = {
-		OPT_BOOLEAN('f', "fetch", &fetch, N_("fetch the remote branches")),
+		OPT_BOOL('f', "fetch", &fetch, N_("fetch the remote branches")),
 		OPT_SET_INT(0, "tags", &fetch_tags,
 			    N_("import all tags and associated objects when fetching"),
 			    TAGS_SET),
@@ -269,7 +259,7 @@
 
 static int config_read_branches(const char *key, const char *value, void *cb)
 {
-	if (!prefixcmp(key, "branch.")) {
+	if (starts_with(key, "branch.")) {
 		const char *orig_key = key;
 		char *name;
 		struct string_list_item *item;
@@ -277,13 +267,13 @@
 		enum { REMOTE, MERGE, REBASE } type;
 
 		key += 7;
-		if (!postfixcmp(key, ".remote")) {
+		if (ends_with(key, ".remote")) {
 			name = xstrndup(key, strlen(key) - 7);
 			type = REMOTE;
-		} else if (!postfixcmp(key, ".merge")) {
+		} else if (ends_with(key, ".merge")) {
 			name = xstrndup(key, strlen(key) - 6);
 			type = MERGE;
-		} else if (!postfixcmp(key, ".rebase")) {
+		} else if (ends_with(key, ".rebase")) {
 			name = xstrndup(key, strlen(key) - 7);
 			type = REBASE;
 		} else
@@ -309,8 +299,13 @@
 				space = strchr(value, ' ');
 			}
 			string_list_append(&info->merge, xstrdup(value));
-		} else
-			info->rebase = git_config_bool(orig_key, value);
+		} else {
+			int v = git_config_maybe_bool(orig_key, value);
+			if (v >= 0)
+				info->rebase = v;
+			else if (!strcmp(value, "preserve"))
+				info->rebase = 1;
+		}
 	}
 	return 0;
 }
@@ -534,9 +529,9 @@
 	}
 
 	/* don't delete non-remote-tracking refs */
-	if (prefixcmp(refname, "refs/remotes/")) {
+	if (!starts_with(refname, "refs/remotes/")) {
 		/* advise user how to delete local branches */
-		if (!prefixcmp(refname, "refs/heads/"))
+		if (starts_with(refname, "refs/heads/"))
 			string_list_append(branches->skipped,
 					   abbrev_branch(refname));
 		/* silently skip over other non-remote refs */
@@ -571,7 +566,7 @@
 	const char *symref;
 
 	strbuf_addf(&buf, "refs/remotes/%s/", rename->old);
-	if (!prefixcmp(refname, buf.buf)) {
+	if (starts_with(refname, buf.buf)) {
 		item = string_list_append(rename->remote_branches, xstrdup(refname));
 		symref = resolve_ref_unsafe(refname, orig_sha1, 1, &flag);
 		if (flag & REF_ISSYMREF)
@@ -1084,11 +1079,69 @@
 	return 0;
 }
 
+static int get_one_entry(struct remote *remote, void *priv)
+{
+	struct string_list *list = priv;
+	struct strbuf url_buf = STRBUF_INIT;
+	const char **url;
+	int i, url_nr;
+
+	if (remote->url_nr > 0) {
+		strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]);
+		string_list_append(list, remote->name)->util =
+				strbuf_detach(&url_buf, NULL);
+	} else
+		string_list_append(list, remote->name)->util = NULL;
+	if (remote->pushurl_nr) {
+		url = remote->pushurl;
+		url_nr = remote->pushurl_nr;
+	} else {
+		url = remote->url;
+		url_nr = remote->url_nr;
+	}
+	for (i = 0; i < url_nr; i++)
+	{
+		strbuf_addf(&url_buf, "%s (push)", url[i]);
+		string_list_append(list, remote->name)->util =
+				strbuf_detach(&url_buf, NULL);
+	}
+
+	return 0;
+}
+
+static int show_all(void)
+{
+	struct string_list list = STRING_LIST_INIT_NODUP;
+	int result;
+
+	list.strdup_strings = 1;
+	result = for_each_remote(get_one_entry, &list);
+
+	if (!result) {
+		int i;
+
+		sort_string_list(&list);
+		for (i = 0; i < list.nr; i++) {
+			struct string_list_item *item = list.items + i;
+			if (verbose)
+				printf("%s\t%s\n", item->string,
+					item->util ? (const char *)item->util : "");
+			else {
+				if (i && !strcmp((item - 1)->string, item->string))
+					continue;
+				printf("%s\n", item->string);
+			}
+		}
+	}
+	string_list_clear(&list, 1);
+	return result;
+}
+
 static int show(int argc, const char **argv)
 {
 	int no_query = 0, result = 0, query_flag = 0;
 	struct option options[] = {
-		OPT_BOOLEAN('n', NULL, &no_query, N_("do not query remotes")),
+		OPT_BOOL('n', NULL, &no_query, N_("do not query remotes")),
 		OPT_END()
 	};
 	struct ref_states states;
@@ -1195,10 +1248,10 @@
 	char *head_name = NULL;
 
 	struct option options[] = {
-		OPT_BOOLEAN('a', "auto", &opt_a,
-			    N_("set refs/remotes/<name>/HEAD according to remote")),
-		OPT_BOOLEAN('d', "delete", &opt_d,
-			    N_("delete refs/remotes/<name>/HEAD")),
+		OPT_BOOL('a', "auto", &opt_a,
+			 N_("set refs/remotes/<name>/HEAD according to remote")),
+		OPT_BOOL('d', "delete", &opt_d,
+			 N_("delete refs/remotes/<name>/HEAD")),
 		OPT_END()
 	};
 	argc = parse_options(argc, argv, NULL, options, builtin_remote_sethead_usage,
@@ -1246,26 +1299,6 @@
 	return result;
 }
 
-static int prune(int argc, const char **argv)
-{
-	int dry_run = 0, result = 0;
-	struct option options[] = {
-		OPT__DRY_RUN(&dry_run, N_("dry run")),
-		OPT_END()
-	};
-
-	argc = parse_options(argc, argv, NULL, options, builtin_remote_prune_usage,
-			     0);
-
-	if (argc < 1)
-		usage_with_options(builtin_remote_prune_usage, options);
-
-	for (; argc; argc--, argv++)
-		result |= prune_remote(*argv, dry_run);
-
-	return result;
-}
-
 static int prune_remote(const char *remote, int dry_run)
 {
 	int result = 0, i;
@@ -1304,6 +1337,26 @@
 	return result;
 }
 
+static int prune(int argc, const char **argv)
+{
+	int dry_run = 0, result = 0;
+	struct option options[] = {
+		OPT__DRY_RUN(&dry_run, N_("dry run")),
+		OPT_END()
+	};
+
+	argc = parse_options(argc, argv, NULL, options, builtin_remote_prune_usage,
+			     0);
+
+	if (argc < 1)
+		usage_with_options(builtin_remote_prune_usage, options);
+
+	for (; argc; argc--, argv++)
+		result |= prune_remote(*argv, dry_run);
+
+	return result;
+}
+
 static int get_remote_default(const char *key, const char *value, void *priv)
 {
 	if (strcmp(key, "remotes.default") == 0) {
@@ -1315,42 +1368,42 @@
 
 static int update(int argc, const char **argv)
 {
-	int i, prune = 0;
+	int i, prune = -1;
 	struct option options[] = {
-		OPT_BOOLEAN('p', "prune", &prune,
-			    N_("prune remotes after fetching")),
+		OPT_BOOL('p', "prune", &prune,
+			 N_("prune remotes after fetching")),
 		OPT_END()
 	};
-	const char **fetch_argv;
-	int fetch_argc = 0;
+	struct argv_array fetch_argv = ARGV_ARRAY_INIT;
 	int default_defined = 0;
-
-	fetch_argv = xmalloc(sizeof(char *) * (argc+5));
+	int retval;
 
 	argc = parse_options(argc, argv, NULL, options, builtin_remote_update_usage,
 			     PARSE_OPT_KEEP_ARGV0);
 
-	fetch_argv[fetch_argc++] = "fetch";
+	argv_array_push(&fetch_argv, "fetch");
 
-	if (prune)
-		fetch_argv[fetch_argc++] = "--prune";
+	if (prune != -1)
+		argv_array_push(&fetch_argv, prune ? "--prune" : "--no-prune");
 	if (verbose)
-		fetch_argv[fetch_argc++] = "-v";
-	fetch_argv[fetch_argc++] = "--multiple";
+		argv_array_push(&fetch_argv, "-v");
+	argv_array_push(&fetch_argv, "--multiple");
 	if (argc < 2)
-		fetch_argv[fetch_argc++] = "default";
+		argv_array_push(&fetch_argv, "default");
 	for (i = 1; i < argc; i++)
-		fetch_argv[fetch_argc++] = argv[i];
+		argv_array_push(&fetch_argv, argv[i]);
 
-	if (strcmp(fetch_argv[fetch_argc-1], "default") == 0) {
+	if (strcmp(fetch_argv.argv[fetch_argv.argc-1], "default") == 0) {
 		git_config(get_remote_default, &default_defined);
-		if (!default_defined)
-			fetch_argv[fetch_argc-1] = "--all";
+		if (!default_defined) {
+			argv_array_pop(&fetch_argv);
+			argv_array_push(&fetch_argv, "--all");
+		}
 	}
 
-	fetch_argv[fetch_argc] = NULL;
-
-	return run_command_v_opt(fetch_argv, RUN_GIT_CMD);
+	retval = run_command_v_opt(fetch_argv.argv, RUN_GIT_CMD);
+	argv_array_clear(&fetch_argv);
+	return retval;
 }
 
 static int remove_all_fetch_refspecs(const char *remote, const char *key)
@@ -1404,7 +1457,7 @@
 {
 	int add_mode = 0;
 	struct option options[] = {
-		OPT_BOOLEAN('\0', "add", &add_mode, N_("add branch")),
+		OPT_BOOL('\0', "add", &add_mode, N_("add branch")),
 		OPT_END()
 	};
 
@@ -1432,11 +1485,11 @@
 	int urlset_nr;
 	struct strbuf name_buf = STRBUF_INIT;
 	struct option options[] = {
-		OPT_BOOLEAN('\0', "push", &push_mode,
-			    N_("manipulate push URLs")),
-		OPT_BOOLEAN('\0', "add", &add_mode,
-			    N_("add URL")),
-		OPT_BOOLEAN('\0', "delete", &delete_mode,
+		OPT_BOOL('\0', "push", &push_mode,
+			 N_("manipulate push URLs")),
+		OPT_BOOL('\0', "add", &add_mode,
+			 N_("add URL")),
+		OPT_BOOL('\0', "delete", &delete_mode,
 			    N_("delete URLs")),
 		OPT_END()
 	};
@@ -1505,64 +1558,6 @@
 	return 0;
 }
 
-static int get_one_entry(struct remote *remote, void *priv)
-{
-	struct string_list *list = priv;
-	struct strbuf url_buf = STRBUF_INIT;
-	const char **url;
-	int i, url_nr;
-
-	if (remote->url_nr > 0) {
-		strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]);
-		string_list_append(list, remote->name)->util =
-				strbuf_detach(&url_buf, NULL);
-	} else
-		string_list_append(list, remote->name)->util = NULL;
-	if (remote->pushurl_nr) {
-		url = remote->pushurl;
-		url_nr = remote->pushurl_nr;
-	} else {
-		url = remote->url;
-		url_nr = remote->url_nr;
-	}
-	for (i = 0; i < url_nr; i++)
-	{
-		strbuf_addf(&url_buf, "%s (push)", url[i]);
-		string_list_append(list, remote->name)->util =
-				strbuf_detach(&url_buf, NULL);
-	}
-
-	return 0;
-}
-
-static int show_all(void)
-{
-	struct string_list list = STRING_LIST_INIT_NODUP;
-	int result;
-
-	list.strdup_strings = 1;
-	result = for_each_remote(get_one_entry, &list);
-
-	if (!result) {
-		int i;
-
-		sort_string_list(&list);
-		for (i = 0; i < list.nr; i++) {
-			struct string_list_item *item = list.items + i;
-			if (verbose)
-				printf("%s\t%s\n", item->string,
-					item->util ? (const char *)item->util : "");
-			else {
-				if (i && !strcmp((item - 1)->string, item->string))
-					continue;
-				printf("%s\n", item->string);
-			}
-		}
-	}
-	string_list_clear(&list, 1);
-	return result;
-}
-
 int cmd_remote(int argc, const char **argv, const char *prefix)
 {
 	struct option options[] = {
diff --git a/builtin/repack.c b/builtin/repack.c
new file mode 100644
index 0000000..6284846
--- /dev/null
+++ b/builtin/repack.c
@@ -0,0 +1,386 @@
+#include "builtin.h"
+#include "cache.h"
+#include "dir.h"
+#include "parse-options.h"
+#include "run-command.h"
+#include "sigchain.h"
+#include "strbuf.h"
+#include "string-list.h"
+#include "argv-array.h"
+
+static int delta_base_offset = 1;
+static char *packdir, *packtmp;
+
+static const char *const git_repack_usage[] = {
+	N_("git repack [options]"),
+	NULL
+};
+
+static int repack_config(const char *var, const char *value, void *cb)
+{
+	if (!strcmp(var, "repack.usedeltabaseoffset")) {
+		delta_base_offset = git_config_bool(var, value);
+		return 0;
+	}
+	return git_default_config(var, value, cb);
+}
+
+/*
+ * Remove temporary $GIT_OBJECT_DIRECTORY/pack/.tmp-$$-pack-* files.
+ */
+static void remove_temporary_files(void)
+{
+	struct strbuf buf = STRBUF_INIT;
+	size_t dirlen, prefixlen;
+	DIR *dir;
+	struct dirent *e;
+
+	dir = opendir(packdir);
+	if (!dir)
+		return;
+
+	/* Point at the slash at the end of ".../objects/pack/" */
+	dirlen = strlen(packdir) + 1;
+	strbuf_addstr(&buf, packtmp);
+	/* Hold the length of  ".tmp-%d-pack-" */
+	prefixlen = buf.len - dirlen;
+
+	while ((e = readdir(dir))) {
+		if (strncmp(e->d_name, buf.buf + dirlen, prefixlen))
+			continue;
+		strbuf_setlen(&buf, dirlen);
+		strbuf_addstr(&buf, e->d_name);
+		unlink(buf.buf);
+	}
+	closedir(dir);
+	strbuf_release(&buf);
+}
+
+static void remove_pack_on_signal(int signo)
+{
+	remove_temporary_files();
+	sigchain_pop(signo);
+	raise(signo);
+}
+
+/*
+ * Adds all packs hex strings to the fname list, which do not
+ * have a corresponding .keep file.
+ */
+static void get_non_kept_pack_filenames(struct string_list *fname_list)
+{
+	DIR *dir;
+	struct dirent *e;
+	char *fname;
+	size_t len;
+
+	if (!(dir = opendir(packdir)))
+		return;
+
+	while ((e = readdir(dir)) != NULL) {
+		if (!ends_with(e->d_name, ".pack"))
+			continue;
+
+		len = strlen(e->d_name) - strlen(".pack");
+		fname = xmemdupz(e->d_name, len);
+
+		if (!file_exists(mkpath("%s/%s.keep", packdir, fname)))
+			string_list_append_nodup(fname_list, fname);
+		else
+			free(fname);
+	}
+	closedir(dir);
+}
+
+static void remove_redundant_pack(const char *dir_name, const char *base_name)
+{
+	const char *exts[] = {".pack", ".idx", ".keep"};
+	int i;
+	struct strbuf buf = STRBUF_INIT;
+	size_t plen;
+
+	strbuf_addf(&buf, "%s/%s", dir_name, base_name);
+	plen = buf.len;
+
+	for (i = 0; i < ARRAY_SIZE(exts); i++) {
+		strbuf_setlen(&buf, plen);
+		strbuf_addstr(&buf, exts[i]);
+		unlink(buf.buf);
+	}
+	strbuf_release(&buf);
+}
+
+#define ALL_INTO_ONE 1
+#define LOOSEN_UNREACHABLE 2
+
+int cmd_repack(int argc, const char **argv, const char *prefix)
+{
+	const char *exts[2] = {".pack", ".idx"};
+	struct child_process cmd;
+	struct string_list_item *item;
+	struct argv_array cmd_args = ARGV_ARRAY_INIT;
+	struct string_list names = STRING_LIST_INIT_DUP;
+	struct string_list rollback = STRING_LIST_INIT_NODUP;
+	struct string_list existing_packs = STRING_LIST_INIT_DUP;
+	struct strbuf line = STRBUF_INIT;
+	int ext, ret, failed;
+	FILE *out;
+
+	/* variables to be filled by option parsing */
+	int pack_everything = 0;
+	int delete_redundant = 0;
+	const char *unpack_unreachable = NULL;
+	const char *window = NULL, *window_memory = NULL;
+	const char *depth = NULL;
+	const char *max_pack_size = NULL;
+	int no_reuse_delta = 0, no_reuse_object = 0;
+	int no_update_server_info = 0;
+	int quiet = 0;
+	int local = 0;
+
+	struct option builtin_repack_options[] = {
+		OPT_BIT('a', NULL, &pack_everything,
+				N_("pack everything in a single pack"), ALL_INTO_ONE),
+		OPT_BIT('A', NULL, &pack_everything,
+				N_("same as -a, and turn unreachable objects loose"),
+				   LOOSEN_UNREACHABLE | ALL_INTO_ONE),
+		OPT_BOOL('d', NULL, &delete_redundant,
+				N_("remove redundant packs, and run git-prune-packed")),
+		OPT_BOOL('f', NULL, &no_reuse_delta,
+				N_("pass --no-reuse-delta to git-pack-objects")),
+		OPT_BOOL('F', NULL, &no_reuse_object,
+				N_("pass --no-reuse-object to git-pack-objects")),
+		OPT_BOOL('n', NULL, &no_update_server_info,
+				N_("do not run git-update-server-info")),
+		OPT__QUIET(&quiet, N_("be quiet")),
+		OPT_BOOL('l', "local", &local,
+				N_("pass --local to git-pack-objects")),
+		OPT_STRING(0, "unpack-unreachable", &unpack_unreachable, N_("approxidate"),
+				N_("with -A, do not loosen objects older than this")),
+		OPT_STRING(0, "window", &window, N_("n"),
+				N_("size of the window used for delta compression")),
+		OPT_STRING(0, "window-memory", &window_memory, N_("bytes"),
+				N_("same as the above, but limit memory size instead of entries count")),
+		OPT_STRING(0, "depth", &depth, N_("n"),
+				N_("limits the maximum delta depth")),
+		OPT_STRING(0, "max-pack-size", &max_pack_size, N_("bytes"),
+				N_("maximum size of each packfile")),
+		OPT_END()
+	};
+
+	git_config(repack_config, NULL);
+
+	argc = parse_options(argc, argv, prefix, builtin_repack_options,
+				git_repack_usage, 0);
+
+	packdir = mkpathdup("%s/pack", get_object_directory());
+	packtmp = mkpathdup("%s/.tmp-%d-pack", packdir, (int)getpid());
+
+	sigchain_push_common(remove_pack_on_signal);
+
+	argv_array_push(&cmd_args, "pack-objects");
+	argv_array_push(&cmd_args, "--keep-true-parents");
+	argv_array_push(&cmd_args, "--honor-pack-keep");
+	argv_array_push(&cmd_args, "--non-empty");
+	argv_array_push(&cmd_args, "--all");
+	argv_array_push(&cmd_args, "--reflog");
+	if (window)
+		argv_array_pushf(&cmd_args, "--window=%s", window);
+	if (window_memory)
+		argv_array_pushf(&cmd_args, "--window-memory=%s", window_memory);
+	if (depth)
+		argv_array_pushf(&cmd_args, "--depth=%s", depth);
+	if (max_pack_size)
+		argv_array_pushf(&cmd_args, "--max-pack-size=%s", max_pack_size);
+	if (no_reuse_delta)
+		argv_array_pushf(&cmd_args, "--no-reuse-delta");
+	if (no_reuse_object)
+		argv_array_pushf(&cmd_args, "--no-reuse-object");
+
+	if (pack_everything & ALL_INTO_ONE) {
+		get_non_kept_pack_filenames(&existing_packs);
+
+		if (existing_packs.nr && delete_redundant) {
+			if (unpack_unreachable)
+				argv_array_pushf(&cmd_args,
+						"--unpack-unreachable=%s",
+						unpack_unreachable);
+			else if (pack_everything & LOOSEN_UNREACHABLE)
+				argv_array_push(&cmd_args,
+						"--unpack-unreachable");
+		}
+	} else {
+		argv_array_push(&cmd_args, "--unpacked");
+		argv_array_push(&cmd_args, "--incremental");
+	}
+
+	if (local)
+		argv_array_push(&cmd_args,  "--local");
+	if (quiet)
+		argv_array_push(&cmd_args,  "--quiet");
+	if (delta_base_offset)
+		argv_array_push(&cmd_args,  "--delta-base-offset");
+
+	argv_array_push(&cmd_args, packtmp);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.argv = cmd_args.argv;
+	cmd.git_cmd = 1;
+	cmd.out = -1;
+	cmd.no_stdin = 1;
+
+	ret = start_command(&cmd);
+	if (ret)
+		return ret;
+
+	out = xfdopen(cmd.out, "r");
+	while (strbuf_getline(&line, out, '\n') != EOF) {
+		if (line.len != 40)
+			die("repack: Expecting 40 character sha1 lines only from pack-objects.");
+		string_list_append(&names, line.buf);
+	}
+	fclose(out);
+	ret = finish_command(&cmd);
+	if (ret)
+		return ret;
+	argv_array_clear(&cmd_args);
+
+	if (!names.nr && !quiet)
+		printf("Nothing new to pack.\n");
+
+	/*
+	 * Ok we have prepared all new packfiles.
+	 * First see if there are packs of the same name and if so
+	 * if we can move them out of the way (this can happen if we
+	 * repacked immediately after packing fully.
+	 */
+	failed = 0;
+	for_each_string_list_item(item, &names) {
+		for (ext = 0; ext < 2; ext++) {
+			char *fname, *fname_old;
+			fname = mkpathdup("%s/%s%s", packdir,
+						item->string, exts[ext]);
+			if (!file_exists(fname)) {
+				free(fname);
+				continue;
+			}
+
+			fname_old = mkpath("%s/old-%s%s", packdir,
+						item->string, exts[ext]);
+			if (file_exists(fname_old))
+				if (unlink(fname_old))
+					failed = 1;
+
+			if (!failed && rename(fname, fname_old)) {
+				free(fname);
+				failed = 1;
+				break;
+			} else {
+				string_list_append(&rollback, fname);
+			}
+		}
+		if (failed)
+			break;
+	}
+	if (failed) {
+		struct string_list rollback_failure = STRING_LIST_INIT_DUP;
+		for_each_string_list_item(item, &rollback) {
+			char *fname, *fname_old;
+			fname = mkpathdup("%s/%s", packdir, item->string);
+			fname_old = mkpath("%s/old-%s", packdir, item->string);
+			if (rename(fname_old, fname))
+				string_list_append(&rollback_failure, fname);
+			free(fname);
+		}
+
+		if (rollback_failure.nr) {
+			int i;
+			fprintf(stderr,
+				"WARNING: Some packs in use have been renamed by\n"
+				"WARNING: prefixing old- to their name, in order to\n"
+				"WARNING: replace them with the new version of the\n"
+				"WARNING: file.  But the operation failed, and the\n"
+				"WARNING: attempt to rename them back to their\n"
+				"WARNING: original names also failed.\n"
+				"WARNING: Please rename them in %s manually:\n", packdir);
+			for (i = 0; i < rollback_failure.nr; i++)
+				fprintf(stderr, "WARNING:   old-%s -> %s\n",
+					rollback_failure.items[i].string,
+					rollback_failure.items[i].string);
+		}
+		exit(1);
+	}
+
+	/* Now the ones with the same name are out of the way... */
+	for_each_string_list_item(item, &names) {
+		for (ext = 0; ext < 2; ext++) {
+			char *fname, *fname_old;
+			struct stat statbuffer;
+			fname = mkpathdup("%s/pack-%s%s",
+					packdir, item->string, exts[ext]);
+			fname_old = mkpathdup("%s-%s%s",
+					packtmp, item->string, exts[ext]);
+			if (!stat(fname_old, &statbuffer)) {
+				statbuffer.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+				chmod(fname_old, statbuffer.st_mode);
+			}
+			if (rename(fname_old, fname))
+				die_errno(_("renaming '%s' failed"), fname_old);
+			free(fname);
+			free(fname_old);
+		}
+	}
+
+	/* Remove the "old-" files */
+	for_each_string_list_item(item, &names) {
+		for (ext = 0; ext < 2; ext++) {
+			char *fname;
+			fname = mkpath("%s/old-pack-%s%s",
+					packdir,
+					item->string,
+					exts[ext]);
+			if (remove_path(fname))
+				warning(_("removing '%s' failed"), fname);
+		}
+	}
+
+	/* End of pack replacement. */
+
+	if (delete_redundant) {
+		sort_string_list(&names);
+		for_each_string_list_item(item, &existing_packs) {
+			char *sha1;
+			size_t len = strlen(item->string);
+			if (len < 40)
+				continue;
+			sha1 = item->string + len - 40;
+			if (!string_list_has_string(&names, sha1))
+				remove_redundant_pack(packdir, item->string);
+		}
+		argv_array_push(&cmd_args, "prune-packed");
+		if (quiet)
+			argv_array_push(&cmd_args, "--quiet");
+
+		memset(&cmd, 0, sizeof(cmd));
+		cmd.argv = cmd_args.argv;
+		cmd.git_cmd = 1;
+		run_command(&cmd);
+		argv_array_clear(&cmd_args);
+	}
+
+	if (!no_update_server_info) {
+		argv_array_push(&cmd_args, "update-server-info");
+		memset(&cmd, 0, sizeof(cmd));
+		cmd.argv = cmd_args.argv;
+		cmd.git_cmd = 1;
+		run_command(&cmd);
+		argv_array_clear(&cmd_args);
+	}
+	remove_temporary_files();
+	string_list_clear(&names, 0);
+	string_list_clear(&rollback, 0);
+	string_list_clear(&existing_packs, 0);
+	strbuf_release(&line);
+
+	return 0;
+}
diff --git a/builtin/replace.c b/builtin/replace.c
index 59d3115..2336325 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -16,27 +16,69 @@
 static const char * const git_replace_usage[] = {
 	N_("git replace [-f] <object> <replacement>"),
 	N_("git replace -d <object>..."),
-	N_("git replace -l [<pattern>]"),
+	N_("git replace [--format=<format>] [-l [<pattern>]]"),
 	NULL
 };
 
+enum replace_format {
+      REPLACE_FORMAT_SHORT,
+      REPLACE_FORMAT_MEDIUM,
+      REPLACE_FORMAT_LONG
+};
+
+struct show_data {
+	const char *pattern;
+	enum replace_format format;
+};
+
 static int show_reference(const char *refname, const unsigned char *sha1,
 			  int flag, void *cb_data)
 {
-	const char *pattern = cb_data;
+	struct show_data *data = cb_data;
 
-	if (!fnmatch(pattern, refname, 0))
-		printf("%s\n", refname);
+	if (!fnmatch(data->pattern, refname, 0)) {
+		if (data->format == REPLACE_FORMAT_SHORT)
+			printf("%s\n", refname);
+		else if (data->format == REPLACE_FORMAT_MEDIUM)
+			printf("%s -> %s\n", refname, sha1_to_hex(sha1));
+		else { /* data->format == REPLACE_FORMAT_LONG */
+			unsigned char object[20];
+			enum object_type obj_type, repl_type;
+
+			if (get_sha1(refname, object))
+				return error("Failed to resolve '%s' as a valid ref.", refname);
+
+			obj_type = sha1_object_info(object, NULL);
+			repl_type = sha1_object_info(sha1, NULL);
+
+			printf("%s (%s) -> %s (%s)\n", refname, typename(obj_type),
+			       sha1_to_hex(sha1), typename(repl_type));
+		}
+	}
 
 	return 0;
 }
 
-static int list_replace_refs(const char *pattern)
+static int list_replace_refs(const char *pattern, const char *format)
 {
+	struct show_data data;
+
 	if (pattern == NULL)
 		pattern = "*";
+	data.pattern = pattern;
 
-	for_each_replace_ref(show_reference, (void *) pattern);
+	if (format == NULL || *format == '\0' || !strcmp(format, "short"))
+		data.format = REPLACE_FORMAT_SHORT;
+	else if (!strcmp(format, "medium"))
+		data.format = REPLACE_FORMAT_MEDIUM;
+	else if (!strcmp(format, "long"))
+		data.format = REPLACE_FORMAT_LONG;
+	else
+		die("invalid replace format '%s'\n"
+		    "valid formats are 'short', 'medium' and 'long'\n",
+		    format);
+
+	for_each_replace_ref(show_reference, (void *) &data);
 
 	return 0;
 }
@@ -85,6 +127,7 @@
 			  int force)
 {
 	unsigned char object[20], prev[20], repl[20];
+	enum object_type obj_type, repl_type;
 	char ref[PATH_MAX];
 	struct ref_lock *lock;
 
@@ -100,12 +143,21 @@
 	if (check_refname_format(ref, 0))
 		die("'%s' is not a valid ref name.", ref);
 
+	obj_type = sha1_object_info(object, NULL);
+	repl_type = sha1_object_info(repl, NULL);
+	if (!force && obj_type != repl_type)
+		die("Objects must be of the same type.\n"
+		    "'%s' points to a replaced object of type '%s'\n"
+		    "while '%s' points to a replacement object of type '%s'.",
+		    object_ref, typename(obj_type),
+		    replace_ref, typename(repl_type));
+
 	if (read_ref(ref, prev))
 		hashclr(prev);
 	else if (!force)
 		die("replace ref '%s' already exists", ref);
 
-	lock = lock_any_ref_for_update(ref, prev, 0);
+	lock = lock_any_ref_for_update(ref, prev, 0, NULL);
 	if (!lock)
 		die("%s: cannot lock the ref", ref);
 	if (write_ref_sha1(lock, repl, NULL) < 0)
@@ -117,19 +169,27 @@
 int cmd_replace(int argc, const char **argv, const char *prefix)
 {
 	int list = 0, delete = 0, force = 0;
+	const char *format = NULL;
 	struct option options[] = {
-		OPT_BOOLEAN('l', NULL, &list, N_("list replace refs")),
-		OPT_BOOLEAN('d', NULL, &delete, N_("delete replace refs")),
-		OPT_BOOLEAN('f', NULL, &force, N_("replace the ref if it exists")),
+		OPT_BOOL('l', "list", &list, N_("list replace refs")),
+		OPT_BOOL('d', "delete", &delete, N_("delete replace refs")),
+		OPT_BOOL('f', "force", &force, N_("replace the ref if it exists")),
+		OPT_STRING(0, "format", &format, N_("format"), N_("use this format")),
 		OPT_END()
 	};
 
+	read_replace_refs = 0;
+
 	argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0);
 
 	if (list && delete)
 		usage_msg_opt("-l and -d cannot be used together",
 			      git_replace_usage, options);
 
+	if (format && delete)
+		usage_msg_opt("--format and -d cannot be used together",
+			      git_replace_usage, options);
+
 	if (force && (list || delete))
 		usage_msg_opt("-f cannot be used with -d or -l",
 			      git_replace_usage, options);
@@ -147,6 +207,9 @@
 		if (argc != 2)
 			usage_msg_opt("bad number of arguments",
 				      git_replace_usage, options);
+		if (format)
+			usage_msg_opt("--format cannot be used when not listing",
+				      git_replace_usage, options);
 		return replace_object(argv[0], argv[1], force);
 	}
 
@@ -158,5 +221,5 @@
 		usage_msg_opt("-f needs some arguments",
 			      git_replace_usage, options);
 
-	return list_replace_refs(argv[0]);
+	return list_replace_refs(argv[0], format);
 }
diff --git a/builtin/rerere.c b/builtin/rerere.c
index dc1708e..4e51add 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -6,6 +6,7 @@
 #include "rerere.h"
 #include "xdiff/xdiff.h"
 #include "xdiff-interface.h"
+#include "pathspec.h"
 
 static const char * const rerere_usage[] = {
 	N_("git rerere [clear | forget path... | status | remaining | diff | gc]"),
@@ -68,11 +69,12 @@
 		return rerere(flags);
 
 	if (!strcmp(argv[0], "forget")) {
-		const char **pathspec;
+		struct pathspec pathspec;
 		if (argc < 2)
 			warning("'git rerere forget' without paths is deprecated");
-		pathspec = get_pathspec(prefix, argv + 1);
-		return rerere_forget(pathspec);
+		parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD,
+			       prefix, argv + 1);
+		return rerere_forget(&pathspec);
 	}
 
 	fd = setup_rerere(&merge_rr, flags);
diff --git a/builtin/reset.c b/builtin/reset.c
index afa6e02..6004803 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -133,21 +133,21 @@
 	}
 }
 
-static int read_from_tree(const char **pathspec, unsigned char *tree_sha1)
+static int read_from_tree(const struct pathspec *pathspec,
+			  unsigned char *tree_sha1)
 {
 	struct diff_options opt;
 
 	memset(&opt, 0, sizeof(opt));
-	diff_tree_setup_paths(pathspec, &opt);
+	copy_pathspec(&opt.pathspec, pathspec);
 	opt.output_format = DIFF_FORMAT_CALLBACK;
 	opt.format_callback = update_index_from_diff;
 
-	read_cache();
 	if (do_diff_cache(tree_sha1, &opt))
 		return 1;
 	diffcore_std(&opt);
 	diff_flush(&opt);
-	diff_tree_release_paths(&opt);
+	free_pathspec(&opt.pathspec);
 
 	return 0;
 }
@@ -168,13 +168,16 @@
 
 static void die_if_unmerged_cache(int reset_type)
 {
-	if (is_merge() || read_cache() < 0 || unmerged_cache())
+	if (is_merge() || unmerged_cache())
 		die(_("Cannot do a %s reset in the middle of a merge."),
 		    _(reset_type_names[reset_type]));
 
 }
 
-static const char **parse_args(const char **argv, const char *prefix, const char **rev_ret)
+static void parse_args(struct pathspec *pathspec,
+		       const char **argv, const char *prefix,
+		       int patch_mode,
+		       const char **rev_ret)
 {
 	const char *rev = "HEAD";
 	unsigned char unused[20];
@@ -216,10 +219,18 @@
 		}
 	}
 	*rev_ret = rev;
-	return argv[0] ? get_pathspec(prefix, argv) : NULL;
+
+	if (read_cache() < 0)
+		die(_("index file corrupt"));
+
+	parse_pathspec(pathspec, 0,
+		       PATHSPEC_PREFER_FULL |
+		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP |
+		       (patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0),
+		       prefix, argv);
 }
 
-static int update_refs(const char *rev, const unsigned char *sha1)
+static int reset_refs(const char *rev, const unsigned char *sha1)
 {
 	int update_ref_status;
 	struct strbuf msg = STRBUF_INIT;
@@ -246,7 +257,7 @@
 	int patch_mode = 0, unborn;
 	const char *rev;
 	unsigned char sha1[20];
-	const char **pathspec = NULL;
+	struct pathspec pathspec;
 	const struct option options[] = {
 		OPT__QUIET(&quiet, N_("be quiet, only report errors")),
 		OPT_SET_INT(0, "mixed", &reset_type,
@@ -258,7 +269,7 @@
 				N_("reset HEAD, index and working tree"), MERGE),
 		OPT_SET_INT(0, "keep", &reset_type,
 				N_("reset HEAD but keep local changes"), KEEP),
-		OPT_BOOLEAN('p', "patch", &patch_mode, N_("select hunks interactively")),
+		OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
 		OPT_END()
 	};
 
@@ -266,13 +277,13 @@
 
 	argc = parse_options(argc, argv, prefix, options, git_reset_usage,
 						PARSE_OPT_KEEP_DASHDASH);
-	pathspec = parse_args(argv, prefix, &rev);
+	parse_args(&pathspec, argv, prefix, patch_mode, &rev);
 
 	unborn = !strcmp(rev, "HEAD") && get_sha1("HEAD", sha1);
 	if (unborn) {
 		/* reset on unborn branch: treat as reset to empty tree */
 		hashcpy(sha1, EMPTY_TREE_SHA1_BIN);
-	} else if (!pathspec) {
+	} else if (!pathspec.nr) {
 		struct commit *commit;
 		if (get_sha1_committish(rev, sha1))
 			die(_("Failed to resolve '%s' as a valid revision."), rev);
@@ -293,13 +304,13 @@
 	if (patch_mode) {
 		if (reset_type != NONE)
 			die(_("--patch is incompatible with --{hard,mixed,soft}"));
-		return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", pathspec);
+		return run_add_interactive(rev, "--patch=reset", &pathspec);
 	}
 
 	/* git reset tree [--] paths... can be used to
 	 * load chosen paths from the tree into the index without
 	 * affecting the working tree nor HEAD. */
-	if (pathspec) {
+	if (pathspec.nr) {
 		if (reset_type == MIXED)
 			warning(_("--mixed with paths is deprecated; use 'git reset -- <paths>' instead."));
 		else if (reset_type != NONE)
@@ -323,11 +334,14 @@
 		die_if_unmerged_cache(reset_type);
 
 	if (reset_type != SOFT) {
-		struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+		struct lock_file *lock = xcalloc(1, sizeof(*lock));
 		int newfd = hold_locked_index(lock, 1);
 		if (reset_type == MIXED) {
-			if (read_from_tree(pathspec, sha1))
+			int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
+			if (read_from_tree(&pathspec, sha1))
 				return 1;
+			refresh_index(&the_index, flags, NULL, NULL,
+				      _("Unstaged changes after reset:"));
 		} else {
 			int err = reset_index(sha1, reset_type, quiet);
 			if (reset_type == KEEP && !err)
@@ -336,26 +350,20 @@
 				die(_("Could not reset index file to revision '%s'."), rev);
 		}
 
-		if (reset_type == MIXED) { /* Report what has not been updated. */
-			int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
-			refresh_index(&the_index, flags, NULL, NULL,
-				      _("Unstaged changes after reset:"));
-		}
-
 		if (write_cache(newfd, active_cache, active_nr) ||
 		    commit_locked_index(lock))
 			die(_("Could not write new index file."));
 	}
 
-	if (!pathspec && !unborn) {
+	if (!pathspec.nr && !unborn) {
 		/* Any resets without paths update HEAD to the head being
 		 * switched to, saving the previous head in ORIG_HEAD before. */
-		update_ref_status = update_refs(rev, sha1);
+		update_ref_status = reset_refs(rev, sha1);
 
 		if (reset_type == HARD && !update_ref_status && !quiet)
 			print_new_head_line(lookup_commit_reference(sha1));
 	}
-	if (!pathspec)
+	if (!pathspec.nr)
 		remove_branch_state();
 
 	return update_ref_status;
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 4fc1616..0745e2d 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -322,7 +322,7 @@
 		revs.commit_format = CMIT_FMT_RAW;
 
 	if ((!revs.commits &&
-	     (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) &&
+	     (!(revs.tag_objects || revs.tree_objects || revs.blob_objects) &&
 	      !revs.pending.nr)) ||
 	    revs.diff)
 		usage(rev_list_usage);
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index de894c7..aaeb611 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -9,6 +9,8 @@
 #include "quote.h"
 #include "builtin.h"
 #include "parse-options.h"
+#include "diff.h"
+#include "revision.h"
 
 #define DO_REVS		1
 #define DO_NOREV	2
@@ -30,6 +32,9 @@
 static int abbrev_ref_strict;
 static int output_sq;
 
+static int stuck_long;
+static struct string_list *ref_excludes;
+
 /*
  * Some arguments are relevant "revision" arguments,
  * others are about output format or other details.
@@ -185,6 +190,8 @@
 
 static int show_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 {
+	if (ref_excluded(ref_excludes, refname))
+		return 0;
 	show_rev(NORMAL, sha1, refname);
 	return 0;
 }
@@ -279,6 +286,7 @@
 				exclude = n;
 			}
 		}
+		*dotdot = '.';
 		return 1;
 	}
 	*dotdot = '.';
@@ -302,8 +310,10 @@
 		return 0;
 
 	*dotdot = 0;
-	if (get_sha1_committish(arg, sha1))
+	if (get_sha1_committish(arg, sha1)) {
+		*dotdot = '^';
 		return 0;
+	}
 
 	if (!parents_only)
 		show_rev(NORMAL, sha1, arg);
@@ -312,6 +322,7 @@
 		show_rev(parents_only ? NORMAL : REVERSED,
 				parents->item->object.sha1, arg);
 
+	*dotdot = '^';
 	return 1;
 }
 
@@ -320,12 +331,15 @@
 	struct strbuf *parsed = o->value;
 	if (unset)
 		strbuf_addf(parsed, " --no-%s", o->long_name);
-	else if (o->short_name)
+	else if (o->short_name && (o->long_name == NULL || !stuck_long))
 		strbuf_addf(parsed, " -%c", o->short_name);
 	else
 		strbuf_addf(parsed, " --%s", o->long_name);
 	if (arg) {
-		strbuf_addch(parsed, ' ');
+		if (!stuck_long)
+			strbuf_addch(parsed, ' ');
+		else if (o->long_name)
+			strbuf_addch(parsed, '=');
 		sq_quote_buf(parsed, arg);
 	}
 	return 0;
@@ -346,11 +360,13 @@
 		NULL
 	};
 	static struct option parseopt_opts[] = {
-		OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash,
+		OPT_BOOL(0, "keep-dashdash", &keep_dashdash,
 					N_("keep the `--` passed as an arg")),
-		OPT_BOOLEAN(0, "stop-at-non-option", &stop_at_non_option,
+		OPT_BOOL(0, "stop-at-non-option", &stop_at_non_option,
 					N_("stop parsing after the "
 					   "first non-option argument")),
+		OPT_BOOL(0, "stuck-long", &stuck_long,
+					N_("output in stuck long form")),
 		OPT_END(),
 	};
 
@@ -476,6 +492,7 @@
 int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 {
 	int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+	int has_dashdash = 0;
 	int output_prefix = 0;
 	unsigned char sha1[20];
 	const char *name = NULL;
@@ -486,24 +503,16 @@
 	if (argc > 1 && !strcmp("--sq-quote", argv[1]))
 		return cmd_sq_quote(argc - 2, argv + 2);
 
-	if (argc == 2 && !strcmp("--local-env-vars", argv[1])) {
-		int i;
-		for (i = 0; local_repo_env[i]; i++)
-			printf("%s\n", local_repo_env[i]);
-		return 0;
-	}
-
-	if (argc > 2 && !strcmp(argv[1], "--resolve-git-dir")) {
-		const char *gitdir = resolve_gitdir(argv[2]);
-		if (!gitdir)
-			die("not a gitdir '%s'", argv[2]);
-		puts(gitdir);
-		return 0;
-	}
-
 	if (argc > 1 && !strcmp("-h", argv[1]))
 		usage(builtin_rev_parse_usage);
 
+	for (i = 1; i < argc; i++) {
+		if (!strcmp(argv[i], "--")) {
+			has_dashdash = 1;
+			break;
+		}
+	}
+
 	prefix = setup_git_directory();
 	git_config(git_default_config, NULL);
 	for (i = 1; i < argc; i++) {
@@ -523,7 +532,7 @@
 			}
 			continue;
 		}
-		if (!prefixcmp(arg, "-n")) {
+		if (starts_with(arg, "-n")) {
 			if ((filter & DO_FLAGS) && (filter & DO_REVS))
 				show(arg);
 			continue;
@@ -575,7 +584,7 @@
 				continue;
 			}
 			if (!strcmp(arg, "--short") ||
-			    !prefixcmp(arg, "--short=")) {
+			    starts_with(arg, "--short=")) {
 				filter &= ~(DO_FLAGS|DO_NOREV);
 				verify = 1;
 				abbrev = DEFAULT_ABBREV;
@@ -603,7 +612,7 @@
 				symbolic = SHOW_SYMBOLIC_FULL;
 				continue;
 			}
-			if (!prefixcmp(arg, "--abbrev-ref") &&
+			if (starts_with(arg, "--abbrev-ref") &&
 			    (!arg[12] || arg[12] == '=')) {
 				abbrev_ref = 1;
 				abbrev_ref_strict = warn_ambiguous_refs;
@@ -621,7 +630,7 @@
 				for_each_ref(show_reference, NULL);
 				continue;
 			}
-			if (!prefixcmp(arg, "--disambiguate=")) {
+			if (starts_with(arg, "--disambiguate=")) {
 				for_each_abbrev(arg + 15, show_abbrev, NULL);
 				continue;
 			}
@@ -630,35 +639,52 @@
 				for_each_ref_in("refs/bisect/good", anti_reference, NULL);
 				continue;
 			}
-			if (!prefixcmp(arg, "--branches=")) {
+			if (starts_with(arg, "--branches=")) {
 				for_each_glob_ref_in(show_reference, arg + 11,
 					"refs/heads/", NULL);
+				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
 			if (!strcmp(arg, "--branches")) {
 				for_each_branch_ref(show_reference, NULL);
+				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
-			if (!prefixcmp(arg, "--tags=")) {
+			if (starts_with(arg, "--tags=")) {
 				for_each_glob_ref_in(show_reference, arg + 7,
 					"refs/tags/", NULL);
+				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
 			if (!strcmp(arg, "--tags")) {
 				for_each_tag_ref(show_reference, NULL);
+				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
-			if (!prefixcmp(arg, "--glob=")) {
+			if (starts_with(arg, "--glob=")) {
 				for_each_glob_ref(show_reference, arg + 7, NULL);
+				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
-			if (!prefixcmp(arg, "--remotes=")) {
+			if (starts_with(arg, "--remotes=")) {
 				for_each_glob_ref_in(show_reference, arg + 10,
 					"refs/remotes/", NULL);
+				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
 			if (!strcmp(arg, "--remotes")) {
 				for_each_remote_ref(show_reference, NULL);
+				clear_ref_exclusion(&ref_excludes);
+				continue;
+			}
+			if (starts_with(arg, "--exclude=")) {
+				add_ref_exclusion(&ref_excludes, arg + 10);
+				continue;
+			}
+			if (!strcmp(arg, "--local-env-vars")) {
+				int i;
+				for (i = 0; local_repo_env[i]; i++)
+					printf("%s\n", local_repo_env[i]);
 				continue;
 			}
 			if (!strcmp(arg, "--show-toplevel")) {
@@ -711,6 +737,13 @@
 				printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : "");
 				continue;
 			}
+			if (!strcmp(arg, "--resolve-git-dir")) {
+				const char *gitdir = resolve_gitdir(argv[i+1]);
+				if (!gitdir)
+					die("not a gitdir '%s'", argv[i+1]);
+				puts(gitdir);
+				continue;
+			}
 			if (!strcmp(arg, "--is-inside-git-dir")) {
 				printf("%s\n", is_inside_git_dir() ? "true"
 						: "false");
@@ -726,19 +759,19 @@
 						: "false");
 				continue;
 			}
-			if (!prefixcmp(arg, "--since=")) {
+			if (starts_with(arg, "--since=")) {
 				show_datestring("--max-age=", arg+8);
 				continue;
 			}
-			if (!prefixcmp(arg, "--after=")) {
+			if (starts_with(arg, "--after=")) {
 				show_datestring("--max-age=", arg+8);
 				continue;
 			}
-			if (!prefixcmp(arg, "--before=")) {
+			if (starts_with(arg, "--before=")) {
 				show_datestring("--min-age=", arg+9);
 				continue;
 			}
-			if (!prefixcmp(arg, "--until=")) {
+			if (starts_with(arg, "--until=")) {
 				show_datestring("--min-age=", arg+8);
 				continue;
 			}
@@ -767,6 +800,8 @@
 		}
 		if (verify)
 			die_no_single_rev(quiet);
+		if (has_dashdash)
+			die("bad revision '%s'", arg);
 		as_is = 1;
 		if (!show_file(arg, output_prefix))
 			continue;
diff --git a/builtin/revert.c b/builtin/revert.c
index 1d2648b..87659c9 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -71,44 +71,19 @@
 		die(_("%s: %s cannot be used with %s"), me, this_opt, base_opt);
 }
 
-LAST_ARG_MUST_BE_NULL
-static void verify_opt_mutually_compatible(const char *me, ...)
-{
-	const char *opt1, *opt2 = NULL;
-	va_list ap;
-
-	va_start(ap, me);
-	while ((opt1 = va_arg(ap, const char *))) {
-		if (va_arg(ap, int))
-			break;
-	}
-	if (opt1) {
-		while ((opt2 = va_arg(ap, const char *))) {
-			if (va_arg(ap, int))
-				break;
-		}
-	}
-	va_end(ap);
-
-	if (opt1 && opt2)
-		die(_("%s: %s cannot be used with %s"),	me, opt1, opt2);
-}
-
 static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 {
 	const char * const * usage_str = revert_or_cherry_pick_usage(opts);
 	const char *me = action_name(opts);
-	int remove_state = 0;
-	int contin = 0;
-	int rollback = 0;
+	int cmd = 0;
 	struct option options[] = {
-		OPT_BOOLEAN(0, "quit", &remove_state, N_("end revert or cherry-pick sequence")),
-		OPT_BOOLEAN(0, "continue", &contin, N_("resume revert or cherry-pick sequence")),
-		OPT_BOOLEAN(0, "abort", &rollback, N_("cancel revert or cherry-pick sequence")),
-		OPT_BOOLEAN('n', "no-commit", &opts->no_commit, N_("don't automatically commit")),
-		OPT_BOOLEAN('e', "edit", &opts->edit, N_("edit the commit message")),
+		OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
+		OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
+		OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'),
+		OPT_BOOL('n', "no-commit", &opts->no_commit, N_("don't automatically commit")),
+		OPT_BOOL('e', "edit", &opts->edit, N_("edit the commit message")),
 		OPT_NOOP_NOARG('r', NULL),
-		OPT_BOOLEAN('s', "signoff", &opts->signoff, N_("add Signed-off-by:")),
+		OPT_BOOL('s', "signoff", &opts->signoff, N_("add Signed-off-by:")),
 		OPT_INTEGER('m', "mainline", &opts->mainline, N_("parent number")),
 		OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
 		OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
@@ -124,11 +99,11 @@
 
 	if (opts->action == REPLAY_PICK) {
 		struct option cp_extra[] = {
-			OPT_BOOLEAN('x', NULL, &opts->record_origin, N_("append commit name")),
-			OPT_BOOLEAN(0, "ff", &opts->allow_ff, N_("allow fast-forward")),
-			OPT_BOOLEAN(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")),
-			OPT_BOOLEAN(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")),
-			OPT_BOOLEAN(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
+			OPT_BOOL('x', NULL, &opts->record_origin, N_("append commit name")),
+			OPT_BOOL(0, "ff", &opts->allow_ff, N_("allow fast-forward")),
+			OPT_BOOL(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")),
+			OPT_BOOL(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")),
+			OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
 			OPT_END(),
 		};
 		if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
@@ -139,23 +114,16 @@
 			PARSE_OPT_KEEP_ARGV0 |
 			PARSE_OPT_KEEP_UNKNOWN);
 
-	/* Check for incompatible subcommands */
-	verify_opt_mutually_compatible(me,
-				"--quit", remove_state,
-				"--continue", contin,
-				"--abort", rollback,
-				NULL);
-
 	/* implies allow_empty */
 	if (opts->keep_redundant_commits)
 		opts->allow_empty = 1;
 
 	/* Set the subcommand */
-	if (remove_state)
+	if (cmd == 'q')
 		opts->subcommand = REPLAY_REMOVE_STATE;
-	else if (contin)
+	else if (cmd == 'c')
 		opts->subcommand = REPLAY_CONTINUE;
-	else if (rollback)
+	else if (cmd == 'a')
 		opts->subcommand = REPLAY_ROLLBACK;
 	else
 		opts->subcommand = REPLAY_NONE;
@@ -200,6 +168,8 @@
 		opts->revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED;
 		if (argc < 2)
 			usage_with_options(usage_str, options);
+		if (!strcmp(argv[1], "-"))
+			argv[1] = "@{-1}";
 		memset(&s_r_opt, 0, sizeof(s_r_opt));
 		s_r_opt.assume_dashdash = 1;
 		argc = setup_revisions(argc, argv, opts->revs, &s_r_opt);
diff --git a/builtin/rm.c b/builtin/rm.c
index 0df0b4d..3a0e0ea 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -11,6 +11,7 @@
 #include "parse-options.h"
 #include "string-list.h"
 #include "submodule.h"
+#include "pathspec.h"
 
 static const char * const builtin_rm_usage[] = {
 	N_("git rm [options] [--] <file>..."),
@@ -267,10 +268,10 @@
 static struct option builtin_rm_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
 	OPT__QUIET(&quiet, N_("do not list removed files")),
-	OPT_BOOLEAN( 0 , "cached",         &index_only, N_("only remove from the index")),
+	OPT_BOOL( 0 , "cached",         &index_only, N_("only remove from the index")),
 	OPT__FORCE(&force, N_("override the up-to-date check")),
-	OPT_BOOLEAN('r', NULL,             &recursive,  N_("allow recursive removal")),
-	OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch,
+	OPT_BOOL('r', NULL,             &recursive,  N_("allow recursive removal")),
+	OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
 				N_("exit with a zero status even if nothing matched")),
 	OPT_END(),
 };
@@ -278,9 +279,10 @@
 int cmd_rm(int argc, const char **argv, const char *prefix)
 {
 	int i, newfd;
-	const char **pathspec;
+	struct pathspec pathspec;
 	char *seen;
 
+	gitmodules_config();
 	git_config(git_default_config, NULL);
 
 	argc = parse_options(argc, argv, prefix, builtin_rm_options,
@@ -296,46 +298,35 @@
 	if (read_cache() < 0)
 		die(_("index file corrupt"));
 
-	/*
-	 * Drop trailing directory separators from directories so we'll find
-	 * submodules in the index.
-	 */
-	for (i = 0; i < argc; i++) {
-		size_t pathlen = strlen(argv[i]);
-		if (pathlen && is_dir_sep(argv[i][pathlen - 1]) &&
-		    is_directory(argv[i])) {
-			do {
-				pathlen--;
-			} while (pathlen && is_dir_sep(argv[i][pathlen - 1]));
-			argv[i] = xmemdupz(argv[i], pathlen);
-		}
-	}
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_CWD |
+		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
+		       prefix, argv);
+	refresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL);
 
-	pathspec = get_pathspec(prefix, argv);
-	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
-
-	seen = NULL;
-	for (i = 0; pathspec[i] ; i++)
-		/* nothing */;
-	seen = xcalloc(i, 1);
+	seen = xcalloc(pathspec.nr, 1);
 
 	for (i = 0; i < active_nr; i++) {
 		const struct cache_entry *ce = active_cache[i];
-		if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+		if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))
 			continue;
 		ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
 		list.entry[list.nr].name = ce->name;
-		list.entry[list.nr++].is_submodule = S_ISGITLINK(ce->ce_mode);
+		list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);
+		if (list.entry[list.nr++].is_submodule &&
+		    !is_staging_gitmodules_ok())
+			die (_("Please, stage your changes to .gitmodules or stash them to proceed"));
 	}
 
-	if (pathspec) {
-		const char *match;
+	if (pathspec.nr) {
+		const char *original;
 		int seen_any = 0;
-		for (i = 0; (match = pathspec[i]) != NULL ; i++) {
+		for (i = 0; i < pathspec.nr; i++) {
+			original = pathspec.items[i].original;
 			if (!seen[i]) {
 				if (!ignore_unmatch) {
 					die(_("pathspec '%s' did not match any files"),
-					    match);
+					    original);
 				}
 			}
 			else {
@@ -343,10 +334,10 @@
 			}
 			if (!recursive && seen[i] == MATCHED_RECURSIVELY)
 				die(_("not removing '%s' recursively without -r"),
-				    *match ? match : ".");
+				    *original ? original : ".");
 		}
 
-		if (! seen_any)
+		if (!seen_any)
 			exit(0);
 	}
 
@@ -396,13 +387,15 @@
 	 * in the middle)
 	 */
 	if (!index_only) {
-		int removed = 0;
+		int removed = 0, gitmodules_modified = 0;
 		for (i = 0; i < list.nr; i++) {
 			const char *path = list.entry[i].name;
 			if (list.entry[i].is_submodule) {
 				if (is_empty_dir(path)) {
 					if (!rmdir(path)) {
 						removed = 1;
+						if (!remove_path_from_gitmodules(path))
+							gitmodules_modified = 1;
 						continue;
 					}
 				} else {
@@ -410,9 +403,14 @@
 					strbuf_addstr(&buf, path);
 					if (!remove_dir_recursively(&buf, 0)) {
 						removed = 1;
+						if (!remove_path_from_gitmodules(path))
+							gitmodules_modified = 1;
 						strbuf_release(&buf);
 						continue;
-					}
+					} else if (!file_exists(path))
+						/* Submodule was removed by user */
+						if (!remove_path_from_gitmodules(path))
+							gitmodules_modified = 1;
 					strbuf_release(&buf);
 					/* Fallthrough and let remove_path() fail. */
 				}
@@ -424,6 +422,8 @@
 			if (!removed)
 				die_errno("git rm: '%s'", path);
 		}
+		if (gitmodules_modified)
+			stage_updated_gitmodules();
 	}
 
 	if (active_cache_changed) {
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 152c4ea..f420b74 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -5,10 +5,12 @@
 #include "sideband.h"
 #include "run-command.h"
 #include "remote.h"
+#include "connect.h"
 #include "send-pack.h"
 #include "quote.h"
 #include "transport.h"
 #include "version.h"
+#include "sha1-array.h"
 
 static const char send_pack_usage[] =
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
@@ -54,6 +56,11 @@
 			msg = "needs force";
 			break;
 
+		case REF_STATUS_REJECT_STALE:
+			res = "error";
+			msg = "stale info";
+			break;
+
 		case REF_STATUS_REJECT_ALREADY_EXISTS:
 			res = "error";
 			msg = "already exists";
@@ -93,7 +100,8 @@
 	const char *dest = NULL;
 	int fd[2];
 	struct child_process *conn;
-	struct extra_have_objects extra_have;
+	struct sha1_array extra_have = SHA1_ARRAY_INIT;
+	struct sha1_array shallow = SHA1_ARRAY_INIT;
 	struct ref *remote_refs, *local_refs;
 	int ret;
 	int helper_status = 0;
@@ -102,21 +110,22 @@
 	int flags;
 	unsigned int reject_reasons;
 	int progress = -1;
+	struct push_cas_option cas = {0};
 
 	argv++;
 	for (i = 1; i < argc; i++, argv++) {
 		const char *arg = *argv;
 
 		if (*arg == '-') {
-			if (!prefixcmp(arg, "--receive-pack=")) {
+			if (starts_with(arg, "--receive-pack=")) {
 				receivepack = arg + 15;
 				continue;
 			}
-			if (!prefixcmp(arg, "--exec=")) {
+			if (starts_with(arg, "--exec=")) {
 				receivepack = arg + 7;
 				continue;
 			}
-			if (!prefixcmp(arg, "--remote=")) {
+			if (starts_with(arg, "--remote=")) {
 				remote_name = arg + 9;
 				continue;
 			}
@@ -164,6 +173,22 @@
 				helper_status = 1;
 				continue;
 			}
+			if (!strcmp(arg, "--" CAS_OPT_NAME)) {
+				if (parse_push_cas_option(&cas, NULL, 0) < 0)
+					exit(1);
+				continue;
+			}
+			if (!strcmp(arg, "--no-" CAS_OPT_NAME)) {
+				if (parse_push_cas_option(&cas, NULL, 1) < 0)
+					exit(1);
+				continue;
+			}
+			if (starts_with(arg, "--" CAS_OPT_NAME "=")) {
+				if (parse_push_cas_option(&cas,
+							  strchr(arg, '=') + 1, 0) < 0)
+					exit(1);
+				continue;
+			}
 			usage(send_pack_usage);
 		}
 		if (!dest) {
@@ -205,9 +230,8 @@
 			args.verbose ? CONNECT_VERBOSE : 0);
 	}
 
-	memset(&extra_have, 0, sizeof(extra_have));
-
-	get_remote_heads(fd[0], NULL, 0, &remote_refs, REF_NORMAL, &extra_have);
+	get_remote_heads(fd[0], NULL, 0, &remote_refs, REF_NORMAL,
+			 &extra_have, &shallow);
 
 	transport_verify_remote_names(nr_refspecs, refspecs);
 
@@ -224,6 +248,9 @@
 	if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
 		return -1;
 
+	if (!is_empty_cas(&cas))
+		apply_push_cas(&cas, remote, remote_refs);
+
 	set_ref_status_for_push(remote_refs, args.send_mirror,
 		args.force_update);
 
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 84ffbb7..4b7e536 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -65,7 +65,7 @@
 	eol = strchr(oneline, '\n');
 	if (!eol)
 		eol = oneline + strlen(oneline);
-	if (!prefixcmp(oneline, "[PATCH")) {
+	if (starts_with(oneline, "[PATCH")) {
 		char *eob = strchr(oneline, ']');
 		if (eob && (!eol || eob < eol))
 			oneline = eob + 1;
@@ -95,7 +95,7 @@
 
 	while (fgets(author, sizeof(author), stdin) != NULL) {
 		if (!(author[0] == 'A' || author[0] == 'a') ||
-		    prefixcmp(author + 1, "uthor: "))
+		    !starts_with(author + 1, "uthor: "))
 			continue;
 		while (fgets(oneline, sizeof(oneline), stdin) &&
 		       oneline[0] != '\n')
@@ -123,7 +123,7 @@
 		else
 			eol++;
 
-		if (!prefixcmp(buffer, "author "))
+		if (starts_with(buffer, "author "))
 			author = buffer + 7;
 		buffer = eol;
 	}
@@ -226,12 +226,12 @@
 	int nongit = !startup_info->have_repository;
 
 	static const struct option options[] = {
-		OPT_BOOLEAN('n', "numbered", &log.sort_by_number,
-			    N_("sort output according to the number of commits per author")),
-		OPT_BOOLEAN('s', "summary", &log.summary,
-			    N_("Suppress commit descriptions, only provides commit count")),
-		OPT_BOOLEAN('e', "email", &log.email,
-			    N_("Show the email address of each author")),
+		OPT_BOOL('n', "numbered", &log.sort_by_number,
+			 N_("sort output according to the number of commits per author")),
+		OPT_BOOL('s', "summary", &log.summary,
+			 N_("Suppress commit descriptions, only provides commit count")),
+		OPT_BOOL('e', "email", &log.email,
+			 N_("Show the email address of each author")),
 		{ OPTION_CALLBACK, 'w', NULL, &log, N_("w[,i1[,i2]]"),
 			N_("Linewrap output"), PARSE_OPT_OPTARG, &parse_wrap_args },
 		OPT_END(),
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 9788eb1..d9217ce 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -227,8 +227,7 @@
 			parents = parents->next;
 			if ((this_flag & flags) == flags)
 				continue;
-			if (!p->object.parsed)
-				parse_commit(p);
+			parse_commit(p);
 			if (mark_seen(p, seen_p) && !still_interesting)
 				extra--;
 			p->object.flags |= flags;
@@ -285,7 +284,7 @@
 		pp_commit_easy(CMIT_FMT_ONELINE, commit, &pretty);
 		pretty_str = pretty.buf;
 	}
-	if (!prefixcmp(pretty_str, "[PATCH] "))
+	if (starts_with(pretty_str, "[PATCH] "))
 		pretty_str += 8;
 
 	if (!no_name) {
@@ -396,7 +395,7 @@
 {
 	unsigned char tmp[20];
 	int ofs = 11;
-	if (prefixcmp(refname, "refs/heads/"))
+	if (!starts_with(refname, "refs/heads/"))
 		return 0;
 	/* If both heads/foo and tags/foo exists, get_sha1 would
 	 * get confused.
@@ -410,7 +409,7 @@
 {
 	unsigned char tmp[20];
 	int ofs = 13;
-	if (prefixcmp(refname, "refs/remotes/"))
+	if (!starts_with(refname, "refs/remotes/"))
 		return 0;
 	/* If both heads/foo and tags/foo exists, get_sha1 would
 	 * get confused.
@@ -422,7 +421,7 @@
 
 static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 {
-	if (prefixcmp(refname, "refs/tags/"))
+	if (!starts_with(refname, "refs/tags/"))
 		return 0;
 	return append_ref(refname + 5, sha1, 0);
 }
@@ -453,9 +452,9 @@
 		return 0;
 	if (fnmatch(match_ref_pattern, tail, 0))
 		return 0;
-	if (!prefixcmp(refname, "refs/heads/"))
+	if (starts_with(refname, "refs/heads/"))
 		return append_head_ref(refname, sha1, flag, cb_data);
-	if (!prefixcmp(refname, "refs/tags/"))
+	if (starts_with(refname, "refs/tags/"))
 		return append_tag_ref(refname, sha1, flag, cb_data);
 	return append_ref(refname, sha1, 0);
 }
@@ -480,11 +479,11 @@
 	if ((!head[0]) ||
 	    (head_sha1 && sha1 && hashcmp(head_sha1, sha1)))
 		return 0;
-	if (!prefixcmp(head, "refs/heads/"))
+	if (starts_with(head, "refs/heads/"))
 		head += 11;
-	if (!prefixcmp(name, "refs/heads/"))
+	if (starts_with(name, "refs/heads/"))
 		name += 11;
-	else if (!prefixcmp(name, "heads/"))
+	else if (starts_with(name, "heads/"))
 		name += 6;
 	return !strcmp(head, name);
 }
@@ -646,30 +645,30 @@
 	int dense = 1;
 	const char *reflog_base = NULL;
 	struct option builtin_show_branch_options[] = {
-		OPT_BOOLEAN('a', "all", &all_heads,
-			    N_("show remote-tracking and local branches")),
-		OPT_BOOLEAN('r', "remotes", &all_remotes,
-			    N_("show remote-tracking branches")),
+		OPT_BOOL('a', "all", &all_heads,
+			 N_("show remote-tracking and local branches")),
+		OPT_BOOL('r', "remotes", &all_remotes,
+			 N_("show remote-tracking branches")),
 		OPT__COLOR(&showbranch_use_color,
 			    N_("color '*!+-' corresponding to the branch")),
 		{ OPTION_INTEGER, 0, "more", &extra, N_("n"),
 			    N_("show <n> more commits after the common ancestor"),
 			    PARSE_OPT_OPTARG, NULL, (intptr_t)1 },
 		OPT_SET_INT(0, "list", &extra, N_("synonym to more=-1"), -1),
-		OPT_BOOLEAN(0, "no-name", &no_name, N_("suppress naming strings")),
-		OPT_BOOLEAN(0, "current", &with_current_branch,
-			    N_("include the current branch")),
-		OPT_BOOLEAN(0, "sha1-name", &sha1_name,
-			    N_("name commits with their object names")),
-		OPT_BOOLEAN(0, "merge-base", &merge_base,
-			    N_("show possible merge bases")),
-		OPT_BOOLEAN(0, "independent", &independent,
+		OPT_BOOL(0, "no-name", &no_name, N_("suppress naming strings")),
+		OPT_BOOL(0, "current", &with_current_branch,
+			 N_("include the current branch")),
+		OPT_BOOL(0, "sha1-name", &sha1_name,
+			 N_("name commits with their object names")),
+		OPT_BOOL(0, "merge-base", &merge_base,
+			 N_("show possible merge bases")),
+		OPT_BOOL(0, "independent", &independent,
 			    N_("show refs unreachable from any other ref")),
 		OPT_SET_INT(0, "topo-order", &sort_order,
 			    N_("show commits in topological order"),
 			    REV_SORT_IN_GRAPH_ORDER),
-		OPT_BOOLEAN(0, "topics", &topics,
-			    N_("show only commits not on the first branch")),
+		OPT_BOOL(0, "topics", &topics,
+			 N_("show only commits not on the first branch")),
 		OPT_SET_INT(0, "sparse", &dense,
 			    N_("show merges reachable from only one tip"), 0),
 		OPT_SET_INT(0, "date-order", &sort_order,
@@ -813,7 +812,7 @@
 				has_head++;
 		}
 		if (!has_head) {
-			int offset = !prefixcmp(head, "refs/heads/") ? 11 : 0;
+			int offset = starts_with(head, "refs/heads/") ? 11 : 0;
 			append_one_rev(head + offset);
 		}
 	}
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 87806ad..5ba1f30 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -37,8 +37,8 @@
 	if (tags_only || heads_only) {
 		int match;
 
-		match = heads_only && !prefixcmp(refname, "refs/heads/");
-		match |= tags_only && !prefixcmp(refname, "refs/tags/");
+		match = heads_only && starts_with(refname, "refs/heads/");
+		match |= tags_only && starts_with(refname, "refs/tags/");
 		if (!match)
 			return 0;
 	}
@@ -165,16 +165,15 @@
 }
 
 static const struct option show_ref_options[] = {
-	OPT_BOOLEAN(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")),
-	OPT_BOOLEAN(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")),
-	OPT_BOOLEAN(0, "verify", &verify, N_("stricter reference checking, "
+	OPT_BOOL(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")),
+	OPT_BOOL(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")),
+	OPT_BOOL(0, "verify", &verify, N_("stricter reference checking, "
 		    "requires exact ref path")),
-	{ OPTION_BOOLEAN, 'h', NULL, &show_head, NULL,
-	  N_("show the HEAD reference, even if it would be filtered out"),
-	  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
-	OPT_BOOLEAN(0, "head", &show_head,
+	OPT_HIDDEN_BOOL('h', NULL, &show_head,
+			N_("show the HEAD reference, even if it would be filtered out")),
+	OPT_BOOL(0, "head", &show_head,
 	  N_("show the HEAD reference, even if it would be filtered out")),
-	OPT_BOOLEAN('d', "dereference", &deref_tags,
+	OPT_BOOL('d', "dereference", &deref_tags,
 		    N_("dereference tags into object IDs")),
 	{ OPTION_CALLBACK, 's', "hash", &abbrev, N_("n"),
 	  N_("only show SHA1 hash using <n> digits"),
@@ -211,7 +210,7 @@
 		while (*pattern) {
 			unsigned char sha1[20];
 
-			if (!prefixcmp(*pattern, "refs/") &&
+			if (starts_with(*pattern, "refs/") &&
 			    !read_ref(*pattern, sha1)) {
 				if (!quiet)
 					show_one(*pattern, sha1);
diff --git a/builtin/stripspace.c b/builtin/stripspace.c
index e981dfb..1259ed7 100644
--- a/builtin/stripspace.c
+++ b/builtin/stripspace.c
@@ -89,11 +89,11 @@
 
 	if (argc == 2) {
 		if (!strcmp(argv[1], "-s") ||
-			!strcmp(argv[1], "--strip-comments")) {
-			 strip_comments = 1;
+		    !strcmp(argv[1], "--strip-comments")) {
+			strip_comments = 1;
 		} else if (!strcmp(argv[1], "-c") ||
-					 !strcmp(argv[1], "--comment-lines")) {
-			 mode = COMMENT_LINES;
+			   !strcmp(argv[1], "--comment-lines")) {
+			mode = COMMENT_LINES;
 		} else {
 			mode = INVAL;
 		}
diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c
index f481959..b6a711d 100644
--- a/builtin/symbolic-ref.c
+++ b/builtin/symbolic-ref.c
@@ -47,7 +47,7 @@
 	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, prefix, options,
 			     git_symbolic_ref_usage, 0);
-	if (msg &&!*msg)
+	if (msg && !*msg)
 		die("Refusing to perform update with empty message");
 
 	if (delete) {
@@ -65,7 +65,7 @@
 		break;
 	case 2:
 		if (!strcmp(argv[0], "HEAD") &&
-		    prefixcmp(argv[1], "refs/"))
+		    !starts_with(argv[1], "refs/"))
 			die("Refusing to point HEAD outside of refs/");
 		create_symref(argv[0], argv[1], msg);
 		break;
diff --git a/builtin/tag.c b/builtin/tag.c
index af3af3f..74d3780 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -259,7 +259,7 @@
 	int status = git_gpg_config(var, value, cb);
 	if (status)
 		return status;
-	if (!prefixcmp(var, "column."))
+	if (starts_with(var, "column."))
 		return git_column_config(var, value, "tag", &colopts);
 	return git_default_config(var, value, cb);
 }
@@ -436,26 +436,26 @@
 	struct ref_lock *lock;
 	struct create_tag_options opt;
 	char *cleanup_arg = NULL;
-	int annotate = 0, force = 0, lines = -1, list = 0,
-		delete = 0, verify = 0;
+	int annotate = 0, force = 0, lines = -1;
+	int cmdmode = 0;
 	const char *msgfile = NULL, *keyid = NULL;
 	struct msg_arg msg = { 0, STRBUF_INIT };
 	struct commit_list *with_commit = NULL;
 	struct option options[] = {
-		OPT_BOOLEAN('l', "list", &list, N_("list tag names")),
+		OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'),
 		{ OPTION_INTEGER, 'n', NULL, &lines, N_("n"),
 				N_("print <n> lines of each tag message"),
 				PARSE_OPT_OPTARG, NULL, 1 },
-		OPT_BOOLEAN('d', "delete", &delete, N_("delete tags")),
-		OPT_BOOLEAN('v', "verify", &verify, N_("verify tags")),
+		OPT_CMDMODE('d', "delete", &cmdmode, N_("delete tags"), 'd'),
+		OPT_CMDMODE('v', "verify", &cmdmode, N_("verify tags"), 'v'),
 
 		OPT_GROUP(N_("Tag creation options")),
-		OPT_BOOLEAN('a', "annotate", &annotate,
+		OPT_BOOL('a', "annotate", &annotate,
 					N_("annotated tag, needs a message")),
 		OPT_CALLBACK('m', "message", &msg, N_("message"),
 			     N_("tag message"), parse_msg_arg),
 		OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
-		OPT_BOOLEAN('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
+		OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
 		OPT_STRING(0, "cleanup", &cleanup_arg, N_("mode"),
 			N_("how to strip spaces and #comments from message")),
 		OPT_STRING('u', "local-user", &keyid, N_("key id"),
@@ -489,22 +489,19 @@
 	}
 	if (opt.sign)
 		annotate = 1;
-	if (argc == 0 && !(delete || verify))
-		list = 1;
+	if (argc == 0 && !cmdmode)
+		cmdmode = 'l';
 
-	if ((annotate || msg.given || msgfile || force) &&
-	    (list || delete || verify))
+	if ((annotate || msg.given || msgfile || force) && (cmdmode != 0))
 		usage_with_options(git_tag_usage, options);
 
-	if (list + delete + verify > 1)
-		usage_with_options(git_tag_usage, options);
 	finalize_colopts(&colopts, -1);
-	if (list && lines != -1) {
+	if (cmdmode == 'l' && lines != -1) {
 		if (explicitly_enable_column(colopts))
 			die(_("--column and -n are incompatible"));
 		colopts = 0;
 	}
-	if (list) {
+	if (cmdmode == 'l') {
 		int ret;
 		if (column_active(colopts)) {
 			struct column_options copts;
@@ -523,9 +520,9 @@
 		die(_("--contains option is only allowed with -l."));
 	if (points_at.nr)
 		die(_("--points-at option is only allowed with -l."));
-	if (delete)
+	if (cmdmode == 'd')
 		return for_each_tag_name(argv, delete_tag);
-	if (verify)
+	if (cmdmode == 'v')
 		return for_each_tag_name(argv, verify_tag);
 
 	if (msg.given || msgfile) {
@@ -577,7 +574,7 @@
 	if (annotate)
 		create_tag(object, tag, &buf, &opt, prev, object);
 
-	lock = lock_any_ref_for_update(ref.buf, prev, 0);
+	lock = lock_any_ref_for_update(ref.buf, prev, 0, NULL);
 	if (!lock)
 		die(_("%s: cannot lock the ref"), ref.buf);
 	if (write_ref_sha1(lock, object, NULL) < 0)
diff --git a/builtin/tar-tree.c b/builtin/tar-tree.c
deleted file mode 100644
index 3f1e701..0000000
--- a/builtin/tar-tree.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2005, 2006 Rene Scharfe
- */
-#include "cache.h"
-#include "commit.h"
-#include "tar.h"
-#include "builtin.h"
-#include "quote.h"
-
-static const char tar_tree_usage[] =
-"git tar-tree [--remote=<repo>] <tree-ish> [basedir]\n"
-"*** Note that this command is now deprecated; use \"git archive\" instead.";
-
-static const char builtin_get_tar_commit_id_usage[] =
-"git get-tar-commit-id < <tarfile>";
-
-int cmd_tar_tree(int argc, const char **argv, const char *prefix)
-{
-	/*
-	 * "git tar-tree" is now a wrapper around "git archive --format=tar"
-	 *
-	 * $0 --remote=<repo> arg... ==>
-	 *	git archive --format=tar --remote=<repo> arg...
-	 * $0 tree-ish ==>
-	 *	git archive --format=tar tree-ish
-	 * $0 tree-ish basedir ==>
-	 * 	git archive --format-tar --prefix=basedir tree-ish
-	 */
-	int i;
-	const char **nargv = xcalloc(sizeof(*nargv), argc + 3);
-	char *basedir_arg;
-	int nargc = 0;
-
-	nargv[nargc++] = "archive";
-	nargv[nargc++] = "--format=tar";
-
-	if (2 <= argc && !prefixcmp(argv[1], "--remote=")) {
-		nargv[nargc++] = argv[1];
-		argv++;
-		argc--;
-	}
-
-	/*
-	 * Because it's just a compatibility wrapper, tar-tree supports only
-	 * the old behaviour of reading attributes from the work tree.
-	 */
-	nargv[nargc++] = "--worktree-attributes";
-
-	switch (argc) {
-	default:
-		usage(tar_tree_usage);
-		break;
-	case 3:
-		/* base-path */
-		basedir_arg = xmalloc(strlen(argv[2]) + 11);
-		sprintf(basedir_arg, "--prefix=%s/", argv[2]);
-		nargv[nargc++] = basedir_arg;
-		/* fallthru */
-	case 2:
-		/* tree-ish */
-		nargv[nargc++] = argv[1];
-	}
-	nargv[nargc] = NULL;
-
-	fprintf(stderr,
-		"*** \"git tar-tree\" is now deprecated.\n"
-		"*** Running \"git archive\" instead.\n***");
-	for (i = 0; i < nargc; i++) {
-		fputc(' ', stderr);
-		sq_quote_print(stderr, nargv[i]);
-	}
-	fputc('\n', stderr);
-	return cmd_archive(nargc, nargv, prefix);
-}
-
-/* ustar header + extended global header content */
-#define RECORDSIZE	(512)
-#define HEADERSIZE (2 * RECORDSIZE)
-
-int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
-{
-	char buffer[HEADERSIZE];
-	struct ustar_header *header = (struct ustar_header *)buffer;
-	char *content = buffer + RECORDSIZE;
-	ssize_t n;
-
-	if (argc != 1)
-		usage(builtin_get_tar_commit_id_usage);
-
-	n = read_in_full(0, buffer, HEADERSIZE);
-	if (n < HEADERSIZE)
-		die("git get-tar-commit-id: read error");
-	if (header->typeflag[0] != 'g')
-		return 1;
-	if (memcmp(content, "52 comment=", 11))
-		return 1;
-
-	n = write_in_full(1, content + 11, 41);
-	if (n < 41)
-		die_errno("git get-tar-commit-id: write error");
-
-	return 0;
-}
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 2217d7b..62ff673 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -523,7 +523,7 @@
 				strict = 1;
 				continue;
 			}
-			if (!prefixcmp(arg, "--pack_header=")) {
+			if (starts_with(arg, "--pack_header=")) {
 				struct pack_header *hdr;
 				char *c;
 
diff --git a/builtin/update-index.c b/builtin/update-index.c
index c317981..e3a10d7 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -11,6 +11,7 @@
 #include "refs.h"
 #include "resolve-undo.h"
 #include "parse-options.h"
+#include "pathspec.h"
 
 /*
  * Default to not allowing changes to the list of files. The
@@ -546,10 +547,11 @@
 	 */
 	int pos;
 	int has_head = 1;
-	const char **paths = get_pathspec(prefix, av + 1);
 	struct pathspec pathspec;
 
-	init_pathspec(&pathspec, paths);
+	parse_pathspec(&pathspec, 0,
+		       PATHSPEC_PREFER_CWD,
+		       prefix, av + 1);
 
 	if (read_ref("HEAD", head_sha1))
 		/* If there is no HEAD, that means it is an initial
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 51d2684..1292cfe 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -2,23 +2,261 @@
 #include "refs.h"
 #include "builtin.h"
 #include "parse-options.h"
+#include "quote.h"
+#include "argv-array.h"
 
 static const char * const git_update_ref_usage[] = {
 	N_("git update-ref [options] -d <refname> [<oldval>]"),
 	N_("git update-ref [options]    <refname> <newval> [<oldval>]"),
+	N_("git update-ref [options] --stdin [-z]"),
 	NULL
 };
 
+static int updates_alloc;
+static int updates_count;
+static const struct ref_update **updates;
+
+static char line_termination = '\n';
+static int update_flags;
+
+static struct ref_update *update_alloc(void)
+{
+	struct ref_update *update;
+
+	/* Allocate and zero-init a struct ref_update */
+	update = xcalloc(1, sizeof(*update));
+	ALLOC_GROW(updates, updates_count + 1, updates_alloc);
+	updates[updates_count++] = update;
+
+	/* Store and reset accumulated options */
+	update->flags = update_flags;
+	update_flags = 0;
+
+	return update;
+}
+
+static void update_store_ref_name(struct ref_update *update,
+				  const char *ref_name)
+{
+	if (check_refname_format(ref_name, REFNAME_ALLOW_ONELEVEL))
+		die("invalid ref format: %s", ref_name);
+	update->ref_name = xstrdup(ref_name);
+}
+
+static void update_store_new_sha1(struct ref_update *update,
+				  const char *newvalue)
+{
+	if (*newvalue && get_sha1(newvalue, update->new_sha1))
+		die("invalid new value for ref %s: %s",
+		    update->ref_name, newvalue);
+}
+
+static void update_store_old_sha1(struct ref_update *update,
+				  const char *oldvalue)
+{
+	if (*oldvalue && get_sha1(oldvalue, update->old_sha1))
+		die("invalid old value for ref %s: %s",
+		    update->ref_name, oldvalue);
+
+	/* We have an old value if non-empty, or if empty without -z */
+	update->have_old = *oldvalue || line_termination;
+}
+
+static const char *parse_arg(const char *next, struct strbuf *arg)
+{
+	/* Parse SP-terminated, possibly C-quoted argument */
+	if (*next != '"')
+		while (*next && !isspace(*next))
+			strbuf_addch(arg, *next++);
+	else if (unquote_c_style(arg, next, &next))
+		die("badly quoted argument: %s", next);
+
+	/* Return position after the argument */
+	return next;
+}
+
+static const char *parse_first_arg(const char *next, struct strbuf *arg)
+{
+	/* Parse argument immediately after "command SP" */
+	strbuf_reset(arg);
+	if (line_termination) {
+		/* Without -z, use the next argument */
+		next = parse_arg(next, arg);
+	} else {
+		/* With -z, use rest of first NUL-terminated line */
+		strbuf_addstr(arg, next);
+		next = next + arg->len;
+	}
+	return next;
+}
+
+static const char *parse_next_arg(const char *next, struct strbuf *arg)
+{
+	/* Parse next SP-terminated or NUL-terminated argument, if any */
+	strbuf_reset(arg);
+	if (line_termination) {
+		/* Without -z, consume SP and use next argument */
+		if (!*next)
+			return NULL;
+		if (*next != ' ')
+			die("expected SP but got: %s", next);
+		next = parse_arg(next + 1, arg);
+	} else {
+		/* With -z, read the next NUL-terminated line */
+		if (*next)
+			die("expected NUL but got: %s", next);
+		if (strbuf_getline(arg, stdin, '\0') == EOF)
+			return NULL;
+		next = arg->buf + arg->len;
+	}
+	return next;
+}
+
+static void parse_cmd_update(const char *next)
+{
+	struct strbuf ref = STRBUF_INIT;
+	struct strbuf newvalue = STRBUF_INIT;
+	struct strbuf oldvalue = STRBUF_INIT;
+	struct ref_update *update;
+
+	update = update_alloc();
+
+	if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
+		update_store_ref_name(update, ref.buf);
+	else
+		die("update line missing <ref>");
+
+	if ((next = parse_next_arg(next, &newvalue)) != NULL)
+		update_store_new_sha1(update, newvalue.buf);
+	else
+		die("update %s missing <newvalue>", ref.buf);
+
+	if ((next = parse_next_arg(next, &oldvalue)) != NULL)
+		update_store_old_sha1(update, oldvalue.buf);
+	else if(!line_termination)
+		die("update %s missing [<oldvalue>] NUL", ref.buf);
+
+	if (next && *next)
+		die("update %s has extra input: %s", ref.buf, next);
+}
+
+static void parse_cmd_create(const char *next)
+{
+	struct strbuf ref = STRBUF_INIT;
+	struct strbuf newvalue = STRBUF_INIT;
+	struct ref_update *update;
+
+	update = update_alloc();
+
+	if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
+		update_store_ref_name(update, ref.buf);
+	else
+		die("create line missing <ref>");
+
+	if ((next = parse_next_arg(next, &newvalue)) != NULL)
+		update_store_new_sha1(update, newvalue.buf);
+	else
+		die("create %s missing <newvalue>", ref.buf);
+	if (is_null_sha1(update->new_sha1))
+		die("create %s given zero new value", ref.buf);
+
+	if (next && *next)
+		die("create %s has extra input: %s", ref.buf, next);
+}
+
+static void parse_cmd_delete(const char *next)
+{
+	struct strbuf ref = STRBUF_INIT;
+	struct strbuf oldvalue = STRBUF_INIT;
+	struct ref_update *update;
+
+	update = update_alloc();
+
+	if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
+		update_store_ref_name(update, ref.buf);
+	else
+		die("delete line missing <ref>");
+
+	if ((next = parse_next_arg(next, &oldvalue)) != NULL)
+		update_store_old_sha1(update, oldvalue.buf);
+	else if(!line_termination)
+		die("delete %s missing [<oldvalue>] NUL", ref.buf);
+	if (update->have_old && is_null_sha1(update->old_sha1))
+		die("delete %s given zero old value", ref.buf);
+
+	if (next && *next)
+		die("delete %s has extra input: %s", ref.buf, next);
+}
+
+static void parse_cmd_verify(const char *next)
+{
+	struct strbuf ref = STRBUF_INIT;
+	struct strbuf value = STRBUF_INIT;
+	struct ref_update *update;
+
+	update = update_alloc();
+
+	if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
+		update_store_ref_name(update, ref.buf);
+	else
+		die("verify line missing <ref>");
+
+	if ((next = parse_next_arg(next, &value)) != NULL) {
+		update_store_old_sha1(update, value.buf);
+		update_store_new_sha1(update, value.buf);
+	} else if(!line_termination)
+		die("verify %s missing [<oldvalue>] NUL", ref.buf);
+
+	if (next && *next)
+		die("verify %s has extra input: %s", ref.buf, next);
+}
+
+static void parse_cmd_option(const char *next)
+{
+	if (!strcmp(next, "no-deref"))
+		update_flags |= REF_NODEREF;
+	else
+		die("option unknown: %s", next);
+}
+
+static void update_refs_stdin(void)
+{
+	struct strbuf cmd = STRBUF_INIT;
+
+	/* Read each line dispatch its command */
+	while (strbuf_getline(&cmd, stdin, line_termination) != EOF)
+		if (!cmd.buf[0])
+			die("empty command in input");
+		else if (isspace(*cmd.buf))
+			die("whitespace before command: %s", cmd.buf);
+		else if (starts_with(cmd.buf, "update "))
+			parse_cmd_update(cmd.buf + 7);
+		else if (starts_with(cmd.buf, "create "))
+			parse_cmd_create(cmd.buf + 7);
+		else if (starts_with(cmd.buf, "delete "))
+			parse_cmd_delete(cmd.buf + 7);
+		else if (starts_with(cmd.buf, "verify "))
+			parse_cmd_verify(cmd.buf + 7);
+		else if (starts_with(cmd.buf, "option "))
+			parse_cmd_option(cmd.buf + 7);
+		else
+			die("unknown command: %s", cmd.buf);
+
+	strbuf_release(&cmd);
+}
+
 int cmd_update_ref(int argc, const char **argv, const char *prefix)
 {
 	const char *refname, *oldval, *msg = NULL;
 	unsigned char sha1[20], oldsha1[20];
-	int delete = 0, no_deref = 0, flags = 0;
+	int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0, flags = 0;
 	struct option options[] = {
 		OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")),
-		OPT_BOOLEAN('d', NULL, &delete, N_("delete the reference")),
-		OPT_BOOLEAN( 0 , "no-deref", &no_deref,
+		OPT_BOOL('d', NULL, &delete, N_("delete the reference")),
+		OPT_BOOL( 0 , "no-deref", &no_deref,
 					N_("update <refname> not the one it points to")),
+		OPT_BOOL('z', NULL, &end_null, N_("stdin has NUL-terminated arguments")),
+		OPT_BOOL( 0 , "stdin", &read_stdin, N_("read updates from stdin")),
 		OPT_END(),
 	};
 
@@ -28,6 +266,18 @@
 	if (msg && !*msg)
 		die("Refusing to perform update with empty message.");
 
+	if (read_stdin) {
+		if (delete || no_deref || argc > 0)
+			usage_with_options(git_update_ref_usage, options);
+		if (end_null)
+			line_termination = '\0';
+		update_refs_stdin();
+		return update_refs(msg, updates, updates_count, DIE_ON_ERR);
+	}
+
+	if (end_null)
+		usage_with_options(git_update_ref_usage, options);
+
 	if (delete) {
 		if (argc < 1 || argc > 2)
 			usage_with_options(git_update_ref_usage, options);
diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c
index af2da35..32ab94c 100644
--- a/builtin/upload-archive.c
+++ b/builtin/upload-archive.c
@@ -37,7 +37,7 @@
 		if (sent_argv.argc > MAX_ARGS)
 			die("Too many options (>%d)", MAX_ARGS - 1);
 
-		if (prefixcmp(buf, arg_cmd))
+		if (!starts_with(buf, arg_cmd))
 			die("'argument' token or flush expected");
 		argv_array_push(&sent_argv, buf + strlen(arg_cmd));
 	}
diff --git a/bundle.c b/bundle.c
index 3d64311..e99065c 100644
--- a/bundle.c
+++ b/bundle.c
@@ -7,6 +7,7 @@
 #include "list-objects.h"
 #include "run-command.h"
 #include "refs.h"
+#include "argv-array.h"
 
 static const char bundle_signature[] = "# v2 git bundle\n";
 
@@ -234,13 +235,13 @@
 }
 
 int create_bundle(struct bundle_header *header, const char *path,
-		int argc, const char **argv)
+		  int argc, const char **argv)
 {
 	static struct lock_file lock;
 	int bundle_fd = -1;
 	int bundle_to_stdout;
-	const char **argv_boundary = xmalloc((argc + 4) * sizeof(const char *));
-	const char **argv_pack = xmalloc(6 * sizeof(const char *));
+	struct argv_array argv_boundary = ARGV_ARRAY_INIT;
+	struct argv_array argv_pack = ARGV_ARRAY_INIT;
 	int i, ref_count = 0;
 	struct strbuf buf = STRBUF_INIT;
 	struct rev_info revs;
@@ -262,13 +263,14 @@
 	init_revisions(&revs, NULL);
 
 	/* write prerequisites */
-	memcpy(argv_boundary + 3, argv + 1, argc * sizeof(const char *));
-	argv_boundary[0] = "rev-list";
-	argv_boundary[1] = "--boundary";
-	argv_boundary[2] = "--pretty=oneline";
-	argv_boundary[argc + 2] = NULL;
+	argv_array_pushl(&argv_boundary,
+			 "rev-list", "--boundary", "--pretty=oneline",
+			 NULL);
+	for (i = 1; i < argc; i++)
+		argv_array_push(&argv_boundary, argv[i]);
+
 	memset(&rls, 0, sizeof(rls));
-	rls.argv = argv_boundary;
+	rls.argv = argv_boundary.argv;
 	rls.out = -1;
 	rls.git_cmd = 1;
 	if (start_command(&rls))
@@ -383,14 +385,12 @@
 	write_or_die(bundle_fd, "\n", 1);
 
 	/* write pack */
-	argv_pack[0] = "pack-objects";
-	argv_pack[1] = "--all-progress-implied";
-	argv_pack[2] = "--stdout";
-	argv_pack[3] = "--thin";
-	argv_pack[4] = "--delta-base-offset";
-	argv_pack[5] = NULL;
+	argv_array_pushl(&argv_pack,
+			 "pack-objects", "--all-progress-implied",
+			 "--stdout", "--thin", "--delta-base-offset",
+			 NULL);
 	memset(&rls, 0, sizeof(rls));
-	rls.argv = argv_pack;
+	rls.argv = argv_pack.argv;
 	rls.in = -1;
 	rls.out = bundle_fd;
 	rls.git_cmd = 1;
diff --git a/cache.h b/cache.h
index 415d883..dc040fb 100644
--- a/cache.h
+++ b/cache.h
@@ -101,9 +101,9 @@
 
 #define CACHE_SIGNATURE 0x44495243	/* "DIRC" */
 struct cache_header {
-	unsigned int hdr_signature;
-	unsigned int hdr_version;
-	unsigned int hdr_entries;
+	uint32_t hdr_signature;
+	uint32_t hdr_version;
+	uint32_t hdr_entries;
 };
 
 #define INDEX_FORMAT_LB 2
@@ -115,8 +115,8 @@
  * check it for equality in the 32 bits we save.
  */
 struct cache_time {
-	unsigned int sec;
-	unsigned int nsec;
+	uint32_t sec;
+	uint32_t nsec;
 };
 
 struct stat_data {
@@ -189,6 +189,8 @@
 #error "CE_EXTENDED_FLAGS out of range"
 #endif
 
+struct pathspec;
+
 /*
  * Copy the sha1 and stat state of a cache entry from one to
  * another. But we never change the name, or the hash state!
@@ -312,6 +314,8 @@
 #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)
 #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
 #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
+#define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))
+#define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase))
 #define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase))
 #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))
 #define resolve_undo_clear() resolve_undo_clear_index(&the_index)
@@ -350,6 +354,7 @@
 #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
 #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
 #define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE"
+#define GIT_SHALLOW_FILE_ENVIRONMENT "GIT_SHALLOW_FILE"
 #define TEMPLATE_DIR_ENVIRONMENT "GIT_TEMPLATE_DIR"
 #define CONFIG_ENVIRONMENT "GIT_CONFIG"
 #define CONFIG_DATA_ENVIRONMENT "GIT_CONFIG_PARAMETERS"
@@ -365,6 +370,9 @@
 #define GIT_NOTES_REWRITE_REF_ENVIRONMENT "GIT_NOTES_REWRITE_REF"
 #define GIT_NOTES_REWRITE_MODE_ENVIRONMENT "GIT_NOTES_REWRITE_MODE"
 #define GIT_LITERAL_PATHSPECS_ENVIRONMENT "GIT_LITERAL_PATHSPECS"
+#define GIT_GLOB_PATHSPECS_ENVIRONMENT "GIT_GLOB_PATHSPECS"
+#define GIT_NOGLOB_PATHSPECS_ENVIRONMENT "GIT_NOGLOB_PATHSPECS"
+#define GIT_ICASE_PATHSPECS_ENVIRONMENT "GIT_ICASE_PATHSPECS"
 
 /*
  * This environment variable is expected to contain a boolean indicating
@@ -391,7 +399,6 @@
 extern int is_inside_git_dir(void);
 extern char *git_work_tree_cfg;
 extern int is_inside_work_tree(void);
-extern int have_git_dir(void);
 extern const char *get_git_dir(void);
 extern int is_git_directory(const char *path);
 extern char *get_object_directory(void);
@@ -412,6 +419,7 @@
 extern const char *setup_git_directory_gently(int *);
 extern const char *setup_git_directory(void);
 extern char *prefix_path(const char *prefix, int len, const char *path);
+extern char *prefix_path_gently(const char *prefix, int len, int *remaining, const char *path);
 extern const char *prefix_filename(const char *prefix, int len, const char *path);
 extern int check_filename(const char *prefix, const char *name);
 extern void verify_filename(const char *prefix,
@@ -449,7 +457,7 @@
 
 /* Initialize and use the cache information */
 extern int read_index(struct index_state *);
-extern int read_index_preload(struct index_state *, const char **pathspec);
+extern int read_index_preload(struct index_state *, const struct pathspec *pathspec);
 extern int read_index_from(struct index_state *, const char *path);
 extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
@@ -457,6 +465,8 @@
 extern int discard_index(struct index_state *);
 extern int unmerged_index(const struct index_state *);
 extern int verify_path(const char *path);
+extern struct cache_entry *index_dir_exists(struct index_state *istate, const char *name, int namelen);
+extern struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int igncase);
 extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase);
 extern int index_name_pos(const struct index_state *, const char *name, int namelen);
 #define ADD_CACHE_OK_TO_ADD 1		/* Ok to add */
@@ -491,28 +501,8 @@
 extern int ie_match_stat(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
 extern int ie_modified(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
 
-#define PATHSPEC_ONESTAR 1	/* the pathspec pattern satisfies GFNM_ONESTAR */
-
-struct pathspec {
-	const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
-	int nr;
-	unsigned int has_wildcard:1;
-	unsigned int recursive:1;
-	int max_depth;
-	struct pathspec_item {
-		const char *match;
-		int len;
-		int nowildcard_len;
-		int flags;
-	} *items;
-};
-
-extern int init_pathspec(struct pathspec *, const char **);
-extern void free_pathspec(struct pathspec *);
 extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
 
-extern int limit_pathspec_to_literal(void);
-
 #define HASH_WRITE_OBJECT 1
 #define HASH_FORMAT_CHECK 2
 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
@@ -540,7 +530,7 @@
 #define REFRESH_IGNORE_MISSING	0x0008	/* ignore non-existent */
 #define REFRESH_IGNORE_SUBMODULES	0x0010	/* ignore submodules */
 #define REFRESH_IN_PORCELAIN	0x0020	/* user friendly output, not "needs update" */
-extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, const char *header_msg);
+extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
 
 struct lock_file {
 	struct lock_file *next;
@@ -747,8 +737,29 @@
 };
 int git_config_perm(const char *var, const char *value);
 int adjust_shared_perm(const char *path);
-int safe_create_leading_directories(char *path);
-int safe_create_leading_directories_const(const char *path);
+
+/*
+ * Create the directory containing the named path, using care to be
+ * somewhat safe against races.  Return one of the scld_error values
+ * to indicate success/failure.
+ *
+ * SCLD_VANISHED indicates that one of the ancestor directories of the
+ * path existed at one point during the function call and then
+ * suddenly vanished, probably because another process pruned the
+ * directory while we were working.  To be robust against this kind of
+ * race, callers might want to try invoking the function again when it
+ * returns SCLD_VANISHED.
+ */
+enum scld_error {
+	SCLD_OK = 0,
+	SCLD_FAILED = -1,
+	SCLD_PERMS = -2,
+	SCLD_EXISTS = -3,
+	SCLD_VANISHED = -4
+};
+enum scld_error safe_create_leading_directories(char *path);
+enum scld_error safe_create_leading_directories_const(const char *path);
+
 int mkdir_in_gitdir(const char *path);
 extern void home_config_paths(char **global, char **xdg, char *file);
 extern char *expand_user_path(const char *path);
@@ -761,7 +772,9 @@
 const char *real_path(const char *path);
 const char *real_path_if_valid(const char *path);
 const char *absolute_path(const char *path);
+const char *remove_leading_path(const char *in, const char *prefix);
 const char *relative_path(const char *in, const char *prefix, struct strbuf *sb);
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
 int normalize_path_copy(char *dst, const char *src);
 int longest_ancestor_length(const char *path, struct string_list *prefixes);
 char *strip_path_suffix(const char *path, const char *suffix);
@@ -769,11 +782,11 @@
 int offset_1st_component(const char *path);
 
 /* object replacement */
-#define READ_SHA1_FILE_REPLACE 1
+#define LOOKUP_REPLACE_OBJECT 1
 extern void *read_sha1_file_extended(const unsigned char *sha1, enum object_type *type, unsigned long *size, unsigned flag);
 static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
 {
-	return read_sha1_file_extended(sha1, type, size, READ_SHA1_FILE_REPLACE);
+	return read_sha1_file_extended(sha1, type, size, LOOKUP_REPLACE_OBJECT);
 }
 extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
 static inline const unsigned char *lookup_replace_object(const unsigned char *sha1)
@@ -782,6 +795,12 @@
 		return sha1;
 	return do_lookup_replace_object(sha1);
 }
+static inline const unsigned char *lookup_replace_object_extended(const unsigned char *sha1, unsigned flag)
+{
+	if (!(flag & LOOKUP_REPLACE_OBJECT))
+		return sha1;
+	return lookup_replace_object(sha1);
+}
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
 extern int sha1_object_info(const unsigned char *, unsigned long *);
@@ -893,12 +912,15 @@
 
 extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
 extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
-extern int interpret_branch_name(const char *str, struct strbuf *);
+extern int interpret_branch_name(const char *str, int len, struct strbuf *);
 extern int get_sha1_mb(const char *str, unsigned char *sha1);
 
-extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules);
-extern const char *ref_rev_parse_rules[];
-#define ref_fetch_rules ref_rev_parse_rules
+/*
+ * Return true iff abbrev_name is a possible abbreviation for
+ * full_name according to the rules defined by ref_rev_parse_rules in
+ * refs.c.
+ */
+extern int refname_match(const char *abbrev_name, const char *full_name);
 
 extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
 extern int validate_headref(const char *ref);
@@ -984,6 +1006,7 @@
 		 refresh_cache:1;
 };
 
+#define TEMPORARY_FILENAME_LENGTH 25
 extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
 
 struct cache_def {
@@ -1047,67 +1070,6 @@
 	struct packed_git *p;
 };
 
-struct ref {
-	struct ref *next;
-	unsigned char old_sha1[20];
-	unsigned char new_sha1[20];
-	char *symref;
-	unsigned int
-		force:1,
-		forced_update:1,
-		deletion:1,
-		matched:1;
-
-	/*
-	 * Order is important here, as we write to FETCH_HEAD
-	 * in numeric order. And the default NOT_FOR_MERGE
-	 * should be 0, so that xcalloc'd structures get it
-	 * by default.
-	 */
-	enum {
-		FETCH_HEAD_MERGE = -1,
-		FETCH_HEAD_NOT_FOR_MERGE = 0,
-		FETCH_HEAD_IGNORE = 1
-	} fetch_head_status;
-
-	enum {
-		REF_STATUS_NONE = 0,
-		REF_STATUS_OK,
-		REF_STATUS_REJECT_NONFASTFORWARD,
-		REF_STATUS_REJECT_ALREADY_EXISTS,
-		REF_STATUS_REJECT_NODELETE,
-		REF_STATUS_REJECT_FETCH_FIRST,
-		REF_STATUS_REJECT_NEEDS_FORCE,
-		REF_STATUS_UPTODATE,
-		REF_STATUS_REMOTE_REJECT,
-		REF_STATUS_EXPECTING_REPORT
-	} status;
-	char *remote_status;
-	struct ref *peer_ref; /* when renaming */
-	char name[FLEX_ARRAY]; /* more */
-};
-
-#define REF_NORMAL	(1u << 0)
-#define REF_HEADS	(1u << 1)
-#define REF_TAGS	(1u << 2)
-
-extern struct ref *find_ref_by_name(const struct ref *list, const char *name);
-
-#define CONNECT_VERBOSE       (1u << 0)
-extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
-extern int finish_connect(struct child_process *conn);
-extern int git_connection_is_socket(struct child_process *conn);
-struct extra_have_objects {
-	int nr, alloc;
-	unsigned char (*array)[20];
-};
-extern struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
-				     struct ref **list, unsigned int flags,
-				     struct extra_have_objects *);
-extern int server_supports(const char *feature);
-extern int parse_feature_request(const char *features, const char *feature);
-extern const char *server_feature_value(const char *feature, int *len_ret);
-
 extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
 
 /* A hook for count-objects to report invalid files in pack directory */
@@ -1143,6 +1105,7 @@
 	enum object_type *typep;
 	unsigned long *sizep;
 	unsigned long *disk_sizep;
+	unsigned char *delta_base_sha1;
 
 	/* Response */
 	enum {
@@ -1167,7 +1130,7 @@
 		} packed;
 	} u;
 };
-extern int sha1_object_info_extended(const unsigned char *, struct object_info *);
+extern int sha1_object_info_extended(const unsigned char *, struct object_info *, unsigned flags);
 
 /* Dumb servers support */
 extern int update_server_info(int);
@@ -1198,6 +1161,7 @@
 extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
 extern int git_parse_ulong(const char *, unsigned long *);
 extern int git_config_int(const char *, const char *);
+extern int64_t git_config_int64(const char *, const char *);
 extern unsigned long git_config_ulong(const char *, const char *);
 extern int git_config_bool_or_int(const char *, const char *, int *);
 extern int git_config_bool(const char *, const char *);
@@ -1304,6 +1268,8 @@
 extern void trace_argv_printf(const char **argv, const char *format, ...);
 extern void trace_repo_setup(const char *prefix);
 extern int trace_want(const char *key);
+__attribute__((format (printf, 2, 3)))
+extern void trace_printf_key(const char *key, const char *fmt, ...);
 extern void trace_strbuf(const char *key, const struct strbuf *buf);
 
 void packet_trace_identity(const char *prog);
@@ -1313,7 +1279,7 @@
  * return 0 if success, 1 - if addition of a file failed and
  * ADD_FILES_IGNORE_ERRORS was specified in flags
  */
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags);
+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);
 
 /* diff.c */
 extern int diff_auto_refresh_index;
@@ -1347,7 +1313,7 @@
 #define ws_tab_width(rule)     ((rule) & WS_TAB_WIDTH_MASK)
 
 /* ls-files */
-int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix);
+int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix);
 void overlay_tree_on_cache(const char *tree_name, const char *prefix);
 
 char *alias_lookup(const char *alias);
diff --git a/combine-diff.c b/combine-diff.c
index 4fc16ad..3b92c448 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1306,7 +1306,7 @@
 	int i, num_paths, needsep, show_log_first, num_parent = parents->nr;
 
 	diffopts = *opt;
-	diff_tree_setup_paths(diffopts.pathspec.raw, &diffopts);
+	copy_pathspec(&diffopts.pathspec, &opt->pathspec);
 	diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
 	DIFF_OPT_SET(&diffopts, RECURSIVE);
 	DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL);
@@ -1378,7 +1378,7 @@
 		free(tmp);
 	}
 
-	diff_tree_release_paths(&diffopts);
+	free_pathspec(&diffopts.pathspec);
 }
 
 void diff_tree_combined_merge(const struct commit *commit, int dense,
diff --git a/command-list.txt b/command-list.txt
index 08b04e2..cf36c3d 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -64,7 +64,6 @@
 git-instaweb                            ancillaryinterrogators
 gitk                                    mainporcelain
 git-log                                 mainporcelain common
-git-lost-found                          ancillarymanipulators	deprecated
 git-ls-files                            plumbinginterrogators
 git-ls-remote                           plumbinginterrogators
 git-ls-tree                             plumbinginterrogators
@@ -88,7 +87,6 @@
 git-pack-refs                           ancillarymanipulators
 git-parse-remote                        synchelpers
 git-patch-id                            purehelpers
-git-peek-remote                         purehelpers	deprecated
 git-prune                               ancillarymanipulators
 git-prune-packed                        plumbingmanipulators
 git-pull                                mainporcelain common
@@ -102,7 +100,6 @@
 git-remote                              ancillarymanipulators
 git-repack                              ancillarymanipulators
 git-replace                             ancillarymanipulators
-git-repo-config                         ancillarymanipulators	deprecated
 git-request-pull                        foreignscminterface
 git-rerere                              ancillaryinterrogators
 git-reset                               mainporcelain common
@@ -127,7 +124,6 @@
 git-svn                                 foreignscminterface
 git-symbolic-ref                        plumbingmanipulators
 git-tag                                 mainporcelain common
-git-tar-tree                            plumbinginterrogators	deprecated
 git-unpack-file                         plumbinginterrogators
 git-unpack-objects                      plumbingmanipulators
 git-update-index                        plumbingmanipulators
diff --git a/commit-slab.h b/commit-slab.h
index d4c8286..cc114b5 100644
--- a/commit-slab.h
+++ b/commit-slab.h
@@ -22,8 +22,17 @@
  *
  *   Initializes the indegree slab that associates an array of integers
  *   to each commit. 'stride' specifies how big each array is.  The slab
- *   that id initialied by the variant without "_with_stride" associates
+ *   that is initialized by the variant without "_with_stride" associates
  *   each commit with an array of one integer.
+ *
+ * - void clear_indegree(struct indegree *);
+ *
+ *   Empties the slab.  The slab can be reused with the same stride
+ *   without calling init_indegree() again or can be reconfigured to a
+ *   different stride by calling init_indegree_with_stride().
+ *
+ *   Call this function before the slab falls out of scope to avoid
+ *   leaking memory.
  */
 
 /* allocate ~512kB at once, allowing for malloc overhead */
@@ -31,6 +40,8 @@
 #define COMMIT_SLAB_SIZE (512*1024-32)
 #endif
 
+#define MAYBE_UNUSED __attribute__((__unused__))
+
 #define define_commit_slab(slabname, elemtype) 				\
 									\
 struct slabname {							\
@@ -41,8 +52,8 @@
 };									\
 static int stat_ ##slabname## realloc;					\
 									\
-static void init_ ##slabname## _with_stride(struct slabname *s,		\
-					    unsigned stride)		\
+static MAYBE_UNUSED void init_ ##slabname## _with_stride(struct slabname *s, \
+						   unsigned stride)	\
 {									\
 	unsigned int elem_size;						\
 	if (!stride)							\
@@ -54,12 +65,12 @@
 	s->slab = NULL;							\
 }									\
 									\
-static void init_ ##slabname(struct slabname *s)			\
+static MAYBE_UNUSED void init_ ##slabname(struct slabname *s)		\
 {									\
 	init_ ##slabname## _with_stride(s, 1);				\
 }									\
 									\
-static void clear_ ##slabname(struct slabname *s)			\
+static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s)		\
 {									\
 	int i;								\
 	for (i = 0; i < s->slab_count; i++)				\
@@ -69,8 +80,8 @@
 	s->slab = NULL;							\
 }									\
 									\
-static elemtype *slabname## _at(struct slabname *s,			\
-				const struct commit *c)			\
+static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,	\
+				       const struct commit *c)		\
 {									\
 	int nth_slab, nth_slot;						\
 									\
@@ -80,7 +91,7 @@
 	if (s->slab_count <= nth_slab) {				\
 		int i;							\
 		s->slab = xrealloc(s->slab,				\
-				   (nth_slab + 1) * sizeof(s->slab));	\
+				   (nth_slab + 1) * sizeof(*s->slab));	\
 		stat_ ##slabname## realloc++;				\
 		for (i = s->slab_count; i <= nth_slab; i++)		\
 			s->slab[i] = NULL;				\
@@ -94,4 +105,16 @@
 									\
 static int stat_ ##slabname## realloc
 
+/*
+ * Note that this seemingly redundant second declaration is required
+ * to allow a terminating semicolon, which makes instantiations look
+ * like function declarations.  I.e., the expansion of
+ *
+ *    define_commit_slab(indegree, int);
+ *
+ * ends in 'static int stat_indegreerealloc;'.  This would otherwise
+ * be a syntax error according (at least) to ISO C.  It's hard to
+ * catch because GCC silently parses it by default.
+ */
+
 #endif /* COMMIT_SLAB_H */
diff --git a/commit.c b/commit.c
index de16a3c..6bf4fe0 100644
--- a/commit.c
+++ b/commit.c
@@ -79,7 +79,7 @@
 	if (get_sha1_committish(name, sha1))
 		return NULL;
 	commit = lookup_commit_reference(sha1);
-	if (!commit || parse_commit(commit))
+	if (parse_commit(commit))
 		return NULL;
 	return commit;
 }
@@ -196,19 +196,19 @@
 static int read_graft_file(const char *graft_file)
 {
 	FILE *fp = fopen(graft_file, "r");
-	char buf[1024];
+	struct strbuf buf = STRBUF_INIT;
 	if (!fp)
 		return -1;
-	while (fgets(buf, sizeof(buf), fp)) {
+	while (!strbuf_getwholeline(&buf, fp, '\n')) {
 		/* The format is just "Commit Parent1 Parent2 ...\n" */
-		int len = strlen(buf);
-		struct commit_graft *graft = read_graft_line(buf, len);
+		struct commit_graft *graft = read_graft_line(buf.buf, buf.len);
 		if (!graft)
 			continue;
 		if (register_commit_graft(graft, 1))
-			error("duplicate graft data: %s", buf);
+			error("duplicate graft data: %s", buf.buf);
 	}
 	fclose(fp);
+	strbuf_release(&buf);
 	return 0;
 }
 
@@ -341,6 +341,13 @@
 	return ret;
 }
 
+void parse_commit_or_die(struct commit *item)
+{
+	if (parse_commit(item))
+		die("unable to parse commit %s",
+		    item ? sha1_to_hex(item->object.sha1) : "(null)");
+}
+
 int find_commit_subject(const char *commit_buffer, const char **subject)
 {
 	const char *eol;
@@ -559,7 +566,7 @@
 	     buf;
 	     buf = line_end + 1) {
 		line_end = strchrnul(buf, '\n');
-		if (prefixcmp(buf, "author ")) {
+		if (!starts_with(buf, "author ")) {
 			if (!line_end[0] || line_end[1] == '\n')
 				return; /* end of header */
 			continue;
@@ -834,26 +841,26 @@
 struct commit_list *get_octopus_merge_bases(struct commit_list *in)
 {
 	struct commit_list *i, *j, *k, *ret = NULL;
-	struct commit_list **pptr = &ret;
 
-	for (i = in; i; i = i->next) {
-		if (!ret)
-			pptr = &commit_list_insert(i->item, pptr)->next;
-		else {
-			struct commit_list *new = NULL, *end = NULL;
+	if (!in)
+		return ret;
 
-			for (j = ret; j; j = j->next) {
-				struct commit_list *bases;
-				bases = get_merge_bases(i->item, j->item, 1);
-				if (!new)
-					new = bases;
-				else
-					end->next = bases;
-				for (k = bases; k; k = k->next)
-					end = k;
-			}
-			ret = new;
+	commit_list_insert(in->item, &ret);
+
+	for (i = in->next; i; i = i->next) {
+		struct commit_list *new = NULL, *end = NULL;
+
+		for (j = ret; j; j = j->next) {
+			struct commit_list *bases;
+			bases = get_merge_bases(i->item, j->item, 1);
+			if (!new)
+				new = bases;
+			else
+				end->next = bases;
+			for (k = bases; k; k = k->next)
+				end = k;
 		}
+		ret = new;
 	}
 	return ret;
 }
@@ -1106,7 +1113,7 @@
 		next = next ? next + 1 : tail;
 		if (in_signature && line[0] == ' ')
 			sig = line + 1;
-		else if (!prefixcmp(line, gpg_sig_header) &&
+		else if (starts_with(line, gpg_sig_header) &&
 			 line[gpg_sig_header_len] == ' ')
 			sig = line + gpg_sig_header_len + 1;
 		if (sig) {
@@ -1186,7 +1193,7 @@
 	for (i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) {
 		const char *found, *next;
 
-		if (!prefixcmp(buf, sigcheck_gpg_status[i].check + 1)) {
+		if (starts_with(buf, sigcheck_gpg_status[i].check + 1)) {
 			/* At the very beginning of the buffer */
 			found = buf + strlen(sigcheck_gpg_status[i].check + 1);
 		} else {
@@ -1349,7 +1356,7 @@
 	}
 }
 
-int commit_tree(const struct strbuf *msg, unsigned char *tree,
+int commit_tree(const struct strbuf *msg, const unsigned char *tree,
 		struct commit_list *parents, unsigned char *ret,
 		const char *author, const char *sign_commit)
 {
@@ -1478,7 +1485,7 @@
 "You may want to amend it after fixing the message, or set the config\n"
 "variable i18n.commitencoding to the encoding your project uses.\n";
 
-int commit_tree_extended(const struct strbuf *msg, unsigned char *tree,
+int commit_tree_extended(const struct strbuf *msg, const unsigned char *tree,
 			 struct commit_list *parents, unsigned char *ret,
 			 const char *author, const char *sign_commit,
 			 struct commit_extra_header *extra)
diff --git a/commit.h b/commit.h
index c308674..16d9c43 100644
--- a/commit.h
+++ b/commit.h
@@ -49,6 +49,7 @@
 
 int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size);
 int parse_commit(struct commit *item);
+void parse_commit_or_die(struct commit *item);
 
 /* Find beginning and length of commit subject. */
 int find_commit_subject(const char *commit_buffer, const char **subject);
@@ -193,6 +194,8 @@
 /* largest positive number a signed 32-bit integer can contain */
 #define INFINITE_DEPTH 0x7fffffff
 
+struct sha1_array;
+struct ref;
 extern int register_shallow(const unsigned char *sha1);
 extern int unregister_shallow(const unsigned char *sha1);
 extern int for_each_commit_graft(each_commit_graft_fn, void *);
@@ -200,11 +203,38 @@
 extern struct commit_list *get_shallow_commits(struct object_array *heads,
 		int depth, int shallow_flag, int not_shallow_flag);
 extern void check_shallow_file_for_update(void);
-extern void set_alternate_shallow_file(const char *path);
-extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol);
+extern void set_alternate_shallow_file(const char *path, int override);
+extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
+				 const struct sha1_array *extra);
 extern void setup_alternate_shallow(struct lock_file *shallow_lock,
-				    const char **alternate_shallow_file);
-extern char *setup_temporary_shallow(void);
+				    const char **alternate_shallow_file,
+				    const struct sha1_array *extra);
+extern char *setup_temporary_shallow(const struct sha1_array *extra);
+extern void advertise_shallow_grafts(int);
+
+struct shallow_info {
+	struct sha1_array *shallow;
+	int *ours, nr_ours;
+	int *theirs, nr_theirs;
+	struct sha1_array *ref;
+
+	/* for receive-pack */
+	uint32_t **used_shallow;
+	int *need_reachability_test;
+	int *reachable;
+	int *shallow_ref;
+	struct commit **commits;
+	int nr_commits;
+};
+
+extern void prepare_shallow_info(struct shallow_info *, struct sha1_array *);
+extern void clear_shallow_info(struct shallow_info *);
+extern void remove_nonexistent_theirs_shallow(struct shallow_info *);
+extern void assign_shallow_commits_to_refs(struct shallow_info *info,
+					   uint32_t **used,
+					   int *ref_status);
+extern int delayed_reachability_test(struct shallow_info *si, int c);
+extern void prune_shallow(int show_only);
 
 int is_descendant_of(struct commit *, struct commit_list *);
 int in_merge_bases(struct commit *, struct commit *);
@@ -212,7 +242,7 @@
 
 extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
 extern int run_add_interactive(const char *revision, const char *patch_mode,
-			       const char **pathspec);
+			       const struct pathspec *pathspec);
 
 static inline int single_parent(struct commit *commit)
 {
@@ -231,11 +261,11 @@
 extern void append_merge_tag_headers(struct commit_list *parents,
 				     struct commit_extra_header ***tail);
 
-extern int commit_tree(const struct strbuf *msg, unsigned char *tree,
+extern int commit_tree(const struct strbuf *msg, const unsigned char *tree,
 		       struct commit_list *parents, unsigned char *ret,
 		       const char *author, const char *sign_commit);
 
-extern int commit_tree_extended(const struct strbuf *msg, unsigned char *tree,
+extern int commit_tree_extended(const struct strbuf *msg, const unsigned char *tree,
 				struct commit_list *parents, unsigned char *ret,
 				const char *author, const char *sign_commit,
 				struct commit_extra_header *);
diff --git a/compat/apple-common-crypto.h b/compat/apple-common-crypto.h
new file mode 100644
index 0000000..c8b9b0e
--- /dev/null
+++ b/compat/apple-common-crypto.h
@@ -0,0 +1,86 @@
+/* suppress inclusion of conflicting openssl functions */
+#define OPENSSL_NO_MD5
+#define HEADER_HMAC_H
+#define HEADER_SHA_H
+#include <CommonCrypto/CommonHMAC.h>
+#define HMAC_CTX CCHmacContext
+#define HMAC_Init(hmac, key, len, algo) CCHmacInit(hmac, algo, key, len)
+#define HMAC_Update CCHmacUpdate
+#define HMAC_Final(hmac, hash, ptr) CCHmacFinal(hmac, hash)
+#define HMAC_CTX_cleanup(ignore)
+#define EVP_md5(...) kCCHmacAlgMD5
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+#define APPLE_LION_OR_NEWER
+#include <Security/Security.h>
+/* Apple's TYPE_BOOL conflicts with config.c */
+#undef TYPE_BOOL
+#endif
+
+#ifdef APPLE_LION_OR_NEWER
+#define git_CC_error_check(pattern, err) \
+	do { \
+		if (err) { \
+			die(pattern, (long)CFErrorGetCode(err)); \
+		} \
+	} while(0)
+
+#define EVP_EncodeBlock git_CC_EVP_EncodeBlock
+static inline int git_CC_EVP_EncodeBlock(unsigned char *out,
+		const unsigned char *in, int inlen)
+{
+	CFErrorRef err;
+	SecTransformRef encoder;
+	CFDataRef input, output;
+	CFIndex length;
+
+	encoder = SecEncodeTransformCreate(kSecBase64Encoding, &err);
+	git_CC_error_check("SecEncodeTransformCreate failed: %ld", err);
+
+	input = CFDataCreate(kCFAllocatorDefault, in, inlen);
+	SecTransformSetAttribute(encoder, kSecTransformInputAttributeName,
+			input, &err);
+	git_CC_error_check("SecTransformSetAttribute failed: %ld", err);
+
+	output = SecTransformExecute(encoder, &err);
+	git_CC_error_check("SecTransformExecute failed: %ld", err);
+
+	length = CFDataGetLength(output);
+	CFDataGetBytes(output, CFRangeMake(0, length), out);
+
+	CFRelease(output);
+	CFRelease(input);
+	CFRelease(encoder);
+
+	return (int)strlen((const char *)out);
+}
+
+#define EVP_DecodeBlock git_CC_EVP_DecodeBlock
+static int inline git_CC_EVP_DecodeBlock(unsigned char *out,
+		const unsigned char *in, int inlen)
+{
+	CFErrorRef err;
+	SecTransformRef decoder;
+	CFDataRef input, output;
+	CFIndex length;
+
+	decoder = SecDecodeTransformCreate(kSecBase64Encoding, &err);
+	git_CC_error_check("SecEncodeTransformCreate failed: %ld", err);
+
+	input = CFDataCreate(kCFAllocatorDefault, in, inlen);
+	SecTransformSetAttribute(decoder, kSecTransformInputAttributeName,
+			input, &err);
+	git_CC_error_check("SecTransformSetAttribute failed: %ld", err);
+
+	output = SecTransformExecute(decoder, &err);
+	git_CC_error_check("SecTransformExecute failed: %ld", err);
+
+	length = CFDataGetLength(output);
+	CFDataGetBytes(output, CFRangeMake(0, length), out);
+
+	CFRelease(output);
+	CFRelease(input);
+	CFRelease(decoder);
+
+	return (int)strlen((const char *)out);
+}
+#endif /* APPLE_LION_OR_NEWER */
diff --git a/compat/mingw.c b/compat/mingw.c
index bb92c43..e9892f8 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -304,23 +304,6 @@
 	return fd;
 }
 
-#undef write
-ssize_t mingw_write(int fd, const void *buf, size_t count)
-{
-	/*
-	 * While write() calls to a file on a local disk are translated
-	 * into WriteFile() calls with a maximum size of 64KB on Windows
-	 * XP and 256KB on Vista, no such cap is placed on writes to
-	 * files over the network on Windows XP.  Unfortunately, there
-	 * seems to be a limit of 32MB-28KB on X64 and 64MB-32KB on x86;
-	 * bigger writes fail on Windows XP.
-	 * So we cap to a nice 31MB here to avoid write failures over
-	 * the net without changing the number of WriteFile() calls in
-	 * the local case.
-	 */
-	return write(fd, buf, min(count, 31 * 1024 * 1024));
-}
-
 static BOOL WINAPI ctrl_ignore(DWORD type)
 {
 	return TRUE;
@@ -491,7 +474,6 @@
 	return do_stat_internal(1, file_name, buf);
 }
 
-#undef fstat
 int mingw_fstat(int fd, struct stat *buf)
 {
 	HANDLE fh = (HANDLE)_get_osfhandle(fd);
@@ -1086,6 +1068,12 @@
 		errno = err_win_to_posix(GetLastError());
 		CloseHandle(h);
 		return -1;
+	} else if (pid > 0 && sig == 0) {
+		HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+		if (h) {
+			CloseHandle(h);
+			return 0;
+		}
 	}
 
 	errno = EINVAL;
diff --git a/compat/mingw.h b/compat/mingw.h
index bd0a88b..e033e72 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -32,7 +32,9 @@
 #define WEXITSTATUS(x) ((x) & 0xff)
 #define WTERMSIG(x) SIGTERM
 
+#ifndef EWOULDBLOCK
 #define EWOULDBLOCK EAGAIN
+#endif
 #define SHUT_WR SD_SEND
 
 #define SIGHUP 1
@@ -46,8 +48,12 @@
 #define F_SETFD 2
 #define FD_CLOEXEC 0x1
 
+#ifndef EAFNOSUPPORT
 #define EAFNOSUPPORT WSAEAFNOSUPPORT
+#endif
+#ifndef ECONNABORTED
 #define ECONNABORTED WSAECONNABORTED
+#endif
 
 struct passwd {
 	char *pw_name;
@@ -174,9 +180,6 @@
 int mingw_open (const char *filename, int oflags, ...);
 #define open mingw_open
 
-ssize_t mingw_write(int fd, const void *buf, size_t count);
-#define write mingw_write
-
 int mingw_fgetc(FILE *stream);
 #define fgetc mingw_fgetc
 
@@ -258,19 +261,35 @@
 	return 0;
 }
 
-/* Use mingw_lstat() instead of lstat()/stat() and
- * mingw_fstat() instead of fstat() on Windows.
+/*
+ * Use mingw specific stat()/lstat()/fstat() implementations on Windows.
  */
 #define off_t off64_t
 #define lseek _lseeki64
-#ifndef ALREADY_DECLARED_STAT_FUNCS
+
+/* use struct stat with 64 bit st_size */
+#ifdef stat
+#undef stat
+#endif
 #define stat _stati64
 int mingw_lstat(const char *file_name, struct stat *buf);
 int mingw_stat(const char *file_name, struct stat *buf);
 int mingw_fstat(int fd, struct stat *buf);
+#ifdef fstat
+#undef fstat
+#endif
 #define fstat mingw_fstat
+#ifdef lstat
+#undef lstat
+#endif
 #define lstat mingw_lstat
-#define _stati64(x,y) mingw_stat(x,y)
+
+#ifndef _stati64
+# define _stati64(x,y) mingw_stat(x,y)
+#elif defined (_USE_32BIT_TIME_T)
+# define _stat32i64(x,y) mingw_stat(x,y)
+#else
+# define _stat64(x,y) mingw_stat(x,y)
 #endif
 
 int mingw_utime(const char *file_name, const struct utimbuf *times);
@@ -322,6 +341,7 @@
 #define find_last_dir_sep mingw_find_last_dir_sep
 #define PATH_SEP ';'
 #define PRIuMAX "I64u"
+#define PRId64 "I64d"
 
 void mingw_open_html(const char *path);
 #define open_html mingw_open_html
diff --git a/compat/msvc.h b/compat/msvc.h
index 96b6d60..580bb55 100644
--- a/compat/msvc.h
+++ b/compat/msvc.h
@@ -24,21 +24,6 @@
 
 #undef ERROR
 
-/* Use mingw_lstat() instead of lstat()/stat() and mingw_fstat() instead
- * of fstat(). We add the declaration of these functions here, suppressing
- * the corresponding declarations in mingw.h, so that we can use the
- * appropriate structure type (and function) names from the msvc headers.
- */
-#define stat _stat64
-int mingw_lstat(const char *file_name, struct stat *buf);
-int mingw_fstat(int fd, struct stat *buf);
-#define fstat mingw_fstat
-#define lstat mingw_lstat
-#define _stat64(x,y) mingw_lstat(x,y)
-#define ALREADY_DECLARED_STAT_FUNCS
-
 #include "compat/mingw.h"
 
-#undef ALREADY_DECLARED_STAT_FUNCS
-
 #endif
diff --git a/compat/nedmalloc/malloc.c.h b/compat/nedmalloc/malloc.c.h
index ed4f1fa..f216a2a 100644
--- a/compat/nedmalloc/malloc.c.h
+++ b/compat/nedmalloc/malloc.c.h
@@ -499,7 +499,9 @@
 #endif  /* WIN32 */
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
+#ifndef _WIN32_WINNT
 #define _WIN32_WINNT 0x403
+#endif
 #include <windows.h>
 #define HAVE_MMAP 1
 #define HAVE_MORECORE 0
diff --git a/compat/poll/poll.c b/compat/poll/poll.c
index 4410310..31163f2 100644
--- a/compat/poll/poll.c
+++ b/compat/poll/poll.c
@@ -39,7 +39,7 @@
 
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 # define WIN32_NATIVE
-# if defined (_MSC_VER)
+# if defined (_MSC_VER) && !defined(_WIN32_WINNT)
 #  define _WIN32_WINNT 0x0502
 # endif
 # include <winsock2.h>
diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c
index 7980abd..95fe849 100644
--- a/compat/precompose_utf8.c
+++ b/compat/precompose_utf8.c
@@ -48,11 +48,8 @@
 	if (output_fd >= 0) {
 		close(output_fd);
 		strcpy(path + len, auml_nfd);
-		/* Indicate to the user, that we can configure it to true */
-		if (!access(path, R_OK))
-			git_config_set("core.precomposeunicode", "false");
-		/* To be backward compatible, set precomposed_unicode to 0 */
-		precomposed_unicode = 0;
+		precomposed_unicode = access(path, R_OK) ? 0 : 1;
+		git_config_set("core.precomposeunicode", precomposed_unicode ? "true" : "false");
 		strcpy(path + len, auml_nfc);
 		if (unlink(path))
 			die_errno(_("failed to unlink '%s'"), path);
diff --git a/compat/regex/regcomp.c b/compat/regex/regcomp.c
index b2c5d46..06f3088 100644
--- a/compat/regex/regcomp.c
+++ b/compat/regex/regcomp.c
@@ -339,7 +339,7 @@
 	      p = buf;
 	      *p++ = dfa->nodes[node].opr.c;
 	      while (++node < dfa->nodes_len
-		     &&	dfa->nodes[node].type == CHARACTER
+		     && dfa->nodes[node].type == CHARACTER
 		     && dfa->nodes[node].mb_partial)
 		*p++ = dfa->nodes[node].opr.c;
 	      memset (&state, '\0', sizeof (state));
diff --git a/compat/vcbuild/scripts/clink.pl b/compat/vcbuild/scripts/clink.pl
old mode 100644
new mode 100755
diff --git a/compat/vcbuild/scripts/lib.pl b/compat/vcbuild/scripts/lib.pl
old mode 100644
new mode 100755
diff --git a/config.c b/config.c
index 9f9bf0c..d969a5a 100644
--- a/config.c
+++ b/config.c
@@ -468,7 +468,7 @@
 	return 0;
 }
 
-static int git_parse_long(const char *value, long *ret)
+static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
 {
 	if (value && *value) {
 		char *end;
@@ -480,21 +480,25 @@
 		val = strtoimax(value, &end, 0);
 		if (errno == ERANGE)
 			return 0;
-		if (!parse_unit_factor(end, &factor))
+		if (!parse_unit_factor(end, &factor)) {
+			errno = EINVAL;
 			return 0;
+		}
 		uval = abs(val);
 		uval *= factor;
-		if ((uval > maximum_signed_value_of_type(long)) ||
-		    (abs(val) > uval))
+		if (uval > max || abs(val) > uval) {
+			errno = ERANGE;
 			return 0;
+		}
 		val *= factor;
 		*ret = val;
 		return 1;
 	}
+	errno = EINVAL;
 	return 0;
 }
 
-int git_parse_ulong(const char *value, unsigned long *ret)
+static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
 {
 	if (value && *value) {
 		char *end;
@@ -506,29 +510,75 @@
 		if (errno == ERANGE)
 			return 0;
 		oldval = val;
-		if (!parse_unit_factor(end, &val))
+		if (!parse_unit_factor(end, &val)) {
+			errno = EINVAL;
 			return 0;
-		if ((val > maximum_unsigned_value_of_type(long)) ||
-		    (oldval > val))
+		}
+		if (val > max || oldval > val) {
+			errno = ERANGE;
 			return 0;
+		}
 		*ret = val;
 		return 1;
 	}
+	errno = EINVAL;
 	return 0;
 }
 
-static void die_bad_config(const char *name)
+static int git_parse_int(const char *value, int *ret)
 {
+	intmax_t tmp;
+	if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int)))
+		return 0;
+	*ret = tmp;
+	return 1;
+}
+
+static int git_parse_int64(const char *value, int64_t *ret)
+{
+	intmax_t tmp;
+	if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int64_t)))
+		return 0;
+	*ret = tmp;
+	return 1;
+}
+
+int git_parse_ulong(const char *value, unsigned long *ret)
+{
+	uintmax_t tmp;
+	if (!git_parse_unsigned(value, &tmp, maximum_unsigned_value_of_type(long)))
+		return 0;
+	*ret = tmp;
+	return 1;
+}
+
+static void die_bad_number(const char *name, const char *value)
+{
+	const char *reason = errno == ERANGE ?
+			     "out of range" :
+			     "invalid unit";
+	if (!value)
+		value = "";
+
 	if (cf && cf->name)
-		die("bad config value for '%s' in %s", name, cf->name);
-	die("bad config value for '%s'", name);
+		die("bad numeric config value '%s' for '%s' in %s: %s",
+		    value, name, cf->name, reason);
+	die("bad numeric config value '%s' for '%s': %s", value, name, reason);
 }
 
 int git_config_int(const char *name, const char *value)
 {
-	long ret = 0;
-	if (!git_parse_long(value, &ret))
-		die_bad_config(name);
+	int ret;
+	if (!git_parse_int(value, &ret))
+		die_bad_number(name, value);
+	return ret;
+}
+
+int64_t git_config_int64(const char *name, const char *value)
+{
+	int64_t ret;
+	if (!git_parse_int64(value, &ret))
+		die_bad_number(name, value);
 	return ret;
 }
 
@@ -536,7 +586,7 @@
 {
 	unsigned long ret;
 	if (!git_parse_ulong(value, &ret))
-		die_bad_config(name);
+		die_bad_number(name, value);
 	return ret;
 }
 
@@ -559,10 +609,10 @@
 
 int git_config_maybe_bool(const char *name, const char *value)
 {
-	long v = git_config_maybe_bool_text(name, value);
+	int v = git_config_maybe_bool_text(name, value);
 	if (0 <= v)
 		return v;
-	if (git_parse_long(value, &v))
+	if (git_parse_int(value, &v))
 		return !!v;
 	return -1;
 }
@@ -919,25 +969,25 @@
 
 int git_default_config(const char *var, const char *value, void *dummy)
 {
-	if (!prefixcmp(var, "core."))
+	if (starts_with(var, "core."))
 		return git_default_core_config(var, value);
 
-	if (!prefixcmp(var, "user."))
+	if (starts_with(var, "user."))
 		return git_ident_config(var, value, dummy);
 
-	if (!prefixcmp(var, "i18n."))
+	if (starts_with(var, "i18n."))
 		return git_default_i18n_config(var, value);
 
-	if (!prefixcmp(var, "branch."))
+	if (starts_with(var, "branch."))
 		return git_default_branch_config(var, value);
 
-	if (!prefixcmp(var, "push."))
+	if (starts_with(var, "push."))
 		return git_default_push_config(var, value);
 
-	if (!prefixcmp(var, "mailmap."))
+	if (starts_with(var, "mailmap."))
 		return git_default_mailmap_config(var, value);
 
-	if (!prefixcmp(var, "advice."))
+	if (starts_with(var, "advice."))
 		return git_default_advice_config(var, value);
 
 	if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
@@ -1160,15 +1210,14 @@
  * Find all the stuff for git_config_set() below.
  */
 
-#define MAX_MATCHES 512
-
 static struct {
 	int baselen;
 	char *key;
 	int do_not_match;
 	regex_t *value_regex;
 	int multi_replace;
-	size_t offset[MAX_MATCHES];
+	size_t *offset;
+	unsigned int offset_alloc;
 	enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state;
 	int seen;
 } store;
@@ -1191,11 +1240,11 @@
 		if (matches(key, value)) {
 			if (store.seen == 1 && store.multi_replace == 0) {
 				warning("%s has multiple values", key);
-			} else if (store.seen >= MAX_MATCHES) {
-				error("too many matches for %s", key);
-				return 1;
 			}
 
+			ALLOC_GROW(store.offset, store.seen + 1,
+				   store.offset_alloc);
+
 			store.offset[store.seen] = cf->do_ftell(cf);
 			store.seen++;
 		}
@@ -1223,11 +1272,15 @@
 		 * Do not increment matches: this is no match, but we
 		 * just made sure we are in the desired section.
 		 */
+		ALLOC_GROW(store.offset, store.seen + 1,
+			   store.offset_alloc);
 		store.offset[store.seen] = cf->do_ftell(cf);
 		/* fallthru */
 	case SECTION_END_SEEN:
 	case START:
 		if (matches(key, value)) {
+			ALLOC_GROW(store.offset, store.seen + 1,
+				   store.offset_alloc);
 			store.offset[store.seen] = cf->do_ftell(cf);
 			store.state = KEY_SEEN;
 			store.seen++;
@@ -1235,6 +1288,9 @@
 			if (strrchr(key, '.') - key == store.baselen &&
 			      !strncmp(key, store.key, store.baselen)) {
 					store.state = SECTION_SEEN;
+					ALLOC_GROW(store.offset,
+						   store.seen + 1,
+						   store.offset_alloc);
 					store.offset[store.seen] = cf->do_ftell(cf);
 			}
 		}
@@ -1533,6 +1589,7 @@
 			}
 		}
 
+		ALLOC_GROW(store.offset, 1, store.offset_alloc);
 		store.offset[0] = 0;
 		store.state = START;
 		store.seen = 0;
@@ -1822,7 +1879,7 @@
 	const char *dot;
 
 	/* Does it start with "section." ? */
-	if (prefixcmp(var, section) || var[section_len] != '.')
+	if (!starts_with(var, section) || var[section_len] != '.')
 		return -1;
 
 	/*
diff --git a/config.mak.uname b/config.mak.uname
index 7d61531..7d31fad 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -198,6 +198,13 @@
 	BASIC_LDFLAGS += -L/usr/local/lib
 	HAVE_PATHS_H = YesPlease
 endif
+ifeq ($(uname_S),MirBSD)
+	NO_STRCASESTR = YesPlease
+	NO_MEMMEM = YesPlease
+	USE_ST_TIMESPEC = YesPlease
+	NEEDS_LIBICONV = YesPlease
+	HAVE_PATHS_H = YesPlease
+endif
 ifeq ($(uname_S),NetBSD)
 	ifeq ($(shell expr "$(uname_R)" : '[01]\.'),2)
 		NEEDS_LIBICONV = YesPlease
@@ -339,6 +346,7 @@
 	OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
 	NO_REGEX = YesPlease
 	NO_CURL = YesPlease
+	NO_GETTEXT = YesPlease
 	NO_PYTHON = YesPlease
 	BLK_SHA1 = YesPlease
 	ETAGS_TARGET = ETAGS
@@ -499,7 +507,7 @@
 	NO_INET_NTOP = YesPlease
 	NO_POSIX_GOODIES = UnfortunatelyYes
 	DEFAULT_HELP_FORMAT = html
-	COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/win32
+	COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -D_USE_32BIT_TIME_T -DNOGDI -Icompat -Icompat/win32
 	COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
 	COMPAT_OBJS += compat/mingw.o compat/winansi.o \
 		compat/win32/pthread.o compat/win32/syslog.o \
diff --git a/connect.c b/connect.c
index 553a80c..4150412 100644
--- a/connect.c
+++ b/connect.c
@@ -5,8 +5,10 @@
 #include "refs.h"
 #include "run-command.h"
 #include "remote.h"
+#include "connect.h"
 #include "url.h"
 #include "string-list.h"
+#include "sha1-array.h"
 
 static char *server_capabilities;
 static const char *parse_feature_value(const char *, const char *, int *);
@@ -44,13 +46,6 @@
 	return check_ref(ref->name, strlen(ref->name), flags);
 }
 
-static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1)
-{
-	ALLOC_GROW(extra->array, extra->nr + 1, extra->alloc);
-	hashcpy(&(extra->array[extra->nr][0]), sha1);
-	extra->nr++;
-}
-
 static void die_initial_contact(int got_at_least_one_head)
 {
 	if (got_at_least_one_head)
@@ -121,7 +116,8 @@
  */
 struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
 			      struct ref **list, unsigned int flags,
-			      struct extra_have_objects *extra_have)
+			      struct sha1_array *extra_have,
+			      struct sha1_array *shallow_points)
 {
 	struct ref **orig_list = list;
 	int got_at_least_one_head = 0;
@@ -144,9 +140,18 @@
 		if (!len)
 			break;
 
-		if (len > 4 && !prefixcmp(buffer, "ERR "))
+		if (len > 4 && starts_with(buffer, "ERR "))
 			die("remote error: %s", buffer + 4);
 
+		if (len == 48 && starts_with(buffer, "shallow ")) {
+			if (get_sha1_hex(buffer + 8, old_sha1))
+				die("protocol error: expected shallow sha-1, got '%s'", buffer + 8);
+			if (!shallow_points)
+				die("repository on the other end cannot be shallow");
+			sha1_array_append(shallow_points, old_sha1);
+			continue;
+		}
+
 		if (len < 42 || get_sha1_hex(buffer, old_sha1) || buffer[40] != ' ')
 			die("protocol error: expected sha/ref, got '%s'", buffer);
 		name = buffer + 41;
@@ -159,7 +164,7 @@
 
 		if (extra_have &&
 		    name_len == 5 && !memcmp(".have", name, 5)) {
-			add_extra_have(extra_have, old_sha1);
+			sha1_array_append(extra_have, old_sha1);
 			continue;
 		}
 
@@ -231,10 +236,34 @@
 
 enum protocol {
 	PROTO_LOCAL = 1,
+	PROTO_FILE,
 	PROTO_SSH,
 	PROTO_GIT
 };
 
+int url_is_local_not_ssh(const char *url)
+{
+	const char *colon = strchr(url, ':');
+	const char *slash = strchr(url, '/');
+	return !colon || (slash && slash < colon) ||
+		has_dos_drive_prefix(url);
+}
+
+static const char *prot_name(enum protocol protocol)
+{
+	switch (protocol) {
+		case PROTO_LOCAL:
+		case PROTO_FILE:
+			return "file";
+		case PROTO_SSH:
+			return "ssh";
+		case PROTO_GIT:
+			return "git";
+		default:
+			return "unkown protocol";
+	}
+}
+
 static enum protocol get_protocol(const char *name)
 {
 	if (!strcmp(name, "ssh"))
@@ -246,7 +275,7 @@
 	if (!strcmp(name, "ssh+git"))
 		return PROTO_SSH;
 	if (!strcmp(name, "file"))
-		return PROTO_LOCAL;
+		return PROTO_FILE;
 	die("I don't handle protocol '%s'", name);
 }
 
@@ -526,24 +555,95 @@
 	return proxy;
 }
 
-#define MAX_CMD_LEN 1024
-
-static char *get_port(char *host)
+static const char *get_port_numeric(const char *p)
 {
 	char *end;
-	char *p = strchr(host, ':');
-
 	if (p) {
 		long port = strtol(p + 1, &end, 10);
 		if (end != p + 1 && *end == '\0' && 0 <= port && port < 65536) {
-			*p = '\0';
-			return p+1;
+			return p;
 		}
 	}
 
 	return NULL;
 }
 
+/*
+ * Extract protocol and relevant parts from the specified connection URL.
+ * The caller must free() the returned strings.
+ */
+static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
+				       char **ret_path)
+{
+	char *url;
+	char *host, *path;
+	char *end;
+	int separator = '/';
+	enum protocol protocol = PROTO_LOCAL;
+
+	if (is_url(url_orig))
+		url = url_decode(url_orig);
+	else
+		url = xstrdup(url_orig);
+
+	host = strstr(url, "://");
+	if (host) {
+		*host = '\0';
+		protocol = get_protocol(url);
+		host += 3;
+	} else {
+		host = url;
+		if (!url_is_local_not_ssh(url)) {
+			protocol = PROTO_SSH;
+			separator = ':';
+		}
+	}
+
+	/*
+	 * Don't do destructive transforms as protocol code does
+	 * '[]' unwrapping in get_host_and_port()
+	 */
+	if (host[0] == '[') {
+		end = strchr(host + 1, ']');
+		if (end) {
+			end++;
+		} else
+			end = host;
+	} else
+		end = host;
+
+	if (protocol == PROTO_LOCAL)
+		path = end;
+	else if (protocol == PROTO_FILE && has_dos_drive_prefix(end))
+		path = end; /* "file://$(pwd)" may be "file://C:/projects/repo" */
+	else
+		path = strchr(end, separator);
+
+	if (!path || !*path)
+		die("No path specified. See 'man git-pull' for valid url syntax");
+
+	/*
+	 * null-terminate hostname and point path to ~ for URL's like this:
+	 *    ssh://host.xz/~user/repo
+	 */
+
+	end = path; /* Need to \0 terminate host here */
+	if (separator == ':')
+		path++; /* path starts after ':' */
+	if (protocol == PROTO_GIT || protocol == PROTO_SSH) {
+		if (path[1] == '~')
+			path++;
+	}
+
+	path = xstrdup(path);
+	*end = '\0';
+
+	*ret_host = xstrdup(host);
+	*ret_path = path;
+	free(url);
+	return protocol;
+}
+
 static struct child_process no_fork;
 
 /*
@@ -557,104 +657,36 @@
  * will hopefully be changed in a libification effort, to return NULL when
  * the connection failed).
  */
-struct child_process *git_connect(int fd[2], const char *url_orig,
+struct child_process *git_connect(int fd[2], const char *url,
 				  const char *prog, int flags)
 {
-	char *url;
-	char *host, *path;
-	char *end;
-	int c;
+	char *hostandport, *path;
 	struct child_process *conn = &no_fork;
-	enum protocol protocol = PROTO_LOCAL;
-	int free_path = 0;
-	char *port = NULL;
+	enum protocol protocol;
 	const char **arg;
-	struct strbuf cmd;
+	struct strbuf cmd = STRBUF_INIT;
 
 	/* Without this we cannot rely on waitpid() to tell
 	 * what happened to our children.
 	 */
 	signal(SIGCHLD, SIG_DFL);
 
-	if (is_url(url_orig))
-		url = url_decode(url_orig);
-	else
-		url = xstrdup(url_orig);
-
-	host = strstr(url, "://");
-	if (host) {
-		*host = '\0';
-		protocol = get_protocol(url);
-		host += 3;
-		c = '/';
-	} else {
-		host = url;
-		c = ':';
-	}
-
-	/*
-	 * Don't do destructive transforms with git:// as that
-	 * protocol code does '[]' unwrapping of its own.
-	 */
-	if (host[0] == '[') {
-		end = strchr(host + 1, ']');
-		if (end) {
-			if (protocol != PROTO_GIT) {
-				*end = 0;
-				host++;
-			}
-			end++;
-		} else
-			end = host;
-	} else
-		end = host;
-
-	path = strchr(end, c);
-	if (path && !has_dos_drive_prefix(end)) {
-		if (c == ':') {
-			if (path < strchrnul(host, '/')) {
-				protocol = PROTO_SSH;
-				*path++ = '\0';
-			} else /* '/' in the host part, assume local path */
-				path = end;
-		}
-	} else
-		path = end;
-
-	if (!path || !*path)
-		die("No path specified. See 'man git-pull' for valid url syntax");
-
-	/*
-	 * null-terminate hostname and point path to ~ for URL's like this:
-	 *    ssh://host.xz/~user/repo
-	 */
-	if (protocol != PROTO_LOCAL && host != url) {
-		char *ptr = path;
-		if (path[1] == '~')
-			path++;
-		else {
-			path = xstrdup(ptr);
-			free_path = 1;
-		}
-
-		*ptr = '\0';
-	}
-
-	/*
-	 * Add support for ssh port: ssh://host.xy:<port>/...
-	 */
-	if (protocol == PROTO_SSH && host != url)
-		port = get_port(end);
-
-	if (protocol == PROTO_GIT) {
+	protocol = parse_connect_url(url, &hostandport, &path);
+	if (flags & CONNECT_DIAG_URL) {
+		printf("Diag: url=%s\n", url ? url : "NULL");
+		printf("Diag: protocol=%s\n", prot_name(protocol));
+		printf("Diag: hostandport=%s\n", hostandport ? hostandport : "NULL");
+		printf("Diag: path=%s\n", path ? path : "NULL");
+		conn = NULL;
+	} else if (protocol == PROTO_GIT) {
 		/* These underlying connection commands die() if they
 		 * cannot connect.
 		 */
-		char *target_host = xstrdup(host);
-		if (git_use_proxy(host))
-			conn = git_proxy_connect(fd, host);
+		char *target_host = xstrdup(hostandport);
+		if (git_use_proxy(hostandport))
+			conn = git_proxy_connect(fd, hostandport);
 		else
-			git_tcp_connect(fd, host, flags);
+			git_tcp_connect(fd, hostandport, flags);
 		/*
 		 * Separate original protocol components prog and path
 		 * from extended host header with a NUL byte.
@@ -667,55 +699,51 @@
 			     prog, path, 0,
 			     target_host, 0);
 		free(target_host);
-		free(url);
-		if (free_path)
-			free(path);
-		return conn;
-	}
+	} else {
+		conn = xcalloc(1, sizeof(*conn));
 
-	conn = xcalloc(1, sizeof(*conn));
+		strbuf_addstr(&cmd, prog);
+		strbuf_addch(&cmd, ' ');
+		sq_quote_buf(&cmd, path);
 
-	strbuf_init(&cmd, MAX_CMD_LEN);
-	strbuf_addstr(&cmd, prog);
-	strbuf_addch(&cmd, ' ');
-	sq_quote_buf(&cmd, path);
-	if (cmd.len >= MAX_CMD_LEN)
-		die("command line too long");
+		conn->in = conn->out = -1;
+		conn->argv = arg = xcalloc(7, sizeof(*arg));
+		if (protocol == PROTO_SSH) {
+			const char *ssh = getenv("GIT_SSH");
+			int putty = ssh && strcasestr(ssh, "plink");
+			char *ssh_host = hostandport;
+			const char *port = NULL;
+			get_host_and_port(&ssh_host, &port);
+			port = get_port_numeric(port);
 
-	conn->in = conn->out = -1;
-	conn->argv = arg = xcalloc(7, sizeof(*arg));
-	if (protocol == PROTO_SSH) {
-		const char *ssh = getenv("GIT_SSH");
-		int putty = ssh && strcasestr(ssh, "plink");
-		if (!ssh) ssh = "ssh";
+			if (!ssh) ssh = "ssh";
 
-		*arg++ = ssh;
-		if (putty && !strcasestr(ssh, "tortoiseplink"))
-			*arg++ = "-batch";
-		if (port) {
-			/* P is for PuTTY, p is for OpenSSH */
-			*arg++ = putty ? "-P" : "-p";
-			*arg++ = port;
+			*arg++ = ssh;
+			if (putty && !strcasestr(ssh, "tortoiseplink"))
+				*arg++ = "-batch";
+			if (port) {
+				/* P is for PuTTY, p is for OpenSSH */
+				*arg++ = putty ? "-P" : "-p";
+				*arg++ = port;
+			}
+			*arg++ = ssh_host;
+		}	else {
+			/* remove repo-local variables from the environment */
+			conn->env = local_repo_env;
+			conn->use_shell = 1;
 		}
-		*arg++ = host;
-	}
-	else {
-		/* remove repo-local variables from the environment */
-		conn->env = local_repo_env;
-		conn->use_shell = 1;
-	}
-	*arg++ = cmd.buf;
-	*arg = NULL;
+		*arg++ = cmd.buf;
+		*arg = NULL;
 
-	if (start_command(conn))
-		die("unable to fork");
+		if (start_command(conn))
+			die("unable to fork");
 
-	fd[0] = conn->out; /* read from child's stdout */
-	fd[1] = conn->in;  /* write to child's stdin */
-	strbuf_release(&cmd);
-	free(url);
-	if (free_path)
-		free(path);
+		fd[0] = conn->out; /* read from child's stdout */
+		fd[1] = conn->in;  /* write to child's stdin */
+		strbuf_release(&cmd);
+	}
+	free(hostandport);
+	free(path);
 	return conn;
 }
 
diff --git a/connect.h b/connect.h
new file mode 100644
index 0000000..c41a685
--- /dev/null
+++ b/connect.h
@@ -0,0 +1,14 @@
+#ifndef CONNECT_H
+#define CONNECT_H
+
+#define CONNECT_VERBOSE       (1u << 0)
+#define CONNECT_DIAG_URL      (1u << 1)
+extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
+extern int finish_connect(struct child_process *conn);
+extern int git_connection_is_socket(struct child_process *conn);
+extern int server_supports(const char *feature);
+extern int parse_feature_request(const char *features, const char *feature);
+extern const char *server_feature_value(const char *feature, int *len_ret);
+extern int url_is_local_not_ssh(const char *url);
+
+#endif
diff --git a/connected.c b/connected.c
index fae8d64..be0253e 100644
--- a/connected.c
+++ b/connected.c
@@ -19,17 +19,17 @@
  *
  * Returns 0 if everything is connected, non-zero otherwise.
  */
-int check_everything_connected_with_transport(sha1_iterate_fn fn,
-					      int quiet,
-					      void *cb_data,
-					      struct transport *transport)
+static int check_everything_connected_real(sha1_iterate_fn fn,
+					   int quiet,
+					   void *cb_data,
+					   struct transport *transport,
+					   const char *shallow_file)
 {
 	struct child_process rev_list;
-	const char *argv[] = {"rev-list", "--objects",
-			      "--stdin", "--not", "--all", NULL, NULL};
+	const char *argv[9];
 	char commit[41];
 	unsigned char sha1[20];
-	int err = 0;
+	int err = 0, ac = 0;
 	struct packed_git *new_pack = NULL;
 
 	if (fn(cb_data, sha1))
@@ -38,7 +38,7 @@
 	if (transport && transport->smart_options &&
 	    transport->smart_options->self_contained_and_connected &&
 	    transport->pack_lockfile &&
-	    !suffixcmp(transport->pack_lockfile, ".keep")) {
+	    ends_with(transport->pack_lockfile, ".keep")) {
 		struct strbuf idx_file = STRBUF_INIT;
 		strbuf_addstr(&idx_file, transport->pack_lockfile);
 		strbuf_setlen(&idx_file, idx_file.len - 5); /* ".keep" */
@@ -47,8 +47,18 @@
 		strbuf_release(&idx_file);
 	}
 
+	if (shallow_file) {
+		argv[ac++] = "--shallow-file";
+		argv[ac++] = shallow_file;
+	}
+	argv[ac++] = "rev-list";
+	argv[ac++] = "--objects";
+	argv[ac++] = "--stdin";
+	argv[ac++] = "--not";
+	argv[ac++] = "--all";
 	if (quiet)
-		argv[5] = "--quiet";
+		argv[ac++] = "--quiet";
+	argv[ac] = NULL;
 
 	memset(&rev_list, 0, sizeof(rev_list));
 	rev_list.argv = argv;
@@ -92,3 +102,19 @@
 	sigchain_pop(SIGPIPE);
 	return finish_command(&rev_list) || err;
 }
+
+int check_everything_connected_with_transport(sha1_iterate_fn fn,
+					      int quiet,
+					      void *cb_data,
+					      struct transport *transport)
+{
+	return check_everything_connected_real(fn, quiet, cb_data,
+					       transport, NULL);
+}
+
+int check_shallow_connected(sha1_iterate_fn fn, int quiet, void *cb_data,
+			    const char *shallow_file)
+{
+	return check_everything_connected_real(fn, quiet, cb_data,
+					       NULL, shallow_file);
+}
diff --git a/connected.h b/connected.h
index 0b060b7..071d408 100644
--- a/connected.h
+++ b/connected.h
@@ -18,6 +18,8 @@
  * Return 0 if Ok, non zero otherwise (i.e. some missing objects)
  */
 extern int check_everything_connected(sha1_iterate_fn, int quiet, void *cb_data);
+extern int check_shallow_connected(sha1_iterate_fn, int quiet, void *cb_data,
+				   const char *shallow_file);
 extern int check_everything_connected_with_transport(sha1_iterate_fn, int quiet,
 						     void *cb_data,
 						     struct transport *transport);
diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl
old mode 100644
new mode 100755
diff --git a/contrib/buildsystems/generate b/contrib/buildsystems/generate
old mode 100644
new mode 100755
diff --git a/contrib/buildsystems/parse.pl b/contrib/buildsystems/parse.pl
old mode 100644
new mode 100755
diff --git a/contrib/ciabot/INSTALL b/contrib/ciabot/INSTALL
deleted file mode 100644
index 7222961..0000000
--- a/contrib/ciabot/INSTALL
+++ /dev/null
@@ -1,54 +0,0 @@
-= Installation instructions =
-
-Two scripts are included.  The Python one (ciabot.py) is faster and
-more capable; the shell one (ciabot.sh) is a fallback in case Python
-gives your git hosting site indigestion. (I know of no such sites.)
-
-It is no longer necessary to modify the script in order to put it
-in place; in fact, this is now discouraged. It is entirely
-configurable with the following git config variables:
-
-ciabot.project = name of the project
-ciabot.repo = name of the project repo for gitweb/cgit purposes
-ciabot.xmlrpc  = if true, ship notifications via XML-RPC
-ciabot.revformat = format in which the revision is shown
-
-The revformat variable may have the following values
-raw -> full hex ID of commit
-short -> first 12 chars of hex ID
-describe -> describe relative to last tag, falling back to short
-
-ciabot.project defaults to the directory name of the repository toplevel.
-ciabot.repo defaults to ciabot.project lowercased.
-ciabot.xmlrpc defaults to True
-ciabot.revformat defaults to 'describe'.
-
-This means that in the normal case you need not do any configuration at all,
-however setting ciabot.project will allow the hook to run slightly faster.
-
-Once you've set these variables, try your script with -n to see the
-notification message dumped to stdout and verify that it looks sane.
-
-To live-test these scripts, your project needs to have been registered with
-the CIA site.  Here are the steps:
-
-1. Open an IRC window on irc://freenode/commits or your registered
-   project IRC channel.
-
-2. Run ciabot.py and/or ciabot.sh from any directory under git
-   control.
-
-You should see a notification on the channel for your most recent commit.
-
-After verifying correct function, install one of these scripts either
-in a post-commit hook or in an update hook.
-
-In post-commit, run it without arguments. It will query for
-current HEAD and the latest commit ID to get the information it
-needs.
-
-In update, call it with a refname followed by a list of commits:
-You want to reverse the order git rev-list emits because it lists
-from most recent to oldest.
-
-/path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac)
diff --git a/contrib/ciabot/README b/contrib/ciabot/README
deleted file mode 100644
index 2dfe1f9..0000000
--- a/contrib/ciabot/README
+++ /dev/null
@@ -1,11 +0,0 @@
-These are hook scripts for the CIA notification service at <http://cia.vc/>
-
-They are maintained by Eric S. Raymond <esr@thyrsus.com>.  There is an
-upstream resource page for them at <http://www.catb.org/esr/ciabot/>,
-but they are unlikely to change rapidly.
-
-You probably want the Python version; it's faster, more capable, and
-better documented.  The shell version is maintained only as a fallback
-for use on hosting sites that don't permit Python hook scripts.
-
-See the file INSTALL for installation instructions.
diff --git a/contrib/ciabot/ciabot.py b/contrib/ciabot/ciabot.py
deleted file mode 100755
index befa0c3..0000000
--- a/contrib/ciabot/ciabot.py
+++ /dev/null
@@ -1,255 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com>
-# Distributed under BSD terms.
-#
-# This script contains porcelain and porcelain byproducts.
-# It's Python because the Python standard libraries avoid portability/security
-# issues raised by callouts in the ancestral Perl and sh scripts.  It should
-# be compatible back to Python 2.1.5
-#
-# usage: ciabot.py [-V] [-n] [-p projectname]  [refname [commits...]]
-#
-# This script is meant to be run either in a post-commit hook or in an
-# update hook. Try it with -n to see the notification mail dumped to
-# stdout and verify that it looks sane. With -V it dumps its version
-# and exits.
-#
-# In post-commit, run it without arguments. It will query for
-# current HEAD and the latest commit ID to get the information it
-# needs.
-#
-# In update, call it with a refname followed by a list of commits:
-# You want to reverse the order git rev-list emits because it lists
-# from most recent to oldest.
-#
-# /path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac)
-#
-# Configuration variables affecting this script:
-#
-# ciabot.project = name of the project
-# ciabot.repo = name of the project repo for gitweb/cgit purposes
-# ciabot.xmlrpc  = if true (default), ship notifications via XML-RPC
-# ciabot.revformat = format in which the revision is shown
-#
-# ciabot.project defaults to the directory name of the repository toplevel.
-# ciabot.repo defaults to ciabot.project lowercased.
-#
-# This means that in the normal case you need not do any configuration at all,
-# but setting the project name will speed it up slightly.
-#
-# The revformat variable may have the following values
-# raw -> full hex ID of commit
-# short -> first 12 chars of hex ID
-# describe = -> describe relative to last tag, falling back to short
-# The default is 'describe'.
-#
-# Note: the CIA project now says only XML-RPC is reliable, so
-# we default to that.
-#
-
-import sys
-if sys.hexversion < 0x02000000:
-        # The limiter is the xml.sax module
-        sys.stderr.write("ciabot.py: requires Python 2.0.0 or later.\n")
-        sys.exit(1)
-
-import os, commands, socket, urllib
-from xml.sax.saxutils import escape
-
-# Changeset URL prefix for your repo: when the commit ID is appended
-# to this, it should point at a CGI that will display the commit
-# through gitweb or something similar. The defaults will probably
-# work if you have a typical gitweb/cgit setup.
-#
-#urlprefix="http://%(host)s/cgi-bin/gitweb.cgi?p=%(repo)s;a=commit;h="
-urlprefix="http://%(host)s/cgi-bin/cgit.cgi/%(repo)s/commit/?id="
-
-# The service used to turn your gitwebbish URL into a tinyurl so it
-# will take up less space on the IRC notification line.
-tinyifier = "http://tinyurl.com/api-create.php?url="
-
-# The template used to generate the XML messages to CIA.  You can make
-# visible changes to the IRC-bot notification lines by hacking this.
-# The default will produce a notification line that looks like this:
-#
-# ${project}: ${author} ${repo}:${branch} * ${rev} ${files}: ${logmsg} ${url}
-#
-# By omitting $files you can collapse the files part to a single slash.
-xml = '''\
-<message>
-  <generator>
-    <name>CIA Python client for Git</name>
-    <version>%(version)s</version>
-    <url>%(generator)s</url>
-  </generator>
-  <source>
-    <project>%(project)s</project>
-    <branch>%(repo)s:%(branch)s</branch>
-  </source>
-  <timestamp>%(ts)s</timestamp>
-  <body>
-    <commit>
-      <author>%(author)s</author>
-      <revision>%(rev)s</revision>
-      <files>
-        %(files)s
-      </files>
-      <log>%(logmsg)s %(url)s</log>
-      <url>%(url)s</url>
-    </commit>
-  </body>
-</message>
-'''
-
-#
-# No user-serviceable parts below this line:
-#
-
-# Where to ship e-mail notifications.
-toaddr = "cia@cia.vc"
-
-# Identify the generator script.
-# Should only change when the script itself gets a new home and maintainer.
-generator = "http://www.catb.org/~esr/ciabot.py"
-version = "3.6"
-
-def do(command):
-    return commands.getstatusoutput(command)[1]
-
-def report(refname, merged, xmlrpc=True):
-    "Generate a commit notification to be reported to CIA"
-
-    # Try to tinyfy a reference to a web view for this commit.
-    try:
-        url = open(urllib.urlretrieve(tinyifier + urlprefix + merged)[0]).read()
-    except:
-        url = urlprefix + merged
-
-    branch = os.path.basename(refname)
-
-    # Compute a description for the revision
-    if revformat == 'raw':
-        rev = merged
-    elif revformat == 'short':
-        rev = ''
-    else: # revformat == 'describe'
-        rev = do("git describe %s 2>/dev/null" % merged)
-    if not rev:
-        rev = merged[:12]
-
-    # Extract the meta-information for the commit
-    files=do("git diff-tree -r --name-only '"+ merged +"' | sed -e '1d' -e 's-.*-<file>&</file>-'")
-    metainfo = do("git log -1 '--pretty=format:%an <%ae>%n%at%n%s' " + merged)
-    (author, ts, logmsg) = metainfo.split("\n")
-    logmsg = escape(logmsg)
-
-    # This discards the part of the author's address after @.
-    # Might be be nice to ship the full email address, if not
-    # for spammers' address harvesters - getting this wrong
-    # would make the freenode #commits channel into harvester heaven.
-    author = escape(author.replace("<", "").split("@")[0].split()[-1])
-
-    # This ignores the timezone.  Not clear what to do with it...
-    ts = ts.strip().split()[0]
-
-    context = locals()
-    context.update(globals())
-
-    out = xml % context
-    mail = '''\
-Message-ID: <%(merged)s.%(author)s@%(project)s>
-From: %(fromaddr)s
-To: %(toaddr)s
-Content-type: text/xml
-Subject: DeliverXML
-
-%(out)s''' % locals()
-
-    if xmlrpc:
-        return out
-    else:
-        return mail
-
-if __name__ == "__main__":
-    import getopt
-
-    # Get all config variables
-    revformat = do("git config --get ciabot.revformat")
-    project = do("git config --get ciabot.project")
-    repo = do("git config --get ciabot.repo")
-    xmlrpc = do("git config --get ciabot.xmlrpc")
-    xmlrpc = not (xmlrpc and xmlrpc == "false")
-
-    host = socket.getfqdn()
-    fromaddr = "CIABOT-NOREPLY@" + host
-
-    try:
-        (options, arguments) = getopt.getopt(sys.argv[1:], "np:xV")
-    except getopt.GetoptError, msg:
-        print "ciabot.py: " + str(msg)
-        raise SystemExit, 1
-
-    notify = True
-    for (switch, val) in options:
-        if switch == '-p':
-            project = val
-        elif switch == '-n':
-            notify = False
-        elif switch == '-x':
-            xmlrpc = True
-        elif switch == '-V':
-            print "ciabot.py: version", version
-            sys.exit(0)
-
-    # The project variable defaults to the name of the repository toplevel.
-    if not project:
-        here = os.getcwd()
-        while True:
-            if os.path.exists(os.path.join(here, ".git")):
-                project = os.path.basename(here)
-                break
-            elif here == '/':
-                sys.stderr.write("ciabot.py: no .git below root!\n")
-                sys.exit(1)
-            here = os.path.dirname(here)
-
-    if not repo:
-        repo = project.lower()
-
-    urlprefix = urlprefix % globals()
-
-    # The script wants a reference to head followed by the list of
-    # commit ID to report about.
-    if len(arguments) == 0:
-        refname = do("git symbolic-ref HEAD 2>/dev/null")
-        merges = [do("git rev-parse HEAD")]
-    else:
-        refname = arguments[0]
-        merges = arguments[1:]
-
-    if notify:
-        if xmlrpc:
-            import xmlrpclib
-            server = xmlrpclib.Server('http://cia.vc/RPC2');
-        else:
-            import smtplib
-            server = smtplib.SMTP('localhost')
-
-    for merged in merges:
-        message = report(refname, merged, xmlrpc)
-        if not notify:
-            print message
-        elif xmlrpc:
-            try:
-                # RPC server is flaky, this can fail due to timeout.
-                server.hub.deliver(message)
-            except socket.error, e:
-                sys.stderr.write("%s\n" % e)
-        else:
-            server.sendmail(fromaddr, [toaddr], message)
-
-    if notify:
-        if not xmlrpc:
-            server.quit()
-
-#End
diff --git a/contrib/ciabot/ciabot.sh b/contrib/ciabot/ciabot.sh
deleted file mode 100755
index dfb71a1..0000000
--- a/contrib/ciabot/ciabot.sh
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/bin/sh
-# Distributed under the terms of the GNU General Public License v2
-# Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
-# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com>
-# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com>
-# Assistance and review by Petr Baudis, author of ciabot.pl,
-# is gratefully acknowledged.
-#
-# This is a version 3.x of ciabot.sh; use -V to find the exact
-# version.  Versions 1 and 2 were shipped in 2006 and 2008 and are not
-# version-stamped.  The version 2 maintainer has passed the baton.
-#
-# Note: This script should be considered obsolete.
-# There is a faster, better-documented rewrite in Python: find it as ciabot.py
-# Use this only if your hosting site forbids Python hooks.
-# It requires: git(1), hostname(1), cut(1), sendmail(1), and wget(1).
-#
-# Originally based on Git ciabot.pl by Petr Baudis.
-# This script contains porcelain and porcelain byproducts.
-#
-# usage: ciabot.sh [-V] [-n] [-p projectname] [refname commit]
-#
-# This script is meant to be run either in a post-commit hook or in an
-# update hook. Try it with -n to see the notification mail dumped to
-# stdout and verify that it looks sane. With -V it dumps its version
-# and exits.
-#
-# In post-commit, run it without arguments. It will query for
-# current HEAD and the latest commit ID to get the information it
-# needs.
-#
-# In update, you have to call it once per merged commit:
-#
-#       refname=$1
-#       oldhead=$2
-#       newhead=$3
-#       for merged in $(git rev-list ${oldhead}..${newhead} | tac) ; do
-#               /path/to/ciabot.sh ${refname} ${merged}
-#       done
-#
-# The reason for the tac call is that git rev-list emits commits from
-# most recent to least - better to ship notifications from oldest to newest.
-#
-# Configuration variables affecting this script:
-#
-# ciabot.project = name of the project
-# ciabot.repo = name of the project repo for gitweb/cgit purposes
-# ciabot.revformat = format in which the revision is shown
-#
-# ciabot.project defaults to the directory name of the repository toplevel.
-# ciabot.repo defaults to ciabot.project lowercased.
-#
-# This means that in the normal case you need not do any configuration at all,
-# but setting the project name will speed it up slightly.
-#
-# The revformat variable may have the following values
-# raw -> full hex ID of commit
-# short -> first 12 chars of hex ID
-# describe = -> describe relative to last tag, falling back to short
-# The default is 'describe'.
-#
-# Note: the shell ancestors of this script used mail, not XML-RPC, in
-# order to avoid stalling until timeout when the CIA XML-RPC server is
-# down. It is unknown whether this is still an issue in 2010, but
-# XML-RPC would be annoying to do from sh in any case. (XML-RPC does
-# have the advantage that it guarantees notification of multiple commits
-# shipped from an update in their actual order.)
-#
-
-# The project as known to CIA. You can set this with a -p option,
-# or let it default to the directory name of the repo toplevel.
-project=$(git config --get ciabot.project)
-
-if [ -z $project ]
-then
-    here=`pwd`;
-    while :; do
-	if [ -d $here/.git ]
-	then
-	    project=`basename $here`
-	    break
-	elif [ $here = '/' ]
-	then
-	    echo "ciabot.sh: no .git below root!"
-	    exit 1
-	fi
-	here=`dirname $here`
-    done
-fi
-
-# Name of the repo for gitweb/cgit purposes
-repo=$(git config --get ciabot.repo)
-[ -z $repo] && repo=$(echo "${project}" | tr '[A-Z]' '[a-z]')
-
-# What revision format do we want in the summary?
-revformat=$(git config --get ciabot.revformat)
-
-# Fully qualified domain name of the repo host.  You can hardwire this
-# to make the script faster. The -f option works under Linux and FreeBSD,
-# but not OpenBSD and NetBSD. But under OpenBSD and NetBSD,
-# hostname without options gives the FQDN.
-if hostname -f >/dev/null 2>&1
-then
-    hostname=`hostname -f`
-else
-    hostname=`hostname`
-fi
-
-# Changeset URL prefix for your repo: when the commit ID is appended
-# to this, it should point at a CGI that will display the commit
-# through gitweb or something similar. The defaults will probably
-# work if you have a typical gitweb/cgit setup.
-#urlprefix="http://${host}/cgi-bin/gitweb.cgi?p=${repo};a=commit;h="
-urlprefix="http://${host}/cgi-bin/cgit.cgi/${repo}/commit/?id="
-
-#
-# You probably will not need to change the following:
-#
-
-# Identify the script. The 'generator' variable should change only
-# when the script itself gets a new home and maintainer.
-generator="http://www.catb.org/~esr/ciabot/ciabot.sh"
-version=3.5
-
-# Addresses for the e-mail
-from="CIABOT-NOREPLY@${hostname}"
-to="cia@cia.vc"
-
-# SMTP client to use - may need to edit the absolute pathname for your system
-sendmail="sendmail -t -f ${from}"
-
-#
-# No user-serviceable parts below this line:
-#
-
-# Should include all places sendmail is likely to lurk.
-PATH="$PATH:/usr/sbin/"
-
-mode=mailit
-while getopts pnV opt
-do
-    case $opt in
-	p) project=$2; shift ; shift ;;
-	n) mode=dumpit; shift ;;
-	V) echo "ciabot.sh: version $version"; exit 0; shift ;;
-    esac
-done
-
-# Cough and die if user has not specified a project
-if [ -z "$project" ]
-then
-    echo "ciabot.sh: no project specified, bailing out." >&2
-    exit 1
-fi
-
-if [ $# -eq 0 ] ; then
-	refname=$(git symbolic-ref HEAD 2>/dev/null)
-	merged=$(git rev-parse HEAD)
-else
-	refname=$1
-	merged=$2
-fi
-
-# This tries to turn your gitwebbish URL into a tinyurl so it will take up
-# less space on the IRC notification line. Some repo sites (I'm looking at
-# you, berlios.de!) forbid wget calls for security reasons.  On these,
-# the code will fall back to the full un-tinyfied URL.
-longurl=${urlprefix}${merged}
-url=$(wget -O - -q http://tinyurl.com/api-create.php?url=${longurl} 2>/dev/null)
-if [ -z "$url" ]; then
-	url="${longurl}"
-fi
-
-refname=${refname##refs/heads/}
-
-case $revformat in
-raw) rev=$merged ;;
-short) rev='' ;;
-*) rev=$(git describe ${merged} 2>/dev/null) ;;
-esac
-[ -z ${rev} ] && rev=$(echo "$merged" | cut -c 1-12)
-
-# We discard the part of the author's address after @.
-# Might be nice to ship the full email address, if not
-# for spammers' address harvesters - getting this wrong
-# would make the freenode #commits channel into harvester heaven.
-author=$(git log -1 '--pretty=format:%an <%ae>' $merged)
-author=$(echo "$author" | sed -n -e '/^.*<\([^@]*\).*$/s--\1-p')
-
-logmessage=$(git log -1 '--pretty=format:%s' $merged)
-ts=$(git log -1 '--pretty=format:%at' $merged)
-files=$(git diff-tree -r --name-only ${merged} | sed -e '1d' -e 's-.*-<file>&</file>-')
-
-out="
-<message>
-  <generator>
-    <name>CIA Shell client for Git</name>
-    <version>${version}</version>
-    <url>${generator}</url>
-  </generator>
-  <source>
-    <project>${project}</project>
-    <branch>$repo:${refname}</branch>
-  </source>
-  <timestamp>${ts}</timestamp>
-  <body>
-    <commit>
-      <author>${author}</author>
-      <revision>${rev}</revision>
-      <files>
-	${files}
-      </files>
-      <log>${logmessage} ${url}</log>
-      <url>${url}</url>
-    </commit>
-  </body>
-</message>"
-
-if [ "$mode" = "dumpit" ]
-then
-    sendmail=cat
-fi
-
-${sendmail} << EOM
-Message-ID: <${merged}.${author}@${project}>
-From: ${from}
-To: ${to}
-Content-type: text/xml
-Subject: DeliverXML
-${out}
-EOM
-
-# vim: set tw=70 :
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index e1b7313..9525343 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1,5 +1,3 @@
-#!bash
-#
 # bash/zsh completion support for core Git.
 #
 # Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
@@ -180,9 +178,9 @@
 }
 fi
 
-__gitcompadd ()
+__gitcompappend ()
 {
-	local i=0
+	local i=${#COMPREPLY[@]}
 	for x in $1; do
 		if [[ "$x" == "$3"* ]]; then
 			COMPREPLY[i++]="$2$x$4"
@@ -190,6 +188,12 @@
 	done
 }
 
+__gitcompadd ()
+{
+	COMPREPLY=()
+	__gitcompappend "$@"
+}
+
 # Generates completion reply, appending a space to possible completion words,
 # if necessary.
 # It accepts 1 to 4 arguments:
@@ -220,6 +224,14 @@
 	esac
 }
 
+# Variation of __gitcomp_nl () that appends to the existing list of
+# completion candidates, COMPREPLY.
+__gitcomp_nl_append ()
+{
+	local IFS=$'\n'
+	__gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }"
+}
+
 # Generates completion reply from newline-separated possible completion words
 # by appending a space to all of them.
 # It accepts 1 to 4 arguments:
@@ -231,8 +243,8 @@
 #    appended.
 __gitcomp_nl ()
 {
-	local IFS=$'\n'
-	__gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
+	COMPREPLY=()
+	__gitcomp_nl_append "$@"
 }
 
 # Generates completion reply with compgen from newline-separated possible
@@ -673,7 +685,6 @@
 		index-pack)       : plumbing;;
 		init-db)          : deprecated;;
 		local-fetch)      : plumbing;;
-		lost-found)       : infrequent;;
 		ls-files)         : plumbing;;
 		ls-remote)        : plumbing;;
 		ls-tree)          : plumbing;;
@@ -687,14 +698,12 @@
 		pack-refs)        : plumbing;;
 		parse-remote)     : plumbing;;
 		patch-id)         : plumbing;;
-		peek-remote)      : plumbing;;
 		prune)            : plumbing;;
 		prune-packed)     : plumbing;;
 		quiltimport)      : import;;
 		read-tree)        : plumbing;;
 		receive-pack)     : plumbing;;
 		remote-*)         : transport;;
-		repo-config)      : deprecated;;
 		rerere)           : plumbing;;
 		rev-list)         : plumbing;;
 		rev-parse)        : plumbing;;
@@ -707,7 +716,6 @@
 		ssh-*)            : transport;;
 		stripspace)       : plumbing;;
 		symbolic-ref)     : plumbing;;
-		tar-tree)         : deprecated;;
 		unpack-file)      : plumbing;;
 		unpack-objects)   : plumbing;;
 		update-index)     : plumbing;;
@@ -901,7 +909,7 @@
 	esac
 
 	# XXX should we check for --update and --all options ?
-	__git_complete_index_file "--others --modified"
+	__git_complete_index_file "--others --modified --directory --no-empty-directory"
 }
 
 _git_archive ()
@@ -1063,7 +1071,7 @@
 	esac
 
 	# XXX should we check for -x option ?
-	__git_complete_index_file "--others"
+	__git_complete_index_file "--others --directory"
 }
 
 _git_clone ()
@@ -1188,7 +1196,7 @@
 	__git_complete_revlist_file
 }
 
-__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
+__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
 			tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3 codecompare
 "
 
@@ -1491,6 +1499,12 @@
 
 _git_merge_base ()
 {
+	case "$cur" in
+	--*)
+		__gitcomp "--octopus --independent --is-ancestor --fork-point"
+		return
+		;;
+	esac
 	__gitcomp_nl "$(__git_refs)"
 }
 
@@ -1623,7 +1637,7 @@
 			--preserve-merges --stat --no-stat
 			--committer-date-is-author-date --ignore-date
 			--ignore-whitespace --whitespace=
-			--autosquash
+			--autosquash --fork-point --no-fork-point
 			"
 
 		return
@@ -1833,6 +1847,7 @@
 	branch.*)
 		local pfx="${cur%.*}." cur_="${cur#*.}"
 		__gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
+		__gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
 		return
 		;;
 	guitool.*.*)
@@ -1875,6 +1890,7 @@
 	remote.*)
 		local pfx="${cur%.*}." cur_="${cur#*.}"
 		__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
+		__gitcomp_nl_append "pushdefault" "$pfx" "$cur_"
 		return
 		;;
 	url.*.*)
@@ -1997,6 +2013,7 @@
 		fetch.unpackLimit
 		format.attach
 		format.cc
+		format.coverLetter
 		format.headers
 		format.numbered
 		format.pretty
diff --git a/contrib/completion/git-completion.tcsh b/contrib/completion/git-completion.tcsh
index eaacaf0..6104a42 100644
--- a/contrib/completion/git-completion.tcsh
+++ b/contrib/completion/git-completion.tcsh
@@ -1,5 +1,3 @@
-#!tcsh
-#
 # tcsh completion support for core Git.
 #
 # Copyright (C) 2012 Marc Khouzam <marc.khouzam@gmail.com>
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index fac5e71..6b77968 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -30,10 +30,10 @@
 	local -a locations
 	local e
 	locations=(
+		$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
 		'/etc/bash_completion.d/git' # fedora, old debian
 		'/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian
 		'/usr/share/bash-completion/git' # gentoo
-		$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
 		)
 	for e in $locations; do
 		test -f $e && script="$e" && break
@@ -76,6 +76,14 @@
 	compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
 }
 
+__gitcomp_nl_append ()
+{
+	emulate -L zsh
+
+	local IFS=$'\n'
+	compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+}
+
 __gitcomp_file ()
 {
 	emulate -L zsh
diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 998722c..7b732d2 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -60,6 +60,7 @@
 # of values:
 #
 #     verbose       show number of commits ahead/behind (+/-) upstream
+#     name          if verbose, then also show the upstream abbrev name
 #     legacy        don't use the '--count' option available in recent
 #                   versions of git-rev-list
 #     git           always compare HEAD to @{upstream}
@@ -94,7 +95,7 @@
 {
 	local key value
 	local svn_remote svn_url_pattern count n
-	local upstream=git legacy="" verbose=""
+	local upstream=git legacy="" verbose="" name=""
 
 	svn_remote=()
 	# get some config options from git-config
@@ -122,6 +123,7 @@
 		git|svn) upstream="$option" ;;
 		verbose) verbose=1 ;;
 		legacy)  legacy=1  ;;
+		name)    name=1 ;;
 		esac
 	done
 
@@ -204,6 +206,9 @@
 		*)	    # diverged from upstream
 			p=" u+${count#*	}-${count%	*}" ;;
 		esac
+		if [[ -n "$count" && -n "$name" ]]; then
+			p="$p $(git rev-parse --abbrev-ref "$upstream" 2>/dev/null)"
+		fi
 	fi
 
 }
diff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts
index d80f7d1..428cc1a 100755
--- a/contrib/contacts/git-contacts
+++ b/contrib/contacts/git-contacts
@@ -59,11 +59,11 @@
 }
 
 sub get_blame {
-	my ($commits, $source, $start, $len, $from) = @_;
-	$len = 1 unless defined($len);
-	return if $len == 0;
+	my ($commits, $source, $from, $ranges) = @_;
+	return unless @$ranges;
 	open my $f, '-|',
-		qw(git blame --porcelain -C), '-L', "$start,+$len",
+		qw(git blame --porcelain -C),
+		map({"-L$_->[0],+$_->[1]"} @$ranges),
 		'--since', $since, "$from^", '--', $source or die;
 	while (<$f>) {
 		if (/^([0-9a-f]{40}) \d+ \d+ \d+$/) {
@@ -76,8 +76,17 @@
 	close $f;
 }
 
+sub blame_sources {
+	my ($sources, $commits) = @_;
+	for my $s (keys %$sources) {
+		for my $id (keys %{$sources->{$s}}) {
+			get_blame($commits, $s, $id, $sources->{$s}{$id});
+		}
+	}
+}
+
 sub scan_patches {
-	my ($commits, $id, $f) = @_;
+	my ($sources, $id, $f) = @_;
 	my $source;
 	while (<$f>) {
 		if (/^From ([0-9a-f]{40}) Mon Sep 17 00:00:00 2001$/) {
@@ -90,7 +99,8 @@
 		} elsif (/^--- /) {
 			die "Cannot parse hunk source: $_\n";
 		} elsif (/^@@ -(\d+)(?:,(\d+))?/ && $source) {
-			get_blame($commits, $source, $1, $2, $id);
+			my $len = defined($2) ? $2 : 1;
+			push @{$sources->{$source}{$id}}, [$1, $len] if $len;
 		}
 	}
 }
@@ -163,13 +173,20 @@
 	}
 }
 
-my %commits;
+my %sources;
 for (@files) {
-	scan_patch_file(\%commits, $_);
+	scan_patch_file(\%sources, $_);
 }
 if (@rev_args) {
-	scan_rev_args(\%commits, \@rev_args)
+	scan_rev_args(\%sources, \@rev_args)
 }
+
+my $toplevel = `git rev-parse --show-toplevel`;
+chomp $toplevel;
+chdir($toplevel) or die "chdir failure: $toplevel: $!\n";
+
+my %commits;
+blame_sources(\%sources, \%commits);
 import_commits(\%commits);
 
 my $contacts = {};
diff --git a/contrib/credential/gnome-keyring/Makefile b/contrib/credential/gnome-keyring/Makefile
index e6561d8..c3c7c98 100644
--- a/contrib/credential/gnome-keyring/Makefile
+++ b/contrib/credential/gnome-keyring/Makefile
@@ -8,8 +8,8 @@
 -include ../../../config.mak.autogen
 -include ../../../config.mak
 
-INCS:=$(shell pkg-config --cflags gnome-keyring-1)
-LIBS:=$(shell pkg-config --libs gnome-keyring-1)
+INCS:=$(shell pkg-config --cflags gnome-keyring-1 glib-2.0)
+LIBS:=$(shell pkg-config --libs gnome-keyring-1 glib-2.0)
 
 SRCS:=$(MAIN).c
 OBJS:=$(SRCS:.c=.o)
diff --git a/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
index f2cdefe..2a317fc 100644
--- a/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
+++ b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
@@ -25,135 +25,148 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <stdarg.h>
 #include <stdlib.h>
-#include <errno.h>
+#include <glib.h>
 #include <gnome-keyring.h>
 
+#ifdef GNOME_KEYRING_DEFAULT
+
+   /* Modern gnome-keyring */
+
+#include <gnome-keyring-memory.h>
+
+#else
+
+   /*
+    * Support ancient gnome-keyring, circ. RHEL 5.X.
+    * GNOME_KEYRING_DEFAULT seems to have been introduced with Gnome 2.22,
+    * and the other features roughly around Gnome 2.20, 6 months before.
+    * Ubuntu 8.04 used Gnome 2.22 (I think).  Not sure any distro used 2.20.
+    * So the existence/non-existence of GNOME_KEYRING_DEFAULT seems like
+    * a decent thing to use as an indicator.
+    */
+
+#define GNOME_KEYRING_DEFAULT NULL
+
+/*
+ * ancient gnome-keyring returns DENIED when an entry is not found.
+ * Setting NO_MATCH to DENIED will prevent us from reporting DENIED
+ * errors during get and erase operations, but we will still report
+ * DENIED errors during a store.
+ */
+#define GNOME_KEYRING_RESULT_NO_MATCH GNOME_KEYRING_RESULT_DENIED
+
+#define gnome_keyring_memory_alloc g_malloc
+#define gnome_keyring_memory_free gnome_keyring_free_password
+#define gnome_keyring_memory_strdup g_strdup
+
+static const char *gnome_keyring_result_to_message(GnomeKeyringResult result)
+{
+	switch (result) {
+	case GNOME_KEYRING_RESULT_OK:
+		return "OK";
+	case GNOME_KEYRING_RESULT_DENIED:
+		return "Denied";
+	case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON:
+		return "No Keyring Daemon";
+	case GNOME_KEYRING_RESULT_ALREADY_UNLOCKED:
+		return "Already UnLocked";
+	case GNOME_KEYRING_RESULT_NO_SUCH_KEYRING:
+		return "No Such Keyring";
+	case GNOME_KEYRING_RESULT_BAD_ARGUMENTS:
+		return "Bad Arguments";
+	case GNOME_KEYRING_RESULT_IO_ERROR:
+		return "IO Error";
+	case GNOME_KEYRING_RESULT_CANCELLED:
+		return "Cancelled";
+	case GNOME_KEYRING_RESULT_ALREADY_EXISTS:
+		return "Already Exists";
+	default:
+		return "Unknown Error";
+	}
+}
+
+/*
+ * Support really ancient gnome-keyring, circ. RHEL 4.X.
+ * Just a guess for the Glib version.  Glib 2.8 was roughly Gnome 2.12 ?
+ * Which was released with gnome-keyring 0.4.3 ??
+ */
+#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 8
+
+static void gnome_keyring_done_cb(GnomeKeyringResult result, gpointer user_data)
+{
+	gpointer *data = (gpointer *)user_data;
+	int *done = (int *)data[0];
+	GnomeKeyringResult *r = (GnomeKeyringResult *)data[1];
+
+	*r = result;
+	*done = 1;
+}
+
+static void wait_for_request_completion(int *done)
+{
+	GMainContext *mc = g_main_context_default();
+	while (!*done)
+		g_main_context_iteration(mc, TRUE);
+}
+
+static GnomeKeyringResult gnome_keyring_item_delete_sync(const char *keyring, guint32 id)
+{
+	int done = 0;
+	GnomeKeyringResult result;
+	gpointer data[] = { &done, &result };
+
+	gnome_keyring_item_delete(keyring, id, gnome_keyring_done_cb, data,
+		NULL);
+
+	wait_for_request_completion(&done);
+
+	return result;
+}
+
+#endif
+#endif
+
 /*
  * This credential struct and API is simplified from git's credential.{h,c}
  */
-struct credential
-{
-	char          *protocol;
-	char          *host;
+struct credential {
+	char *protocol;
+	char *host;
 	unsigned short port;
-	char          *path;
-	char          *username;
-	char          *password;
+	char *path;
+	char *username;
+	char *password;
 };
 
-#define CREDENTIAL_INIT \
-  { NULL,NULL,0,NULL,NULL,NULL }
+#define CREDENTIAL_INIT { NULL, NULL, 0, NULL, NULL, NULL }
 
-void credential_init(struct credential *c);
-void credential_clear(struct credential *c);
-int  credential_read(struct credential *c);
-void credential_write(const struct credential *c);
+typedef int (*credential_op_cb)(struct credential *);
 
-typedef int (*credential_op_cb)(struct credential*);
-
-struct credential_operation
-{
-	char             *name;
+struct credential_operation {
+	char *name;
 	credential_op_cb op;
 };
 
-#define CREDENTIAL_OP_END \
-  { NULL,NULL }
-
-/*
- * Table with operation callbacks is defined in concrete
- * credential helper implementation and contains entries
- * like { "get", function_to_get_credential } terminated
- * by CREDENTIAL_OP_END.
- */
-struct credential_operation const credential_helper_ops[];
-
-/* ---------------- common helper functions ----------------- */
-
-static inline void free_password(char *password)
-{
-	char *c = password;
-	if (!password)
-		return;
-
-	while (*c) *c++ = '\0';
-	free(password);
-}
-
-static inline void warning(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	fprintf(stderr, "warning: ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, "\n" );
-	va_end(ap);
-}
-
-static inline void error(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	fprintf(stderr, "error: ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, "\n" );
-	va_end(ap);
-}
-
-static inline void die(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap,fmt);
-	error(fmt, ap);
-	va_end(ap);
-	exit(EXIT_FAILURE);
-}
-
-static inline void die_errno(int err)
-{
-	error("%s", strerror(err));
-	exit(EXIT_FAILURE);
-}
-
-static inline char *xstrdup(const char *str)
-{
-	char *ret = strdup(str);
-	if (!ret)
-		die_errno(errno);
-
-	return ret;
-}
+#define CREDENTIAL_OP_END { NULL, NULL }
 
 /* ----------------- GNOME Keyring functions ----------------- */
 
 /* create a special keyring option string, if path is given */
-static char* keyring_object(struct credential *c)
+static char *keyring_object(struct credential *c)
 {
-	char* object = NULL;
-
 	if (!c->path)
-		return object;
+		return NULL;
 
-	object = (char*) malloc(strlen(c->host)+strlen(c->path)+8);
-	if(!object)
-		die_errno(errno);
+	if (c->port)
+		return g_strdup_printf("%s:%hd/%s", c->host, c->port, c->path);
 
-	if(c->port)
-		sprintf(object,"%s:%hd/%s",c->host,c->port,c->path);
-	else
-		sprintf(object,"%s/%s",c->host,c->path);
-
-	return object;
+	return g_strdup_printf("%s/%s", c->host, c->path);
 }
 
-int keyring_get(struct credential *c)
+static int keyring_get(struct credential *c)
 {
-	char* object = NULL;
+	char *object = NULL;
 	GList *entries;
 	GnomeKeyringNetworkPasswordData *password_data;
 	GnomeKeyringResult result;
@@ -173,7 +186,7 @@
 				c->port,
 				&entries);
 
-	free(object);
+	g_free(object);
 
 	if (result == GNOME_KEYRING_RESULT_NO_MATCH)
 		return EXIT_SUCCESS;
@@ -182,18 +195,18 @@
 		return EXIT_SUCCESS;
 
 	if (result != GNOME_KEYRING_RESULT_OK) {
-		error("%s",gnome_keyring_result_to_message(result));
+		g_critical("%s", gnome_keyring_result_to_message(result));
 		return EXIT_FAILURE;
 	}
 
 	/* pick the first one from the list */
-	password_data = (GnomeKeyringNetworkPasswordData *) entries->data;
+	password_data = (GnomeKeyringNetworkPasswordData *)entries->data;
 
-	free_password(c->password);
-	c->password = xstrdup(password_data->password);
+	gnome_keyring_memory_free(c->password);
+	c->password = gnome_keyring_memory_strdup(password_data->password);
 
 	if (!c->username)
-		c->username = xstrdup(password_data->user);
+		c->username = g_strdup(password_data->user);
 
 	gnome_keyring_network_password_list_free(entries);
 
@@ -201,10 +214,11 @@
 }
 
 
-int keyring_store(struct credential *c)
+static int keyring_store(struct credential *c)
 {
 	guint32 item_id;
-	char  *object = NULL;
+	char *object = NULL;
+	GnomeKeyringResult result;
 
 	/*
 	 * Sanity check that what we are storing is actually sensible.
@@ -219,7 +233,7 @@
 
 	object = keyring_object(c);
 
-	gnome_keyring_set_network_password_sync(
+	result = gnome_keyring_set_network_password_sync(
 				GNOME_KEYRING_DEFAULT,
 				c->username,
 				NULL /* domain */,
@@ -231,13 +245,20 @@
 				c->password,
 				&item_id);
 
-	free(object);
+	g_free(object);
+
+	if (result != GNOME_KEYRING_RESULT_OK &&
+	    result != GNOME_KEYRING_RESULT_CANCELLED) {
+		g_critical("%s", gnome_keyring_result_to_message(result));
+		return EXIT_FAILURE;
+	}
+
 	return EXIT_SUCCESS;
 }
 
-int keyring_erase(struct credential *c)
+static int keyring_erase(struct credential *c)
 {
-	char  *object = NULL;
+	char *object = NULL;
 	GList *entries;
 	GnomeKeyringNetworkPasswordData *password_data;
 	GnomeKeyringResult result;
@@ -265,7 +286,7 @@
 				c->port,
 				&entries);
 
-	free(object);
+	g_free(object);
 
 	if (result == GNOME_KEYRING_RESULT_NO_MATCH)
 		return EXIT_SUCCESS;
@@ -273,23 +294,21 @@
 	if (result == GNOME_KEYRING_RESULT_CANCELLED)
 		return EXIT_SUCCESS;
 
-	if (result != GNOME_KEYRING_RESULT_OK)
-	{
-		error("%s",gnome_keyring_result_to_message(result));
+	if (result != GNOME_KEYRING_RESULT_OK) {
+		g_critical("%s", gnome_keyring_result_to_message(result));
 		return EXIT_FAILURE;
 	}
 
 	/* pick the first one from the list (delete all matches?) */
-	password_data = (GnomeKeyringNetworkPasswordData *) entries->data;
+	password_data = (GnomeKeyringNetworkPasswordData *)entries->data;
 
 	result = gnome_keyring_item_delete_sync(
 		password_data->keyring, password_data->item_id);
 
 	gnome_keyring_network_password_list_free(entries);
 
-	if (result != GNOME_KEYRING_RESULT_OK)
-	{
-		error("%s",gnome_keyring_result_to_message(result));
+	if (result != GNOME_KEYRING_RESULT_OK) {
+		g_critical("%s", gnome_keyring_result_to_message(result));
 		return EXIT_FAILURE;
 	}
 
@@ -300,9 +319,8 @@
  * Table with helper operation callbacks, used by generic
  * credential helper main function.
  */
-struct credential_operation const credential_helper_ops[] =
-{
-	{ "get",   keyring_get   },
+static struct credential_operation const credential_helper_ops[] = {
+	{ "get",   keyring_get },
 	{ "store", keyring_store },
 	{ "erase", keyring_erase },
 	CREDENTIAL_OP_END
@@ -310,67 +328,70 @@
 
 /* ------------------ credential functions ------------------ */
 
-void credential_init(struct credential *c)
+static void credential_init(struct credential *c)
 {
 	memset(c, 0, sizeof(*c));
 }
 
-void credential_clear(struct credential *c)
+static void credential_clear(struct credential *c)
 {
-	free(c->protocol);
-	free(c->host);
-	free(c->path);
-	free(c->username);
-	free_password(c->password);
+	g_free(c->protocol);
+	g_free(c->host);
+	g_free(c->path);
+	g_free(c->username);
+	gnome_keyring_memory_free(c->password);
 
 	credential_init(c);
 }
 
-int credential_read(struct credential *c)
+static int credential_read(struct credential *c)
 {
-	char    buf[1024];
-	ssize_t line_len = 0;
-	char   *key      = buf;
-	char   *value;
+	char *buf;
+	size_t line_len;
+	char *key;
+	char *value;
 
-	while (fgets(buf, sizeof(buf), stdin))
-	{
+	key = buf = gnome_keyring_memory_alloc(1024);
+
+	while (fgets(buf, 1024, stdin)) {
 		line_len = strlen(buf);
 
-		if(buf[line_len-1]=='\n')
-			buf[--line_len]='\0';
+		if (line_len && buf[line_len-1] == '\n')
+			buf[--line_len] = '\0';
 
-		if(!line_len)
+		if (!line_len)
 			break;
 
-		value = strchr(buf,'=');
-		if(!value) {
-			warning("invalid credential line: %s", key);
+		value = strchr(buf, '=');
+		if (!value) {
+			g_warning("invalid credential line: %s", key);
+			gnome_keyring_memory_free(buf);
 			return -1;
 		}
 		*value++ = '\0';
 
 		if (!strcmp(key, "protocol")) {
-			free(c->protocol);
-			c->protocol = xstrdup(value);
+			g_free(c->protocol);
+			c->protocol = g_strdup(value);
 		} else if (!strcmp(key, "host")) {
-			free(c->host);
-			c->host = xstrdup(value);
-			value = strrchr(c->host,':');
+			g_free(c->host);
+			c->host = g_strdup(value);
+			value = strrchr(c->host, ':');
 			if (value) {
 				*value++ = '\0';
 				c->port = atoi(value);
 			}
 		} else if (!strcmp(key, "path")) {
-			free(c->path);
-			c->path = xstrdup(value);
+			g_free(c->path);
+			c->path = g_strdup(value);
 		} else if (!strcmp(key, "username")) {
-			free(c->username);
-			c->username = xstrdup(value);
+			g_free(c->username);
+			c->username = g_strdup(value);
 		} else if (!strcmp(key, "password")) {
-			free_password(c->password);
-			c->password = xstrdup(value);
-			while (*value) *value++ = '\0';
+			gnome_keyring_memory_free(c->password);
+			c->password = gnome_keyring_memory_strdup(value);
+			while (*value)
+				*value++ = '\0';
 		}
 		/*
 		 * Ignore other lines; we don't know what they mean, but
@@ -378,17 +399,20 @@
 		 * learn new lines, and the helpers are updated to match.
 		 */
 	}
+
+	gnome_keyring_memory_free(buf);
+
 	return 0;
 }
 
-void credential_write_item(FILE *fp, const char *key, const char *value)
+static void credential_write_item(FILE *fp, const char *key, const char *value)
 {
 	if (!value)
 		return;
 	fprintf(fp, "%s=%s\n", key, value);
 }
 
-void credential_write(const struct credential *c)
+static void credential_write(const struct credential *c)
 {
 	/* only write username/password, if set */
 	credential_write_item(stdout, "username", c->username);
@@ -398,16 +422,16 @@
 static void usage(const char *name)
 {
 	struct credential_operation const *try_op = credential_helper_ops;
-	const char *basename = strrchr(name,'/');
+	const char *basename = strrchr(name, '/');
 
 	basename = (basename) ? basename + 1 : name;
 	fprintf(stderr, "usage: %s <", basename);
-	while(try_op->name) {
-		fprintf(stderr,"%s",(try_op++)->name);
-		if(try_op->name)
-			fprintf(stderr,"%s","|");
+	while (try_op->name) {
+		fprintf(stderr, "%s", (try_op++)->name);
+		if (try_op->name)
+			fprintf(stderr, "%s", "|");
 	}
-	fprintf(stderr,"%s",">\n");
+	fprintf(stderr, "%s", ">\n");
 }
 
 int main(int argc, char *argv[])
@@ -415,23 +439,25 @@
 	int ret = EXIT_SUCCESS;
 
 	struct credential_operation const *try_op = credential_helper_ops;
-	struct credential                  cred   = CREDENTIAL_INIT;
+	struct credential cred = CREDENTIAL_INIT;
 
 	if (!argv[1]) {
 		usage(argv[0]);
-		goto out;
+		exit(EXIT_FAILURE);
 	}
 
+	g_set_application_name("Git Credential Helper");
+
 	/* lookup operation callback */
-	while(try_op->name && strcmp(argv[1], try_op->name))
+	while (try_op->name && strcmp(argv[1], try_op->name))
 		try_op++;
 
 	/* unsupported operation given -- ignore silently */
-	if(!try_op->name || !try_op->op)
+	if (!try_op->name || !try_op->op)
 		goto out;
 
 	ret = credential_read(&cred);
-	if(ret)
+	if (ret)
 		goto out;
 
 	/* perform credential operation */
diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc
index 6c51c43..1571a7b 100755
--- a/contrib/credential/netrc/git-credential-netrc
+++ b/contrib/credential/netrc/git-credential-netrc
@@ -369,7 +369,9 @@
 	{
 		my $entry_text = join ', ', map { "$_=$entry->{$_}" } keys %$entry;
 		foreach my $check (sort keys %$query) {
-			if (defined $query->{$check}) {
+			if (!defined $entry->{$check}) {
+			        log_debug("OK: entry has no $check token, so any value satisfies check $check");
+			} elsif (defined $query->{$check}) {
 				log_debug("compare %s [%s] to [%s] (entry: %s)",
 					  $check,
 					  $entry->{$check},
diff --git a/contrib/examples/git-log.sh b/contrib/examples/git-log.sh
new file mode 100755
index 0000000..c2ea71c
--- /dev/null
+++ b/contrib/examples/git-log.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+#
+
+USAGE='[--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [git-rev-list options]'
+SUBDIRECTORY_OK='Yes'
+. git-sh-setup
+
+revs=$(git-rev-parse --revs-only --no-flags --default HEAD "$@") || exit
+[ "$revs" ] || {
+	die "No HEAD ref"
+}
+git-rev-list --pretty $(git-rev-parse --default HEAD "$@") |
+LESS=-S ${PAGER:-less}
diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh
index 7b922c3..a5e42a9 100755
--- a/contrib/examples/git-merge.sh
+++ b/contrib/examples/git-merge.sh
@@ -263,7 +263,7 @@
 
 # This could be traditional "merge <msg> HEAD <commit>..."  and the
 # way we can tell it is to see if the second token is HEAD, but some
-# people might have misused the interface and used a committish that
+# people might have misused the interface and used a commit-ish that
 # is the same as HEAD there instead.  Traditional format never would
 # have "-m" so it is an additional safety measure to check for it.
 
diff --git a/git-repack.sh b/contrib/examples/git-repack.sh
similarity index 100%
rename from git-repack.sh
rename to contrib/examples/git-repack.sh
diff --git a/contrib/examples/git-whatchanged.sh b/contrib/examples/git-whatchanged.sh
new file mode 100755
index 0000000..2edbdc6
--- /dev/null
+++ b/contrib/examples/git-whatchanged.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+USAGE='[-p] [--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [-m] [git-diff-tree options] [git-rev-list options]'
+SUBDIRECTORY_OK='Yes'
+. git-sh-setup
+
+diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@") || exit
+case "$0" in
+*whatchanged)
+	count=
+	test -z "$diff_tree_flags" &&
+		diff_tree_flags=$(git config --get whatchanged.difftree)
+	diff_tree_default_flags='-c -M --abbrev' ;;
+*show)
+	count=-n1
+	test -z "$diff_tree_flags" &&
+		diff_tree_flags=$(git config --get show.difftree)
+	diff_tree_default_flags='--cc --always' ;;
+esac
+test -z "$diff_tree_flags" &&
+	diff_tree_flags="$diff_tree_default_flags"
+
+rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") &&
+diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") &&
+
+eval "git-rev-list $count $rev_list_args" |
+eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" |
+LESS="$LESS -S" ${PAGER:-less}
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 4c99dfb..4e23c65 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -1205,7 +1205,7 @@
 
 		#The first parent always continue on the same line
 		try:
-			# check we alreay have the value
+			# check we already have the value
 			tmp_node_pos = self.nodepos[commit.parent_sha1[0]]
 		except KeyError:
 			self.colours[commit.parent_sha1[0]] = colour
diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index 1531150..8747b84 100755
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -22,7 +22,6 @@
 # For example, on debian the hook is stored in
 # /usr/share/git-core/contrib/hooks/post-receive-email:
 #
-#  chmod a+x post-receive-email
 #  cd /path/to/your/repository.git
 #  ln -sf /usr/share/git-core/contrib/hooks/post-receive-email hooks/post-receive
 #
@@ -242,6 +241,9 @@
 	cat <<-EOF
 	To: $recipients
 	Subject: ${emailprefix}$projectdesc $refname_type $short_refname ${change_type}d. $describe
+	MIME-Version: 1.0
+	Content-Type: text/plain; charset=utf-8
+	Content-Transfer-Encoding: 8bit
 	X-Git-Refname: $refname
 	X-Git-Reftype: $refname_type
 	X-Git-Oldrev: $oldrev
@@ -471,7 +473,7 @@
 	echo "       was  $oldrev"
 	echo ""
 	echo $LOGBEGIN
-	git show -s --pretty=oneline $oldrev
+	git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
 	echo $LOGEND
 }
 
@@ -547,11 +549,11 @@
 		# performed on them
 		if [ -n "$prevtag" ]; then
 			# Show changes since the previous release
-			git rev-list --pretty=short "$prevtag..$newrev" | git shortlog
+			git shortlog "$prevtag..$newrev"
 		else
 			# No previous tag, show all the changes since time
 			# began
-			git rev-list --pretty=short $newrev | git shortlog
+			git shortlog $newrev
 		fi
 		;;
 	*)
@@ -571,7 +573,7 @@
 	echo "       was  $oldrev"
 	echo ""
 	echo $LOGBEGIN
-	git show -s --pretty=oneline $oldrev
+	git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
 	echo $LOGEND
 }
 
@@ -617,7 +619,7 @@
 	echo ""
 	if [ "$newrev_type" = "commit" ]; then
 		echo $LOGBEGIN
-		git show --no-color --root -s --pretty=medium $newrev
+		git diff-tree -s --always --encoding=UTF-8 --pretty=medium $newrev
 		echo $LOGEND
 	else
 		# What can we do here?  The tag marks an object that is not
@@ -636,7 +638,7 @@
 	echo "       was  $oldrev"
 	echo ""
 	echo $LOGBEGIN
-	git show -s --pretty=oneline $oldrev
+	git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
 	echo $LOGEND
 }
 
diff --git a/contrib/hooks/pre-auto-gc-battery b/contrib/hooks/pre-auto-gc-battery
old mode 100644
new mode 100755
index 1f914c9..9d0c2d1
--- a/contrib/hooks/pre-auto-gc-battery
+++ b/contrib/hooks/pre-auto-gc-battery
@@ -13,7 +13,6 @@
 # For example, if the hook is stored in
 # /usr/share/git-core/contrib/hooks/pre-auto-gc-battery:
 #
-# chmod a+x pre-auto-gc-battery
 # cd /path/to/your/repository.git
 # ln -sf /usr/share/git-core/contrib/hooks/pre-auto-gc-battery \
 #	hooks/pre-auto-gc
diff --git a/contrib/hooks/setgitperms.perl b/contrib/hooks/setgitperms.perl
old mode 100644
new mode 100755
diff --git a/contrib/hooks/update-paranoid b/contrib/hooks/update-paranoid
old mode 100644
new mode 100755
diff --git a/contrib/mw-to-git/Makefile b/contrib/mw-to-git/Makefile
index 76fcd4d..a4b6f7a 100644
--- a/contrib/mw-to-git/Makefile
+++ b/contrib/mw-to-git/Makefile
@@ -18,14 +18,25 @@
 GIT_ROOT_DIR=../..
 HERE=contrib/mw-to-git/
 
+INSTALL = install
+
 SCRIPT_PERL_FULL=$(patsubst %,$(HERE)/%,$(SCRIPT_PERL))
 INSTLIBDIR=$(shell $(MAKE) -C $(GIT_ROOT_DIR)/perl \
                 -s --no-print-directory instlibdir)
+DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
+INSTLIBDIR_SQ = $(subst ','\'',$(INSTLIBDIR))
 
 all: build
 
+test: all
+	$(MAKE) -C t
+
+check: perlcritic test
+
 install_pm:
-	install $(GIT_MEDIAWIKI_PM) $(INSTLIBDIR)/$(GIT_MEDIAWIKI_PM)
+	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(INSTLIBDIR_SQ)/Git'
+	$(INSTALL) -m 644 $(GIT_MEDIAWIKI_PM) \
+		'$(DESTDIR_SQ)$(INSTLIBDIR_SQ)/$(GIT_MEDIAWIKI_PM)'
 
 build:
 	$(MAKE) -C $(GIT_ROOT_DIR) SCRIPT_PERL="$(SCRIPT_PERL_FULL)" \
@@ -38,7 +49,9 @@
 clean:
 	$(MAKE) -C $(GIT_ROOT_DIR) SCRIPT_PERL="$(SCRIPT_PERL_FULL)" \
                 clean-perl-script
-	rm $(INSTLIBDIR)/$(GIT_MEDIAWIKI_PM)
 
 perlcritic:
-	perlcritic -2 *.perl
+	perlcritic -5 $(SCRIPT_PERL)
+	-perlcritic -2 $(SCRIPT_PERL)
+
+.PHONY: all test check install_pm install clean perlcritic
diff --git a/contrib/mw-to-git/git-remote-mediawiki.perl b/contrib/mw-to-git/git-remote-mediawiki.perl
index 85d0c42..3f8d993 100755
--- a/contrib/mw-to-git/git-remote-mediawiki.perl
+++ b/contrib/mw-to-git/git-remote-mediawiki.perl
@@ -590,6 +590,9 @@
 	print {*STDOUT} "import\n";
 	print {*STDOUT} "list\n";
 	print {*STDOUT} "push\n";
+	if ($dumb_push) {
+		print {*STDOUT} "no-private-update\n";
+	}
 	print {*STDOUT} "\n";
 	return;
 }
@@ -1221,7 +1224,6 @@
 		}
 		if (!$dumb_push) {
 			run_git(qq(notes --ref=${remotename}/mediawiki add -f -m "mediawiki_revision: ${mw_revision}" ${sha1_commit}));
-			run_git(qq(update-ref -m "Git-MediaWiki push" refs/mediawiki/${remotename}/master ${sha1_commit} ${sha1_child}));
 		}
 	}
 
@@ -1313,7 +1315,7 @@
 	# Store "notANameSpace" as special value for inexisting namespaces
 	my $store_id = ($id || 'notANameSpace');
 
-	# Store explicitely requested namespaces on disk
+	# Store explicitly requested namespaces on disk
 	if (!exists $cached_mw_namespace_id{$name}) {
 		run_git(qq(config --add remote.${remotename}.namespaceCache "${name}:${store_id}"));
 		$cached_mw_namespace_id{$name} = 1;
diff --git a/contrib/mw-to-git/t/test-gitmw-lib.sh b/contrib/mw-to-git/t/test-gitmw-lib.sh
index ca6860f..3372b2a 100755
--- a/contrib/mw-to-git/t/test-gitmw-lib.sh
+++ b/contrib/mw-to-git/t/test-gitmw-lib.sh
@@ -91,7 +91,7 @@
 # Check that <dir> contains exactly <N> files
 test_contains_N_files () {
 	if test `ls -- "$1" | wc -l` -ne "$2"; then
-		echo "directory $1 sould contain $2 files"
+		echo "directory $1 should contain $2 files"
 		echo "it contains these files:"
 		ls "$1"
 		false
diff --git a/contrib/mw-to-git/t/test.config b/contrib/mw-to-git/t/test.config
index 4cfebe9..5ba0684 100644
--- a/contrib/mw-to-git/t/test.config
+++ b/contrib/mw-to-git/t/test.config
@@ -12,7 +12,7 @@
 TMP=/tmp
 DB_FILE=wikidb.sqlite
 
-# If LIGHTTPD is not set to true, the script will use the defaut
+# If LIGHTTPD is not set to true, the script will use the default
 # web server running in WIKI_DIR_INST.
 WIKI_DIR_INST=/var/www
 
diff --git a/contrib/p4import/README b/contrib/p4import/README
deleted file mode 100644
index b9892b6..0000000
--- a/contrib/p4import/README
+++ /dev/null
@@ -1 +0,0 @@
-Please see contrib/fast-import/git-p4 for a better Perforce importer.
diff --git a/contrib/p4import/git-p4import.py b/contrib/p4import/git-p4import.py
deleted file mode 100644
index 593d6a0..0000000
--- a/contrib/p4import/git-p4import.py
+++ /dev/null
@@ -1,365 +0,0 @@
-#!/usr/bin/env python
-#
-# This tool is copyright (c) 2006, Sean Estabrooks.
-# It is released under the Gnu Public License, version 2.
-#
-# Import Perforce branches into Git repositories.
-# Checking out the files is done by calling the standard p4
-# client which you must have properly configured yourself
-#
-
-import marshal
-import os
-import sys
-import time
-import getopt
-
-if sys.hexversion < 0x02020000:
-   # The behavior of the marshal module changed significantly in 2.2
-   sys.stderr.write("git-p4import.py: requires Python 2.2 or later.\n")
-   sys.exit(1)
-
-from signal import signal, \
-   SIGPIPE, SIGINT, SIG_DFL, \
-   default_int_handler
-
-signal(SIGPIPE, SIG_DFL)
-s = signal(SIGINT, SIG_DFL)
-if s != default_int_handler:
-   signal(SIGINT, s)
-
-def die(msg, *args):
-    for a in args:
-        msg = "%s %s" % (msg, a)
-    print "git-p4import fatal error:", msg
-    sys.exit(1)
-
-def usage():
-    print "USAGE: git-p4import [-q|-v]  [--authors=<file>]  [-t <timezone>]  [//p4repo/path <branch>]"
-    sys.exit(1)
-
-verbosity = 1
-logfile = "/dev/null"
-ignore_warnings = False
-stitch = 0
-tagall = True
-
-def report(level, msg, *args):
-    global verbosity
-    global logfile
-    for a in args:
-        msg = "%s %s" % (msg, a)
-    fd = open(logfile, "a")
-    fd.writelines(msg)
-    fd.close()
-    if level <= verbosity:
-        print msg
-
-class p4_command:
-    def __init__(self, _repopath):
-        try:
-            global logfile
-            self.userlist = {}
-            if _repopath[-1] == '/':
-                self.repopath = _repopath[:-1]
-            else:
-                self.repopath = _repopath
-            if self.repopath[-4:] != "/...":
-                self.repopath= "%s/..." % self.repopath
-            f=os.popen('p4 -V 2>>%s'%logfile, 'rb')
-            a = f.readlines()
-            if f.close():
-                raise
-        except:
-                die("Could not find the \"p4\" command")
-
-    def p4(self, cmd, *args):
-        global logfile
-        cmd = "%s %s" % (cmd, ' '.join(args))
-        report(2, "P4:", cmd)
-        f=os.popen('p4 -G %s 2>>%s' % (cmd,logfile), 'rb')
-        list = []
-        while 1:
-           try:
-                list.append(marshal.load(f))
-           except EOFError:
-                break
-        self.ret = f.close()
-        return list
-
-    def sync(self, id, force=False, trick=False, test=False):
-        if force:
-            ret = self.p4("sync -f %s@%s"%(self.repopath, id))[0]
-        elif trick:
-            ret = self.p4("sync -k %s@%s"%(self.repopath, id))[0]
-        elif test:
-            ret = self.p4("sync -n %s@%s"%(self.repopath, id))[0]
-        else:
-            ret = self.p4("sync    %s@%s"%(self.repopath, id))[0]
-        if ret['code'] == "error":
-             data = ret['data'].upper()
-             if data.find('VIEW') > 0:
-                 die("Perforce reports %s is not in client view"% self.repopath)
-             elif data.find('UP-TO-DATE') < 0:
-                 die("Could not sync files from perforce", self.repopath)
-
-    def changes(self, since=0):
-        try:
-            list = []
-            for rec in self.p4("changes %s@%s,#head" % (self.repopath, since+1)):
-                list.append(rec['change'])
-            list.reverse()
-            return list
-        except:
-            return []
-
-    def authors(self, filename):
-        f=open(filename)
-        for l in f.readlines():
-            self.userlist[l[:l.find('=')].rstrip()] = \
-                    (l[l.find('=')+1:l.find('<')].rstrip(),l[l.find('<')+1:l.find('>')])
-        f.close()
-        for f,e in self.userlist.items():
-                report(2, f, ":", e[0], "  <", e[1], ">")
-
-    def _get_user(self, id):
-        if not self.userlist.has_key(id):
-            try:
-                user = self.p4("users", id)[0]
-                self.userlist[id] = (user['FullName'], user['Email'])
-            except:
-                self.userlist[id] = (id, "")
-        return self.userlist[id]
-
-    def _format_date(self, ticks):
-        symbol='+'
-        name = time.tzname[0]
-        offset = time.timezone
-        if ticks[8]:
-            name = time.tzname[1]
-            offset = time.altzone
-        if offset < 0:
-            offset *= -1
-            symbol = '-'
-        localo = "%s%02d%02d %s" % (symbol, offset / 3600, offset % 3600, name)
-        tickso = time.strftime("%a %b %d %H:%M:%S %Y", ticks)
-        return "%s %s" % (tickso, localo)
-
-    def where(self):
-        try:
-            return self.p4("where %s" % self.repopath)[-1]['path']
-        except:
-            return ""
-
-    def describe(self, num):
-        desc = self.p4("describe -s", num)[0]
-        self.msg = desc['desc']
-        self.author, self.email = self._get_user(desc['user'])
-        self.date = self._format_date(time.localtime(long(desc['time'])))
-        return self
-
-class git_command:
-    def __init__(self):
-        try:
-            self.version = self.git("--version")[0][12:].rstrip()
-        except:
-            die("Could not find the \"git\" command")
-        try:
-            self.gitdir = self.get_single("rev-parse --git-dir")
-            report(2, "gdir:", self.gitdir)
-        except:
-            die("Not a git repository... did you forget to \"git init\" ?")
-        try:
-            self.cdup = self.get_single("rev-parse --show-cdup")
-            if self.cdup != "":
-                os.chdir(self.cdup)
-            self.topdir = os.getcwd()
-            report(2, "topdir:", self.topdir)
-        except:
-            die("Could not find top git directory")
-
-    def git(self, cmd):
-        global logfile
-        report(2, "GIT:", cmd)
-        f=os.popen('git %s 2>>%s' % (cmd,logfile), 'rb')
-        r=f.readlines()
-        self.ret = f.close()
-        return r
-
-    def get_single(self, cmd):
-        return self.git(cmd)[0].rstrip()
-
-    def current_branch(self):
-        try:
-            testit = self.git("rev-parse --verify HEAD")[0]
-            return self.git("symbolic-ref HEAD")[0][11:].rstrip()
-        except:
-            return None
-
-    def get_config(self, variable):
-        try:
-            return self.git("config --get %s" % variable)[0].rstrip()
-        except:
-            return None
-
-    def set_config(self, variable, value):
-        try:
-            self.git("config %s %s"%(variable, value) )
-        except:
-            die("Could not set %s to " % variable, value)
-
-    def make_tag(self, name, head):
-        self.git("tag -f %s %s"%(name,head))
-
-    def top_change(self, branch):
-        try:
-            a=self.get_single("name-rev --tags refs/heads/%s" % branch)
-            loc = a.find(' tags/') + 6
-            if a[loc:loc+3] != "p4/":
-                raise
-            return int(a[loc+3:][:-2])
-        except:
-            return 0
-
-    def update_index(self):
-        self.git("ls-files -m -d -o -z | git update-index --add --remove -z --stdin")
-
-    def checkout(self, branch):
-        self.git("checkout %s" % branch)
-
-    def repoint_head(self, branch):
-        self.git("symbolic-ref HEAD refs/heads/%s" % branch)
-
-    def remove_files(self):
-        self.git("ls-files | xargs rm")
-
-    def clean_directories(self):
-        self.git("clean -d")
-
-    def fresh_branch(self, branch):
-        report(1, "Creating new branch", branch)
-        self.git("ls-files | xargs rm")
-        os.remove(".git/index")
-        self.repoint_head(branch)
-        self.git("clean -d")
-
-    def basedir(self):
-        return self.topdir
-
-    def commit(self, author, email, date, msg, id):
-        self.update_index()
-        fd=open(".msg", "w")
-        fd.writelines(msg)
-        fd.close()
-        try:
-                current = self.get_single("rev-parse --verify HEAD")
-                head = "-p HEAD"
-        except:
-                current = ""
-                head = ""
-        tree = self.get_single("write-tree")
-        for r,l in [('DATE',date),('NAME',author),('EMAIL',email)]:
-            os.environ['GIT_AUTHOR_%s'%r] = l
-            os.environ['GIT_COMMITTER_%s'%r] = l
-        commit = self.get_single("commit-tree %s %s < .msg" % (tree,head))
-        os.remove(".msg")
-        self.make_tag("p4/%s"%id, commit)
-        self.git("update-ref HEAD %s %s" % (commit, current) )
-
-try:
-    opts, args = getopt.getopt(sys.argv[1:], "qhvt:",
-            ["authors=","help","stitch=","timezone=","log=","ignore","notags"])
-except getopt.GetoptError:
-    usage()
-
-for o, a in opts:
-    if o == "-q":
-        verbosity = 0
-    if o == "-v":
-        verbosity += 1
-    if o in ("--log"):
-        logfile = a
-    if o in ("--notags"):
-        tagall = False
-    if o in ("-h", "--help"):
-        usage()
-    if o in ("--ignore"):
-        ignore_warnings = True
-
-git = git_command()
-branch=git.current_branch()
-
-for o, a in opts:
-    if o in ("-t", "--timezone"):
-        git.set_config("perforce.timezone", a)
-    if o in ("--stitch"):
-        git.set_config("perforce.%s.path" % branch, a)
-        stitch = 1
-
-if len(args) == 2:
-    branch = args[1]
-    git.checkout(branch)
-    if branch == git.current_branch():
-        die("Branch %s already exists!" % branch)
-    report(1, "Setting perforce to ", args[0])
-    git.set_config("perforce.%s.path" % branch, args[0])
-elif len(args) != 0:
-    die("You must specify the perforce //depot/path and git branch")
-
-p4path = git.get_config("perforce.%s.path" % branch)
-if p4path == None:
-    die("Do not know Perforce //depot/path for git branch", branch)
-
-p4 = p4_command(p4path)
-
-for o, a in opts:
-    if o in ("-a", "--authors"):
-        p4.authors(a)
-
-localdir = git.basedir()
-if p4.where()[:len(localdir)] != localdir:
-    report(1, "**WARNING** Appears p4 client is misconfigured")
-    report(1, "   for sync from %s to %s" % (p4.repopath, localdir))
-    if ignore_warnings != True:
-        die("Reconfigure or use \"--ignore\" on command line")
-
-if stitch == 0:
-    top = git.top_change(branch)
-else:
-    top = 0
-changes = p4.changes(top)
-count = len(changes)
-if count == 0:
-    report(1, "Already up to date...")
-    sys.exit(0)
-
-ptz = git.get_config("perforce.timezone")
-if ptz:
-    report(1, "Setting timezone to", ptz)
-    os.environ['TZ'] = ptz
-    time.tzset()
-
-if stitch == 1:
-    git.remove_files()
-    git.clean_directories()
-    p4.sync(changes[0], force=True)
-elif top == 0 and branch != git.current_branch():
-    p4.sync(changes[0], test=True)
-    report(1, "Creating new initial commit");
-    git.fresh_branch(branch)
-    p4.sync(changes[0], force=True)
-else:
-    p4.sync(changes[0], trick=True)
-
-report(1, "processing %s changes from p4 (%s) to git (%s)" % (count, p4.repopath, branch))
-for id in changes:
-    report(1, "Importing changeset", id)
-    change = p4.describe(id)
-    p4.sync(id)
-    if tagall :
-            git.commit(change.author, change.email, change.date, change.msg, id)
-    else:
-            git.commit(change.author, change.email, change.date, change.msg, "import")
-    if stitch == 1:
-        git.clean_directories()
-        stitch = 0
diff --git a/contrib/p4import/git-p4import.txt b/contrib/p4import/git-p4import.txt
deleted file mode 100644
index 9967587..0000000
--- a/contrib/p4import/git-p4import.txt
+++ /dev/null
@@ -1,167 +0,0 @@
-git-p4import(1)
-===============
-
-NAME
-----
-git-p4import - Import a Perforce repository into git
-
-
-SYNOPSIS
---------
-[verse]
-`git-p4import` [-q|-v] [--notags] [--authors <file>] [-t <timezone>]
-               <//p4repo/path> <branch>
-`git-p4import` --stitch <//p4repo/path>
-`git-p4import`
-
-
-DESCRIPTION
------------
-Import a Perforce repository into an existing git repository.  When
-a <//p4repo/path> and <branch> are specified a new branch with the
-given name will be created and the initial import will begin.
-
-Once the initial import is complete you can do an incremental import
-of new commits from the Perforce repository.  You do this by checking
-out the appropriate git branch and then running `git-p4import` without
-any options.
-
-The standard p4 client is used to communicate with the Perforce
-repository; it must be configured correctly in order for `git-p4import`
-to operate (see below).
-
-
-OPTIONS
--------
--q::
-	Do not display any progress information.
-
--v::
-        Give extra progress information.
-
-\--authors::
-	Specify an authors file containing a mapping of Perforce user
-	ids to full names and email addresses (see Notes below).
-
-\--notags::
-	Do not create a tag for each imported commit.
-
-\--stitch::
-	Import the contents of the given perforce branch into the
-	currently checked out git branch.
-
-\--log::
-	Store debugging information in the specified file.
-
--t::
-	Specify that the remote repository is in the specified timezone.
-	Timezone must be in the format "US/Pacific" or "Europe/London"
-	etc.  You only need to specify this once, it will be saved in
-	the git config file for the repository.
-
-<//p4repo/path>::
-	The Perforce path that will be imported into the specified branch.
-
-<branch>::
-	The new branch that will be created to hold the Perforce imports.
-
-
-P4 Client
----------
-You must make the `p4` client command available in your $PATH and
-configure it to communicate with the target Perforce repository.
-Typically this means you must set the "$P4PORT" and "$P4CLIENT"
-environment variables.
-
-You must also configure a `p4` client "view" which maps the Perforce
-branch into the top level of your git repository, for example:
-
-------------
-Client: myhost
-
-Root:   /home/sean/import
-
-Options:   noallwrite clobber nocompress unlocked modtime rmdir
-
-View:
-        //public/jam/... //myhost/jam/...
-------------
-
-With the above `p4` client setup, you could import the "jam"
-perforce branch into a branch named "jammy", like so:
-
-------------
-$ mkdir -p /home/sean/import/jam
-$ cd /home/sean/import/jam
-$ git init
-$ git p4import //public/jam jammy
-------------
-
-
-Multiple Branches
------------------
-Note that by creating multiple "views" you can use `git-p4import`
-to import additional branches into the same git repository.
-However, the `p4` client has a limitation in that it silently
-ignores all but the last "view" that maps into the same local
-directory.  So the following will *not* work:
-
-------------
-View:
-        //public/jam/... //myhost/jam/...
-        //public/other/... //myhost/jam/...
-        //public/guest/... //myhost/jam/...
-------------
-
-If you want more than one Perforce branch to be imported into the
-same directory you must employ a workaround.  A simple option is
-to adjust your `p4` client before each import to only include a
-single view.
-
-Another option is to create multiple symlinks locally which all
-point to the same directory in your git repository and then use
-one per "view" instead of listing the actual directory.
-
-
-Tags
-----
-A git tag of the form p4/xx is created for every change imported from
-the Perforce repository where xx is the Perforce changeset number.
-Therefore after the import you can use git to access any commit by its
-Perforce number, e.g. git show p4/327.
-
-The tag associated with the HEAD commit is also how `git-p4import`
-determines if there are new changes to incrementally import from the
-Perforce repository.
-
-If you import from a repository with many thousands of changes
-you will have an equal number of p4/xxxx git tags.  Git tags can
-be expensive in terms of disk space and repository operations.
-If you don't need to perform further incremental imports, you
-may delete the tags.
-
-
-Notes
------
-You can interrupt the import (e.g. ctrl-c) at any time and restart it
-without worry.
-
-Author information is automatically determined by querying the
-Perforce "users" table using the id associated with each change.
-However, if you want to manually supply these mappings you can do
-so with the "--authors" option.  It accepts a file containing a list
-of mappings with each line containing one mapping in the format:
-
-------------
-    perforce_id = Full Name <email@address.com>
-------------
-
-
-Author
-------
-Written by Sean Estabrooks <seanlkml@sympatico.ca>
-
-
-GIT
----
-Part of the gitlink:git[7] suite
diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr
index c3a3cac..332aba7 100755
--- a/contrib/remote-helpers/git-remote-bzr
+++ b/contrib/remote-helpers/git-remote-bzr
@@ -13,8 +13,11 @@
 # or
 # % git clone bzr::lp:myrepo
 #
-# If you want to specify which branches you want track (per repo):
-# git config remote-bzr.branches 'trunk, devel, test'
+# If you want to specify which branches you want to track (per repo):
+# % git config remote.origin.bzr-branches 'trunk, devel, test'
+#
+# Where 'origin' is the name of the repository you want to specify the
+# branches.
 #
 
 import sys
@@ -41,8 +44,8 @@
 import atexit, shutil, hashlib, urlparse, subprocess
 
 NAME_RE = re.compile('^([^<>]+)')
-AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$')
-EMAIL_RE = re.compile('^([^<>]+[^ \\\t<>])?\\b(?:[ \\t<>]*?)\\b([^ \\t<>]+@[^ \\t<>]+)')
+AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
+EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
 RAW_AUTHOR_RE = re.compile('^(\w+) (.+)? <(.*)> (\d+) ([+-]\d+)')
 
 def die(msg, *args):
@@ -168,17 +171,16 @@
         if not m:
             return None
         _, name, email, date, tz = m.groups()
+        name = name.decode('utf-8')
         committer = '%s <%s>' % (name, email)
         tz = int(tz)
         tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
         return (committer, int(date), tz)
 
 def rev_to_mark(rev):
-    global marks
     return marks.from_rev(rev)
 
 def mark_to_rev(mark):
-    global marks
     return marks.to_rev(mark)
 
 def fixup_user(user):
@@ -191,8 +193,7 @@
     else:
         m = EMAIL_RE.match(user)
         if m:
-            name = m.group(1)
-            mail = m.group(2)
+            mail = m.group(1)
         else:
             m = NAME_RE.match(user)
             if m:
@@ -233,8 +234,6 @@
     return modified, removed
 
 def export_files(tree, files):
-    global marks, filenodes
-
     final = []
     for path, fid in files.iteritems():
         kind = tree.kind(fid)
@@ -276,8 +275,6 @@
     return final
 
 def export_branch(repo, name):
-    global prefix
-
     ref = '%s/heads/%s' % (prefix, name)
     tip = marks.get_tip(name)
 
@@ -378,16 +375,12 @@
     marks.set_tip(name, revid)
 
 def export_tag(repo, name):
-    global tags, prefix
-
     ref = '%s/tags/%s' % (prefix, name)
     print "reset %s" % ref
     print "from :%u" % rev_to_mark(tags[name])
     print
 
 def do_import(parser):
-    global dirname
-
     repo = parser.repo
     path = os.path.join(dirname, 'marks-git')
 
@@ -413,8 +406,6 @@
     sys.stdout.flush()
 
 def parse_blob(parser):
-    global blob_marks
-
     parser.next()
     mark = parser.get_mark()
     parser.next()
@@ -425,8 +416,6 @@
 class CustomTree():
 
     def __init__(self, branch, revid, parents, files):
-        global files_cache
-
         self.updates = {}
         self.branch = branch
 
@@ -484,7 +473,7 @@
             add_entry(fid, dirname, 'directory')
             return fid
 
-        def add_entry(fid, path, kind, mode = None):
+        def add_entry(fid, path, kind, mode=None):
             dirname, basename = os.path.split(path)
             parent_fid = get_parent(dirname, basename)
 
@@ -505,7 +494,7 @@
             self.files[path] = [change[0], None]
             changes.append(change)
 
-        def update_entry(fid, path, kind, mode = None):
+        def update_entry(fid, path, kind, mode=None):
             dirname, basename = os.path.split(path)
             parent_fid = get_parent(dirname, basename)
 
@@ -583,9 +572,6 @@
     return string
 
 def parse_commit(parser):
-    global marks, blob_marks, parsed_refs
-    global mode
-
     parents = []
 
     ref = parser[1]
@@ -657,8 +643,6 @@
     marks.new_mark(revid, commit_mark)
 
 def parse_reset(parser):
-    global parsed_refs
-
     ref = parser[1]
     parser.next()
 
@@ -674,8 +658,6 @@
     parsed_refs[ref] = mark_to_rev(from_mark)
 
 def do_export(parser):
-    global parsed_refs, dirname
-
     parser.next()
 
     for line in parser.each_block('done'):
@@ -699,7 +681,8 @@
             branch.generate_revision_history(revid, marks.get_tip(name))
 
             if name in peers:
-                peer = bzrlib.branch.Branch.open(peers[name])
+                peer = bzrlib.branch.Branch.open(peers[name],
+                                                 possible_transports=transports)
                 try:
                     peer.bzrdir.push_branch(branch, revision_id=revid)
                 except bzrlib.errors.DivergedBranches:
@@ -724,8 +707,6 @@
     print
 
 def do_capabilities(parser):
-    global dirname
-
     print "import"
     print "export"
     print "refspec refs/heads/*:%s/heads/*" % prefix
@@ -743,8 +724,6 @@
     return not True in [c in name for c in '~^: \\']
 
 def do_list(parser):
-    global tags
-
     master_branch = None
 
     for name in branches:
@@ -770,24 +749,24 @@
 
 def clone(path, remote_branch):
     try:
-        bdir = bzrlib.bzrdir.BzrDir.create(path)
+        bdir = bzrlib.bzrdir.BzrDir.create(path, possible_transports=transports)
     except bzrlib.errors.AlreadyControlDirError:
-        bdir = bzrlib.bzrdir.BzrDir.open(path)
+        bdir = bzrlib.bzrdir.BzrDir.open(path, possible_transports=transports)
     repo = bdir.find_repository()
     repo.fetch(remote_branch.repository)
     return remote_branch.sprout(bdir, repository=repo)
 
 def get_remote_branch(name):
-    global dirname, branches
-
-    remote_branch = bzrlib.branch.Branch.open(branches[name])
+    remote_branch = bzrlib.branch.Branch.open(branches[name],
+                                              possible_transports=transports)
     if isinstance(remote_branch.user_transport, bzrlib.transport.local.LocalTransport):
         return remote_branch
 
     branch_path = os.path.join(dirname, 'clone', name)
 
     try:
-        branch = bzrlib.branch.Branch.open(branch_path)
+        branch = bzrlib.branch.Branch.open(branch_path,
+                                           possible_transports=transports)
     except bzrlib.errors.NotBranchError:
         # clone
         branch = clone(branch_path, remote_branch)
@@ -821,17 +800,17 @@
             yield name, branch.base
 
 def get_repo(url, alias):
-    global dirname, peer, branches
-
     normal_url = bzrlib.urlutils.normalize_url(url)
-    origin = bzrlib.bzrdir.BzrDir.open(url)
+    origin = bzrlib.bzrdir.BzrDir.open(url, possible_transports=transports)
     is_local = isinstance(origin.transport, bzrlib.transport.local.LocalTransport)
 
     shared_path = os.path.join(gitdir, 'bzr')
     try:
-        shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path)
+        shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path,
+                                               possible_transports=transports)
     except bzrlib.errors.NotBranchError:
-        shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path)
+        shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path,
+                                                 possible_transports=transports)
     try:
         shared_repo = shared_dir.open_repository()
     except bzrlib.errors.NoRepositoryPresent:
@@ -844,16 +823,21 @@
         else:
             # check and remove old organization
             try:
-                bdir = bzrlib.bzrdir.BzrDir.open(clone_path)
+                bdir = bzrlib.bzrdir.BzrDir.open(clone_path,
+                                                 possible_transports=transports)
                 bdir.destroy_repository()
             except bzrlib.errors.NotBranchError:
                 pass
             except bzrlib.errors.NoRepositoryPresent:
                 pass
 
-    wanted = get_config('remote-bzr.branches').rstrip().split(', ')
+    wanted = get_config('remote.%s.bzr-branches' % alias).rstrip().split(', ')
     # stupid python
     wanted = [e for e in wanted if e]
+    if not wanted:
+        wanted = get_config('remote-bzr.branches').rstrip().split(', ')
+        # stupid python
+        wanted = [e for e in wanted if e]
 
     if not wanted:
         try:
@@ -897,6 +881,17 @@
     global files_cache
     global is_tmp
     global branches, peers
+    global transports
+
+    marks = None
+    is_tmp = False
+    gitdir = os.environ.get('GIT_DIR', None)
+
+    if len(args) < 3:
+        die('Not enough arguments.')
+
+    if not gitdir:
+        die('GIT_DIR not set')
 
     alias = args[1]
     url = args[2]
@@ -906,18 +901,15 @@
     blob_marks = {}
     parsed_refs = {}
     files_cache = {}
-    marks = None
     branches = {}
     peers = {}
+    transports = []
 
     if alias[5:] == url:
         is_tmp = True
         alias = hashlib.sha1(alias).hexdigest()
-    else:
-        is_tmp = False
 
     prefix = 'refs/bzr/%s' % alias
-    gitdir = os.environ['GIT_DIR']
     dirname = os.path.join(gitdir, 'bzr', alias)
 
     if not is_tmp:
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index 1c713e0..eb89ef6 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -23,8 +23,12 @@
 import urllib
 import atexit
 import urlparse, hashlib
+import time as ptime
 
 #
+# If you want to see Mercurial revisions as Git commit notes:
+# git config core.notesRef refs/notes/hg
+#
 # If you are not in hg-git-compat mode and want to disable the tracking of
 # named branches:
 # git config --global remote-hg.track-branches false
@@ -47,8 +51,8 @@
 #
 
 NAME_RE = re.compile('^([^<>]+)')
-AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$')
-EMAIL_RE = re.compile('^([^<>]+[^ \\\t<>])?\\b(?:[ \\t<>]*?)\\b([^ \\t<>]+@[^ \\t<>]+)')
+AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
+EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
 AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$')
 RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
 
@@ -126,6 +130,7 @@
         self.rev_marks = {}
         self.last_mark = 0
         self.version = 0
+        self.last_note = 0
 
     def load(self):
         if not os.path.exists(self.path):
@@ -137,6 +142,7 @@
         self.marks = tmp['marks']
         self.last_mark = tmp['last-mark']
         self.version = tmp.get('version', 1)
+        self.last_note = tmp.get('last-note', 0)
 
         for rev, mark in self.marks.iteritems():
             self.rev_marks[mark] = rev
@@ -150,7 +156,7 @@
         self.version = 2
 
     def dict(self):
-        return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version }
+        return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version, 'last-note' : self.last_note }
 
     def store(self):
         json.dump(self.dict(), open(self.path, 'w'))
@@ -227,8 +233,6 @@
         return sys.stdin.read(size)
 
     def get_author(self):
-        global bad_mail
-
         ex = None
         m = RAW_AUTHOR_RE.match(self.line)
         if not m:
@@ -261,8 +265,6 @@
     return os.path.relpath(path, '/')
 
 def export_files(files):
-    global marks, filenodes
-
     final = []
     for f in files:
         fid = node.hex(f.filenode())
@@ -314,8 +316,7 @@
     else:
         m = EMAIL_RE.match(user)
         if m:
-            name = m.group(1)
-            mail = m.group(2)
+            mail = m.group(1)
         else:
             m = NAME_RE.match(user)
             if m:
@@ -344,8 +345,6 @@
     return (name, mail)
 
 def fixup_user(user):
-    global mode, bad_mail
-
     if mode == 'git':
         name, mail = fixup_user_git(user)
     else:
@@ -374,7 +373,7 @@
         bookmarks.write(repo)
 
 def get_repo(url, alias):
-    global dirname, peer
+    global peer
 
     myui = ui.ui()
     myui.setconfig('ui', 'interactive', 'off')
@@ -391,11 +390,24 @@
             os.makedirs(dirname)
     else:
         shared_path = os.path.join(gitdir, 'hg')
-        if not os.path.exists(shared_path):
-            try:
-                hg.clone(myui, {}, url, shared_path, update=False, pull=True)
-            except:
-                die('Repository error')
+
+        # check and upgrade old organization
+        hg_path = os.path.join(shared_path, '.hg')
+        if os.path.exists(shared_path) and not os.path.exists(hg_path):
+            repos = os.listdir(shared_path)
+            for x in repos:
+                local_hg = os.path.join(shared_path, x, 'clone', '.hg')
+                if not os.path.exists(local_hg):
+                    continue
+                if not os.path.exists(hg_path):
+                    shutil.move(local_hg, hg_path)
+                shutil.rmtree(os.path.join(shared_path, x, 'clone'))
+
+        # setup shared repo (if not there)
+        try:
+            hg.peer(myui, {}, shared_path, create=True)
+        except error.RepoError:
+            pass
 
         if not os.path.exists(dirname):
             os.makedirs(dirname)
@@ -403,6 +415,9 @@
         local_path = os.path.join(dirname, 'clone')
         if not os.path.exists(local_path):
             hg.share(myui, shared_path, local_path, update=False)
+        else:
+            # make sure the shared path is always up-to-date
+            util.writefile(os.path.join(local_path, '.hg', 'sharedpath'), hg_path)
 
         repo = hg.repository(myui, local_path)
         try:
@@ -416,16 +431,12 @@
     return repo
 
 def rev_to_mark(rev):
-    global marks
     return marks.from_rev(rev.hex())
 
 def mark_to_rev(mark):
-    global marks
     return marks.to_rev(mark)
 
 def export_ref(repo, name, kind, head):
-    global prefix, marks, mode
-
     ename = '%s/%s' % (kind, name)
     try:
         tip = marks.get_tip(ename)
@@ -522,6 +533,31 @@
     print "from :%u" % rev_to_mark(head)
     print
 
+    pending_revs = set(revs) - notes
+    if pending_revs:
+        note_mark = marks.next_mark()
+        ref = "refs/notes/hg"
+
+        print "commit %s" % ref
+        print "mark :%d" % (note_mark)
+        print "committer remote-hg <> %d %s" % (ptime.time(), gittz(ptime.timezone))
+        desc = "Notes for %s\n" % (name)
+        print "data %d" % (len(desc))
+        print desc
+        if marks.last_note:
+            print "from :%u" % marks.last_note
+
+        for rev in pending_revs:
+            notes.add(rev)
+            c = repo[rev]
+            print "N inline :%u" % rev_to_mark(c)
+            msg = c.hex()
+            print "data %d" % (len(msg))
+            print msg
+        print
+
+        marks.last_note = note_mark
+
     marks.set_tip(ename, head.hex())
 
 def export_tag(repo, tag):
@@ -537,12 +573,9 @@
     export_ref(repo, branch, 'branches', head)
 
 def export_head(repo):
-    global g_head
     export_ref(repo, g_head[0], 'bookmarks', g_head[1])
 
 def do_capabilities(parser):
-    global prefix, dirname
-
     print "import"
     print "export"
     print "refspec refs/heads/branches/*:%s/branches/*" % prefix
@@ -562,8 +595,6 @@
     return branches[branch][-1]
 
 def get_branch_tip(repo, branch):
-    global branches
-
     heads = branches.get(hgref(branch), None)
     if not heads:
         return None
@@ -576,7 +607,7 @@
     return heads[0]
 
 def list_head(repo, cur):
-    global g_head, bmarks, fake_bmark
+    global g_head, fake_bmark
 
     if 'default' not in branches:
         # empty repo
@@ -592,8 +623,6 @@
     g_head = (head, node)
 
 def do_list(parser):
-    global branches, bmarks, track_branches
-
     repo = parser.repo
     for bmark, node in bookmarks.listbookmarks(repo).iteritems():
         bmarks[bmark] = repo[node]
@@ -661,8 +690,6 @@
     print 'done'
 
 def parse_blob(parser):
-    global blob_marks
-
     parser.next()
     mark = parser.get_mark()
     parser.next()
@@ -684,9 +711,6 @@
     return string
 
 def parse_commit(parser):
-    global marks, blob_marks, parsed_refs
-    global mode
-
     from_mark = merge_mark = None
 
     ref = parser[1]
@@ -805,8 +829,6 @@
     marks.new_mark(node, commit_mark)
 
 def parse_reset(parser):
-    global parsed_refs
-
     ref = parser[1]
     parser.next()
     # ugh
@@ -999,8 +1021,6 @@
         return tip in heads
 
 def do_export(parser):
-    global parsed_refs, bmarks, peer
-
     p_bmarks = []
     p_revs = {}
 
@@ -1072,7 +1092,7 @@
             author, msg = parsed_tags.get(tag, (None, None))
             if mode == 'git':
                 if not msg:
-                    msg = 'Added tag %s for changeset %s' % (tag, node[:12]);
+                    msg = 'Added tag %s for changeset %s' % (tag, node[:12])
                 tagnode, branch = write_tag(parser.repo, tag, node, msg, author)
                 p_revs[tagnode] = 'refs/heads/branches/' + gitref(branch)
             else:
@@ -1130,7 +1150,7 @@
 
 def fix_path(alias, repo, orig_url):
     url = urlparse.urlparse(orig_url, 'file')
-    if url.scheme != 'file' or os.path.isabs(url.path):
+    if url.scheme != 'file' or os.path.isabs(os.path.expanduser(url.path)):
         return
     abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url)
     cmd = ['git', 'config', 'remote.%s.url' % alias, "hg::%s" % abs_url]
@@ -1145,6 +1165,17 @@
     global filenodes
     global fake_bmark, hg_version
     global dry_run
+    global notes, alias
+
+    marks = None
+    is_tmp = False
+    gitdir = os.environ.get('GIT_DIR', None)
+
+    if len(args) < 3:
+        die('Not enough arguments.')
+
+    if not gitdir:
+        die('GIT_DIR not set')
 
     alias = args[1]
     url = args[2]
@@ -1166,16 +1197,12 @@
     if alias[4:] == url:
         is_tmp = True
         alias = hashlib.sha1(alias).hexdigest()
-    else:
-        is_tmp = False
 
-    gitdir = os.environ['GIT_DIR']
     dirname = os.path.join(gitdir, 'hg', alias)
     branches = {}
     bmarks = {}
     blob_marks = {}
     parsed_refs = {}
-    marks = None
     parsed_tags = {}
     filenodes = {}
     fake_bmark = None
@@ -1184,6 +1211,7 @@
     except:
         hg_version = None
     dry_run = False
+    notes = set()
 
     repo = get_repo(url, alias)
     prefix = 'refs/hg/%s' % alias
diff --git a/contrib/remote-helpers/test-bzr.sh b/contrib/remote-helpers/test-bzr.sh
index dce281f..1e53ff9 100755
--- a/contrib/remote-helpers/test-bzr.sh
+++ b/contrib/remote-helpers/test-bzr.sh
@@ -5,21 +5,24 @@
 
 test_description='Test remote-bzr'
 
-. ./test-lib.sh
+test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
+. "$TEST_DIRECTORY"/test-lib.sh
 
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
 	skip_all='skipping remote-bzr tests; python not available'
 	test_done
 fi
 
-if ! python -c 'import bzrlib'; then
+if ! python -c 'import bzrlib'
+then
 	skip_all='skipping remote-bzr tests; bzr not available'
 	test_done
 fi
 
 check () {
-	echo $3 > expected &&
-	git --git-dir=$1/.git log --format='%s' -1 $2 > actual
+	echo $3 >expected &&
+	git --git-dir=$1/.git log --format='%s' -1 $2 >actual
 	test_cmp expected actual
 }
 
@@ -29,7 +32,7 @@
 	(
 	bzr init bzrrepo &&
 	cd bzrrepo &&
-	echo one > content &&
+	echo one >content &&
 	bzr add content &&
 	bzr commit -m one
 	) &&
@@ -41,7 +44,7 @@
 test_expect_success 'pulling' '
 	(
 	cd bzrrepo &&
-	echo two > content &&
+	echo two >content &&
 	bzr commit -m two
 	) &&
 
@@ -53,13 +56,13 @@
 test_expect_success 'pushing' '
 	(
 	cd gitrepo &&
-	echo three > content &&
+	echo three >content &&
 	git commit -a -m three &&
 	git push
 	) &&
 
-	echo three > expected &&
-	cat bzrrepo/content > actual &&
+	echo three >expected &&
+	cat bzrrepo/content >actual &&
 	test_cmp expected actual
 '
 
@@ -67,16 +70,16 @@
 	(
 	cd gitrepo &&
 	git pull &&
-	git log --format="%s" -1 origin/master > actual
+	git log --format="%s" -1 origin/master >actual
 	) &&
-	echo three > expected &&
+	echo three >expected &&
 	test_cmp expected actual &&
 
 	(cd gitrepo && git push && git pull) &&
 
 	(
 	cd bzrrepo &&
-	echo four > content &&
+	echo four >content &&
 	bzr commit -m four
 	) &&
 
@@ -86,19 +89,19 @@
 
 	(
 	cd gitrepo &&
-	echo five > content &&
+	echo five >content &&
 	git commit -a -m five &&
 	git push && git pull
 	) &&
 
 	(cd bzrrepo && bzr revert) &&
 
-	echo five > expected &&
-	cat bzrrepo/content > actual &&
+	echo five >expected &&
+	cat bzrrepo/content >actual &&
 	test_cmp expected actual
 '
 
-cat > expected <<EOF
+cat >expected <<\EOF
 100644 blob 54f9d6da5c91d556e6b54340b1327573073030af	content
 100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb	executable
 120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea	link
@@ -107,7 +110,7 @@
 test_expect_success 'special modes' '
 	(
 	cd bzrrepo &&
-	echo exec > executable
+	echo exec >executable
 	chmod +x executable &&
 	bzr add executable
 	bzr commit -m exec &&
@@ -122,21 +125,21 @@
 	(
 	cd gitrepo &&
 	git pull
-	git ls-tree HEAD > ../actual
+	git ls-tree HEAD >../actual
 	) &&
 
 	test_cmp expected actual &&
 
 	(
 	cd gitrepo &&
-	git cat-file -p HEAD:link > ../actual
+	git cat-file -p HEAD:link >../actual
 	) &&
 
-	printf content > expected &&
+	printf content >expected &&
 	test_cmp expected actual
 '
 
-cat > expected <<EOF
+cat >expected <<\EOF
 100644 blob 54f9d6da5c91d556e6b54340b1327573073030af	content
 100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb	executable
 120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea	link
@@ -147,8 +150,8 @@
 	(
 	cd bzrrepo &&
 	mkdir movedir &&
-	echo one > movedir/one &&
-	echo two > movedir/two &&
+	echo one >movedir/one &&
+	echo two >movedir/two &&
 	bzr add movedir &&
 	bzr commit -m movedir &&
 	bzr mv movedir movedir-new &&
@@ -158,7 +161,7 @@
 	(
 	cd gitrepo &&
 	git pull &&
-	git ls-tree HEAD > ../actual
+	git ls-tree HEAD >../actual
 	) &&
 
 	test_cmp expected actual
@@ -167,7 +170,7 @@
 test_expect_success 'different authors' '
 	(
 	cd bzrrepo &&
-	echo john >> content &&
+	echo john >>content &&
 	bzr commit -m john \
 	  --author "Jane Rey <jrey@example.com>" \
 	  --author "John Doe <jdoe@example.com>"
@@ -176,10 +179,10 @@
 	(
 	cd gitrepo &&
 	git pull &&
-	git show --format="%an <%ae>, %cn <%ce>" --quiet > ../actual
+	git show --format="%an <%ae>, %cn <%ce>" --quiet >../actual
 	) &&
 
-	echo "Jane Rey <jrey@example.com>, A U Thor <author@example.com>" > expected &&
+	echo "Jane Rey <jrey@example.com>, A U Thor <author@example.com>" >expected &&
 	test_cmp expected actual
 '
 
@@ -196,12 +199,12 @@
 	bzr init bzrrepo &&
 	cd bzrrepo &&
 
-	echo test >> "ærø" &&
+	echo test >>"ærø" &&
 	bzr add "ærø" &&
-	echo test >> "ø~?" &&
+	echo test >>"ø~?" &&
 	bzr add "ø~?" &&
 	bzr commit -m add-utf-8 &&
-	echo test >> "ærø" &&
+	echo test >>"ærø" &&
 	bzr commit -m test-utf-8 &&
 	bzr rm "ø~?" &&
 	bzr mv "ærø" "ø~?" &&
@@ -211,9 +214,9 @@
 	(
 	git clone "bzr::bzrrepo" gitrepo &&
 	cd gitrepo &&
-	git -c core.quotepath=false ls-files > ../actual
+	git -c core.quotepath=false ls-files >../actual
 	) &&
-	echo "ø~?" > expected &&
+	echo "ø~?" >expected &&
 	test_cmp expected actual
 '
 
@@ -229,7 +232,7 @@
 	bzr init bzrrepo &&
 	cd bzrrepo &&
 
-	echo one >> content &&
+	echo one >>content &&
 	bzr add content &&
 	bzr commit -m one
 	) &&
@@ -238,15 +241,15 @@
 	git clone "bzr::bzrrepo" gitrepo &&
 	cd gitrepo &&
 
-	echo test >> "ærø" &&
+	echo test >>"ærø" &&
 	git add "ærø" &&
 	git commit -m utf-8 &&
 
 	git push
 	) &&
 
-	(cd bzrrepo && bzr ls > ../actual) &&
-	printf "content\nærø\n" > expected &&
+	(cd bzrrepo && bzr ls >../actual) &&
+	printf "content\nærø\n" >expected &&
 	test_cmp expected actual
 '
 
@@ -256,7 +259,7 @@
 	(
 	bzr init bzrrepo &&
 	cd bzrrepo &&
-	echo one > content &&
+	echo one >content &&
 	bzr add content &&
 	bzr commit -m one
 	) &&
@@ -265,27 +268,27 @@
 
 	(
 	cd bzrrepo &&
-	echo two > content &&
+	echo two >content &&
 	bzr commit -m two
 	) &&
 
 	(
 	cd gitrepo &&
-	echo three > content &&
+	echo three >content &&
 	git commit -a -m three &&
 	git fetch &&
 	git merge origin/master || true &&
-	echo three > content &&
+	echo three >content &&
 	git commit -a --no-edit &&
 	git push
 	) &&
 
-	echo three > expected &&
-	cat bzrrepo/content > actual &&
+	echo three >expected &&
+	cat bzrrepo/content >actual &&
 	test_cmp expected actual
 '
 
-cat > expected <<EOF
+cat >expected <<\EOF
 origin/HEAD
 origin/branch
 origin/trunk
@@ -299,7 +302,7 @@
 	(
 	bzr init bzrrepo/trunk &&
 	cd bzrrepo/trunk &&
-	echo one >> content &&
+	echo one >>content &&
 	bzr add content &&
 	bzr commit -m one
 	) &&
@@ -307,14 +310,14 @@
 	(
 	bzr branch bzrrepo/trunk bzrrepo/branch &&
 	cd bzrrepo/branch &&
-	echo two >> content &&
+	echo two >>content &&
 	bzr commit -m one
 	) &&
 
 	(
 	git clone "bzr::bzrrepo" gitrepo &&
 	cd gitrepo &&
-	git for-each-ref --format "%(refname:short)" refs/remotes/origin > ../actual
+	git for-each-ref --format "%(refname:short)" refs/remotes/origin >../actual
 	) &&
 
 	test_cmp expected actual
@@ -327,11 +330,11 @@
 	bzr init bzrrepo &&
 	cd bzrrepo &&
 
-	echo one >> content &&
+	echo one >>content &&
 	bzr add content &&
 	bzr commit -m one &&
 
-	echo two >> content &&
+	echo two >>content &&
 	bzr commit -m two
 	) &&
 
@@ -341,21 +344,51 @@
 	cd bzrrepo &&
 	bzr uncommit --force &&
 
-	echo three >> content &&
+	echo three >>content &&
 	bzr commit -m three &&
 
-	echo four >> content &&
+	echo four >>content &&
 	bzr commit -m four &&
-	bzr log --line | sed -e "s/^[0-9][0-9]*: //" > ../expected
+	bzr log --line | sed -e "s/^[0-9][0-9]*: //" >../expected
 	) &&
 
 	(
 	cd gitrepo &&
 	git fetch &&
-	git log --format="%an %ad %s" --date=short origin/master > ../actual
+	git log --format="%an %ad %s" --date=short origin/master >../actual
 	) &&
 
 	test_cmp expected actual
 '
 
+test_expect_success 'export utf-8 authors' '
+	test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C && unset GIT_COMMITTER_NAME" &&
+
+	LC_ALL=en_US.UTF-8
+	export LC_ALL
+
+	GIT_COMMITTER_NAME="Grégoire"
+	export GIT_COMMITTER_NAME
+
+	bzr init bzrrepo &&
+
+	(
+	git init gitrepo &&
+	cd gitrepo &&
+	echo greg >>content &&
+	git add content &&
+	git commit -m one &&
+	git remote add bzr "bzr::../bzrrepo" &&
+	git push bzr master
+	) &&
+
+	(
+	cd bzrrepo &&
+	bzr log | grep "^committer: " >../actual
+	) &&
+
+	echo "committer: Grégoire <committer@example.com>" >expected &&
+	test_cmp expected actual
+'
+
 test_done
diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh
index f83d67d..e24c51d 100755
--- a/contrib/remote-helpers/test-hg-bidi.sh
+++ b/contrib/remote-helpers/test-hg-bidi.sh
@@ -10,12 +10,14 @@
 
 . ./test-lib.sh
 
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
 	skip_all='skipping remote-hg tests; python not available'
 	test_done
 fi
 
-if ! python -c 'import mercurial'; then
+if ! python -c 'import mercurial'
+then
 	skip_all='skipping remote-hg tests; mercurial not available'
 	test_done
 fi
@@ -43,7 +45,7 @@
 	git checkout -q -b tmp &&
 	git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
 	git checkout -q @{-1} &&
-	git branch -q -D tmp 2> /dev/null || true
+	git branch -q -D tmp 2>/dev/null || true
 	)
 }
 
@@ -62,7 +64,7 @@
 	echo "tag = -d \"0 0\""
 	echo "[extensions]"
 	echo "graphlog ="
-	) >> "$HOME"/.hgrc &&
+	) >>"$HOME"/.hgrc &&
 	git config --global remote-hg.hg-git-compat true
 	git config --global remote-hg.track-branches true
 
@@ -81,22 +83,22 @@
 	git init -q gitrepo &&
 	cd gitrepo &&
 
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add älphà" &&
 
 	GIT_AUTHOR_NAME="tést èncödîng" &&
 	export GIT_AUTHOR_NAME &&
-	echo beta > beta &&
+	echo beta >beta &&
 	git add beta &&
 	git commit -m "add beta" &&
 
-	echo gamma > gamma &&
+	echo gamma >gamma &&
 	git add gamma &&
 	git commit -m "add gämmâ" &&
 
 	: TODO git config i18n.commitencoding latin-1 &&
-	echo delta > delta &&
+	echo delta >delta &&
 	git add delta &&
 	git commit -m "add déltà"
 	) &&
@@ -105,8 +107,8 @@
 	git_clone hgrepo gitrepo2 &&
 	hg_clone gitrepo2 hgrepo2 &&
 
-	HGENCODING=utf-8 hg_log hgrepo > expected &&
-	HGENCODING=utf-8 hg_log hgrepo2 > actual &&
+	HGENCODING=utf-8 hg_log hgrepo >expected &&
+	HGENCODING=utf-8 hg_log hgrepo2 >actual &&
 
 	test_cmp expected actual
 '
@@ -117,14 +119,14 @@
 	(
 	git init -q gitrepo &&
 	cd gitrepo &&
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add alpha" &&
-	echo beta > beta &&
+	echo beta >beta &&
 	git add beta &&
 	git commit -m "add beta"
 	mkdir foo &&
-	echo blah > foo/bar &&
+	echo blah >foo/bar &&
 	git add foo &&
 	git commit -m "add foo" &&
 	git rm alpha &&
@@ -137,8 +139,8 @@
 	git_clone hgrepo gitrepo2 &&
 	hg_clone gitrepo2 hgrepo2 &&
 
-	hg_log hgrepo > expected &&
-	hg_log hgrepo2 > actual &&
+	hg_log hgrepo >expected &&
+	hg_log hgrepo2 >actual &&
 
 	test_cmp expected actual
 '
@@ -150,12 +152,12 @@
 	git init -q gitrepo &&
 	cd gitrepo &&
 	git config receive.denyCurrentBranch ignore &&
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add alpha" &&
 	git tag alpha &&
 
-	echo beta > beta &&
+	echo beta >beta &&
 	git add beta &&
 	git commit -m "add beta" &&
 	git tag -a -m "added tag beta" beta
@@ -165,8 +167,8 @@
 	git_clone hgrepo gitrepo2 &&
 	hg_clone gitrepo2 hgrepo2 &&
 
-	hg_log hgrepo > expected &&
-	hg_log hgrepo2 > actual &&
+	hg_log hgrepo >expected &&
+	hg_log hgrepo2 >actual &&
 
 	test_cmp expected actual
 '
@@ -178,7 +180,7 @@
 	git init -q gitrepo &&
 	cd gitrepo &&
 
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -q -m "add alpha" &&
 	git checkout -q -b not-master
@@ -201,8 +203,8 @@
 	: Back to the common revision &&
 	(cd hgrepo && hg checkout default) &&
 
-	hg_log hgrepo > expected &&
-	hg_log hgrepo2 > actual &&
+	hg_log hgrepo >expected &&
+	hg_log hgrepo2 >actual &&
 
 	test_cmp expected actual
 '
@@ -214,7 +216,7 @@
 	git init -q gitrepo &&
 	cd gitrepo &&
 
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add alpha" &&
 	git checkout -q -b not-master
@@ -231,8 +233,8 @@
 	hg_push hgrepo gitrepo &&
 	hg_clone gitrepo hgrepo2 &&
 
-	hg_log hgrepo > expected &&
-	hg_log hgrepo2 > actual &&
+	hg_log hgrepo >expected &&
+	hg_log hgrepo2 >actual &&
 
 	test_cmp expected actual
 '
diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh
index 2219284..6dcd95d 100755
--- a/contrib/remote-helpers/test-hg-hg-git.sh
+++ b/contrib/remote-helpers/test-hg-hg-git.sh
@@ -10,17 +10,20 @@
 
 . ./test-lib.sh
 
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
 	skip_all='skipping remote-hg tests; python not available'
 	test_done
 fi
 
-if ! python -c 'import mercurial'; then
+if ! python -c 'import mercurial'
+then
 	skip_all='skipping remote-hg tests; mercurial not available'
 	test_done
 fi
 
-if ! python -c 'import hggit'; then
+if ! python -c 'import hggit'
+then
 	skip_all='skipping remote-hg tests; hg-git not available'
 	test_done
 fi
@@ -66,7 +69,7 @@
 	git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
 	git branch -D default &&
 	git checkout -q @{-1} &&
-	git branch -q -D tmp 2> /dev/null || true
+	git branch -q -D tmp 2>/dev/null || true
 	)
 }
 
@@ -100,7 +103,7 @@
 	echo "hgext.bookmarks ="
 	echo "hggit ="
 	echo "graphlog ="
-	) >> "$HOME"/.hgrc &&
+	) >>"$HOME"/.hgrc &&
 	git config --global receive.denycurrentbranch warn
 	git config --global remote-hg.hg-git-compat true
 	git config --global remote-hg.track-branches false
@@ -121,7 +124,7 @@
 	(
 	git init -q gitrepo &&
 	cd gitrepo &&
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	chmod 0644 alpha &&
 	git add alpha &&
 	git commit -m "add alpha" &&
@@ -133,17 +136,18 @@
 	git commit -m "clear executable bit"
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		(
 		hg_clone_$x gitrepo hgrepo-$x &&
 		cd hgrepo-$x &&
 		hg_log . &&
 		hg manifest -r 1 -v &&
 		hg manifest -v
-		) > output-$x &&
+		) >"output-$x" &&
 
 		git_clone_$x hgrepo-$x gitrepo2-$x &&
-		git_log gitrepo2-$x > log-$x
+		git_log gitrepo2-$x >"log-$x"
 	done &&
 
 	test_cmp output-hg output-git &&
@@ -156,7 +160,7 @@
 	(
 	git init -q gitrepo &&
 	cd gitrepo &&
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add alpha" &&
 	ln -s alpha beta &&
@@ -164,16 +168,17 @@
 	git commit -m "add beta"
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		(
 		hg_clone_$x gitrepo hgrepo-$x &&
 		cd hgrepo-$x &&
 		hg_log . &&
 		hg manifest -v
-		) > output-$x &&
+		) >"output-$x" &&
 
 		git_clone_$x hgrepo-$x gitrepo2-$x &&
-		git_log gitrepo2-$x > log-$x
+		git_log gitrepo2-$x >"log-$x"
 	done &&
 
 	test_cmp output-hg output-git &&
@@ -186,28 +191,29 @@
 	(
 	hg init hgrepo1 &&
 	cd hgrepo1 &&
-	echo A > afile &&
+	echo A >afile &&
 	hg add afile &&
 	hg ci -m "origin" &&
 
-	echo B > afile &&
+	echo B >afile &&
 	hg ci -m "A->B" &&
 
 	hg up -r0 &&
-	echo C > afile &&
+	echo C >afile &&
 	hg ci -m "A->C" &&
 
 	hg merge -r1 &&
-	echo C > afile &&
+	echo C >afile &&
 	hg resolve -m afile &&
 	hg ci -m "merge to C"
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		git_clone_$x hgrepo1 gitrepo-$x &&
 		hg_clone_$x gitrepo-$x hgrepo2-$x &&
-		hg_log hgrepo2-$x > hg-log-$x &&
-		git_log gitrepo-$x > git-log-$x
+		hg_log hgrepo2-$x >"hg-log-$x" &&
+		git_log gitrepo-$x >"git-log-$x"
 	done &&
 
 	test_cmp hg-log-hg hg-log-git &&
@@ -220,28 +226,29 @@
 	(
 	hg init hgrepo1 &&
 	cd hgrepo1 &&
-	echo A > afile &&
+	echo A >afile &&
 	hg add afile &&
 	hg ci -m "origin" &&
 
-	echo B > afile &&
+	echo B >afile &&
 	hg ci -m "A->B" &&
 
 	hg up -r0 &&
-	echo C > afile &&
+	echo C >afile &&
 	hg ci -m "A->C" &&
 
 	hg merge -r1 || true &&
-	echo B > afile &&
+	echo B >afile &&
 	hg resolve -m afile &&
 	hg ci -m "merge to B"
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		git_clone_$x hgrepo1 gitrepo-$x &&
 		hg_clone_$x gitrepo-$x hgrepo2-$x &&
-		hg_log hgrepo2-$x > hg-log-$x &&
-		git_log gitrepo-$x > git-log-$x
+		hg_log hgrepo2-$x >"hg-log-$x" &&
+		git_log gitrepo-$x >"git-log-$x"
 	done &&
 
 	test_cmp hg-log-hg hg-log-git &&
@@ -254,29 +261,30 @@
 	(
 	hg init hgrepo1 &&
 	cd hgrepo1 &&
-	echo A > afile &&
+	echo A >afile &&
 	hg add afile &&
 	hg ci -m "origin" &&
 
-	echo B > afile &&
+	echo B >afile &&
 	hg ci -m "A->B" &&
 
-	echo C > afile &&
+	echo C >afile &&
 	hg ci -m "B->C" &&
 
 	hg up -r0 &&
-	echo C > afile &&
+	echo C >afile &&
 	hg ci -m "A->C" &&
 
 	hg merge -r2 || true &&
 	hg ci -m "merge"
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		git_clone_$x hgrepo1 gitrepo-$x &&
 		hg_clone_$x gitrepo-$x hgrepo2-$x &&
-		hg_log hgrepo2-$x > hg-log-$x &&
-		git_log gitrepo-$x > git-log-$x
+		hg_log hgrepo2-$x >"hg-log-$x" &&
+		git_log gitrepo-$x >"git-log-$x"
 	done &&
 
 	test_cmp hg-log-hg hg-log-git &&
@@ -290,32 +298,33 @@
 	git init -q gitrepo &&
 	cd gitrepo &&
 
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add älphà" &&
 
 	GIT_AUTHOR_NAME="tést èncödîng" &&
 	export GIT_AUTHOR_NAME &&
-	echo beta > beta &&
+	echo beta >beta &&
 	git add beta &&
 	git commit -m "add beta" &&
 
-	echo gamma > gamma &&
+	echo gamma >gamma &&
 	git add gamma &&
 	git commit -m "add gämmâ" &&
 
 	: TODO git config i18n.commitencoding latin-1 &&
-	echo delta > delta &&
+	echo delta >delta &&
 	git add delta &&
 	git commit -m "add déltà"
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		hg_clone_$x gitrepo hgrepo-$x &&
 		git_clone_$x hgrepo-$x gitrepo2-$x &&
 
-		HGENCODING=utf-8 hg_log hgrepo-$x > hg-log-$x &&
-		git_log gitrepo2-$x > git-log-$x
+		HGENCODING=utf-8 hg_log hgrepo-$x >"hg-log-$x" &&
+		git_log gitrepo2-$x >"git-log-$x"
 	done &&
 
 	test_cmp hg-log-hg hg-log-git &&
@@ -328,14 +337,14 @@
 	(
 	git init -q gitrepo &&
 	cd gitrepo &&
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add alpha" &&
-	echo beta > beta &&
+	echo beta >beta &&
 	git add beta &&
 	git commit -m "add beta"
 	mkdir foo &&
-	echo blah > foo/bar &&
+	echo blah >foo/bar &&
 	git add foo &&
 	git commit -m "add foo" &&
 	git rm alpha &&
@@ -344,17 +353,18 @@
 	git commit -m "remove foo/bar"
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		(
 		hg_clone_$x gitrepo hgrepo-$x &&
 		cd hgrepo-$x &&
 		hg_log . &&
 		hg manifest -r 3 &&
 		hg manifest
-		) > output-$x &&
+		) >"output-$x" &&
 
 		git_clone_$x hgrepo-$x gitrepo2-$x &&
-		git_log gitrepo2-$x > log-$x
+		git_log gitrepo2-$x >"log-$x"
 	done &&
 
 	test_cmp output-hg output-git &&
@@ -368,20 +378,21 @@
 	git init -q gitrepo &&
 	cd gitrepo &&
 	git config receive.denyCurrentBranch ignore &&
-	echo alpha > alpha &&
+	echo alpha >alpha &&
 	git add alpha &&
 	git commit -m "add alpha" &&
 	git tag alpha &&
 
-	echo beta > beta &&
+	echo beta >beta &&
 	git add beta &&
 	git commit -m "add beta" &&
 	git tag -a -m "added tag beta" beta
 	) &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		hg_clone_$x gitrepo hgrepo-$x &&
-		hg_log hgrepo-$x > log-$x
+		hg_log hgrepo-$x >"log-$x"
 	done &&
 
 	test_cmp log-hg log-git
@@ -390,12 +401,13 @@
 test_expect_success 'hg author' '
 	test_when_finished "rm -rf gitrepo* hgrepo*" &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		(
 		git init -q gitrepo-$x &&
 		cd gitrepo-$x &&
 
-		echo alpha > alpha &&
+		echo alpha >alpha &&
 		git add alpha &&
 		git commit -m "add alpha" &&
 		git checkout -q -b not-master
@@ -406,38 +418,38 @@
 		cd hgrepo-$x &&
 
 		hg co master &&
-		echo beta > beta &&
+		echo beta >beta &&
 		hg add beta &&
 		hg commit -u "test" -m "add beta" &&
 
-		echo gamma >> beta &&
+		echo gamma >>beta &&
 		hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
 
-		echo gamma > gamma &&
+		echo gamma >gamma &&
 		hg add gamma &&
 		hg commit -u "<test@example.com>" -m "add gamma" &&
 
-		echo delta > delta &&
+		echo delta >delta &&
 		hg add delta &&
 		hg commit -u "name<test@example.com>" -m "add delta" &&
 
-		echo epsilon > epsilon &&
+		echo epsilon >epsilon &&
 		hg add epsilon &&
 		hg commit -u "name <test@example.com" -m "add epsilon" &&
 
-		echo zeta > zeta &&
+		echo zeta >zeta &&
 		hg add zeta &&
 		hg commit -u " test " -m "add zeta" &&
 
-		echo eta > eta &&
+		echo eta >eta &&
 		hg add eta &&
 		hg commit -u "test < test@example.com >" -m "add eta" &&
 
-		echo theta > theta &&
+		echo theta >theta &&
 		hg add theta &&
 		hg commit -u "test >test@example.com>" -m "add theta" &&
 
-		echo iota > iota &&
+		echo iota >iota &&
 		hg add iota &&
 		hg commit -u "test <test <at> example <dot> com>" -m "add iota"
 		) &&
@@ -445,8 +457,8 @@
 		hg_push_$x hgrepo-$x gitrepo-$x &&
 		hg_clone_$x gitrepo-$x hgrepo2-$x &&
 
-		hg_log hgrepo2-$x > hg-log-$x &&
-		git_log gitrepo-$x > git-log-$x
+		hg_log hgrepo2-$x >"hg-log-$x" &&
+		git_log gitrepo-$x >"git-log-$x"
 	done &&
 
 	test_cmp hg-log-hg hg-log-git &&
@@ -456,12 +468,13 @@
 test_expect_success 'hg branch' '
 	test_when_finished "rm -rf gitrepo* hgrepo*" &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		(
 		git init -q gitrepo-$x &&
 		cd gitrepo-$x &&
 
-		echo alpha > alpha &&
+		echo alpha >alpha &&
 		git add alpha &&
 		git commit -q -m "add alpha" &&
 		git checkout -q -b not-master
@@ -481,8 +494,8 @@
 		hg_push_$x hgrepo-$x gitrepo-$x &&
 		hg_clone_$x gitrepo-$x hgrepo2-$x &&
 
-		hg_log hgrepo2-$x > hg-log-$x &&
-		git_log gitrepo-$x > git-log-$x
+		hg_log hgrepo2-$x >"hg-log-$x" &&
+		git_log gitrepo-$x >"git-log-$x"
 	done &&
 
 	test_cmp hg-log-hg hg-log-git &&
@@ -492,12 +505,13 @@
 test_expect_success 'hg tags' '
 	test_when_finished "rm -rf gitrepo* hgrepo*" &&
 
-	for x in hg git; do
+	for x in hg git
+	do
 		(
 		git init -q gitrepo-$x &&
 		cd gitrepo-$x &&
 
-		echo alpha > alpha &&
+		echo alpha >alpha &&
 		git add alpha &&
 		git commit -m "add alpha" &&
 		git checkout -q -b not-master
@@ -518,7 +532,7 @@
 		git --git-dir=gitrepo-$x/.git tag -l &&
 		hg_log hgrepo2-$x &&
 		cat hgrepo2-$x/.hgtags
-		) > output-$x
+		) >"output-$x"
 	done &&
 
 	test_cmp output-hg output-git
diff --git a/contrib/remote-helpers/test-hg.sh b/contrib/remote-helpers/test-hg.sh
index f7ce8aa..5d128a5 100755
--- a/contrib/remote-helpers/test-hg.sh
+++ b/contrib/remote-helpers/test-hg.sh
@@ -8,55 +8,60 @@
 
 test_description='Test remote-hg'
 
-. ./test-lib.sh
+test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
+. "$TEST_DIRECTORY"/test-lib.sh
 
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
 	skip_all='skipping remote-hg tests; python not available'
 	test_done
 fi
 
-if ! python -c 'import mercurial'; then
+if ! python -c 'import mercurial'
+then
 	skip_all='skipping remote-hg tests; mercurial not available'
 	test_done
 fi
 
 check () {
-	echo $3 > expected &&
-	git --git-dir=$1/.git log --format='%s' -1 $2 > actual
+	echo $3 >expected &&
+	git --git-dir=$1/.git log --format='%s' -1 $2 >actual
 	test_cmp expected actual
 }
 
 check_branch () {
-	if [ -n "$3" ]; then
-		echo $3 > expected &&
-		hg -R $1 log -r $2 --template '{desc}\n' > actual &&
+	if test -n "$3"
+	then
+		echo $3 >expected &&
+		hg -R $1 log -r $2 --template '{desc}\n' >actual &&
 		test_cmp expected actual
 	else
-		hg -R $1 branches > out &&
+		hg -R $1 branches >out &&
 		! grep $2 out
 	fi
 }
 
 check_bookmark () {
-	if [ -n "$3" ]; then
-		echo $3 > expected &&
-		hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' > actual &&
+	if test -n "$3"
+	then
+		echo $3 >expected &&
+		hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' >actual &&
 		test_cmp expected actual
 	else
-		hg -R $1 bookmarks > out &&
+		hg -R $1 bookmarks >out &&
 		! grep $2 out
 	fi
 }
 
 check_push () {
-	local expected_ret=$1 ret=0 ref_ret=0 IFS=':'
+	expected_ret=$1 ret=0 ref_ret=0
 
 	shift
-	git push origin "$@" 2> error
+	git push origin "$@" 2>error
 	ret=$?
 	cat error
 
-	while read branch kind
+	while IFS=':' read branch kind
 	do
 		case "$kind" in
 		'new')
@@ -75,10 +80,10 @@
 			grep "^   [a-f0-9]*\.\.[a-f0-9]* *${branch} -> ${branch}$" error || ref_ret=1
 			;;
 		esac
-		let 'ref_ret' && echo "match for '$branch' failed" && break
+		test $ref_ret -ne 0 && echo "match for '$branch' failed" && break
 	done
 
-	if let 'expected_ret != ret || ref_ret'
+	if test $expected_ret -ne $ret || test $ref_ret -ne 0
 	then
 		return 1
 	fi
@@ -92,7 +97,7 @@
 	echo "username = H G Wells <wells@example.com>"
 	echo "[extensions]"
 	echo "mq ="
-	) >> "$HOME"/.hgrc &&
+	) >>"$HOME"/.hgrc &&
 
 	GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" &&
 	GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" &&
@@ -107,7 +112,7 @@
 	(
 	hg init hgrepo &&
 	cd hgrepo &&
-	echo zero > content &&
+	echo zero >content &&
 	hg add content &&
 	hg commit -m zero
 	) &&
@@ -122,7 +127,7 @@
 	(
 	cd hgrepo &&
 	hg branch next &&
-	echo next > content &&
+	echo next >content &&
 	hg commit -m next
 	) &&
 
@@ -137,7 +142,7 @@
 	cd hgrepo &&
 	hg checkout default &&
 	hg bookmark feature-a &&
-	echo feature-a > content &&
+	echo feature-a >content &&
 	hg commit -m feature-a
 	) &&
 
@@ -157,7 +162,7 @@
 	git clone "hg::hgrepo" gitrepo &&
 	cd gitrepo &&
 	git checkout --quiet devel &&
-	echo devel > content &&
+	echo devel >content &&
 	git commit -a -m devel &&
 	git push --quiet
 	) &&
@@ -172,7 +177,7 @@
 	git clone "hg::hgrepo" gitrepo &&
 	cd gitrepo &&
 	git checkout --quiet -b feature-b &&
-	echo feature-b > content &&
+	echo feature-b >content &&
 	git commit -a -m feature-b &&
 	git push --quiet origin feature-b
 	) &&
@@ -184,9 +189,9 @@
 rm -rf hgrepo
 
 author_test () {
-	echo $1 >> content &&
+	echo $1 >>content &&
 	hg commit -u "$2" -m "add $1" &&
-	echo "$3" >> ../expected
+	echo "$3" >>../expected
 }
 
 test_expect_success 'authors' '
@@ -199,22 +204,23 @@
 	touch content &&
 	hg add content &&
 
-	> ../expected &&
+	>../expected &&
 	author_test alpha "" "H G Wells <wells@example.com>" &&
-	author_test beta "test" "test <unknown>" &&
-	author_test beta "test <test@example.com> (comment)" "test <test@example.com>" &&
-	author_test gamma "<test@example.com>" "Unknown <test@example.com>" &&
-	author_test delta "name<test@example.com>" "name <test@example.com>" &&
-	author_test epsilon "name <test@example.com" "name <test@example.com>" &&
-	author_test zeta " test " "test <unknown>" &&
-	author_test eta "test < test@example.com >" "test <test@example.com>" &&
-	author_test theta "test >test@example.com>" "test <test@example.com>" &&
-	author_test iota "test < test <at> example <dot> com>" "test <unknown>" &&
-	author_test kappa "test@example.com" "Unknown <test@example.com>"
+	author_test beta "beta" "beta <unknown>" &&
+	author_test gamma "gamma <test@example.com> (comment)" "gamma <test@example.com>" &&
+	author_test delta "<delta@example.com>" "Unknown <delta@example.com>" &&
+	author_test epsilon "epsilon<test@example.com>" "epsilon <test@example.com>" &&
+	author_test zeta "zeta <test@example.com" "zeta <test@example.com>" &&
+	author_test eta " eta " "eta <unknown>" &&
+	author_test theta "theta < test@example.com >" "theta <test@example.com>" &&
+	author_test iota "iota >test@example.com>" "iota <test@example.com>" &&
+	author_test kappa "kappa < test <at> example <dot> com>" "kappa <unknown>" &&
+	author_test lambda "lambda@example.com" "Unknown <lambda@example.com>" &&
+	author_test mu "mu.mu@example.com" "Unknown <mu.mu@example.com>"
 	) &&
 
 	git clone "hg::hgrepo" gitrepo &&
-	git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" > actual &&
+	git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" >actual &&
 
 	test_cmp expected actual
 '
@@ -226,11 +232,11 @@
 	hg init hgrepo &&
 	cd hgrepo &&
 
-	echo one >> content &&
+	echo one >>content &&
 	hg add content &&
 	hg commit -m one &&
 
-	echo two >> content &&
+	echo two >>content &&
 	hg commit -m two
 	) &&
 
@@ -240,20 +246,20 @@
 	cd hgrepo &&
 	hg strip 1 &&
 
-	echo three >> content &&
+	echo three >>content &&
 	hg commit -m three &&
 
-	echo four >> content &&
+	echo four >>content &&
 	hg commit -m four
 	) &&
 
 	(
 	cd gitrepo &&
 	git fetch &&
-	git log --format="%s" origin/master > ../actual
+	git log --format="%s" origin/master >../actual
 	) &&
 
-	hg -R hgrepo log --template "{desc}\n" > expected &&
+	hg -R hgrepo log --template "{desc}\n" >expected &&
 	test_cmp actual expected
 '
 
@@ -263,18 +269,18 @@
 	(
 	hg init hgrepo &&
 	cd hgrepo &&
-	echo zero > content &&
+	echo zero >content &&
 	hg add content &&
 	hg commit -m zero &&
 	hg bookmark master &&
-	echo one > content &&
+	echo one >content &&
 	hg commit -m one
 	) &&
 
 	(
 	git clone "hg::hgrepo" gitrepo &&
 	cd gitrepo &&
-	echo two > content &&
+	echo two >content &&
 	git commit -a -m two &&
 	git push
 	) &&
@@ -282,7 +288,7 @@
 	check_branch hgrepo default two
 '
 
-cat > expected <<EOF
+cat >expected <<\EOF
 changeset:   0:6e2126489d3d
 tag:         tip
 user:        A U Thor <author@example.com>
@@ -300,13 +306,13 @@
 	git init gitrepo &&
 	cd gitrepo &&
 	git remote add origin "hg::../hgrepo" &&
-	echo one > content &&
+	echo one >content &&
 	git add content &&
 	git commit -a -m one &&
 	git push origin master
 	) &&
 
-	hg -R hgrepo log > actual &&
+	hg -R hgrepo log >actual &&
 	cat actual &&
 	test_cmp expected actual &&
 
@@ -322,7 +328,7 @@
 	(
 	hg init hgrepo &&
 	cd hgrepo &&
-	echo zero > content &&
+	echo zero >content &&
 	hg add content &&
 	hg commit -m zero
 	) &&
@@ -331,6 +337,17 @@
 	check gitrepo HEAD zero
 '
 
+test_expect_success 'moving remote clone' '
+	test_when_finished "rm -rf gitrepo*" &&
+
+	(
+	git clone "hg::hgrepo" gitrepo &&
+	mv gitrepo gitrepo2 &&
+	cd gitrepo2 &&
+	git fetch
+	)
+'
+
 test_expect_success 'remote update bookmark' '
 	test_when_finished "rm -rf gitrepo*" &&
 
@@ -343,7 +360,7 @@
 	git clone "hg::hgrepo" gitrepo &&
 	cd gitrepo &&
 	git checkout --quiet devel &&
-	echo devel > content &&
+	echo devel >content &&
 	git commit -a -m devel &&
 	git push --quiet
 	) &&
@@ -358,7 +375,7 @@
 	git clone "hg::hgrepo" gitrepo &&
 	cd gitrepo &&
 	git checkout --quiet -b feature-b &&
-	echo feature-b > content &&
+	echo feature-b >content &&
 	git commit -a -m feature-b &&
 	git push --quiet origin feature-b
 	) &&
@@ -374,15 +391,15 @@
 	(
 	cd hgrepo &&
 	hg checkout default &&
-	echo bump > content &&
+	echo bump >content &&
 	hg commit -m bump
 	) &&
 
 	(
 	cd gitrepo &&
-	echo diverge > content &&
+	echo diverge >content &&
 	git commit -a -m diverged &&
-	check_push 1 <<-EOF
+	check_push 1 <<-\EOF
 	master:non-fast-forward
 	EOF
 	) &&
@@ -403,16 +420,16 @@
 
 	(
 	cd hgrepo &&
-	echo "bump bookmark" > content &&
+	echo "bump bookmark" >content &&
 	hg commit -m "bump bookmark"
 	) &&
 
 	(
 	cd gitrepo &&
 	git checkout --quiet diverge &&
-	echo diverge > content &&
+	echo diverge >content &&
 	git commit -a -m diverge &&
-	check_push 1 <<-EOF
+	check_push 1 <<-\EOF
 	diverge:fetch-first
 	EOF
 	) &&
@@ -427,7 +444,7 @@
 	git clone "hg::hgrepo" gitrepo &&
 	cd gitrepo &&
 	git checkout --quiet -b feature-c HEAD^ &&
-	echo feature-c > content &&
+	echo feature-c >content &&
 	git commit -a -m feature-c &&
 	git push --quiet origin feature-c
 	) &&
@@ -438,24 +455,92 @@
 # cleanup previous stuff
 rm -rf hgrepo
 
+test_expect_success 'fetch special filenames' '
+	test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
+
+	LC_ALL=en_US.UTF-8
+	export LC_ALL
+
+	(
+	hg init hgrepo &&
+	cd hgrepo &&
+
+	echo test >> "æ rø" &&
+	hg add "æ rø" &&
+	echo test >> "ø~?" &&
+	hg add "ø~?" &&
+	hg commit -m add-utf-8 &&
+	echo test >> "æ rø" &&
+	hg commit -m test-utf-8 &&
+	hg rm "ø~?" &&
+	hg mv "æ rø" "ø~?" &&
+	hg commit -m hg-mv-utf-8
+	) &&
+
+	(
+	git clone "hg::hgrepo" gitrepo &&
+	cd gitrepo &&
+	git -c core.quotepath=false ls-files > ../actual
+	) &&
+	echo "ø~?" > expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'push special filenames' '
+	test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
+
+	mkdir -p tmp && cd tmp &&
+
+	LC_ALL=en_US.UTF-8
+	export LC_ALL
+
+	(
+	hg init hgrepo &&
+	cd hgrepo &&
+
+	echo one >> content &&
+	hg add content &&
+	hg commit -m one
+	) &&
+
+	(
+	git clone "hg::hgrepo" gitrepo &&
+	cd gitrepo &&
+
+	echo test >> "æ rø" &&
+	git add "æ rø" &&
+	git commit -m utf-8 &&
+
+	git push
+	) &&
+
+	(cd hgrepo &&
+	hg update &&
+	hg manifest > ../actual
+	) &&
+
+	printf "content\næ rø\n" > expected &&
+	test_cmp expected actual
+'
+
 setup_big_push () {
 	(
 	hg init hgrepo &&
 	cd hgrepo &&
-	echo zero > content &&
+	echo zero >content &&
 	hg add content &&
 	hg commit -m zero &&
 	hg bookmark bad_bmark1 &&
-	echo one > content &&
+	echo one >content &&
 	hg commit -m one &&
 	hg bookmark bad_bmark2 &&
 	hg bookmark good_bmark &&
 	hg bookmark -i good_bmark &&
 	hg -q branch good_branch &&
-	echo "good branch" > content &&
+	echo "good branch" >content &&
 	hg commit -m "good branch" &&
 	hg -q branch bad_branch &&
-	echo "bad branch" > content &&
+	echo "bad branch" >content &&
 	hg commit -m "bad branch"
 	) &&
 
@@ -463,40 +548,40 @@
 
 	(
 	cd gitrepo &&
-	echo two > content &&
+	echo two >content &&
 	git commit -q -a -m two &&
 
 	git checkout -q good_bmark &&
-	echo three > content &&
+	echo three >content &&
 	git commit -q -a -m three &&
 
 	git checkout -q bad_bmark1 &&
 	git reset --hard HEAD^ &&
-	echo four > content &&
+	echo four >content &&
 	git commit -q -a -m four &&
 
 	git checkout -q bad_bmark2 &&
 	git reset --hard HEAD^ &&
-	echo five > content &&
+	echo five >content &&
 	git commit -q -a -m five &&
 
 	git checkout -q -b new_bmark master &&
-	echo six > content &&
+	echo six >content &&
 	git commit -q -a -m six &&
 
 	git checkout -q branches/good_branch &&
-	echo seven > content &&
+	echo seven >content &&
 	git commit -q -a -m seven &&
-	echo eight > content &&
+	echo eight >content &&
 	git commit -q -a -m eight &&
 
 	git checkout -q branches/bad_branch &&
 	git reset --hard HEAD^ &&
-	echo nine > content &&
+	echo nine >content &&
 	git commit -q -a -m nine &&
 
 	git checkout -q -b branches/new_branch master &&
-	echo ten > content &&
+	echo ten >content &&
 	git commit -q -a -m ten
 	)
 }
@@ -509,7 +594,7 @@
 	(
 	cd gitrepo &&
 
-	check_push 1 --all <<-EOF
+	check_push 1 --all <<-\EOF
 	master
 	good_bmark
 	branches/good_branch
@@ -537,17 +622,17 @@
 	(
 	hg init hgrepo &&
 	cd hgrepo &&
-	echo zero > content &&
+	echo zero >content &&
 	hg add content &&
 	hg commit -m zero &&
 	hg bookmark bad_bmark &&
 	hg bookmark good_bmark &&
 	hg bookmark -i good_bmark &&
 	hg -q branch good_branch &&
-	echo "good branch" > content &&
+	echo "good branch" >content &&
 	hg commit -m "good branch" &&
 	hg -q branch bad_branch &&
-	echo "bad branch" > content &&
+	echo "bad branch" >content &&
 	hg commit -m "bad branch"
 	) &&
 
@@ -556,39 +641,37 @@
 	(
 	cd hgrepo &&
 	hg bookmark -f bad_bmark &&
-	echo update_bmark > content &&
+	echo update_bmark >content &&
 	hg commit -m "update bmark"
 	) &&
 
 	(
 	cd gitrepo &&
-	echo two > content &&
+	echo two >content &&
 	git commit -q -a -m two &&
 
 	git checkout -q good_bmark &&
-	echo three > content &&
+	echo three >content &&
 	git commit -q -a -m three &&
 
 	git checkout -q bad_bmark &&
-	echo four > content &&
+	echo four >content &&
 	git commit -q -a -m four &&
 
 	git checkout -q branches/bad_branch &&
-	echo five > content &&
+	echo five >content &&
 	git commit -q -a -m five &&
 
-	check_push 1 --all <<-EOF
+	check_push 1 --all <<-\EOF &&
 	master
 	good_bmark
-	new_bmark:new
-	new_branch:new
 	bad_bmark:fetch-first
 	branches/bad_branch:festch-first
 	EOF
 
 	git fetch &&
 
-	check_push 1 --all <<-EOF
+	check_push 1 --all <<-\EOF
 	master
 	good_bmark
 	bad_bmark:non-fast-forward
@@ -605,7 +688,7 @@
 	(
 	cd gitrepo &&
 
-	check_push 0 --force --all <<-EOF
+	check_push 0 --force --all <<-\EOF
 	master
 	good_bmark
 	branches/good_branch
@@ -635,7 +718,7 @@
 	(
 	cd gitrepo &&
 
-	check_push 0 --dry-run --all <<-EOF
+	check_push 1 --dry-run --all <<-\EOF &&
 	master
 	good_bmark
 	branches/good_branch
@@ -646,7 +729,7 @@
 	branches/bad_branch:non-fast-forward
 	EOF
 
-	check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-EOF
+	check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-\EOF
 	master
 	good_bmark
 	branches/good_branch
@@ -671,10 +754,10 @@
 	(
 	hg init hgrepo &&
 	cd hgrepo &&
-	echo zero > content &&
+	echo zero >content &&
 	hg add content &&
 	hg commit -m zero &&
-	echo one > content &&
+	echo one >content &&
 	hg commit -m one
 	) &&
 
@@ -682,7 +765,7 @@
 	git clone "hg::hgrepo" gitrepo &&
 	cd gitrepo &&
 	git reset --hard HEAD^ &&
-	echo two > content &&
+	echo two >content &&
 	git commit -a -m two &&
 	test_expect_code 1 git push &&
 	test_expect_code 1 git push
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 7d7af03..dc59a91 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
Binary files differ
diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index e0957ee..02669b1 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -9,10 +9,10 @@
 SYNOPSIS
 --------
 [verse]
-'git subtree' add   -P <prefix> <refspec>
-'git subtree' add   -P <prefix> <repository> <refspec>
-'git subtree' pull  -P <prefix> <repository> <refspec...>
-'git subtree' push  -P <prefix> <repository> <refspec...>
+'git subtree' add   -P <prefix> <commit>
+'git subtree' add   -P <prefix> <repository> <ref>
+'git subtree' pull  -P <prefix> <repository> <ref>
+'git subtree' push  -P <prefix> <repository> <ref>
 'git subtree' merge -P <prefix> <commit>
 'git subtree' split -P <prefix> [OPTIONS] [<commit>]
 
@@ -68,7 +68,7 @@
 --------
 add::
 	Create the <prefix> subtree by importing its contents
-	from the given <refspec> or <repository> and remote <refspec>.
+	from the given <commit> or <repository> and remote <ref>.
 	A new commit is created	automatically, joining the imported
 	project's history with your own.  With '--squash', imports
 	only a single commit from the subproject, rather than its
@@ -90,13 +90,13 @@
 	
 pull::
 	Exactly like 'merge', but parallels 'git pull' in that
-	it fetches the given commit from the specified remote
+	it fetches the given ref from the specified remote
 	repository.
 	
 push::
 	Does a 'split' (see below) using the <prefix> supplied
 	and then does a 'git push' to push the result to the 
-	repository and refspec. This can be used to push your
+	repository and ref. This can be used to push your
 	subtree to different branches of the remote repository.
 
 split::
diff --git a/convert.c b/convert.c
index 11a95fc..ab80b72 100644
--- a/convert.c
+++ b/convert.c
@@ -1121,7 +1121,7 @@
 {
 	int i;
 
-	if (prefixcmp(str, "$Id: "))
+	if (!starts_with(str, "$Id: "))
 		return 0;
 	for (i = 5; str[i]; i++) {
 		if (isspace(str[i]) && str[i+1] != '$')
diff --git a/csum-file.c b/csum-file.c
index 53f5375..b00b215 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -11,7 +11,7 @@
 #include "progress.h"
 #include "csum-file.h"
 
-static void flush(struct sha1file *f, void *buf, unsigned int count)
+static void flush(struct sha1file *f, const void *buf, unsigned int count)
 {
 	if (0 <= f->check_fd && count)  {
 		unsigned char check_buffer[8192];
@@ -86,13 +86,13 @@
 	return fd;
 }
 
-int sha1write(struct sha1file *f, void *buf, unsigned int count)
+void sha1write(struct sha1file *f, const void *buf, unsigned int count)
 {
 	while (count) {
 		unsigned offset = f->offset;
 		unsigned left = sizeof(f->buffer) - offset;
 		unsigned nr = count > left ? left : count;
-		void *data;
+		const void *data;
 
 		if (f->do_crc)
 			f->crc32 = crc32(f->crc32, buf, nr);
@@ -116,7 +116,6 @@
 		}
 		f->offset = offset;
 	}
-	return 0;
 }
 
 struct sha1file *sha1fd(int fd, const char *name)
diff --git a/csum-file.h b/csum-file.h
index 3b540bd..bb543d5 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -34,7 +34,7 @@
 extern struct sha1file *sha1fd_check(const char *name);
 extern struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp);
 extern int sha1close(struct sha1file *, unsigned char *, unsigned int);
-extern int sha1write(struct sha1file *, void *, unsigned int);
+extern void sha1write(struct sha1file *, const void *, unsigned int);
 extern void sha1flush(struct sha1file *f);
 extern void crc32_begin(struct sha1file *);
 extern uint32_t crc32_end(struct sha1file *);
diff --git a/daemon.c b/daemon.c
index 34916c5..503e039 100644
--- a/daemon.c
+++ b/daemon.c
@@ -235,7 +235,7 @@
 
 static int git_daemon_config(const char *var, const char *value, void *cb)
 {
-	if (!prefixcmp(var, "daemon.") &&
+	if (starts_with(var, "daemon.") &&
 	    !strcmp(var + 7, service_looking_at->config_name)) {
 		service_enabled = git_config_bool(var, value);
 		return 0;
@@ -633,7 +633,7 @@
 	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
 		struct daemon_service *s = &(daemon_service[i]);
 		int namelen = strlen(s->name);
-		if (!prefixcmp(line, "git-") &&
+		if (starts_with(line, "git-") &&
 		    !strncmp(s->name, line + 4, namelen) &&
 		    line[namelen + 4] == ' ') {
 			/*
@@ -1165,11 +1165,11 @@
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
 
-		if (!prefixcmp(arg, "--listen=")) {
+		if (starts_with(arg, "--listen=")) {
 			string_list_append(&listen_addr, xstrdup_tolower(arg + 9));
 			continue;
 		}
-		if (!prefixcmp(arg, "--port=")) {
+		if (starts_with(arg, "--port=")) {
 			char *end;
 			unsigned long n;
 			n = strtoul(arg+7, &end, 0);
@@ -1199,19 +1199,19 @@
 			export_all_trees = 1;
 			continue;
 		}
-		if (!prefixcmp(arg, "--access-hook=")) {
+		if (starts_with(arg, "--access-hook=")) {
 			access_hook = arg + 14;
 			continue;
 		}
-		if (!prefixcmp(arg, "--timeout=")) {
+		if (starts_with(arg, "--timeout=")) {
 			timeout = atoi(arg+10);
 			continue;
 		}
-		if (!prefixcmp(arg, "--init-timeout=")) {
+		if (starts_with(arg, "--init-timeout=")) {
 			init_timeout = atoi(arg+15);
 			continue;
 		}
-		if (!prefixcmp(arg, "--max-connections=")) {
+		if (starts_with(arg, "--max-connections=")) {
 			max_connections = atoi(arg+18);
 			if (max_connections < 0)
 				max_connections = 0;	        /* unlimited */
@@ -1221,7 +1221,7 @@
 			strict_paths = 1;
 			continue;
 		}
-		if (!prefixcmp(arg, "--base-path=")) {
+		if (starts_with(arg, "--base-path=")) {
 			base_path = arg+12;
 			continue;
 		}
@@ -1229,7 +1229,7 @@
 			base_path_relaxed = 1;
 			continue;
 		}
-		if (!prefixcmp(arg, "--interpolated-path=")) {
+		if (starts_with(arg, "--interpolated-path=")) {
 			interpolated_path = arg+20;
 			continue;
 		}
@@ -1241,11 +1241,11 @@
 			user_path = "";
 			continue;
 		}
-		if (!prefixcmp(arg, "--user-path=")) {
+		if (starts_with(arg, "--user-path=")) {
 			user_path = arg + 12;
 			continue;
 		}
-		if (!prefixcmp(arg, "--pid-file=")) {
+		if (starts_with(arg, "--pid-file=")) {
 			pid_file = arg + 11;
 			continue;
 		}
@@ -1254,35 +1254,35 @@
 			log_syslog = 1;
 			continue;
 		}
-		if (!prefixcmp(arg, "--user=")) {
+		if (starts_with(arg, "--user=")) {
 			user_name = arg + 7;
 			continue;
 		}
-		if (!prefixcmp(arg, "--group=")) {
+		if (starts_with(arg, "--group=")) {
 			group_name = arg + 8;
 			continue;
 		}
-		if (!prefixcmp(arg, "--enable=")) {
+		if (starts_with(arg, "--enable=")) {
 			enable_service(arg + 9, 1);
 			continue;
 		}
-		if (!prefixcmp(arg, "--disable=")) {
+		if (starts_with(arg, "--disable=")) {
 			enable_service(arg + 10, 0);
 			continue;
 		}
-		if (!prefixcmp(arg, "--allow-override=")) {
+		if (starts_with(arg, "--allow-override=")) {
 			make_service_overridable(arg + 17, 1);
 			continue;
 		}
-		if (!prefixcmp(arg, "--forbid-override=")) {
+		if (starts_with(arg, "--forbid-override=")) {
 			make_service_overridable(arg + 18, 0);
 			continue;
 		}
-		if (!prefixcmp(arg, "--informative-errors")) {
+		if (!strcmp(arg, "--informative-errors")) {
 			informative_errors = 1;
 			continue;
 		}
-		if (!prefixcmp(arg, "--no-informative-errors")) {
+		if (!strcmp(arg, "--no-informative-errors")) {
 			informative_errors = 0;
 			continue;
 		}
diff --git a/date.c b/date.c
index 29f1540..83b4166 100644
--- a/date.c
+++ b/date.c
@@ -907,7 +907,7 @@
 	const char *end = date;
 	int i;
 
-	while (isalpha(*++end));
+	while (isalpha(*++end))
 		;
 
 	for (i = 0; i < 12; i++) {
diff --git a/diff-delta.c b/diff-delta.c
index 93385e1..3797ce6 100644
--- a/diff-delta.c
+++ b/diff-delta.c
@@ -155,7 +155,7 @@
 		entries = 0xfffffffeU / RABIN_WINDOW;
 	}
 	hsize = entries / 4;
-	for (i = 4; (1u << i) < hsize && i < 31; i++);
+	for (i = 4; (1u << i) < hsize; i++);
 	hsize = 1 << i;
 	hmask = hsize - 1;
 
diff --git a/diff-lib.c b/diff-lib.c
index b6f4b21..346cac6 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -87,10 +87,12 @@
 {
 	int entries, i;
 	int diff_unmerged_stage = revs->max_count;
-	int silent_on_removed = option & DIFF_SILENT_ON_REMOVED;
 	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
 			      ? CE_MATCH_RACY_IS_DIRTY : 0);
 
+	if (option & DIFF_SILENT_ON_REMOVED)
+		handle_deprecated_show_diff_q(&revs->diffopt);
+
 	diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
 
 	if (diff_unmerged_stage < 0)
@@ -137,8 +139,6 @@
 					perror(ce->name);
 					continue;
 				}
-				if (silent_on_removed)
-					continue;
 				wt_mode = 0;
 			}
 			dpath->mode = wt_mode;
@@ -204,8 +204,6 @@
 				perror(ce->name);
 				continue;
 			}
-			if (silent_on_removed)
-				continue;
 			diff_addremove(&revs->diffopt, '-', ce->ce_mode,
 				       ce->sha1, !is_null_sha1(ce->sha1),
 				       ce->name, 0);
@@ -476,7 +474,6 @@
 	opts.dst_index = NULL;
 	opts.pathspec = &revs->diffopt.pathspec;
 	opts.pathspec->recursive = 1;
-	opts.pathspec->max_depth = -1;
 
 	init_tree_desc(&t, tree->buffer, tree->size);
 	return unpack_trees(1, &t, &opts);
@@ -502,7 +499,7 @@
 	struct rev_info revs;
 
 	init_revisions(&revs, NULL);
-	init_pathspec(&revs.prune_data, opt->pathspec.raw);
+	copy_pathspec(&revs.prune_data, &opt->pathspec);
 	revs.diffopt = *opt;
 
 	if (diff_cache(&revs, tree_sha1, NULL, 1))
diff --git a/diff-no-index.c b/diff-no-index.c
index e66fdf3..33e5982 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -183,49 +183,19 @@
 
 void diff_no_index(struct rev_info *revs,
 		   int argc, const char **argv,
-		   int nongit, const char *prefix)
+		   const char *prefix)
 {
 	int i, prefixlen;
-	int no_index = 0;
-	unsigned options = 0;
+	unsigned deprecated_show_diff_q_option_used = 0;
 	const char *paths[2];
 
-	/* Were we asked to do --no-index explicitly? */
-	for (i = 1; i < argc; i++) {
-		if (!strcmp(argv[i], "--")) {
-			i++;
-			break;
-		}
-		if (!strcmp(argv[i], "--no-index"))
-			no_index = 1;
-		if (argv[i][0] != '-')
-			break;
-	}
-
-	if (!no_index && !nongit) {
-		/*
-		 * Inside a git repository, without --no-index.  Only
-		 * when a path outside the repository is given,
-		 * e.g. "git diff /var/tmp/[12]", or "git diff
-		 * Makefile /var/tmp/Makefile", allow it to be used as
-		 * a colourful "diff" replacement.
-		 */
-		if ((argc != i + 2) ||
-		    (path_inside_repo(prefix, argv[i]) &&
-		     path_inside_repo(prefix, argv[i+1])))
-			return;
-	}
-	if (argc != i + 2)
-		usagef("git diff %s <path> <path>",
-		       no_index ? "--no-index" : "[--no-index]");
-
 	diff_setup(&revs->diffopt);
 	for (i = 1; i < argc - 2; ) {
 		int j;
 		if (!strcmp(argv[i], "--no-index"))
 			i++;
 		else if (!strcmp(argv[i], "-q")) {
-			options |= DIFF_SILENT_ON_REMOVED;
+			deprecated_show_diff_q_option_used = 1;
 			i++;
 		}
 		else if (!strcmp(argv[i], "--"))
@@ -260,6 +230,9 @@
 	revs->max_count = -2;
 	diff_setup_done(&revs->diffopt);
 
+	if (deprecated_show_diff_q_option_used)
+		handle_deprecated_show_diff_q(&revs->diffopt);
+
 	setup_diff_pager(&revs->diffopt);
 	DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
 
diff --git a/diff.c b/diff.c
index 266112c..8e4a6a9 100644
--- a/diff.c
+++ b/diff.c
@@ -30,6 +30,7 @@
 static int diff_context_default = 3;
 static const char *diff_word_regex_cfg;
 static const char *external_diff_cmd_cfg;
+static const char *diff_order_file_cfg;
 int diff_auto_refresh_index = 1;
 static int diff_mnemonic_prefix;
 static int diff_no_prefix;
@@ -201,6 +202,8 @@
 		return git_config_string(&external_diff_cmd_cfg, var, value);
 	if (!strcmp(var, "diff.wordregex"))
 		return git_config_string(&diff_word_regex_cfg, var, value);
+	if (!strcmp(var, "diff.orderfile"))
+		return git_config_pathname(&diff_order_file_cfg, var, value);
 
 	if (!strcmp(var, "diff.ignoresubmodules"))
 		handle_ignore_submodules_arg(&default_diff_options, value);
@@ -235,7 +238,7 @@
 	if (userdiff_config(var, value) < 0)
 		return -1;
 
-	if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
+	if (starts_with(var, "diff.color.") || starts_with(var, "color.diff.")) {
 		int slot = parse_diff_color_slot(var, 11);
 		if (slot < 0)
 			return 0;
@@ -264,7 +267,7 @@
 		return 0;
 	}
 
-	if (!prefixcmp(var, "submodule."))
+	if (starts_with(var, "submodule."))
 		return parse_submodule_config_option(var, value);
 
 	return git_default_config(var, value, cb);
@@ -669,7 +672,7 @@
 	memset(&ecbdata, 0, sizeof(ecbdata));
 	ecbdata.color_diff = want_color(o->use_color);
 	ecbdata.found_changesp = &o->found_changes;
-	ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
+	ecbdata.ws_rule = whitespace_rule(name_b);
 	ecbdata.opt = o;
 	if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
 		mmfile_t mf1, mf2;
@@ -1215,7 +1218,7 @@
 			diff_words_append(line, len,
 					  &ecbdata->diff_words->plus);
 			return;
-		} else if (!prefixcmp(line, "\\ ")) {
+		} else if (starts_with(line, "\\ ")) {
 			/*
 			 * Eat the "no newline at eof" marker as if we
 			 * saw a "+" or "-" line with nothing on it,
@@ -2252,7 +2255,7 @@
 			(!two->mode || S_ISGITLINK(two->mode))) {
 		const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
 		const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
-		show_submodule_summary(o->file, one ? one->path : two->path,
+		show_submodule_summary(o->file, one->path ? one->path : two->path,
 				line_prefix,
 				one->sha1, two->sha1, two->dirty_submodule,
 				meta, del, add, reset);
@@ -2372,7 +2375,7 @@
 		ecbdata.label_path = lbl;
 		ecbdata.color_diff = want_color(o->use_color);
 		ecbdata.found_changesp = &o->found_changes;
-		ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
+		ecbdata.ws_rule = whitespace_rule(name_b);
 		if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
 			check_blank_at_eof(&mf1, &mf2, &ecbdata);
 		ecbdata.opt = o;
@@ -2387,9 +2390,9 @@
 			xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
 		if (!diffopts)
 			;
-		else if (!prefixcmp(diffopts, "--unified="))
+		else if (starts_with(diffopts, "--unified="))
 			xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
-		else if (!prefixcmp(diffopts, "-u"))
+		else if (starts_with(diffopts, "-u"))
 			xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
 		if (o->word_diff)
 			init_diff_words_data(&ecbdata, o, one, two);
@@ -2899,11 +2902,16 @@
 			      struct diff_filespec *one,
 			      struct diff_filespec *two,
 			      const char *xfrm_msg,
-			      int complete_rewrite)
+			      int complete_rewrite,
+			      struct diff_options *o)
 {
 	const char *spawn_arg[10];
 	int retval;
 	const char **arg = &spawn_arg[0];
+	struct diff_queue_struct *q = &diff_queued_diff;
+	const char *env[3] = { NULL };
+	char env_counter[50];
+	char env_total[50];
 
 	if (one && two) {
 		struct diff_tempfile *temp_one, *temp_two;
@@ -2928,7 +2936,14 @@
 	}
 	*arg = NULL;
 	fflush(NULL);
-	retval = run_command_v_opt(spawn_arg, RUN_USING_SHELL);
+
+	env[0] = env_counter;
+	snprintf(env_counter, sizeof(env_counter), "GIT_DIFF_PATH_COUNTER=%d",
+		 ++o->diff_path_counter);
+	env[1] = env_total;
+	snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr);
+
+	retval = run_command_v_opt_cd_env(spawn_arg, RUN_USING_SHELL, NULL, env);
 	remove_tempfile();
 	if (retval) {
 		fprintf(stderr, "external diff died, stopping at %s.\n", name);
@@ -3042,7 +3057,7 @@
 
 	if (pgm) {
 		run_external_diff(pgm, name, other, one, two, xfrm_msg,
-				  complete_rewrite);
+				  complete_rewrite, o);
 		return;
 	}
 	if (one && two)
@@ -3207,6 +3222,8 @@
 	options->detect_rename = diff_detect_rename_default;
 	options->xdl_opts |= diff_algorithm;
 
+	options->orderfile = diff_order_file_cfg;
+
 	if (diff_no_prefix) {
 		options->a_prefix = options->b_prefix = "";
 	} else if (!diff_mnemonic_prefix) {
@@ -3219,6 +3236,9 @@
 {
 	int count = 0;
 
+	if (options->set_default)
+		options->set_default(options);
+
 	if (options->output_format & DIFF_FORMAT_NAME)
 		count++;
 	if (options->output_format & DIFF_FORMAT_NAME_STATUS)
@@ -3314,6 +3334,8 @@
 		options->output_format = DIFF_FORMAT_NO_OUTPUT;
 		DIFF_OPT_SET(options, EXIT_WITH_STATUS);
 	}
+
+	options->diff_path_counter = 0;
 }
 
 static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
@@ -3388,10 +3410,10 @@
 	if (arg[0] != '-' || arg[1] != '-')
 		return 0;
 	arg += strlen("--");
-	if (prefixcmp(arg, opt))
+	if (!starts_with(arg, opt))
 		return 0;
 	arg += strlen(opt);
-	if (*arg == '=') { /* sticked form: --option=value */
+	if (*arg == '=') { /* stuck form: --option=value */
 		*optarg = arg + 1;
 		return 1;
 	}
@@ -3419,7 +3441,7 @@
 
 	switch (*arg) {
 	case '-':
-		if (!prefixcmp(arg, "-width")) {
+		if (starts_with(arg, "-width")) {
 			arg += strlen("-width");
 			if (*arg == '=')
 				width = strtoul(arg + 1, &end, 10);
@@ -3429,7 +3451,7 @@
 				width = strtoul(av[1], &end, 10);
 				argcount = 2;
 			}
-		} else if (!prefixcmp(arg, "-name-width")) {
+		} else if (starts_with(arg, "-name-width")) {
 			arg += strlen("-name-width");
 			if (*arg == '=')
 				name_width = strtoul(arg + 1, &end, 10);
@@ -3439,7 +3461,7 @@
 				name_width = strtoul(av[1], &end, 10);
 				argcount = 2;
 			}
-		} else if (!prefixcmp(arg, "-graph-width")) {
+		} else if (starts_with(arg, "-graph-width")) {
 			arg += strlen("-graph-width");
 			if (*arg == '=')
 				graph_width = strtoul(arg + 1, &end, 10);
@@ -3449,7 +3471,7 @@
 				graph_width = strtoul(av[1], &end, 10);
 				argcount = 2;
 			}
-		} else if (!prefixcmp(arg, "-count")) {
+		} else if (starts_with(arg, "-count")) {
 			arg += strlen("-count");
 			if (*arg == '=')
 				count = strtoul(arg + 1, &end, 10);
@@ -3503,6 +3525,88 @@
 	return 1;
 }
 
+static const char diff_status_letters[] = {
+	DIFF_STATUS_ADDED,
+	DIFF_STATUS_COPIED,
+	DIFF_STATUS_DELETED,
+	DIFF_STATUS_MODIFIED,
+	DIFF_STATUS_RENAMED,
+	DIFF_STATUS_TYPE_CHANGED,
+	DIFF_STATUS_UNKNOWN,
+	DIFF_STATUS_UNMERGED,
+	DIFF_STATUS_FILTER_AON,
+	DIFF_STATUS_FILTER_BROKEN,
+	'\0',
+};
+
+static unsigned int filter_bit['Z' + 1];
+
+static void prepare_filter_bits(void)
+{
+	int i;
+
+	if (!filter_bit[DIFF_STATUS_ADDED]) {
+		for (i = 0; diff_status_letters[i]; i++)
+			filter_bit[(int) diff_status_letters[i]] = (1 << i);
+	}
+}
+
+static unsigned filter_bit_tst(char status, const struct diff_options *opt)
+{
+	return opt->filter & filter_bit[(int) status];
+}
+
+static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt)
+{
+	int i, optch;
+
+	prepare_filter_bits();
+
+	/*
+	 * If there is a negation e.g. 'd' in the input, and we haven't
+	 * initialized the filter field with another --diff-filter, start
+	 * from full set of bits, except for AON.
+	 */
+	if (!opt->filter) {
+		for (i = 0; (optch = optarg[i]) != '\0'; i++) {
+			if (optch < 'a' || 'z' < optch)
+				continue;
+			opt->filter = (1 << (ARRAY_SIZE(diff_status_letters) - 1)) - 1;
+			opt->filter &= ~filter_bit[DIFF_STATUS_FILTER_AON];
+			break;
+		}
+	}
+
+	for (i = 0; (optch = optarg[i]) != '\0'; i++) {
+		unsigned int bit;
+		int negate;
+
+		if ('a' <= optch && optch <= 'z') {
+			negate = 1;
+			optch = toupper(optch);
+		} else {
+			negate = 0;
+		}
+
+		bit = (0 <= optch && optch <= 'Z') ? filter_bit[optch] : 0;
+		if (!bit)
+			return optarg[i];
+		if (negate)
+			opt->filter &= ~bit;
+		else
+			opt->filter |= bit;
+	}
+	return 0;
+}
+
+/* Used only by "diff-files" and "diff --no-index" */
+void handle_deprecated_show_diff_q(struct diff_options *opt)
+{
+	warning("'diff -q' and 'diff-files -q' are deprecated.");
+	warning("Use 'diff --diff-filter=d' instead to ignore deleted filepairs.");
+	parse_diff_filter_opt("d", opt);
+}
+
 static void enable_patch_output(int *fmt) {
 	*fmt &= ~DIFF_FORMAT_NO_OUTPUT;
 	*fmt |= DIFF_FORMAT_PATCH;
@@ -3529,15 +3633,15 @@
 		options->output_format |= DIFF_FORMAT_SHORTSTAT;
 	else if (!strcmp(arg, "-X") || !strcmp(arg, "--dirstat"))
 		return parse_dirstat_opt(options, "");
-	else if (!prefixcmp(arg, "-X"))
+	else if (starts_with(arg, "-X"))
 		return parse_dirstat_opt(options, arg + 2);
-	else if (!prefixcmp(arg, "--dirstat="))
+	else if (starts_with(arg, "--dirstat="))
 		return parse_dirstat_opt(options, arg + 10);
 	else if (!strcmp(arg, "--cumulative"))
 		return parse_dirstat_opt(options, "cumulative");
 	else if (!strcmp(arg, "--dirstat-by-file"))
 		return parse_dirstat_opt(options, "files");
-	else if (!prefixcmp(arg, "--dirstat-by-file=")) {
+	else if (starts_with(arg, "--dirstat-by-file=")) {
 		parse_dirstat_opt(options, "files");
 		return parse_dirstat_opt(options, arg + 18);
 	}
@@ -3554,17 +3658,17 @@
 		options->output_format |= DIFF_FORMAT_NAME_STATUS;
 	else if (!strcmp(arg, "-s") || !strcmp(arg, "--no-patch"))
 		options->output_format |= DIFF_FORMAT_NO_OUTPUT;
-	else if (!prefixcmp(arg, "--stat"))
+	else if (starts_with(arg, "--stat"))
 		/* --stat, --stat-width, --stat-name-width, or --stat-count */
 		return stat_opt(options, av);
 
 	/* renames options */
-	else if (!prefixcmp(arg, "-B") || !prefixcmp(arg, "--break-rewrites=") ||
+	else if (starts_with(arg, "-B") || starts_with(arg, "--break-rewrites=") ||
 		 !strcmp(arg, "--break-rewrites")) {
 		if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
 			return error("invalid argument to -B: %s", arg+2);
 	}
-	else if (!prefixcmp(arg, "-M") || !prefixcmp(arg, "--find-renames=") ||
+	else if (starts_with(arg, "-M") || starts_with(arg, "--find-renames=") ||
 		 !strcmp(arg, "--find-renames")) {
 		if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
 			return error("invalid argument to -M: %s", arg+2);
@@ -3573,7 +3677,7 @@
 	else if (!strcmp(arg, "-D") || !strcmp(arg, "--irreversible-delete")) {
 		options->irreversible_delete = 1;
 	}
-	else if (!prefixcmp(arg, "-C") || !prefixcmp(arg, "--find-copies=") ||
+	else if (starts_with(arg, "-C") || starts_with(arg, "--find-copies=") ||
 		 !strcmp(arg, "--find-copies")) {
 		if (options->detect_rename == DIFF_DETECT_COPY)
 			DIFF_OPT_SET(options, FIND_COPIES_HARDER);
@@ -3589,7 +3693,7 @@
 		DIFF_OPT_CLR(options, RENAME_EMPTY);
 	else if (!strcmp(arg, "--relative"))
 		DIFF_OPT_SET(options, RELATIVE_NAME);
-	else if (!prefixcmp(arg, "--relative=")) {
+	else if (starts_with(arg, "--relative=")) {
 		DIFF_OPT_SET(options, RELATIVE_NAME);
 		options->prefix = arg + 11;
 	}
@@ -3642,7 +3746,7 @@
 		DIFF_OPT_CLR(options, FOLLOW_RENAMES);
 	else if (!strcmp(arg, "--color"))
 		options->use_color = 1;
-	else if (!prefixcmp(arg, "--color=")) {
+	else if (starts_with(arg, "--color=")) {
 		int value = git_config_colorbool(NULL, arg+8);
 		if (value < 0)
 			return error("option `color' expects \"always\", \"auto\", or \"never\"");
@@ -3654,7 +3758,7 @@
 		options->use_color = 1;
 		options->word_diff = DIFF_WORDS_COLOR;
 	}
-	else if (!prefixcmp(arg, "--color-words=")) {
+	else if (starts_with(arg, "--color-words=")) {
 		options->use_color = 1;
 		options->word_diff = DIFF_WORDS_COLOR;
 		options->word_regex = arg + 14;
@@ -3663,7 +3767,7 @@
 		if (options->word_diff == DIFF_WORDS_NONE)
 			options->word_diff = DIFF_WORDS_PLAIN;
 	}
-	else if (!prefixcmp(arg, "--word-diff=")) {
+	else if (starts_with(arg, "--word-diff=")) {
 		const char *type = arg + 12;
 		if (!strcmp(type, "plain"))
 			options->word_diff = DIFF_WORDS_PLAIN;
@@ -3699,12 +3803,12 @@
 	else if (!strcmp(arg, "--ignore-submodules")) {
 		DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
 		handle_ignore_submodules_arg(options, "all");
-	} else if (!prefixcmp(arg, "--ignore-submodules=")) {
+	} else if (starts_with(arg, "--ignore-submodules=")) {
 		DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
 		handle_ignore_submodules_arg(options, arg + 20);
 	} else if (!strcmp(arg, "--submodule"))
 		DIFF_OPT_SET(options, SUBMODULE_LOG);
-	else if (!prefixcmp(arg, "--submodule="))
+	else if (starts_with(arg, "--submodule="))
 		return parse_submodule_opt(options, arg + 12);
 
 	/* misc options */
@@ -3732,12 +3836,15 @@
 		return argcount;
 	}
 	else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) {
-		options->filter = optarg;
+		int offending = parse_diff_filter_opt(optarg, options);
+		if (offending)
+			die("unknown change class '%c' in --diff-filter=%s",
+			    offending, optarg);
 		return argcount;
 	}
 	else if (!strcmp(arg, "--abbrev"))
 		options->abbrev = DEFAULT_ABBREV;
-	else if (!prefixcmp(arg, "--abbrev=")) {
+	else if (starts_with(arg, "--abbrev=")) {
 		options->abbrev = strtoul(arg + 9, NULL, 10);
 		if (options->abbrev < MINIMUM_ABBREV)
 			options->abbrev = MINIMUM_ABBREV;
@@ -3819,15 +3926,15 @@
 	cmd = *opt++;
 	if (cmd == '-') {
 		/* convert the long-form arguments into short-form versions */
-		if (!prefixcmp(opt, "break-rewrites")) {
+		if (starts_with(opt, "break-rewrites")) {
 			opt += strlen("break-rewrites");
 			if (*opt == 0 || *opt++ == '=')
 				cmd = 'B';
-		} else if (!prefixcmp(opt, "find-copies")) {
+		} else if (starts_with(opt, "find-copies")) {
 			opt += strlen("find-copies");
 			if (*opt == 0 || *opt++ == '=')
 				cmd = 'C';
-		} else if (!prefixcmp(opt, "find-renames")) {
+		} else if (starts_with(opt, "find-renames")) {
 			opt += strlen("find-renames");
 			if (*opt == 0 || *opt++ == '=')
 				cmd = 'M';
@@ -4032,9 +4139,9 @@
 		DIFF_FILE_VALID(s) ? "valid" : "invalid",
 		s->mode,
 		s->sha1_valid ? sha1_to_hex(s->sha1) : "");
-	fprintf(stderr, "queue[%d] %s size %lu flags %d\n",
+	fprintf(stderr, "queue[%d] %s size %lu\n",
 		x, one ? one : "",
-		s->size, s->xfrm_flags);
+		s->size);
 }
 
 void diff_debug_filepair(const struct diff_filepair *p, int i)
@@ -4237,7 +4344,7 @@
 	int new_len;
 
 	/* Ignore line numbers when computing the SHA1 of the patch */
-	if (!prefixcmp(line, "@@ -"))
+	if (starts_with(line, "@@ -"))
 		return;
 
 	new_len = remove_space(line, len);
@@ -4524,27 +4631,32 @@
 	}
 }
 
-static void diffcore_apply_filter(const char *filter)
+static int match_filter(const struct diff_options *options, const struct diff_filepair *p)
+{
+	return (((p->status == DIFF_STATUS_MODIFIED) &&
+		 ((p->score &&
+		   filter_bit_tst(DIFF_STATUS_FILTER_BROKEN, options)) ||
+		  (!p->score &&
+		   filter_bit_tst(DIFF_STATUS_MODIFIED, options)))) ||
+		((p->status != DIFF_STATUS_MODIFIED) &&
+		 filter_bit_tst(p->status, options)));
+}
+
+static void diffcore_apply_filter(struct diff_options *options)
 {
 	int i;
 	struct diff_queue_struct *q = &diff_queued_diff;
 	struct diff_queue_struct outq;
+
 	DIFF_QUEUE_CLEAR(&outq);
 
-	if (!filter)
+	if (!options->filter)
 		return;
 
-	if (strchr(filter, DIFF_STATUS_FILTER_AON)) {
+	if (filter_bit_tst(DIFF_STATUS_FILTER_AON, options)) {
 		int found;
 		for (i = found = 0; !found && i < q->nr; i++) {
-			struct diff_filepair *p = q->queue[i];
-			if (((p->status == DIFF_STATUS_MODIFIED) &&
-			     ((p->score &&
-			       strchr(filter, DIFF_STATUS_FILTER_BROKEN)) ||
-			      (!p->score &&
-			       strchr(filter, DIFF_STATUS_MODIFIED)))) ||
-			    ((p->status != DIFF_STATUS_MODIFIED) &&
-			     strchr(filter, p->status)))
+			if (match_filter(options, q->queue[i]))
 				found++;
 		}
 		if (found)
@@ -4562,14 +4674,7 @@
 		/* Only the matching ones */
 		for (i = 0; i < q->nr; i++) {
 			struct diff_filepair *p = q->queue[i];
-
-			if (((p->status == DIFF_STATUS_MODIFIED) &&
-			     ((p->score &&
-			       strchr(filter, DIFF_STATUS_FILTER_BROKEN)) ||
-			      (!p->score &&
-			       strchr(filter, DIFF_STATUS_MODIFIED)))) ||
-			    ((p->status != DIFF_STATUS_MODIFIED) &&
-			     strchr(filter, p->status)))
+			if (match_filter(options, p))
 				diff_q(&outq, p);
 			else
 				diff_free_filepair(p);
@@ -4676,7 +4781,7 @@
 	if (!options->found_follow)
 		/* See try_to_follow_renames() in tree-diff.c */
 		diff_resolve_rename_copy();
-	diffcore_apply_filter(options->filter);
+	diffcore_apply_filter(options);
 
 	if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
 		DIFF_OPT_SET(options, HAS_CHANGES);
diff --git a/diff.h b/diff.h
index 78b4091..ce123fa 100644
--- a/diff.h
+++ b/diff.h
@@ -5,6 +5,7 @@
 #define DIFF_H
 
 #include "tree-walk.h"
+#include "pathspec.h"
 
 struct rev_info;
 struct diff_options;
@@ -87,8 +88,9 @@
 #define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30)
 
 #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)
-#define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)
-#define DIFF_OPT_CLR(opts, flag)    ((opts)->flags &= ~DIFF_OPT_##flag)
+#define DIFF_OPT_TOUCHED(opts, flag)    ((opts)->touched_flags & DIFF_OPT_##flag)
+#define DIFF_OPT_SET(opts, flag)    (((opts)->flags |= DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag))
+#define DIFF_OPT_CLR(opts, flag)    (((opts)->flags &= ~DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag))
 #define DIFF_XDL_TST(opts, flag)    ((opts)->xdl_opts & XDF_##flag)
 #define DIFF_XDL_SET(opts, flag)    ((opts)->xdl_opts |= XDF_##flag)
 #define DIFF_XDL_CLR(opts, flag)    ((opts)->xdl_opts &= ~XDF_##flag)
@@ -103,12 +105,16 @@
 };
 
 struct diff_options {
-	const char *filter;
 	const char *orderfile;
 	const char *pickaxe;
 	const char *single_follow;
 	const char *a_prefix, *b_prefix;
 	unsigned flags;
+	unsigned touched_flags;
+
+	/* diff-filter bits */
+	unsigned int filter;
+
 	int use_color;
 	int context;
 	int interhunkcontext;
@@ -145,6 +151,8 @@
 	/* to support internal diff recursion by --follow hack*/
 	int found_follow;
 
+	void (*set_default)(struct diff_options *);
+
 	FILE *file;
 	int close_file;
 
@@ -156,6 +164,8 @@
 	diff_prefix_fn_t output_prefix;
 	int output_prefix_length;
 	void *output_prefix_data;
+
+	int diff_path_counter;
 };
 
 enum color_diff {
@@ -179,8 +189,6 @@
 
 extern const char mime_boundary_leader[];
 
-extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
-extern void diff_tree_release_paths(struct diff_options *);
 extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
 		     const char *base, struct diff_options *opt);
 extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new,
@@ -238,7 +246,7 @@
 #define DIFF_SETUP_USE_SIZE_CACHE	4
 
 /*
- * Poor man's alternative to parse-option, to allow both sticked form
+ * Poor man's alternative to parse-option, to allow both stuck form
  * (--option=value) and separate form (--option value).
  */
 extern int parse_long_opt(const char *opt, const char **argv,
@@ -324,7 +332,7 @@
 
 extern int diff_result_code(struct diff_options *, int);
 
-extern void diff_no_index(struct rev_info *, int, const char **, int, const char *);
+extern void diff_no_index(struct rev_info *, int, const char **, const char *);
 
 extern int index_differs_from(const char *def, int diff_flags);
 
@@ -338,6 +346,8 @@
 
 extern long parse_algorithm_value(const char *value);
 
+extern void handle_deprecated_show_diff_q(struct diff_options *);
+
 extern int print_stat_summary(FILE *fp, int files,
 			      int insertions, int deletions);
 extern void setup_diff_pager(struct diff_options *);
diff --git a/diffcore-order.c b/diffcore-order.c
index 23e9385..fe7f1f4 100644
--- a/diffcore-order.c
+++ b/diffcore-order.c
@@ -10,28 +10,21 @@
 
 static void prepare_order(const char *orderfile)
 {
-	int fd, cnt, pass;
+	int cnt, pass;
+	struct strbuf sb = STRBUF_INIT;
 	void *map;
 	char *cp, *endp;
-	struct stat st;
-	size_t sz;
+	ssize_t sz;
 
 	if (order)
 		return;
 
-	fd = open(orderfile, O_RDONLY);
-	if (fd < 0)
-		return;
-	if (fstat(fd, &st)) {
-		close(fd);
-		return;
-	}
-	sz = xsize_t(st.st_size);
-	map = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
-	close(fd);
-	if (map == MAP_FAILED)
-		return;
+	sz = strbuf_read_file(&sb, orderfile, 0);
+	if (sz < 0)
+		die_errno(_("failed to read orderfile '%s'"), orderfile);
+	map = strbuf_detach(&sb, NULL);
 	endp = (char *) map + sz;
+
 	for (pass = 0; pass < 2; pass++) {
 		cnt = 0;
 		cp = map;
@@ -73,15 +66,16 @@
 static int match_order(const char *path)
 {
 	int i;
-	char p[PATH_MAX];
+	static struct strbuf p = STRBUF_INIT;
 
 	for (i = 0; i < order_cnt; i++) {
-		strcpy(p, path);
-		while (p[0]) {
+		strbuf_reset(&p);
+		strbuf_addstr(&p, path);
+		while (p.buf[0]) {
 			char *cp;
-			if (!fnmatch(order[i], p, 0))
+			if (!fnmatch(order[i], p.buf, 0))
 				return i;
-			cp = strrchr(p, '/');
+			cp = strrchr(p.buf, '/');
 			if (!cp)
 				break;
 			*cp = 0;
diff --git a/diffcore.h b/diffcore.h
index 1c16c85..79de8cf 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -29,10 +29,8 @@
 	char *path;
 	void *data;
 	void *cnt_data;
-	const char *funcname_pattern_ident;
 	unsigned long size;
 	int count;               /* Reference count */
-	int xfrm_flags;		 /* for use by the xfrm */
 	int rename_used;         /* Count of rename users */
 	unsigned short mode;	 /* file mode */
 	unsigned sha1_valid : 1; /* if true, use sha1 and trust mode;
@@ -43,13 +41,13 @@
 	unsigned should_free : 1; /* data should be free()'ed */
 	unsigned should_munmap : 1; /* data should be munmap()'ed */
 	unsigned dirty_submodule : 2;  /* For submodules: its work tree is dirty */
-	unsigned is_stdin : 1;
 #define DIRTY_SUBMODULE_UNTRACKED 1
 #define DIRTY_SUBMODULE_MODIFIED  2
+	unsigned is_stdin : 1;
 	unsigned has_more_entries : 1; /* only appear in combined diff */
-	struct userdiff_driver *driver;
 	/* data should be considered "binary"; -1 means "don't know yet" */
-	int is_binary;
+	int is_binary : 2;
+	struct userdiff_driver *driver;
 };
 
 extern struct diff_filespec *alloc_filespec(const char *);
diff --git a/dir.c b/dir.c
index 1d63e98..b35b633 100644
--- a/dir.c
+++ b/dir.c
@@ -11,6 +11,7 @@
 #include "dir.h"
 #include "refs.h"
 #include "wildmatch.h"
+#include "pathspec.h"
 
 struct path_simplify {
 	int len;
@@ -51,26 +52,32 @@
 	return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
 }
 
-inline int git_fnmatch(const char *pattern, const char *string,
-		       int flags, int prefix)
+inline int git_fnmatch(const struct pathspec_item *item,
+		       const char *pattern, const char *string,
+		       int prefix)
 {
-	int fnm_flags = 0;
-	if (flags & GFNM_PATHNAME)
-		fnm_flags |= FNM_PATHNAME;
 	if (prefix > 0) {
-		if (strncmp(pattern, string, prefix))
+		if (ps_strncmp(item, pattern, string, prefix))
 			return FNM_NOMATCH;
 		pattern += prefix;
 		string += prefix;
 	}
-	if (flags & GFNM_ONESTAR) {
+	if (item->flags & PATHSPEC_ONESTAR) {
 		int pattern_len = strlen(++pattern);
 		int string_len = strlen(string);
 		return string_len < pattern_len ||
-		       strcmp(pattern,
-			      string + string_len - pattern_len);
+			ps_strcmp(item, pattern,
+				  string + string_len - pattern_len);
 	}
-	return fnmatch(pattern, string, fnm_flags);
+	if (item->magic & PATHSPEC_GLOB)
+		return wildmatch(pattern, string,
+				 WM_PATHNAME |
+				 (item->magic & PATHSPEC_ICASE ? WM_CASEFOLD : 0),
+				 NULL);
+	else
+		/* wildmatch has not learned no FNM_PATHNAME mode yet */
+		return fnmatch(pattern, string,
+			       item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0);
 }
 
 static int fnmatch_icase_mem(const char *pattern, int patternlen,
@@ -102,26 +109,43 @@
 	return match_status;
 }
 
-static size_t common_prefix_len(const char **pathspec)
+static size_t common_prefix_len(const struct pathspec *pathspec)
 {
-	const char *n, *first;
+	int n;
 	size_t max = 0;
-	int literal = limit_pathspec_to_literal();
 
-	if (!pathspec)
-		return max;
+	/*
+	 * ":(icase)path" is treated as a pathspec full of
+	 * wildcard. In other words, only prefix is considered common
+	 * prefix. If the pathspec is abc/foo abc/bar, running in
+	 * subdir xyz, the common prefix is still xyz, not xuz/abc as
+	 * in non-:(icase).
+	 */
+	GUARD_PATHSPEC(pathspec,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_MAXDEPTH |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE |
+		       PATHSPEC_EXCLUDE);
 
-	first = *pathspec;
-	while ((n = *pathspec++)) {
-		size_t i, len = 0;
-		for (i = 0; first == n || i < max; i++) {
-			char c = n[i];
-			if (!c || c != first[i] || (!literal && is_glob_special(c)))
+	for (n = 0; n < pathspec->nr; n++) {
+		size_t i = 0, len = 0, item_len;
+		if (pathspec->items[n].magic & PATHSPEC_EXCLUDE)
+			continue;
+		if (pathspec->items[n].magic & PATHSPEC_ICASE)
+			item_len = pathspec->items[n].prefix;
+		else
+			item_len = pathspec->items[n].nowildcard_len;
+		while (i < item_len && (n == 0 || i < max)) {
+			char c = pathspec->items[n].match[i];
+			if (c != pathspec->items[0].match[i])
 				break;
 			if (c == '/')
 				len = i + 1;
+			i++;
 		}
-		if (first == n || len < max) {
+		if (n == 0 || len < max) {
 			max = len;
 			if (!max)
 				break;
@@ -134,14 +158,14 @@
  * Returns a copy of the longest leading path common among all
  * pathspecs.
  */
-char *common_prefix(const char **pathspec)
+char *common_prefix(const struct pathspec *pathspec)
 {
 	unsigned long len = common_prefix_len(pathspec);
 
-	return len ? xmemdupz(*pathspec, len) : NULL;
+	return len ? xmemdupz(pathspec->items[0].match, len) : NULL;
 }
 
-int fill_directory(struct dir_struct *dir, const char **pathspec)
+int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
 {
 	size_t len;
 
@@ -152,7 +176,7 @@
 	len = common_prefix_len(pathspec);
 
 	/* Read the directory and prune it */
-	read_directory(dir, pathspec ? *pathspec : "", len, pathspec);
+	read_directory(dir, pathspec->nr ? pathspec->_raw[0] : "", len, pathspec);
 	return len;
 }
 
@@ -183,113 +207,6 @@
  *
  * It returns 0 when there is no match.
  */
-static int match_one(const char *match, const char *name, int namelen)
-{
-	int matchlen;
-	int literal = limit_pathspec_to_literal();
-
-	/* If the match was just the prefix, we matched */
-	if (!*match)
-		return MATCHED_RECURSIVELY;
-
-	if (ignore_case) {
-		for (;;) {
-			unsigned char c1 = tolower(*match);
-			unsigned char c2 = tolower(*name);
-			if (c1 == '\0' || (!literal && is_glob_special(c1)))
-				break;
-			if (c1 != c2)
-				return 0;
-			match++;
-			name++;
-			namelen--;
-		}
-	} else {
-		for (;;) {
-			unsigned char c1 = *match;
-			unsigned char c2 = *name;
-			if (c1 == '\0' || (!literal && is_glob_special(c1)))
-				break;
-			if (c1 != c2)
-				return 0;
-			match++;
-			name++;
-			namelen--;
-		}
-	}
-
-	/*
-	 * If we don't match the matchstring exactly,
-	 * we need to match by fnmatch
-	 */
-	matchlen = strlen(match);
-	if (strncmp_icase(match, name, matchlen)) {
-		if (literal)
-			return 0;
-		return !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0;
-	}
-
-	if (namelen == matchlen)
-		return MATCHED_EXACTLY;
-	if (match[matchlen-1] == '/' || name[matchlen] == '/')
-		return MATCHED_RECURSIVELY;
-	return 0;
-}
-
-/*
- * Given a name and a list of pathspecs, returns the nature of the
- * closest (i.e. most specific) match of the name to any of the
- * pathspecs.
- *
- * The caller typically calls this multiple times with the same
- * pathspec and seen[] array but with different name/namelen
- * (e.g. entries from the index) and is interested in seeing if and
- * how each pathspec matches all the names it calls this function
- * with.  A mark is left in the seen[] array for each pathspec element
- * indicating the closest type of match that element achieved, so if
- * seen[n] remains zero after multiple invocations, that means the nth
- * pathspec did not match any names, which could indicate that the
- * user mistyped the nth pathspec.
- */
-int match_pathspec(const char **pathspec, const char *name, int namelen,
-		int prefix, char *seen)
-{
-	int i, retval = 0;
-
-	if (!pathspec)
-		return 1;
-
-	name += prefix;
-	namelen -= prefix;
-
-	for (i = 0; pathspec[i] != NULL; i++) {
-		int how;
-		const char *match = pathspec[i] + prefix;
-		if (seen && seen[i] == MATCHED_EXACTLY)
-			continue;
-		how = match_one(match, name, namelen);
-		if (how) {
-			if (retval < how)
-				retval = how;
-			if (seen && seen[i] < how)
-				seen[i] = how;
-		}
-	}
-	return retval;
-}
-
-/*
- * Does 'match' match the given name?
- * A match is found if
- *
- * (1) the 'match' string is leading directory of 'name', or
- * (2) the 'match' string is a wildcard and matches 'name', or
- * (3) the 'match' string is exactly the same as 'name'.
- *
- * and the return value tells which case it was.
- *
- * It returns 0 when there is no match.
- */
 static int match_pathspec_item(const struct pathspec_item *item, int prefix,
 			       const char *name, int namelen)
 {
@@ -297,11 +214,44 @@
 	const char *match = item->match + prefix;
 	int matchlen = item->len - prefix;
 
+	/*
+	 * The normal call pattern is:
+	 * 1. prefix = common_prefix_len(ps);
+	 * 2. prune something, or fill_directory
+	 * 3. match_pathspec_depth()
+	 *
+	 * 'prefix' at #1 may be shorter than the command's prefix and
+	 * it's ok for #2 to match extra files. Those extras will be
+	 * trimmed at #3.
+	 *
+	 * Suppose the pathspec is 'foo' and '../bar' running from
+	 * subdir 'xyz'. The common prefix at #1 will be empty, thanks
+	 * to "../". We may have xyz/foo _and_ XYZ/foo after #2. The
+	 * user does not want XYZ/foo, only the "foo" part should be
+	 * case-insensitive. We need to filter out XYZ/foo here. In
+	 * other words, we do not trust the caller on comparing the
+	 * prefix part when :(icase) is involved. We do exact
+	 * comparison ourselves.
+	 *
+	 * Normally the caller (common_prefix_len() in fact) does
+	 * _exact_ matching on name[-prefix+1..-1] and we do not need
+	 * to check that part. Be defensive and check it anyway, in
+	 * case common_prefix_len is changed, or a new caller is
+	 * introduced that does not use common_prefix_len.
+	 *
+	 * If the penalty turns out too high when prefix is really
+	 * long, maybe change it to
+	 * strncmp(match, name, item->prefix - prefix)
+	 */
+	if (item->prefix && (item->magic & PATHSPEC_ICASE) &&
+	    strncmp(item->match, name - prefix, item->prefix))
+		return 0;
+
 	/* If the match was just the prefix, we matched */
 	if (!*match)
 		return MATCHED_RECURSIVELY;
 
-	if (matchlen <= namelen && !strncmp(match, name, matchlen)) {
+	if (matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) {
 		if (matchlen == namelen)
 			return MATCHED_EXACTLY;
 
@@ -310,8 +260,7 @@
 	}
 
 	if (item->nowildcard_len < item->len &&
-	    !git_fnmatch(match, name,
-			 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+	    !git_fnmatch(item, match, name,
 			 item->nowildcard_len - prefix))
 		return MATCHED_FNMATCH;
 
@@ -333,14 +282,25 @@
  * pathspec did not match any names, which could indicate that the
  * user mistyped the nth pathspec.
  */
-int match_pathspec_depth(const struct pathspec *ps,
-			 const char *name, int namelen,
-			 int prefix, char *seen)
+static int match_pathspec_depth_1(const struct pathspec *ps,
+				  const char *name, int namelen,
+				  int prefix, char *seen,
+				  int exclude)
 {
 	int i, retval = 0;
 
+	GUARD_PATHSPEC(ps,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_MAXDEPTH |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE |
+		       PATHSPEC_EXCLUDE);
+
 	if (!ps->nr) {
-		if (!ps->recursive || ps->max_depth == -1)
+		if (!ps->recursive ||
+		    !(ps->magic & PATHSPEC_MAXDEPTH) ||
+		    ps->max_depth == -1)
 			return MATCHED_RECURSIVELY;
 
 		if (within_depth(name, namelen, 0, ps->max_depth))
@@ -354,10 +314,23 @@
 
 	for (i = ps->nr - 1; i >= 0; i--) {
 		int how;
+
+		if ((!exclude &&   ps->items[i].magic & PATHSPEC_EXCLUDE) ||
+		    ( exclude && !(ps->items[i].magic & PATHSPEC_EXCLUDE)))
+			continue;
+
 		if (seen && seen[i] == MATCHED_EXACTLY)
 			continue;
+		/*
+		 * Make exclude patterns optional and never report
+		 * "pathspec ':(exclude)foo' matches no files"
+		 */
+		if (seen && ps->items[i].magic & PATHSPEC_EXCLUDE)
+			seen[i] = MATCHED_FNMATCH;
 		how = match_pathspec_item(ps->items+i, prefix, name, namelen);
-		if (ps->recursive && ps->max_depth != -1 &&
+		if (ps->recursive &&
+		    (ps->magic & PATHSPEC_MAXDEPTH) &&
+		    ps->max_depth != -1 &&
 		    how && how != MATCHED_FNMATCH) {
 			int len = ps->items[i].len;
 			if (name[len] == '/')
@@ -377,10 +350,22 @@
 	return retval;
 }
 
+int match_pathspec_depth(const struct pathspec *ps,
+			 const char *name, int namelen,
+			 int prefix, char *seen)
+{
+	int positive, negative;
+	positive = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 0);
+	if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)
+		return positive;
+	negative = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 1);
+	return negative ? 0 : positive;
+}
+
 /*
  * Return the length of the "simple" part of a path match limiter.
  */
-static int simple_length(const char *match)
+int simple_length(const char *match)
 {
 	int len = -1;
 
@@ -392,7 +377,7 @@
 	}
 }
 
-static int no_wildcard(const char *string)
+int no_wildcard(const char *string)
 {
 	return string[simple_length(string)] == '\0';
 }
@@ -903,7 +888,7 @@
 
 static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len)
 {
-	if (cache_name_exists(pathname, len, ignore_case))
+	if (cache_file_exists(pathname, len, ignore_case))
 		return NULL;
 
 	ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);
@@ -928,11 +913,11 @@
 /*
  * Do not use the alphabetically sorted index to look up
  * the directory name; instead, use the case insensitive
- * name hash.
+ * directory hash.
  */
 static enum exist_status directory_exists_in_index_icase(const char *dirname, int len)
 {
-	const struct cache_entry *ce = cache_name_exists(dirname, len + 1, ignore_case);
+	const struct cache_entry *ce = cache_dir_exists(dirname, len);
 	unsigned char endchar;
 
 	if (!ce)
@@ -1114,7 +1099,7 @@
 	int pos;
 	const struct cache_entry *ce;
 
-	ce = cache_name_exists(path, len, 0);
+	ce = cache_file_exists(path, len, 0);
 	if (ce) {
 		if (!ce_uptodate(ce))
 			return DT_UNKNOWN;
@@ -1174,7 +1159,7 @@
 					  int dtype, struct dirent *de)
 {
 	int exclude;
-	int has_path_in_index = !!cache_name_exists(path->buf, path->len, ignore_case);
+	int has_path_in_index = !!cache_file_exists(path->buf, path->len, ignore_case);
 
 	if (dtype == DT_UNKNOWN)
 		dtype = get_dtype(de, path->buf, path->len);
@@ -1203,21 +1188,9 @@
 	 */
 	if ((dir->flags & DIR_COLLECT_KILLED_ONLY) &&
 	    (dtype == DT_DIR) &&
-	    !has_path_in_index) {
-		/*
-		 * NEEDSWORK: directory_exists_in_index_icase()
-		 * assumes that one byte past the given path is
-		 * readable and has '/', which needs to be fixed, but
-		 * until then, work it around in the caller.
-		 */
-		strbuf_addch(path, '/');
-		if (directory_exists_in_index(path->buf, path->len - 1) ==
-		    index_nonexistent) {
-			strbuf_setlen(path, path->len - 1);
-			return path_none;
-		}
-		strbuf_setlen(path, path->len - 1);
-	}
+	    !has_path_in_index &&
+	    (directory_exists_in_index(path->buf, path->len) == index_nonexistent))
+		return path_none;
 
 	exclude = is_excluded(dir, path->buf, &dtype);
 
@@ -1417,14 +1390,32 @@
 	return rc;
 }
 
-int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec)
+int read_directory(struct dir_struct *dir, const char *path, int len, const struct pathspec *pathspec)
 {
 	struct path_simplify *simplify;
 
+	/*
+	 * Check out create_simplify()
+	 */
+	if (pathspec)
+		GUARD_PATHSPEC(pathspec,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_MAXDEPTH |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB |
+			       PATHSPEC_ICASE |
+			       PATHSPEC_EXCLUDE);
+
 	if (has_symlink_leading_path(path, len))
 		return dir->nr;
 
-	simplify = create_simplify(pathspec);
+	/*
+	 * exclude patterns are treated like positive ones in
+	 * create_simplify. Usually exclude patterns should be a
+	 * subset of positive ones, which has no impacts on
+	 * create_simplify().
+	 */
+	simplify = create_simplify(pathspec ? pathspec->_raw : NULL);
 	if (!len || treat_leading_path(dir, path, len, simplify))
 		read_directory_recursive(dir, path, len, 0, simplify);
 	free_simplify(simplify);
@@ -1520,8 +1511,13 @@
 	flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;
 	dir = opendir(path->buf);
 	if (!dir) {
-		/* an empty dir could be removed even if it is unreadble */
-		if (!keep_toplevel)
+		if (errno == ENOENT)
+			return keep_toplevel ? -1 : 0;
+		else if (errno == EACCES && !keep_toplevel)
+			/*
+			 * An empty dir could be removable even if it
+			 * is unreadable:
+			 */
 			return rmdir(path->buf);
 		else
 			return -1;
@@ -1537,13 +1533,21 @@
 
 		strbuf_setlen(path, len);
 		strbuf_addstr(path, e->d_name);
-		if (lstat(path->buf, &st))
-			; /* fall thru */
-		else if (S_ISDIR(st.st_mode)) {
+		if (lstat(path->buf, &st)) {
+			if (errno == ENOENT)
+				/*
+				 * file disappeared, which is what we
+				 * wanted anyway
+				 */
+				continue;
+			/* fall thru */
+		} else if (S_ISDIR(st.st_mode)) {
 			if (!remove_dir_recurse(path, flag, &kept_down))
 				continue; /* happy */
-		} else if (!only_empty && !unlink(path->buf))
+		} else if (!only_empty &&
+			   (!unlink(path->buf) || errno == ENOENT)) {
 			continue; /* happy, too */
+		}
 
 		/* path too long, stat fails, or non-directory still exists */
 		ret = -1;
@@ -1553,7 +1557,7 @@
 
 	strbuf_setlen(path, original_len);
 	if (!ret && !keep_toplevel && !kept_down)
-		ret = rmdir(path->buf);
+		ret = (!rmdir(path->buf) || errno == ENOENT) ? 0 : -1;
 	else if (kept_up)
 		/*
 		 * report the uplevel that it is not an error that we
@@ -1604,71 +1608,6 @@
 	return 0;
 }
 
-static int pathspec_item_cmp(const void *a_, const void *b_)
-{
-	struct pathspec_item *a, *b;
-
-	a = (struct pathspec_item *)a_;
-	b = (struct pathspec_item *)b_;
-	return strcmp(a->match, b->match);
-}
-
-int init_pathspec(struct pathspec *pathspec, const char **paths)
-{
-	const char **p = paths;
-	int i;
-
-	memset(pathspec, 0, sizeof(*pathspec));
-	if (!p)
-		return 0;
-	while (*p)
-		p++;
-	pathspec->raw = paths;
-	pathspec->nr = p - paths;
-	if (!pathspec->nr)
-		return 0;
-
-	pathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr);
-	for (i = 0; i < pathspec->nr; i++) {
-		struct pathspec_item *item = pathspec->items+i;
-		const char *path = paths[i];
-
-		item->match = path;
-		item->len = strlen(path);
-		item->flags = 0;
-		if (limit_pathspec_to_literal()) {
-			item->nowildcard_len = item->len;
-		} else {
-			item->nowildcard_len = simple_length(path);
-			if (item->nowildcard_len < item->len) {
-				pathspec->has_wildcard = 1;
-				if (path[item->nowildcard_len] == '*' &&
-				    no_wildcard(path + item->nowildcard_len + 1))
-					item->flags |= PATHSPEC_ONESTAR;
-			}
-		}
-	}
-
-	qsort(pathspec->items, pathspec->nr,
-	      sizeof(struct pathspec_item), pathspec_item_cmp);
-
-	return 0;
-}
-
-void free_pathspec(struct pathspec *pathspec)
-{
-	free(pathspec->items);
-	pathspec->items = NULL;
-}
-
-int limit_pathspec_to_literal(void)
-{
-	static int flag = -1;
-	if (flag < 0)
-		flag = git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT, 0);
-	return flag;
-}
-
 /*
  * Frees memory within dir which was allocated for exclude lists and
  * the exclude_stack.  Does not free dir itself.
diff --git a/dir.h b/dir.h
index 4677b86..9b7e4e7 100644
--- a/dir.h
+++ b/dir.h
@@ -129,15 +129,16 @@
 #define MATCHED_RECURSIVELY 1
 #define MATCHED_FNMATCH 2
 #define MATCHED_EXACTLY 3
-extern char *common_prefix(const char **pathspec);
-extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
+extern int simple_length(const char *match);
+extern int no_wildcard(const char *string);
+extern char *common_prefix(const struct pathspec *pathspec);
 extern int match_pathspec_depth(const struct pathspec *pathspec,
 				const char *name, int namelen,
 				int prefix, char *seen);
 extern int within_depth(const char *name, int namelen, int depth, int max_depth);
 
-extern int fill_directory(struct dir_struct *dir, const char **pathspec);
-extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec);
+extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);
+extern int read_directory(struct dir_struct *, const char *path, int len, const struct pathspec *pathspec);
 
 extern int is_excluded_from_list(const char *pathname, int pathlen, const char *basename,
 				 int *dtype, struct exclude_list *el);
@@ -199,10 +200,9 @@
 /*
  * The prefix part of pattern must not contains wildcards.
  */
-#define GFNM_PATHNAME 1		/* similar to FNM_PATHNAME */
-#define GFNM_ONESTAR  2		/* there is only _one_ wildcard, a star */
-
-extern int git_fnmatch(const char *pattern, const char *string,
-		       int flags, int prefix);
+struct pathspec_item;
+extern int git_fnmatch(const struct pathspec_item *item,
+		       const char *pattern, const char *string,
+		       int prefix);
 
 #endif
diff --git a/editor.c b/editor.c
index 27bdecd..0abbd8d 100644
--- a/editor.c
+++ b/editor.c
@@ -37,7 +37,7 @@
 		return error("Terminal is dumb, but EDITOR unset");
 
 	if (strcmp(editor, ":")) {
-		const char *args[] = { editor, path, NULL };
+		const char *args[] = { editor, real_path(path), NULL };
 		struct child_process p;
 		int ret, sig;
 
diff --git a/entry.c b/entry.c
index acc892f..7b7aa81 100644
--- a/entry.c
+++ b/entry.c
@@ -234,19 +234,30 @@
 	return lstat(path, st);
 }
 
+/*
+ * Write the contents from ce out to the working tree.
+ *
+ * When topath[] is not NULL, instead of writing to the working tree
+ * file named by ce, a temporary file is created by this function and
+ * its name is returned in topath[], which must be able to hold at
+ * least TEMPORARY_FILENAME_LENGTH bytes long.
+ */
 int checkout_entry(struct cache_entry *ce,
 		   const struct checkout *state, char *topath)
 {
-	static char path[PATH_MAX + 1];
+	static struct strbuf path_buf = STRBUF_INIT;
+	char *path;
 	struct stat st;
-	int len = state->base_dir_len;
+	int len;
 
 	if (topath)
 		return write_entry(ce, topath, state, 1);
 
-	memcpy(path, state->base_dir, len);
-	strcpy(path + len, ce->name);
-	len += ce_namelen(ce);
+	strbuf_reset(&path_buf);
+	strbuf_add(&path_buf, state->base_dir, state->base_dir_len);
+	strbuf_add(&path_buf, ce->name, ce_namelen(ce));
+	path = path_buf.buf;
+	len = path_buf.len;
 
 	if (!check_path(path, len, &st, state->base_dir_len)) {
 		unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
diff --git a/environment.c b/environment.c
index 378254c..4a3437d 100644
--- a/environment.c
+++ b/environment.c
@@ -10,6 +10,7 @@
 #include "cache.h"
 #include "refs.h"
 #include "fmt-merge-msg.h"
+#include "commit.h"
 
 int trust_executable_bit = 1;
 int trust_ctime = 1;
@@ -97,6 +98,7 @@
 	INDEX_ENVIRONMENT,
 	NO_REPLACE_OBJECTS_ENVIRONMENT,
 	GIT_PREFIX_ENVIRONMENT,
+	GIT_SHALLOW_FILE_ENVIRONMENT,
 	NULL
 };
 
@@ -124,6 +126,7 @@
 static void setup_git_env(void)
 {
 	const char *gitfile;
+	const char *shallow_file;
 
 	git_dir = getenv(GIT_DIR_ENVIRONMENT);
 	if (!git_dir)
@@ -147,6 +150,9 @@
 		read_replace_refs = 0;
 	namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
 	namespace_len = strlen(namespace);
+	shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
+	if (shallow_file)
+		set_alternate_shallow_file(shallow_file, 0);
 }
 
 int is_bare_repository(void)
@@ -155,11 +161,6 @@
 	return is_bare_repository_cfg && !get_git_work_tree();
 }
 
-int have_git_dir(void)
-{
-	return !!git_dir;
-}
-
 const char *get_git_dir(void)
 {
 	if (!git_dir)
@@ -176,7 +177,7 @@
 
 const char *strip_namespace(const char *namespaced_ref)
 {
-	if (prefixcmp(namespaced_ref, get_git_namespace()) != 0)
+	if (!starts_with(namespaced_ref, get_git_namespace()))
 		return NULL;
 	return namespaced_ref + namespace_len;
 }
diff --git a/fast-import.c b/fast-import.c
index 23f625f..4fd18a3 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -22,8 +22,8 @@
     ('author' (sp name)? sp '<' email '>' sp when lf)?
     'committer' (sp name)? sp '<' email '>' sp when lf
     commit_msg
-    ('from' sp committish lf)?
-    ('merge' sp committish lf)*
+    ('from' sp commit-ish lf)?
+    ('merge' sp commit-ish lf)*
     (file_change | ls)*
     lf?;
   commit_msg ::= data;
@@ -43,18 +43,18 @@
   file_obm ::= 'M' sp mode sp (hexsha1 | idnum) sp path_str lf;
   file_inm ::= 'M' sp mode sp 'inline' sp path_str lf
     data;
-  note_obm ::= 'N' sp (hexsha1 | idnum) sp committish lf;
-  note_inm ::= 'N' sp 'inline' sp committish lf
+  note_obm ::= 'N' sp (hexsha1 | idnum) sp commit-ish lf;
+  note_inm ::= 'N' sp 'inline' sp commit-ish lf
     data;
 
   new_tag ::= 'tag' sp tag_str lf
-    'from' sp committish lf
+    'from' sp commit-ish lf
     ('tagger' (sp name)? sp '<' email '>' sp when lf)?
     tag_msg;
   tag_msg ::= data;
 
   reset_branch ::= 'reset' sp ref_str lf
-    ('from' sp committish lf)?
+    ('from' sp commit-ish lf)?
     lf?;
 
   checkpoint ::= 'checkpoint' lf
@@ -93,7 +93,7 @@
      # stream formatting is: \, " and LF.  Otherwise these values
      # are UTF8.
      #
-  committish  ::= (ref_str | hexsha1 | sha1exp_str | idnum);
+  commit-ish  ::= (ref_str | hexsha1 | sha1exp_str | idnum);
   ref_str     ::= ref;
   sha1exp_str ::= sha1exp;
   tag_str     ::= tag;
@@ -1568,7 +1568,8 @@
 static int tree_content_remove(
 	struct tree_entry *root,
 	const char *p,
-	struct tree_entry *backup_leaf)
+	struct tree_entry *backup_leaf,
+	int allow_root)
 {
 	struct tree_content *t;
 	const char *slash1;
@@ -1583,6 +1584,12 @@
 
 	if (!root->tree)
 		load_tree(root);
+
+	if (!*p && allow_root) {
+		e = root;
+		goto del_entry;
+	}
+
 	t = root->tree;
 	for (i = 0; i < t->entry_count; i++) {
 		e = t->entries[i];
@@ -1599,7 +1606,7 @@
 				goto del_entry;
 			if (!e->tree)
 				load_tree(e);
-			if (tree_content_remove(e, slash1 + 1, backup_leaf)) {
+			if (tree_content_remove(e, slash1 + 1, backup_leaf, 0)) {
 				for (n = 0; n < e->tree->entry_count; n++) {
 					if (e->tree->entries[n]->versions[1].mode) {
 						hashclr(root->versions[1].sha1);
@@ -1629,7 +1636,8 @@
 static int tree_content_get(
 	struct tree_entry *root,
 	const char *p,
-	struct tree_entry *leaf)
+	struct tree_entry *leaf,
+	int allow_root)
 {
 	struct tree_content *t;
 	const char *slash1;
@@ -1641,31 +1649,39 @@
 		n = slash1 - p;
 	else
 		n = strlen(p);
-	if (!n)
+	if (!n && !allow_root)
 		die("Empty path component found in input");
 
 	if (!root->tree)
 		load_tree(root);
+
+	if (!n) {
+		e = root;
+		goto found_entry;
+	}
+
 	t = root->tree;
 	for (i = 0; i < t->entry_count; i++) {
 		e = t->entries[i];
 		if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
-			if (!slash1) {
-				memcpy(leaf, e, sizeof(*leaf));
-				if (e->tree && is_null_sha1(e->versions[1].sha1))
-					leaf->tree = dup_tree_content(e->tree);
-				else
-					leaf->tree = NULL;
-				return 1;
-			}
+			if (!slash1)
+				goto found_entry;
 			if (!S_ISDIR(e->versions[1].mode))
 				return 0;
 			if (!e->tree)
 				load_tree(e);
-			return tree_content_get(e, slash1 + 1, leaf);
+			return tree_content_get(e, slash1 + 1, leaf, 0);
 		}
 	}
 	return 0;
+
+found_entry:
+	memcpy(leaf, e, sizeof(*leaf));
+	if (e->tree && is_null_sha1(e->versions[1].sha1))
+		leaf->tree = dup_tree_content(e->tree);
+	else
+		leaf->tree = NULL;
+	return 1;
 }
 
 static int update_branch(struct branch *b)
@@ -1678,7 +1694,7 @@
 		return 0;
 	if (read_ref(b->name, old_sha1))
 		hashclr(old_sha1);
-	lock = lock_any_ref_for_update(b->name, old_sha1, 0);
+	lock = lock_any_ref_for_update(b->name, old_sha1, 0, NULL);
 	if (!lock)
 		return error("Unable to lock %s", b->name);
 	if (!force_update && !is_null_sha1(old_sha1)) {
@@ -1861,8 +1877,8 @@
 				return EOF;
 
 			if (!seen_data_command
-				&& prefixcmp(command_buf.buf, "feature ")
-				&& prefixcmp(command_buf.buf, "option ")) {
+				&& !starts_with(command_buf.buf, "feature ")
+				&& !starts_with(command_buf.buf, "option ")) {
 				parse_argv();
 			}
 
@@ -1882,7 +1898,7 @@
 			rc->prev->next = rc;
 			cmd_tail = rc;
 		}
-		if (!prefixcmp(command_buf.buf, "cat-blob ")) {
+		if (starts_with(command_buf.buf, "cat-blob ")) {
 			parse_cat_blob();
 			continue;
 		}
@@ -1901,7 +1917,7 @@
 
 static void parse_mark(void)
 {
-	if (!prefixcmp(command_buf.buf, "mark :")) {
+	if (starts_with(command_buf.buf, "mark :")) {
 		next_mark = strtoumax(command_buf.buf + 6, NULL, 10);
 		read_next_command();
 	}
@@ -1913,10 +1929,10 @@
 {
 	strbuf_reset(sb);
 
-	if (prefixcmp(command_buf.buf, "data "))
+	if (!starts_with(command_buf.buf, "data "))
 		die("Expected 'data n' command, found: %s", command_buf.buf);
 
-	if (!prefixcmp(command_buf.buf + 5, "<<")) {
+	if (starts_with(command_buf.buf + 5, "<<")) {
 		char *term = xstrdup(command_buf.buf + 5 + 2);
 		size_t term_len = command_buf.len - 5 - 2;
 
@@ -2179,7 +2195,7 @@
 			}
 
 			/* Rename fullpath to realpath */
-			if (!tree_content_remove(orig_root, fullpath, &leaf))
+			if (!tree_content_remove(orig_root, fullpath, &leaf, 0))
 				die("Failed to remove path %s", fullpath);
 			tree_content_set(orig_root, realpath,
 				leaf.versions[1].sha1,
@@ -2290,7 +2306,7 @@
 	if (*p == ':') {
 		oe = find_mark(parse_mark_ref_space(&p));
 		hashcpy(sha1, oe->idx.sha1);
-	} else if (!prefixcmp(p, "inline ")) {
+	} else if (starts_with(p, "inline ")) {
 		inline_data = 1;
 		oe = NULL; /* not used with inline_data, but makes gcc happy */
 		p += strlen("inline");  /* advance to space */
@@ -2314,7 +2330,7 @@
 
 	/* Git does not track empty, non-toplevel directories. */
 	if (S_ISDIR(mode) && !memcmp(sha1, EMPTY_TREE_SHA1_BIN, 20) && *p) {
-		tree_content_remove(&b->branch_tree, p, NULL);
+		tree_content_remove(&b->branch_tree, p, NULL, 0);
 		return;
 	}
 
@@ -2375,7 +2391,7 @@
 			die("Garbage after path in: %s", command_buf.buf);
 		p = uq.buf;
 	}
-	tree_content_remove(&b->branch_tree, p, NULL);
+	tree_content_remove(&b->branch_tree, p, NULL, 1);
 }
 
 static void file_change_cr(struct branch *b, int rename)
@@ -2413,9 +2429,9 @@
 
 	memset(&leaf, 0, sizeof(leaf));
 	if (rename)
-		tree_content_remove(&b->branch_tree, s, &leaf);
+		tree_content_remove(&b->branch_tree, s, &leaf, 1);
 	else
-		tree_content_get(&b->branch_tree, s, &leaf);
+		tree_content_get(&b->branch_tree, s, &leaf, 1);
 	if (!leaf.versions[1].mode)
 		die("Path %s not in branch", s);
 	if (!*d) {	/* C "path/to/subdir" "" */
@@ -2463,7 +2479,7 @@
 	if (*p == ':') {
 		oe = find_mark(parse_mark_ref_space(&p));
 		hashcpy(sha1, oe->idx.sha1);
-	} else if (!prefixcmp(p, "inline ")) {
+	} else if (starts_with(p, "inline ")) {
 		inline_data = 1;
 		oe = NULL; /* not used with inline_data, but makes gcc happy */
 		p += strlen("inline");  /* advance to space */
@@ -2478,7 +2494,7 @@
 	assert(*p == ' ');
 	p++;  /* skip space */
 
-	/* <committish> */
+	/* <commit-ish> */
 	s = lookup_branch(p);
 	if (s) {
 		if (is_null_sha1(s->sha1))
@@ -2521,7 +2537,7 @@
 	}
 
 	construct_path_with_fanout(sha1_to_hex(commit_sha1), *old_fanout, path);
-	if (tree_content_remove(&b->branch_tree, path, NULL))
+	if (tree_content_remove(&b->branch_tree, path, NULL, 0))
 		b->num_notes--;
 
 	if (is_null_sha1(sha1))
@@ -2574,7 +2590,7 @@
 	const char *from;
 	struct branch *s;
 
-	if (prefixcmp(command_buf.buf, "from "))
+	if (!starts_with(command_buf.buf, "from "))
 		return 0;
 
 	if (b->branch_tree.tree) {
@@ -2620,7 +2636,7 @@
 	struct branch *s;
 
 	*count = 0;
-	while (!prefixcmp(command_buf.buf, "merge ")) {
+	while (starts_with(command_buf.buf, "merge ")) {
 		from = strchr(command_buf.buf, ' ') + 1;
 		n = xmalloc(sizeof(*n));
 		s = lookup_branch(from);
@@ -2671,11 +2687,11 @@
 
 	read_next_command();
 	parse_mark();
-	if (!prefixcmp(command_buf.buf, "author ")) {
+	if (starts_with(command_buf.buf, "author ")) {
 		author = parse_ident(command_buf.buf + 7);
 		read_next_command();
 	}
-	if (!prefixcmp(command_buf.buf, "committer ")) {
+	if (starts_with(command_buf.buf, "committer ")) {
 		committer = parse_ident(command_buf.buf + 10);
 		read_next_command();
 	}
@@ -2696,19 +2712,19 @@
 
 	/* file_change* */
 	while (command_buf.len > 0) {
-		if (!prefixcmp(command_buf.buf, "M "))
+		if (starts_with(command_buf.buf, "M "))
 			file_change_m(b);
-		else if (!prefixcmp(command_buf.buf, "D "))
+		else if (starts_with(command_buf.buf, "D "))
 			file_change_d(b);
-		else if (!prefixcmp(command_buf.buf, "R "))
+		else if (starts_with(command_buf.buf, "R "))
 			file_change_cr(b, 1);
-		else if (!prefixcmp(command_buf.buf, "C "))
+		else if (starts_with(command_buf.buf, "C "))
 			file_change_cr(b, 0);
-		else if (!prefixcmp(command_buf.buf, "N "))
+		else if (starts_with(command_buf.buf, "N "))
 			note_change_n(b, &prev_fanout);
 		else if (!strcmp("deleteall", command_buf.buf))
 			file_change_deleteall(b);
-		else if (!prefixcmp(command_buf.buf, "ls "))
+		else if (starts_with(command_buf.buf, "ls "))
 			parse_ls(b);
 		else {
 			unread_command_buf = 1;
@@ -2777,7 +2793,7 @@
 	read_next_command();
 
 	/* from ... */
-	if (prefixcmp(command_buf.buf, "from "))
+	if (!starts_with(command_buf.buf, "from "))
 		die("Expected from command, got %s", command_buf.buf);
 	from = strchr(command_buf.buf, ' ') + 1;
 	s = lookup_branch(from);
@@ -2805,7 +2821,7 @@
 	read_next_command();
 
 	/* tagger ... */
-	if (!prefixcmp(command_buf.buf, "tagger ")) {
+	if (starts_with(command_buf.buf, "tagger ")) {
 		tagger = parse_ident(command_buf.buf + 7);
 		read_next_command();
 	} else
@@ -2957,7 +2973,7 @@
 	case OBJ_TAG:
 		break;
 	default:
-		die("Not a treeish: %s", command_buf.buf);
+		die("Not a tree-ish: %s", command_buf.buf);
 	}
 
 	if (oe->pack_id != MAX_PACK_ID) {	/* in a pack being written */
@@ -3041,7 +3057,7 @@
 	struct tree_entry *root = NULL;
 	struct tree_entry leaf = {NULL};
 
-	/* ls SP (<treeish> SP)? <path> */
+	/* ls SP (<tree-ish> SP)? <path> */
 	p = command_buf.buf + strlen("ls ");
 	if (*p == '"') {
 		if (!b)
@@ -3051,6 +3067,8 @@
 		struct object_entry *e = parse_treeish_dataref(&p);
 		root = new_tree_entry();
 		hashcpy(root->versions[1].sha1, e->idx.sha1);
+		if (!is_null_sha1(root->versions[1].sha1))
+			root->versions[1].mode = S_IFDIR;
 		load_tree(root);
 		if (*p++ != ' ')
 			die("Missing space after tree-ish: %s", command_buf.buf);
@@ -3065,7 +3083,7 @@
 			die("Garbage after path in: %s", command_buf.buf);
 		p = uq.buf;
 	}
-	tree_content_get(root, p, &leaf);
+	tree_content_get(root, p, &leaf, 1);
 	/*
 	 * A directory in preparation would have a sha1 of zero
 	 * until it is saved.  Save, for simplicity.
@@ -3191,7 +3209,7 @@
 
 static int parse_one_option(const char *option)
 {
-	if (!prefixcmp(option, "max-pack-size=")) {
+	if (starts_with(option, "max-pack-size=")) {
 		unsigned long v;
 		if (!git_parse_ulong(option + 14, &v))
 			return 0;
@@ -3203,20 +3221,20 @@
 			v = 1024 * 1024;
 		}
 		max_packsize = v;
-	} else if (!prefixcmp(option, "big-file-threshold=")) {
+	} else if (starts_with(option, "big-file-threshold=")) {
 		unsigned long v;
 		if (!git_parse_ulong(option + 19, &v))
 			return 0;
 		big_file_threshold = v;
-	} else if (!prefixcmp(option, "depth=")) {
+	} else if (starts_with(option, "depth=")) {
 		option_depth(option + 6);
-	} else if (!prefixcmp(option, "active-branches=")) {
+	} else if (starts_with(option, "active-branches=")) {
 		option_active_branches(option + 16);
-	} else if (!prefixcmp(option, "export-pack-edges=")) {
+	} else if (starts_with(option, "export-pack-edges=")) {
 		option_export_pack_edges(option + 18);
-	} else if (!prefixcmp(option, "quiet")) {
+	} else if (starts_with(option, "quiet")) {
 		show_stats = 0;
-	} else if (!prefixcmp(option, "stats")) {
+	} else if (starts_with(option, "stats")) {
 		show_stats = 1;
 	} else {
 		return 0;
@@ -3227,14 +3245,14 @@
 
 static int parse_one_feature(const char *feature, int from_stream)
 {
-	if (!prefixcmp(feature, "date-format=")) {
+	if (starts_with(feature, "date-format=")) {
 		option_date_format(feature + 12);
-	} else if (!prefixcmp(feature, "import-marks=")) {
+	} else if (starts_with(feature, "import-marks=")) {
 		option_import_marks(feature + 13, from_stream, 0);
-	} else if (!prefixcmp(feature, "import-marks-if-exists=")) {
+	} else if (starts_with(feature, "import-marks-if-exists=")) {
 		option_import_marks(feature + strlen("import-marks-if-exists="),
 					from_stream, 1);
-	} else if (!prefixcmp(feature, "export-marks=")) {
+	} else if (starts_with(feature, "export-marks=")) {
 		option_export_marks(feature + 13);
 	} else if (!strcmp(feature, "cat-blob")) {
 		; /* Don't die - this feature is supported */
@@ -3332,7 +3350,7 @@
 		if (parse_one_feature(a + 2, 0))
 			continue;
 
-		if (!prefixcmp(a + 2, "cat-blob-fd=")) {
+		if (starts_with(a + 2, "cat-blob-fd=")) {
 			option_cat_blob_fd(a + 2 + strlen("cat-blob-fd="));
 			continue;
 		}
@@ -3386,25 +3404,25 @@
 	while (read_next_command() != EOF) {
 		if (!strcmp("blob", command_buf.buf))
 			parse_new_blob();
-		else if (!prefixcmp(command_buf.buf, "ls "))
+		else if (starts_with(command_buf.buf, "ls "))
 			parse_ls(NULL);
-		else if (!prefixcmp(command_buf.buf, "commit "))
+		else if (starts_with(command_buf.buf, "commit "))
 			parse_new_commit();
-		else if (!prefixcmp(command_buf.buf, "tag "))
+		else if (starts_with(command_buf.buf, "tag "))
 			parse_new_tag();
-		else if (!prefixcmp(command_buf.buf, "reset "))
+		else if (starts_with(command_buf.buf, "reset "))
 			parse_reset_branch();
 		else if (!strcmp("checkpoint", command_buf.buf))
 			parse_checkpoint();
 		else if (!strcmp("done", command_buf.buf))
 			break;
-		else if (!prefixcmp(command_buf.buf, "progress "))
+		else if (starts_with(command_buf.buf, "progress "))
 			parse_progress();
-		else if (!prefixcmp(command_buf.buf, "feature "))
+		else if (starts_with(command_buf.buf, "feature "))
 			parse_feature();
-		else if (!prefixcmp(command_buf.buf, "option git "))
+		else if (starts_with(command_buf.buf, "option git "))
 			parse_option();
-		else if (!prefixcmp(command_buf.buf, "option "))
+		else if (starts_with(command_buf.buf, "option "))
 			/* ignore non-git options*/;
 		else
 			die("Unsupported command: %s", command_buf.buf);
diff --git a/fetch-pack.c b/fetch-pack.c
index aff4f5a..90fdd49 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -9,9 +9,11 @@
 #include "fetch-pack.h"
 #include "remote.h"
 #include "run-command.h"
+#include "connect.h"
 #include "transport.h"
 #include "version.h"
 #include "prio-queue.h"
+#include "sha1-array.h"
 
 static int transfer_unpack_limit = -1;
 static int fetch_unpack_limit = -1;
@@ -46,9 +48,8 @@
 	if (!(commit->object.flags & mark)) {
 		commit->object.flags |= mark;
 
-		if (!(commit->object.parsed))
-			if (parse_commit(commit))
-				return;
+		if (parse_commit(commit))
+			return;
 
 		prio_queue_put(&rev_list, commit);
 
@@ -127,8 +128,7 @@
 			return NULL;
 
 		commit = prio_queue_get(&rev_list);
-		if (!commit->object.parsed)
-			parse_commit(commit);
+		parse_commit(commit);
 		parents = commit->parents;
 
 		commit->object.flags |= POPPED;
@@ -175,9 +175,9 @@
 		 */
 		char *line;
 		while ((line = packet_read_line(fd, NULL))) {
-			if (!prefixcmp(line, "shallow "))
+			if (starts_with(line, "shallow "))
 				continue;
-			if (!prefixcmp(line, "unshallow "))
+			if (starts_with(line, "unshallow "))
 				continue;
 			die("git fetch-pack: expected shallow list");
 		}
@@ -193,7 +193,7 @@
 		die("git fetch-pack: expected ACK/NAK, got EOF");
 	if (!strcmp(line, "NAK"))
 		return NAK;
-	if (!prefixcmp(line, "ACK ")) {
+	if (starts_with(line, "ACK ")) {
 		if (!get_sha1_hex(line+4, result_sha1)) {
 			if (len < 45)
 				return ACK;
@@ -310,7 +310,7 @@
 	}
 
 	if (is_repository_shallow())
-		write_shallow_commits(&req_buf, 1);
+		write_shallow_commits(&req_buf, 1, NULL);
 	if (args->depth > 0)
 		packet_buf_write(&req_buf, "deepen %d", args->depth);
 	packet_buf_flush(&req_buf);
@@ -322,13 +322,13 @@
 
 		send_request(args, fd[1], &req_buf);
 		while ((line = packet_read_line(fd[0], NULL))) {
-			if (!prefixcmp(line, "shallow ")) {
+			if (starts_with(line, "shallow ")) {
 				if (get_sha1_hex(line + 8, sha1))
 					die("invalid shallow line: %s", line);
 				register_shallow(sha1);
 				continue;
 			}
-			if (!prefixcmp(line, "unshallow ")) {
+			if (starts_with(line, "unshallow ")) {
 				if (get_sha1_hex(line + 10, sha1))
 					die("invalid unshallow line: %s", line);
 				if (!lookup_object(sha1))
@@ -506,7 +506,7 @@
 		next = ref->next;
 
 		if (!memcmp(ref->name, "refs/", 5) &&
-		    check_refname_format(ref->name + 5, 0))
+		    check_refname_format(ref->name, 0))
 			; /* trash */
 		else {
 			while (i < nr_sought) {
@@ -522,7 +522,7 @@
 		}
 
 		if (!keep && args->fetch_all &&
-		    (!args->depth || prefixcmp(ref->name, "refs/tags/")))
+		    (!args->depth || !starts_with(ref->name, "refs/tags/")))
 			keep = 1;
 
 		if (keep) {
@@ -658,7 +658,7 @@
 	const char *argv[22];
 	char keep_arg[256];
 	char hdr_arg[256];
-	const char **av;
+	const char **av, *cmd_name;
 	int do_keep = args->keep_pack;
 	struct child_process cmd;
 	int ret;
@@ -705,7 +705,7 @@
 	if (do_keep) {
 		if (pack_lockfile)
 			cmd.out = -1;
-		*av++ = "index-pack";
+		*av++ = cmd_name = "index-pack";
 		*av++ = "--stdin";
 		if (!args->quiet && !args->no_progress)
 			*av++ = "-v";
@@ -722,7 +722,7 @@
 			*av++ = "--check-self-contained-and-connected";
 	}
 	else {
-		*av++ = "unpack-objects";
+		*av++ = cmd_name = "unpack-objects";
 		if (args->quiet || args->no_progress)
 			*av++ = "-q";
 		args->check_self_contained_and_connected = 0;
@@ -740,19 +740,23 @@
 	cmd.in = demux.out;
 	cmd.git_cmd = 1;
 	if (start_command(&cmd))
-		die("fetch-pack: unable to fork off %s", argv[0]);
+		die("fetch-pack: unable to fork off %s", cmd_name);
 	if (do_keep && pack_lockfile) {
 		*pack_lockfile = index_pack_lockfile(cmd.out);
 		close(cmd.out);
 	}
 
+	if (!use_sideband)
+		/* Closed by start_command() */
+		xd[0] = -1;
+
 	ret = finish_command(&cmd);
 	if (!ret || (args->check_self_contained_and_connected && ret == 1))
 		args->self_contained_and_connected =
 			args->check_self_contained_and_connected &&
 			ret == 0;
 	else
-		die("%s failed", argv[0]);
+		die("%s failed", cmd_name);
 	if (use_sideband && finish_async(&demux))
 		die("error in sideband demultiplexer");
 	return 0;
@@ -769,6 +773,7 @@
 				 int fd[2],
 				 const struct ref *orig_ref,
 				 struct ref **sought, int nr_sought,
+				 struct shallow_info *si,
 				 char **pack_lockfile)
 {
 	struct ref *ref = copy_ref_list(orig_ref);
@@ -845,7 +850,10 @@
 	if (args->stateless_rpc)
 		packet_flush(fd[1]);
 	if (args->depth > 0)
-		setup_alternate_shallow(&shallow_lock, &alternate_shallow_file);
+		setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
+					NULL);
+	else if (si->nr_ours || si->nr_theirs)
+		alternate_shallow_file = setup_temporary_shallow(si->shallow);
 	else
 		alternate_shallow_file = NULL;
 	if (get_pack(args, fd, pack_lockfile))
@@ -919,14 +927,121 @@
 	return dst;
 }
 
+static void update_shallow(struct fetch_pack_args *args,
+			   struct ref **sought, int nr_sought,
+			   struct shallow_info *si)
+{
+	struct sha1_array ref = SHA1_ARRAY_INIT;
+	int *status;
+	int i;
+
+	if (args->depth > 0 && alternate_shallow_file) {
+		if (*alternate_shallow_file == '\0') { /* --unshallow */
+			unlink_or_warn(git_path("shallow"));
+			rollback_lock_file(&shallow_lock);
+		} else
+			commit_lock_file(&shallow_lock);
+		return;
+	}
+
+	if (!si->shallow || !si->shallow->nr)
+		return;
+
+	if (alternate_shallow_file) {
+		/*
+		 * The temporary shallow file is only useful for
+		 * index-pack and unpack-objects because it may
+		 * contain more roots than we want. Delete it.
+		 */
+		if (*alternate_shallow_file)
+			unlink(alternate_shallow_file);
+		free((char *)alternate_shallow_file);
+	}
+
+	if (args->cloning) {
+		/*
+		 * remote is shallow, but this is a clone, there are
+		 * no objects in repo to worry about. Accept any
+		 * shallow points that exist in the pack (iow in repo
+		 * after get_pack() and reprepare_packed_git())
+		 */
+		struct sha1_array extra = SHA1_ARRAY_INIT;
+		unsigned char (*sha1)[20] = si->shallow->sha1;
+		for (i = 0; i < si->shallow->nr; i++)
+			if (has_sha1_file(sha1[i]))
+				sha1_array_append(&extra, sha1[i]);
+		if (extra.nr) {
+			setup_alternate_shallow(&shallow_lock,
+						&alternate_shallow_file,
+						&extra);
+			commit_lock_file(&shallow_lock);
+		}
+		sha1_array_clear(&extra);
+		return;
+	}
+
+	if (!si->nr_ours && !si->nr_theirs)
+		return;
+
+	remove_nonexistent_theirs_shallow(si);
+	if (!si->nr_ours && !si->nr_theirs)
+		return;
+	for (i = 0; i < nr_sought; i++)
+		sha1_array_append(&ref, sought[i]->old_sha1);
+	si->ref = &ref;
+
+	if (args->update_shallow) {
+		/*
+		 * remote is also shallow, .git/shallow may be updated
+		 * so all refs can be accepted. Make sure we only add
+		 * shallow roots that are actually reachable from new
+		 * refs.
+		 */
+		struct sha1_array extra = SHA1_ARRAY_INIT;
+		unsigned char (*sha1)[20] = si->shallow->sha1;
+		assign_shallow_commits_to_refs(si, NULL, NULL);
+		if (!si->nr_ours && !si->nr_theirs) {
+			sha1_array_clear(&ref);
+			return;
+		}
+		for (i = 0; i < si->nr_ours; i++)
+			sha1_array_append(&extra, sha1[si->ours[i]]);
+		for (i = 0; i < si->nr_theirs; i++)
+			sha1_array_append(&extra, sha1[si->theirs[i]]);
+		setup_alternate_shallow(&shallow_lock,
+					&alternate_shallow_file,
+					&extra);
+		commit_lock_file(&shallow_lock);
+		sha1_array_clear(&extra);
+		sha1_array_clear(&ref);
+		return;
+	}
+
+	/*
+	 * remote is also shallow, check what ref is safe to update
+	 * without updating .git/shallow
+	 */
+	status = xcalloc(nr_sought, sizeof(*status));
+	assign_shallow_commits_to_refs(si, NULL, status);
+	if (si->nr_ours || si->nr_theirs) {
+		for (i = 0; i < nr_sought; i++)
+			if (status[i])
+				sought[i]->status = REF_STATUS_REJECT_SHALLOW;
+	}
+	free(status);
+	sha1_array_clear(&ref);
+}
+
 struct ref *fetch_pack(struct fetch_pack_args *args,
 		       int fd[], struct child_process *conn,
 		       const struct ref *ref,
 		       const char *dest,
 		       struct ref **sought, int nr_sought,
+		       struct sha1_array *shallow,
 		       char **pack_lockfile)
 {
 	struct ref *ref_cpy;
+	struct shallow_info si;
 
 	fetch_pack_setup();
 	if (nr_sought)
@@ -936,16 +1051,11 @@
 		packet_flush(fd[1]);
 		die("no matching remote head");
 	}
-	ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, pack_lockfile);
-
-	if (args->depth > 0 && alternate_shallow_file) {
-		if (*alternate_shallow_file == '\0') { /* --unshallow */
-			unlink_or_warn(git_path("shallow"));
-			rollback_lock_file(&shallow_lock);
-		} else
-			commit_lock_file(&shallow_lock);
-	}
-
+	prepare_shallow_info(&si, shallow);
+	ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
+				&si, pack_lockfile);
 	reprepare_packed_git();
+	update_shallow(args, sought, nr_sought, &si);
+	clear_shallow_info(&si);
 	return ref_cpy;
 }
diff --git a/fetch-pack.h b/fetch-pack.h
index 40f08ba..bb7fd76 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -2,23 +2,29 @@
 #define FETCH_PACK_H
 
 #include "string-list.h"
+#include "run-command.h"
+
+struct sha1_array;
 
 struct fetch_pack_args {
 	const char *uploadpack;
 	int unpacklimit;
 	int depth;
-	unsigned quiet:1,
-		keep_pack:1,
-		lock_pack:1,
-		use_thin_pack:1,
-		fetch_all:1,
-		stdin_refs:1,
-		verbose:1,
-		no_progress:1,
-		include_tag:1,
-		stateless_rpc:1,
-		check_self_contained_and_connected:1,
-		self_contained_and_connected:1;
+	unsigned quiet:1;
+	unsigned keep_pack:1;
+	unsigned lock_pack:1;
+	unsigned use_thin_pack:1;
+	unsigned fetch_all:1;
+	unsigned stdin_refs:1;
+	unsigned diag_url:1;
+	unsigned verbose:1;
+	unsigned no_progress:1;
+	unsigned include_tag:1;
+	unsigned stateless_rpc:1;
+	unsigned check_self_contained_and_connected:1;
+	unsigned self_contained_and_connected:1;
+	unsigned cloning:1;
+	unsigned update_shallow:1;
 };
 
 /*
@@ -32,6 +38,7 @@
 		       const char *dest,
 		       struct ref **sought,
 		       int nr_sought,
+		       struct sha1_array *shallow,
 		       char **pack_lockfile);
 
 #endif
diff --git a/gettext.c b/gettext.c
index 71e9545..8b2da46 100644
--- a/gettext.c
+++ b/gettext.c
@@ -29,6 +29,17 @@
 #endif
 
 #ifndef NO_GETTEXT
+static int test_vsnprintf(const char *fmt, ...)
+{
+	char buf[26];
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsnprintf(buf, sizeof(buf), fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
 static const char *charset;
 static void init_gettext_charset(const char *domain)
 {
@@ -99,9 +110,7 @@
 	   $ LANGUAGE= LANG=de_DE.utf8 ./test
 	   test: Kein passendes Ger?t gefunden
 
-	   In the long term we should probably see about getting that
-	   vsnprintf bug in glibc fixed, and audit our code so it won't
-	   fall apart under a non-C locale.
+	   The vsnprintf bug has been fixed since glibc 2.17.
 
 	   Then we could simply set LC_CTYPE from the environment, which would
 	   make things like the external perror(3) messages work.
@@ -115,7 +124,9 @@
 	setlocale(LC_CTYPE, "");
 	charset = locale_charset();
 	bind_textdomain_codeset(domain, charset);
-	setlocale(LC_CTYPE, "C");
+	/* the string is taken from v0.99.6~1 */
+	if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
+		setlocale(LC_CTYPE, "C");
 }
 
 void git_setup_gettext(void)
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 5156384..24bb1ab 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -263,6 +263,17 @@
 	return '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
 }
 
+sub get_diff_reference {
+	my $ref = shift;
+	if (defined $ref and $ref ne 'HEAD') {
+		return $ref;
+	} elsif (is_initial_commit()) {
+		return get_empty_tree();
+	} else {
+		return 'HEAD';
+	}
+}
+
 # Returns list of hashes, contents of each of which are:
 # VALUE:	pathname
 # BINARY:	is a binary path
@@ -286,14 +297,7 @@
 		return if (!@tracked);
 	}
 
-	my $reference;
-	if (defined $patch_mode_revision and $patch_mode_revision ne 'HEAD') {
-		$reference = $patch_mode_revision;
-	} elsif (is_initial_commit()) {
-		$reference = get_empty_tree();
-	} else {
-		$reference = 'HEAD';
-	}
+	my $reference = get_diff_reference($patch_mode_revision);
 	for (run_cmd_pipe(qw(git diff-index --cached
 			     --numstat --summary), $reference,
 			     '--', @tracked)) {
@@ -737,7 +741,7 @@
 		splice @diff_cmd, 1, 0, "--diff-algorithm=${diff_algorithm}";
 	}
 	if (defined $patch_mode_revision) {
-		push @diff_cmd, $patch_mode_revision;
+		push @diff_cmd, get_diff_reference($patch_mode_revision);
 	}
 	my @diff = run_cmd_pipe("git", @diff_cmd, "--", $path);
 	my @colored = ();
diff --git a/git-am.sh b/git-am.sh
index 7ea40fe..bbea430 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -302,7 +302,7 @@
 			# not starting with Author, From or Date is the
 			# subject, and the body starts with the next nonempty
 			# line not starting with Author, From or Date
-			perl -ne 'BEGIN { $subject = 0 }
+			@@PERL@@ -ne 'BEGIN { $subject = 0 }
 				if ($subject > 1) { print ; }
 				elsif (/^\s+$/) { next ; }
 				elsif (/^Author:/) { s/Author/From/ ; print ;}
@@ -334,7 +334,7 @@
 			# Since we cannot guarantee that the commit message is in
 			# git-friendly format, we put no Subject: line and just consume
 			# all of the message as the body
-			LANG=C LC_ALL=C perl -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
+			LANG=C LC_ALL=C @@PERL@@ -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
 				if ($subject) { print ; }
 				elsif (/^\# User /) { s/\# User/From:/ ; print ; }
 				elsif (/^\# Date /) {
diff --git a/git-bisect.sh b/git-bisect.sh
index 9f064b6..73b4c14 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -137,7 +137,7 @@
 			# cogito usage, and cogito users should understand
 			# it relates to cg-seek.
 			[ -s "$GIT_DIR/head-name" ] &&
-				die "$(gettext "won't bisect on seeked tree")"
+				die "$(gettext "won't bisect on cg-seek'ed tree")"
 			start_head="${head#refs/heads/}"
 			;;
 		*)
diff --git a/git-compat-util.h b/git-compat-util.h
index 96d8881..cbd86c3 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -75,7 +75,7 @@
 # endif
 #elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && \
       !defined(_M_UNIX) && !defined(__sgi) && !defined(__DragonFly__) && \
-      !defined(__TANDEM) && !defined(__QNX__)
+      !defined(__TANDEM) && !defined(__QNX__) && !defined(__MirBSD__)
 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
 #endif
@@ -86,7 +86,7 @@
 #define _SGI_SOURCE 1
 
 #if defined(WIN32) && !defined(__CYGWIN__) /* Both MinGW and MSVC */
-# if defined (_MSC_VER)
+# if defined (_MSC_VER) && !defined(_WIN32_WINNT)
 #  define _WIN32_WINNT 0x0502
 # endif
 #define WIN32_LEAN_AND_MEAN  /* stops windows.h including winsock.h */
@@ -325,6 +325,16 @@
 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
+#ifndef NO_OPENSSL
+#ifdef APPLE_COMMON_CRYPTO
+#include "compat/apple-common-crypto.h"
+#else
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#endif /* APPLE_COMMON_CRYPTO */
+#include <openssl/x509v3.h>
+#endif /* NO_OPENSSL */
+
 /*
  * Let callers be aware of the constant return value; this can help
  * gcc with -Wuninitialized analysis. We restrict this trick to gcc, though,
@@ -340,7 +350,9 @@
 extern void set_error_routine(void (*routine)(const char *err, va_list params));
 extern void set_die_is_recursing_routine(int (*routine)(void));
 
+extern int starts_with(const char *str, const char *prefix);
 extern int prefixcmp(const char *str, const char *prefix);
+extern int ends_with(const char *str, const char *suffix);
 extern int suffixcmp(const char *str, const char *suffix);
 
 static inline const char *skip_prefix(const char *str, const char *prefix)
@@ -509,7 +521,7 @@
 const char *inet_ntop(int af, const void *src, char *dst, size_t size);
 #endif
 
-extern void release_pack_memory(size_t, int);
+extern void release_pack_memory(size_t);
 
 typedef void (*try_to_free_t)(size_t);
 extern try_to_free_t set_try_to_free_routine(try_to_free_t);
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index 67b1e7b..95e69b1 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -430,10 +430,10 @@
 
     $log->debug("req_validrequests");
 
-    $log->debug("SEND : Valid-requests " . join(" ",keys %$methods));
+    $log->debug("SEND : Valid-requests " . join(" ",sort keys %$methods));
     $log->debug("SEND : ok");
 
-    print "Valid-requests " . join(" ",keys %$methods) . "\n";
+    print "Valid-requests " . join(" ",sort keys %$methods) . "\n";
     print "ok\n";
 }
 
@@ -2124,7 +2124,7 @@
             print "M retrieving revision $meta2->{revision}\n"
         }
         print "M diff ";
-        foreach my $opt ( keys %{$state->{opt}} )
+        foreach my $opt ( sort keys %{$state->{opt}} )
         {
             if ( ref $state->{opt}{$opt} eq "ARRAY" )
             {
@@ -4050,7 +4050,7 @@
             close FILELIST;
 
             # Detect deleted files
-            foreach my $file ( keys %$head )
+            foreach my $file ( sort keys %$head )
             {
                 unless ( exists $seen_files->{$file} or $head->{$file}{filehash} eq "deleted" )
                 {
@@ -4078,7 +4078,7 @@
     }
 
     $self->delete_head();
-    foreach my $file ( keys %$head )
+    foreach my $file ( sort keys %$head )
     {
         $self->insert_head(
             $file,
@@ -4338,7 +4338,7 @@
 =head2 getRevisionDirMap
 
 A "revision dir map" contains all the plain-file filenames associated
-with a particular revision (treeish), organized by directory:
+with a particular revision (tree-ish), organized by directory:
 
   $type = $out->{$dir}{$fullName}
 
diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index b00ed95..7ef36b9 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -40,7 +40,8 @@
 	# the user with the real $MERGED name before launching $merge_tool.
 	if should_prompt
 	then
-		printf "\nViewing: '%s'\n" "$MERGED"
+		printf "\nViewing (%s/%s): '%s'\n" "$GIT_DIFF_PATH_COUNTER" \
+			"$GIT_DIFF_PATH_TOTAL" "$MERGED"
 		if use_ext_cmd
 		then
 			printf "Launch '%s' [Y/n]: " \
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index ac2a005..86d6994 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -255,7 +255,7 @@
 	remap_to_ancestor=t
 fi
 
-rev_args=$(git rev-parse --revs-only "$@")
+git rev-parse --revs-only "$@" >../parse
 
 case "$filter_subdir" in
 "")
@@ -268,7 +268,7 @@
 esac
 
 git rev-list --reverse --topo-order --default HEAD \
-	--parents --simplify-merges $rev_args "$@" > ../revs ||
+	--parents --simplify-merges --stdin "$@" <../parse >../revs ||
 	die "Could not get the commits"
 commits=$(wc -l <../revs | tr -d " ")
 
@@ -283,11 +283,12 @@
 
 	case "$filter_subdir" in
 	"")
-		git read-tree -i -m $commit
+		GIT_ALLOW_NULL_SHA1=1 git read-tree -i -m $commit
 		;;
 	*)
 		# The commit may not have the subdirectory at all
-		err=$(git read-tree -i -m $commit:"$filter_subdir" 2>&1) || {
+		err=$(GIT_ALLOW_NULL_SHA1=1 \
+		      git read-tree -i -m $commit:"$filter_subdir" 2>&1) || {
 			if ! git rev-parse -q --verify $commit:"$filter_subdir"
 			then
 				rm -f "$GIT_INDEX_FILE"
diff --git a/git-gui/GIT-VERSION-GEN b/git-gui/GIT-VERSION-GEN
index 0a1f8d4..a9ea218 100755
--- a/git-gui/GIT-VERSION-GEN
+++ b/git-gui/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=0.18.GITGUI
+DEF_VER=0.19.GITGUI
 
 LF='
 '
diff --git a/git-gui/Makefile b/git-gui/Makefile
index e9c2bc3..cde8b2e 100644
--- a/git-gui/Makefile
+++ b/git-gui/Makefile
@@ -4,7 +4,7 @@
 #
 # Define NO_MSGFMT if you do not have msgfmt from the GNU gettext
 # package and want to use our rough pure Tcl po->msg translator.
-# TCL_PATH must be vaild for this to work.
+# TCL_PATH must be valid for this to work.
 #
 
 GIT-VERSION-FILE: FORCE
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index 153f85d..cf2209b 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -894,6 +894,7 @@
 set default_config(gui.pruneduringfetch) false
 set default_config(gui.trustmtime) false
 set default_config(gui.fastcopyblame) false
+set default_config(gui.maxrecentrepo) 10
 set default_config(gui.copyblamethreshold) 40
 set default_config(gui.blamehistoryctx) 7
 set default_config(gui.diffcontext) 5
@@ -912,6 +913,7 @@
 	{fontdiff font_diff {mc "Diff/Console Font"}}
 }
 set default_config(gui.stageuntracked) ask
+set default_config(gui.displayuntracked) true
 
 ######################################################################
 ##
@@ -1282,7 +1284,11 @@
 
 # v1.7.0 introduced --show-toplevel to return the canonical work-tree
 if {[package vsatisfies $_git_version 1.7.0]} {
-	set _gitworktree [git rev-parse --show-toplevel]
+	if { [is_Cygwin] } {
+		catch {set _gitworktree [exec cygpath --windows [git rev-parse --show-toplevel]]}
+	} else {
+		set _gitworktree [git rev-parse --show-toplevel]
+	}
 } else {
 	# try to set work tree from environment, core.worktree or use
 	# cdup to obtain a relative path to the top of the worktree. If
@@ -1550,18 +1556,23 @@
 	set buf_rdf {}
 	set buf_rlo {}
 
-	set rescan_active 3
+	set rescan_active 2
 	ui_status [mc "Scanning for modified files ..."]
 	set fd_di [git_read diff-index --cached -z [PARENT]]
 	set fd_df [git_read diff-files -z]
-	set fd_lo [eval git_read ls-files --others -z $ls_others]
 
 	fconfigure $fd_di -blocking 0 -translation binary -encoding binary
 	fconfigure $fd_df -blocking 0 -translation binary -encoding binary
-	fconfigure $fd_lo -blocking 0 -translation binary -encoding binary
+
 	fileevent $fd_di readable [list read_diff_index $fd_di $after]
 	fileevent $fd_df readable [list read_diff_files $fd_df $after]
-	fileevent $fd_lo readable [list read_ls_others $fd_lo $after]
+
+	if {[is_config_true gui.displayuntracked]} {
+		set fd_lo [eval git_read ls-files --others -z $ls_others]
+		fconfigure $fd_lo -blocking 0 -translation binary -encoding binary
+		fileevent $fd_lo readable [list read_ls_others $fd_lo $after]
+		incr rescan_active
+	}
 }
 
 proc load_message {file {encoding {}}} {
@@ -2654,6 +2665,16 @@
 	.mbar.repository add command \
 		-label [mc "Explore Working Copy"] \
 		-command {do_explore}
+}
+
+if {[is_Windows]} {
+	.mbar.repository add command \
+		-label [mc "Git Bash"] \
+		-command {eval exec [auto_execok start] \
+					  [list "Git Bash" bash --login -l &]}
+}
+
+if {[is_Windows] || ![is_bare]} {
 	.mbar.repository add separator
 }
 
@@ -3203,13 +3224,29 @@
 
 # -- Diff and Commit Area
 #
-${NS}::frame .vpane.lower -height 300 -width 400
-${NS}::frame .vpane.lower.commarea
-${NS}::frame .vpane.lower.diff -relief sunken -borderwidth 1
-pack .vpane.lower.diff -fill both -expand 1
-pack .vpane.lower.commarea -side bottom -fill x
-.vpane add .vpane.lower
-if {!$use_ttk} {.vpane paneconfigure .vpane.lower -sticky nsew}
+if {$have_tk85} {
+	${NS}::panedwindow .vpane.lower -orient vertical
+	${NS}::frame .vpane.lower.commarea
+	${NS}::frame .vpane.lower.diff -relief sunken -borderwidth 1 -height 500
+	.vpane.lower add .vpane.lower.diff
+	.vpane.lower add .vpane.lower.commarea
+	.vpane add .vpane.lower
+	if {$use_ttk} {
+		.vpane.lower pane .vpane.lower.diff -weight 1
+		.vpane.lower pane .vpane.lower.commarea -weight 0
+	} else {
+		.vpane.lower paneconfigure .vpane.lower.diff -stretch always
+		.vpane.lower paneconfigure .vpane.lower.commarea -stretch never
+	}
+} else {
+	frame .vpane.lower -height 300 -width 400
+	frame .vpane.lower.commarea
+	frame .vpane.lower.diff -relief sunken -borderwidth 1
+	pack .vpane.lower.diff -fill both -expand 1
+	pack .vpane.lower.commarea -side bottom -fill x
+	.vpane add .vpane.lower
+	.vpane paneconfigure .vpane.lower -sticky nsew
+}
 
 # -- Commit Area Buttons
 #
diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl
index 324f774..b1d15f4 100644
--- a/git-gui/lib/blame.tcl
+++ b/git-gui/lib/blame.tcl
@@ -5,7 +5,7 @@
 
 image create photo ::blame::img_back_arrow -data {R0lGODlhGAAYAIUAAPwCBEzKXFTSZIz+nGzmhGzqfGTidIT+nEzGXHTqhGzmfGzifFzadETCVES+VARWDFzWbHzyjAReDGTadFTOZDSyRDyyTCymPARaFGTedFzSbDy2TCyqRCyqPARaDAyCHES6VDy6VCyiPAR6HCSeNByWLARyFARiDARqFGTifARiFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAYABgAAAajQIBwSCwaj8ikcsk0BppJwRPqHEypQwHBis0WDAdEFyBIKBaMAKLBdjQeSkFBYTBAIvgEoS6JmhUTEwIUDQ4VFhcMGEhyCgoZExoUaxsWHB0THkgfAXUGAhoBDSAVFR0XBnCbDRmgog0hpSIiDJpJIyEQhBUcJCIlwA22SSYVogknEg8eD82qSigdDSknY0IqJQXPYxIl1dZCGNvWw+Dm510GQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
 
-# Persistant data (survives loads)
+# Persistent data (survives loads)
 #
 field history {}; # viewer history: {commit path}
 field header    ; # array commit,key -> header field
diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl
index ee58981..3c10bc6 100644
--- a/git-gui/lib/choose_repository.tcl
+++ b/git-gui/lib/choose_repository.tcl
@@ -24,6 +24,10 @@
 constructor pick {} {
 	global M1T M1B use_ttk NS
 
+	if {[set maxrecent [get_config gui.maxrecentrepo]] eq {}} {
+		set maxrecent 10
+	}
+
 	make_dialog top w
 	wm title $top [mc "Git Gui"]
 
@@ -148,7 +152,7 @@
 			-background [get_bg_color $w_body.recentlabel] \
 			-wrap none \
 			-width 50 \
-			-height 10
+			-height $maxrecent
 		$w_recentlist tag conf link \
 			-foreground blue \
 			-underline 1
@@ -264,7 +268,11 @@
 	git config --global --add gui.recentrepo $path
 	load_config 1
 
-	while {[llength $recent] > 10} {
+	if {[set maxrecent [get_config gui.maxrecentrepo]] eq {}} {
+		set maxrecent 10
+	}
+
+	while {[llength $recent] > $maxrecent} {
 		_unset_recentrepo [lindex $recent 0]
 		set recent [lrange $recent 1 end]
 	}
diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl
index 8efbbdd..74a81a7 100644
--- a/git-gui/lib/index.tcl
+++ b/git-gui/lib/index.tcl
@@ -414,7 +414,7 @@
 	# such distinction is needed in some languages. Previously, the
 	# code used "Revert changes in" for both, but that can't work
 	# in languages where 'in' must be combined with word from
-	# rest of string (in diffrent way for both cases of course).
+	# rest of string (in different way for both cases of course).
 	#
 	# FIXME: Unfortunately, even that isn't enough in some languages
 	# as they have quite complex plural-form rules. Unfortunately,
diff --git a/git-gui/lib/option.tcl b/git-gui/lib/option.tcl
index 0cf1da1..23c9ae7 100644
--- a/git-gui/lib/option.tcl
+++ b/git-gui/lib/option.tcl
@@ -150,6 +150,7 @@
 		{b gui.matchtrackingbranch {mc "Match Tracking Branches"}}
 		{b gui.textconv {mc "Use Textconv For Diffs and Blames"}}
 		{b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}}
+		{i-0..100 gui.maxrecentrepo {mc "Maximum Length of Recent Repositories List"}}
 		{i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}
 		{i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}}
 		{i-1..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
@@ -159,6 +160,7 @@
 		{c gui.encoding {mc "Default File Contents Encoding"}}
 		{b gui.warndetachedcommit {mc "Warn before committing to a detached head"}}
 		{s gui.stageuntracked {mc "Staging of untracked files"} {list "yes" "no" "ask"}}
+		{b gui.displayuntracked {mc "Show untracked files"}}
 		} {
 		set type [lindex $option 0]
 		set name [lindex $option 1]
diff --git a/git-gui/lib/spellcheck.tcl b/git-gui/lib/spellcheck.tcl
index e612030..538d61c 100644
--- a/git-gui/lib/spellcheck.tcl
+++ b/git-gui/lib/spellcheck.tcl
@@ -14,7 +14,7 @@
 field s_menuidx 0 ; # last index of insertion into $w_menu
 
 field s_i           {} ; # timer registration for _run callbacks
-field s_clear        0 ; # did we erase mispelled tags yet?
+field s_clear        0 ; # did we erase misspelled tags yet?
 field s_seen    [list] ; # lines last seen from $w_text in _run
 field s_checked [list] ; # lines already checked
 field s_pending [list] ; # [$line $data] sent to ispell/aspell
@@ -259,7 +259,7 @@
 		if {$n == $cur_line
 		 && ![regexp {^\W$} [$w_text get $cur_pos insert]]} {
 
-			# If the current word is mispelled remove the tag
+			# If the current word is misspelled remove the tag
 			# but force a spellcheck later.
 			#
 			set tags [$w_text tag names $cur_pos]
diff --git a/git-gui/macosx/Info.plist b/git-gui/macosx/Info.plist
index b3bf15f..1ade121 100644
--- a/git-gui/macosx/Info.plist
+++ b/git-gui/macosx/Info.plist
@@ -24,5 +24,7 @@
 	<string>GITg</string>
 	<key>CFBundleVersion</key>
 	<string>@@GITGUI_VERSION@@</string>
+	<key>NSHighResolutionCapable</key>
+	<true/>
 </dict>
 </plist>
diff --git a/git-gui/po/bg.po b/git-gui/po/bg.po
new file mode 100644
index 0000000..89b3a4e
--- /dev/null
+++ b/git-gui/po/bg.po
@@ -0,0 +1,2694 @@
+# Bulgarian translation of git-gui po-file.
+# Copyright (C) 2012, 2013, 2014 Alexander Shopov <ash@kambanaria.org>.
+# This file is distributed under the same license as the git package.
+# Alexander Shopov <ash@kambanaria.org>, 2012, 2013, 2014.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui master\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-01-13 20:45+0200\n"
+"PO-Revision-Date: 2014-01-13 21:31+0200\n"
+"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
+"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
+"Language: bg\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: git-gui.sh:859
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "Указан е неправилен шрифт в %s:"
+
+#: git-gui.sh:912
+msgid "Main Font"
+msgstr "Основен шрифт"
+
+#: git-gui.sh:913
+msgid "Diff/Console Font"
+msgstr "Шрифт за разликите/конзолата"
+
+#: git-gui.sh:928 git-gui.sh:942 git-gui.sh:955 git-gui.sh:1045
+#: git-gui.sh:1064 git-gui.sh:3115
+msgid "git-gui: fatal error"
+msgstr "git-gui: фатална грешка"
+
+#: git-gui.sh:929
+msgid "Cannot find git in PATH."
+msgstr "Командата git липсва в пътя (PATH)."
+
+#: git-gui.sh:956
+msgid "Cannot parse Git version string:"
+msgstr "Низът с версията на Git не може да бъде интерпретиран:"
+
+#: git-gui.sh:981
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"Версията на Git не може да бъде определена.\n"
+"\n"
+"Версията на %s изглежда, че е „%s“.\n"
+"\n"
+"%s изисква Git, версия поне 1.5.0.\n"
+"\n"
+"Да се приеме ли, че „%s“ е версия 1.5.0?\n"
+
+#: git-gui.sh:1278
+msgid "Git directory not found:"
+msgstr "Директорията на Git не е открита:"
+
+#: git-gui.sh:1312
+msgid "Cannot move to top of working directory:"
+msgstr "Не може да се премине към родителската  директория."
+
+#: git-gui.sh:1320
+msgid "Cannot use bare repository:"
+msgstr "Голо хранилище не може да се използва:"
+
+#: git-gui.sh:1328
+msgid "No working directory"
+msgstr "Работната директория липсва"
+
+#: git-gui.sh:1500 lib/checkout_op.tcl:306
+msgid "Refreshing file status..."
+msgstr "Обновяване на състоянието на файла…"
+
+#: git-gui.sh:1560
+msgid "Scanning for modified files ..."
+msgstr "Проверка за променени файлове…"
+
+#: git-gui.sh:1632
+msgid "Calling prepare-commit-msg hook..."
+msgstr "Куката prepare-commit-msg се изпълнява в момента…"
+
+#: git-gui.sh:1649
+msgid "Commit declined by prepare-commit-msg hook."
+msgstr "Подаването е отхвърлено от куката prepare-commit-msg."
+
+#: git-gui.sh:1807 lib/browser.tcl:252
+msgid "Ready."
+msgstr "Готово."
+
+#: git-gui.sh:1965
+#, tcl-format
+msgid "Displaying only %s of %s files."
+msgstr "Показване на само %s от %s файла."
+
+#: git-gui.sh:2091
+msgid "Unmodified"
+msgstr "Непроменен"
+
+#: git-gui.sh:2093
+msgid "Modified, not staged"
+msgstr "Променен, но не е в индекса"
+
+#: git-gui.sh:2094 git-gui.sh:2106
+msgid "Staged for commit"
+msgstr "В индекса за подаване"
+
+#: git-gui.sh:2095 git-gui.sh:2107
+msgid "Portions staged for commit"
+msgstr "Части са в индекса за подаване"
+
+#: git-gui.sh:2096 git-gui.sh:2108
+msgid "Staged for commit, missing"
+msgstr "В индекса за подаване, но липсва"
+
+#: git-gui.sh:2098
+msgid "File type changed, not staged"
+msgstr "Видът на файла е сменен, но не е в индекса"
+
+#: git-gui.sh:2099 git-gui.sh:2100
+msgid "File type changed, old type staged for commit"
+msgstr "Видът на файла е сменен, в индекса е старият"
+
+#: git-gui.sh:2101
+msgid "File type changed, staged"
+msgstr "Видът на файла е сменен и е в индекса"
+
+#: git-gui.sh:2102
+msgid "File type change staged, modification not staged"
+msgstr "Видът на файла е сменен, промяната не е в индекса"
+
+#: git-gui.sh:2103
+msgid "File type change staged, file missing"
+msgstr "Видът на файла е сменен, файлът липсва"
+
+#: git-gui.sh:2105
+msgid "Untracked, not staged"
+msgstr "Неследен"
+
+#: git-gui.sh:2110
+msgid "Missing"
+msgstr "Липсващ"
+
+#: git-gui.sh:2111
+msgid "Staged for removal"
+msgstr "В индекса за изтриване"
+
+#: git-gui.sh:2112
+msgid "Staged for removal, still present"
+msgstr "В индекса за изтриване, но още го има"
+
+#: git-gui.sh:2114 git-gui.sh:2115 git-gui.sh:2116 git-gui.sh:2117
+#: git-gui.sh:2118 git-gui.sh:2119
+msgid "Requires merge resolution"
+msgstr "Изисква коригиране при сливане"
+
+#: git-gui.sh:2154
+msgid "Starting gitk... please wait..."
+msgstr "Стартиране на gitk…, изчакайте…"
+
+#: git-gui.sh:2166
+msgid "Couldn't find gitk in PATH"
+msgstr "В пътищата, определени от променливата PATH, липсва изпълним gitk"
+
+#: git-gui.sh:2225
+msgid "Couldn't find git gui in PATH"
+msgstr "В пътищата, определени от променливата PATH, липсва изпълним git gui"
+
+#: git-gui.sh:2644 lib/choose_repository.tcl:40
+msgid "Repository"
+msgstr "Хранилище"
+
+#: git-gui.sh:2645
+msgid "Edit"
+msgstr "Редактиране"
+
+#: git-gui.sh:2647 lib/choose_rev.tcl:567
+msgid "Branch"
+msgstr "Клон"
+
+#: git-gui.sh:2650 lib/choose_rev.tcl:554
+msgid "Commit@@noun"
+msgstr "Подаване"
+
+#: git-gui.sh:2653 lib/merge.tcl:123 lib/merge.tcl:152 lib/merge.tcl:170
+msgid "Merge"
+msgstr "Сливане"
+
+#: git-gui.sh:2654 lib/choose_rev.tcl:563
+msgid "Remote"
+msgstr "Отдалечено хранилище"
+
+#: git-gui.sh:2657
+msgid "Tools"
+msgstr "Команди"
+
+#: git-gui.sh:2666
+msgid "Explore Working Copy"
+msgstr "Разглеждане на работното копие"
+
+#: git-gui.sh:2672
+msgid "Git Bash"
+msgstr "Bash на Git"
+
+#: git-gui.sh:2682
+msgid "Browse Current Branch's Files"
+msgstr "Разглеждане на файловете в текущия клон"
+
+#: git-gui.sh:2686
+msgid "Browse Branch Files..."
+msgstr "Разглеждане на текущия клон"
+
+#: git-gui.sh:2691
+msgid "Visualize Current Branch's History"
+msgstr "Визуализация на историята на текущия клон"
+
+#: git-gui.sh:2695
+msgid "Visualize All Branch History"
+msgstr "Визуализация на историята на всички клонове"
+
+#: git-gui.sh:2702
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr "Разглеждане на файловете в %s"
+
+#: git-gui.sh:2704
+#, tcl-format
+msgid "Visualize %s's History"
+msgstr "Визуализация на историята на %s"
+
+#: git-gui.sh:2709 lib/database.tcl:40 lib/database.tcl:66
+msgid "Database Statistics"
+msgstr "Статистика на базата от данни"
+
+#: git-gui.sh:2712 lib/database.tcl:33
+msgid "Compress Database"
+msgstr "Компресиране на базата от данни"
+
+#: git-gui.sh:2715
+msgid "Verify Database"
+msgstr "Проверка на базата от данни"
+
+#: git-gui.sh:2722 git-gui.sh:2726 git-gui.sh:2730 lib/shortcut.tcl:8
+#: lib/shortcut.tcl:40 lib/shortcut.tcl:72
+msgid "Create Desktop Icon"
+msgstr "Добавяне на икона на работния плот"
+
+#: git-gui.sh:2738 lib/choose_repository.tcl:192 lib/choose_repository.tcl:200
+msgid "Quit"
+msgstr "Спиране на програмата"
+
+#: git-gui.sh:2746
+msgid "Undo"
+msgstr "Отмяна"
+
+#: git-gui.sh:2749
+msgid "Redo"
+msgstr "Повторение"
+
+#: git-gui.sh:2753 git-gui.sh:3348
+msgid "Cut"
+msgstr "Отрязване"
+
+#: git-gui.sh:2756 git-gui.sh:3351 git-gui.sh:3425 git-gui.sh:3510
+#: lib/console.tcl:69
+msgid "Copy"
+msgstr "Копиране"
+
+#: git-gui.sh:2759 git-gui.sh:3354
+msgid "Paste"
+msgstr "Поставяне"
+
+#: git-gui.sh:2762 git-gui.sh:3357 lib/remote_branch_delete.tcl:39
+#: lib/branch_delete.tcl:28
+msgid "Delete"
+msgstr "Изтриване"
+
+#: git-gui.sh:2766 git-gui.sh:3361 git-gui.sh:3514 lib/console.tcl:71
+msgid "Select All"
+msgstr "Избиране на всичко"
+
+#: git-gui.sh:2775
+msgid "Create..."
+msgstr "Създаване…"
+
+#: git-gui.sh:2781
+msgid "Checkout..."
+msgstr "Изтегляне…"
+
+#: git-gui.sh:2787
+msgid "Rename..."
+msgstr "Преименуване…"
+
+#: git-gui.sh:2792
+msgid "Delete..."
+msgstr "Изтриване…"
+
+#: git-gui.sh:2797
+msgid "Reset..."
+msgstr "Отмяна на промените…"
+
+#: git-gui.sh:2807
+msgid "Done"
+msgstr "Готово"
+
+#: git-gui.sh:2809
+msgid "Commit@@verb"
+msgstr "Подаване"
+
+#: git-gui.sh:2818 git-gui.sh:3289
+msgid "New Commit"
+msgstr "Подаване"
+
+#: git-gui.sh:2826 git-gui.sh:3296
+msgid "Amend Last Commit"
+msgstr "Поправяне на последното подаване"
+
+#: git-gui.sh:2836 git-gui.sh:3250 lib/remote_branch_delete.tcl:101
+msgid "Rescan"
+msgstr "Обновяване"
+
+#: git-gui.sh:2842
+msgid "Stage To Commit"
+msgstr "Към индекса за подаване"
+
+#: git-gui.sh:2848
+msgid "Stage Changed Files To Commit"
+msgstr "Всички променени файлове към индекса за подаване"
+
+#: git-gui.sh:2854
+msgid "Unstage From Commit"
+msgstr "Изваждане от индекса за подаване"
+
+#: git-gui.sh:2860 lib/index.tcl:442
+msgid "Revert Changes"
+msgstr "Връщане на оригинала"
+
+#: git-gui.sh:2868 git-gui.sh:3561 git-gui.sh:3592
+msgid "Show Less Context"
+msgstr "По-малко контекст"
+
+#: git-gui.sh:2872 git-gui.sh:3565 git-gui.sh:3596
+msgid "Show More Context"
+msgstr "Повече контекст"
+
+#: git-gui.sh:2879 git-gui.sh:3263 git-gui.sh:3372
+msgid "Sign Off"
+msgstr "Подписване"
+
+#: git-gui.sh:2895
+msgid "Local Merge..."
+msgstr "Локално сливане…"
+
+#: git-gui.sh:2900
+msgid "Abort Merge..."
+msgstr "Преустановяване на сливане…"
+
+#: git-gui.sh:2912 git-gui.sh:2940
+msgid "Add..."
+msgstr "Добавяне…"
+
+#: git-gui.sh:2916
+msgid "Push..."
+msgstr "Избутване…"
+
+#: git-gui.sh:2920
+msgid "Delete Branch..."
+msgstr "Изтриване на клон…"
+
+#: git-gui.sh:2930 git-gui.sh:3543
+msgid "Options..."
+msgstr "Опции…"
+
+#: git-gui.sh:2941
+msgid "Remove..."
+msgstr "Премахване…"
+
+#: git-gui.sh:2950 lib/choose_repository.tcl:54
+msgid "Help"
+msgstr "Помощ"
+
+#: git-gui.sh:2954 git-gui.sh:2958 lib/choose_repository.tcl:48
+#: lib/choose_repository.tcl:57 lib/about.tcl:14
+#, tcl-format
+msgid "About %s"
+msgstr "Относно %s"
+
+#: git-gui.sh:2982
+msgid "Online Documentation"
+msgstr "Документация в Интернет"
+
+#: git-gui.sh:2985 lib/choose_repository.tcl:51 lib/choose_repository.tcl:60
+msgid "Show SSH Key"
+msgstr "Показване на ключа за SSH"
+
+#: git-gui.sh:3004 git-gui.sh:3136
+msgid "Usage"
+msgstr "Употреба"
+
+#: git-gui.sh:3085 lib/blame.tcl:573
+msgid "Error"
+msgstr "Грешка"
+
+#: git-gui.sh:3116
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr ""
+"фатално: пътят %s не може да бъде открит: такъв файл или директория няма"
+
+#: git-gui.sh:3149
+msgid "Current Branch:"
+msgstr "Текущ клон:"
+
+#: git-gui.sh:3175
+msgid "Staged Changes (Will Commit)"
+msgstr "Промени в индекса (за подаване)"
+
+#: git-gui.sh:3195
+msgid "Unstaged Changes"
+msgstr "Промени извън индекса"
+
+#: git-gui.sh:3256
+msgid "Stage Changed"
+msgstr "Индексът е променен"
+
+#: git-gui.sh:3275 lib/transport.tcl:137 lib/transport.tcl:229
+msgid "Push"
+msgstr "Изтласкване"
+
+#: git-gui.sh:3310
+msgid "Initial Commit Message:"
+msgstr "Първоначално съобщение при подаване:"
+
+#: git-gui.sh:3311
+msgid "Amended Commit Message:"
+msgstr "Поправено съобщение при подаване:"
+
+#: git-gui.sh:3312
+msgid "Amended Initial Commit Message:"
+msgstr "Поправено първоначално съобщение при подаване:"
+
+#: git-gui.sh:3313
+msgid "Amended Merge Commit Message:"
+msgstr "Поправено съобщение при подаване със сливане:"
+
+#: git-gui.sh:3314
+msgid "Merge Commit Message:"
+msgstr "Съобщение при подаване със сливане:"
+
+#: git-gui.sh:3315
+msgid "Commit Message:"
+msgstr "Съобщение при подаване:"
+
+#: git-gui.sh:3364 git-gui.sh:3518 lib/console.tcl:73
+msgid "Copy All"
+msgstr "Копиране на всичко"
+
+#: git-gui.sh:3388 lib/blame.tcl:105
+msgid "File:"
+msgstr "Файл:"
+
+#: git-gui.sh:3506
+msgid "Refresh"
+msgstr "Обновяване"
+
+#: git-gui.sh:3527
+msgid "Decrease Font Size"
+msgstr "По-едър шрифт"
+
+#: git-gui.sh:3531
+msgid "Increase Font Size"
+msgstr "По-дребен шрифт"
+
+#: git-gui.sh:3539 lib/blame.tcl:294
+msgid "Encoding"
+msgstr "Кодиране"
+
+#: git-gui.sh:3550
+msgid "Apply/Reverse Hunk"
+msgstr "Прилагане/връщане на парче"
+
+#: git-gui.sh:3555
+msgid "Apply/Reverse Line"
+msgstr "Прилагане/връщане на ред"
+
+#: git-gui.sh:3574
+msgid "Run Merge Tool"
+msgstr "Изпълнение на програмата за сливане"
+
+#: git-gui.sh:3579
+msgid "Use Remote Version"
+msgstr "Версия от отдалеченото хранилище"
+
+#: git-gui.sh:3583
+msgid "Use Local Version"
+msgstr "Локална версия"
+
+#: git-gui.sh:3587
+msgid "Revert To Base"
+msgstr "Връщане към родителската версия"
+
+#: git-gui.sh:3605
+msgid "Visualize These Changes In The Submodule"
+msgstr "Визуализиране на промените в подмодула"
+
+#: git-gui.sh:3609
+msgid "Visualize Current Branch History In The Submodule"
+msgstr "Визуализация на историята на текущия клон в историята за подмодула"
+
+#: git-gui.sh:3613
+msgid "Visualize All Branch History In The Submodule"
+msgstr "Визуализация на историята на всички клони в историята за подмодула"
+
+#: git-gui.sh:3618
+msgid "Start git gui In The Submodule"
+msgstr "Стартиране на „git gui“ за подмодула"
+
+#: git-gui.sh:3653
+msgid "Unstage Hunk From Commit"
+msgstr "Изваждане на парчето от подаването"
+
+#: git-gui.sh:3655
+msgid "Unstage Lines From Commit"
+msgstr "Изваждане на редовете от подаването"
+
+#: git-gui.sh:3657
+msgid "Unstage Line From Commit"
+msgstr "Изваждане на реда от подаването"
+
+#: git-gui.sh:3660
+msgid "Stage Hunk For Commit"
+msgstr "Добавяне на парчето за подаване"
+
+#: git-gui.sh:3662
+msgid "Stage Lines For Commit"
+msgstr "Добавяне на редовете за подаване"
+
+#: git-gui.sh:3664
+msgid "Stage Line For Commit"
+msgstr "Добавяне на реда за подаване"
+
+#: git-gui.sh:3689
+msgid "Initializing..."
+msgstr "Инициализиране…"
+
+#: git-gui.sh:3832
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+"Възможно е да има проблем със средата.\n"
+"\n"
+"Най-вероятно следните променливи няма да бъдат\n"
+"взети под внимание от подпроцесите Git изпълнени\n"
+"от %s:\n"
+"\n"
+
+#: git-gui.sh:3861
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+"\n"
+"Това е познат проблем и се дължи на\n"
+"версията на Tcl включена в Cygwin."
+
+#: git-gui.sh:3866
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+"\n"
+"\n"
+"Добър заместител на %s\n"
+"е да поставите настройките user.name и\n"
+"user.email в личния си файл ~/.gitconfig.\n"
+
+#: lib/spellcheck.tcl:57
+msgid "Unsupported spell checker"
+msgstr "Тази програма за проверка на правописа не се поддържа"
+
+#: lib/spellcheck.tcl:65
+msgid "Spell checking is unavailable"
+msgstr "Липсва програма за проверка на правописа"
+
+#: lib/spellcheck.tcl:68
+msgid "Invalid spell checking configuration"
+msgstr "Неправилни настройки на проверката на правописа"
+
+#: lib/spellcheck.tcl:70
+#, tcl-format
+msgid "Reverting dictionary to %s."
+msgstr "Ползване на речник за език „%s“."
+
+#: lib/spellcheck.tcl:73
+msgid "Spell checker silently failed on startup"
+msgstr "Програмата за правопис даже не стартира успешно."
+
+#: lib/spellcheck.tcl:80
+msgid "Unrecognized spell checker"
+msgstr "Непозната програма за проверка на правописа"
+
+#: lib/spellcheck.tcl:186
+msgid "No Suggestions"
+msgstr "Няма предложения"
+
+#: lib/spellcheck.tcl:388
+msgid "Unexpected EOF from spell checker"
+msgstr "Неочакван край на файл от програмата за проверка на правописа"
+
+#: lib/spellcheck.tcl:392
+msgid "Spell Checker Failed"
+msgstr "Грешка в програмата за проверка на правописа"
+
+#: lib/remote_add.tcl:20
+msgid "Add Remote"
+msgstr "Добавяне на отдалечено хранилище"
+
+#: lib/remote_add.tcl:25
+msgid "Add New Remote"
+msgstr "Добавяне на отдалечено хранилище"
+
+#: lib/remote_add.tcl:30 lib/tools_dlg.tcl:37
+msgid "Add"
+msgstr "Добавяне"
+
+#: lib/remote_add.tcl:34 lib/browser.tcl:292 lib/branch_checkout.tcl:30
+#: lib/transport.tcl:141 lib/branch_rename.tcl:32 lib/choose_font.tcl:45
+#: lib/option.tcl:127 lib/tools_dlg.tcl:41 lib/tools_dlg.tcl:202
+#: lib/tools_dlg.tcl:345 lib/remote_branch_delete.tcl:43
+#: lib/checkout_op.tcl:579 lib/branch_create.tcl:37 lib/branch_delete.tcl:34
+#: lib/merge.tcl:174
+msgid "Cancel"
+msgstr "Отказване"
+
+#: lib/remote_add.tcl:39
+msgid "Remote Details"
+msgstr "Данни за отдалеченото хранилище"
+
+#: lib/remote_add.tcl:41 lib/tools_dlg.tcl:51 lib/branch_create.tcl:44
+msgid "Name:"
+msgstr "Име:"
+
+#: lib/remote_add.tcl:50
+msgid "Location:"
+msgstr "Местоположение:"
+
+#: lib/remote_add.tcl:60
+msgid "Further Action"
+msgstr "Следващо действие"
+
+#: lib/remote_add.tcl:63
+msgid "Fetch Immediately"
+msgstr "Незабавно доставяне"
+
+#: lib/remote_add.tcl:69
+msgid "Initialize Remote Repository and Push"
+msgstr "Инициализиране на отдалеченото хранилище и изтласкване на промените"
+
+#: lib/remote_add.tcl:75
+msgid "Do Nothing Else Now"
+msgstr "Да не се прави нищо"
+
+#: lib/remote_add.tcl:100
+msgid "Please supply a remote name."
+msgstr "Задайте име за отдалеченото хранилище."
+
+#: lib/remote_add.tcl:113
+#, tcl-format
+msgid "'%s' is not an acceptable remote name."
+msgstr "Отдалечено хранилище не може да се казва „%s“."
+
+#: lib/remote_add.tcl:124
+#, tcl-format
+msgid "Failed to add remote '%s' of location '%s'."
+msgstr "Неуспешно добавяне на отдалеченото хранилище „%s“ от адрес „%s“."
+
+#: lib/remote_add.tcl:132 lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr "доставяне на „%s“"
+
+#: lib/remote_add.tcl:133
+#, tcl-format
+msgid "Fetching the %s"
+msgstr "Доставяне на „%s“"
+
+#: lib/remote_add.tcl:156
+#, tcl-format
+msgid "Do not know how to initialize repository at location '%s'."
+msgstr "Хранилището с местоположение „%s“ не може да бъде инициализирано."
+
+#: lib/remote_add.tcl:162 lib/transport.tcl:54 lib/transport.tcl:92
+#: lib/transport.tcl:110
+#, tcl-format
+msgid "push %s"
+msgstr "изтласкване на „%s“"
+
+#: lib/remote_add.tcl:163
+#, tcl-format
+msgid "Setting up the %s (at %s)"
+msgstr "Добавяне на хранилище „%s“ (с адрес „%s“)"
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "Стартиране…"
+
+#: lib/browser.tcl:27
+msgid "File Browser"
+msgstr "Файлов браузър"
+
+#: lib/browser.tcl:132 lib/browser.tcl:149
+#, tcl-format
+msgid "Loading %s..."
+msgstr "Зареждане на „%s“…"
+
+#: lib/browser.tcl:193
+msgid "[Up To Parent]"
+msgstr "[Към родителя]"
+
+#: lib/browser.tcl:275 lib/browser.tcl:282
+msgid "Browse Branch Files"
+msgstr "Разглеждане на файловете в клона"
+
+#: lib/browser.tcl:288 lib/choose_repository.tcl:406
+#: lib/choose_repository.tcl:493 lib/choose_repository.tcl:502
+#: lib/choose_repository.tcl:1029
+msgid "Browse"
+msgstr "Разглеждане"
+
+#: lib/browser.tcl:297 lib/branch_checkout.tcl:35 lib/tools_dlg.tcl:321
+msgid "Revision"
+msgstr "Версия"
+
+#: lib/tools.tcl:75
+#, tcl-format
+msgid "Running %s requires a selected file."
+msgstr "За изпълнението на „%s“ трябва да изберете файл."
+
+#: lib/tools.tcl:91
+#, tcl-format
+msgid "Are you sure you want to run %1$s on file \"%2$s\"?"
+msgstr "Сигурни ли сте, че искате да стартирате „%1$s“ върху „%2$s“?"
+
+#: lib/tools.tcl:95
+#, tcl-format
+msgid "Are you sure you want to run %s?"
+msgstr "Сигурни ли сте, че искате да стартирате „%s“?"
+
+#: lib/tools.tcl:116
+#, tcl-format
+msgid "Tool: %s"
+msgstr "Команда: %s"
+
+#: lib/tools.tcl:117
+#, tcl-format
+msgid "Running: %s"
+msgstr "Изпълнение: %s"
+
+#: lib/tools.tcl:155
+#, tcl-format
+msgid "Tool completed successfully: %s"
+msgstr "Командата завърши успешно: %s"
+
+#: lib/tools.tcl:157
+#, tcl-format
+msgid "Tool failed: %s"
+msgstr "Командата върна грешка: %s"
+
+#: lib/branch_checkout.tcl:16 lib/branch_checkout.tcl:21
+msgid "Checkout Branch"
+msgstr "Клон за изтегляне"
+
+#: lib/branch_checkout.tcl:26
+msgid "Checkout"
+msgstr "Изтегляне"
+
+#: lib/branch_checkout.tcl:39 lib/option.tcl:309 lib/branch_create.tcl:69
+msgid "Options"
+msgstr "Опции"
+
+#: lib/branch_checkout.tcl:42 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "Изтегляне на промените от следения клон"
+
+#: lib/branch_checkout.tcl:47
+msgid "Detach From Local Branch"
+msgstr "Изтриване от локалния клон"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr "Доставяне на промените от %s"
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr "окастряне на следящите клони към „%s“"
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr "Окастряне на следящите клони на изтритите клони от „%s“"
+
+#: lib/transport.tcl:25
+msgid "fetch all remotes"
+msgstr "доставяне на всички хранилища"
+
+#: lib/transport.tcl:26
+msgid "Fetching new changes from all remotes"
+msgstr "Доставяне на промените от всички отдалечени хранилища"
+
+#: lib/transport.tcl:40
+msgid "remote prune all remotes"
+msgstr "окастряне на всички клони следящи изтрити клони"
+
+#: lib/transport.tcl:41
+msgid "Pruning tracking branches deleted from all remotes"
+msgstr ""
+"Окастряне на следящите клони на изтритите клони от всички отдалечени "
+"хранилища"
+
+#: lib/transport.tcl:55
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "Изтласкване на промените към %s"
+
+#: lib/transport.tcl:93
+#, tcl-format
+msgid "Mirroring to %s"
+msgstr "Изтласкване на всичко към „%s“"
+
+#: lib/transport.tcl:111
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "Изтласкване на %s %s към %s"
+
+#: lib/transport.tcl:132
+msgid "Push Branches"
+msgstr "Клони за изтласкване"
+
+#: lib/transport.tcl:147
+msgid "Source Branches"
+msgstr "Клони-източници"
+
+#: lib/transport.tcl:162
+msgid "Destination Repository"
+msgstr "Целево хранилище"
+
+#: lib/transport.tcl:165 lib/remote_branch_delete.tcl:51
+msgid "Remote:"
+msgstr "Отдалечено хранилище:"
+
+#: lib/transport.tcl:187 lib/remote_branch_delete.tcl:72
+msgid "Arbitrary Location:"
+msgstr "Произволно местоположение:"
+
+#: lib/transport.tcl:205
+msgid "Transfer Options"
+msgstr "Настройки при пренасянето"
+
+#: lib/transport.tcl:207
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr ""
+"Изрично презаписване на съществуващ клон (някои промени може да бъдат "
+"загубени)"
+
+#: lib/transport.tcl:211
+msgid "Use thin pack (for slow network connections)"
+msgstr "Максимална компресия (за бавни мрежови връзки)"
+
+#: lib/transport.tcl:215
+msgid "Include tags"
+msgstr "Включване на етикетите"
+
+#: lib/status_bar.tcl:87
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr "%s… %*i от общо %*i %s (%3i%%)"
+
+#: lib/remote.tcl:200
+msgid "Push to"
+msgstr "Изтласкване към"
+
+#: lib/remote.tcl:218
+msgid "Remove Remote"
+msgstr "Премахване на отдалечено хранилище"
+
+#: lib/remote.tcl:223
+msgid "Prune from"
+msgstr "Окастряне от"
+
+#: lib/remote.tcl:228
+msgid "Fetch from"
+msgstr "Доставяне от"
+
+#: lib/sshkey.tcl:31
+msgid "No keys found."
+msgstr "Не са открити ключове."
+
+#: lib/sshkey.tcl:34
+#, tcl-format
+msgid "Found a public key in: %s"
+msgstr "Открит е публичен ключ в „%s“"
+
+#: lib/sshkey.tcl:40
+msgid "Generate Key"
+msgstr "Генериране на ключ"
+
+#: lib/sshkey.tcl:55 lib/checkout_op.tcl:146 lib/console.tcl:81
+#: lib/database.tcl:30
+msgid "Close"
+msgstr "Затваряне"
+
+#: lib/sshkey.tcl:58
+msgid "Copy To Clipboard"
+msgstr "Копиране към системния буфер"
+
+#: lib/sshkey.tcl:72
+msgid "Your OpenSSH Public Key"
+msgstr "Публичният ви ключ за OpenSSH"
+
+#: lib/sshkey.tcl:80
+msgid "Generating..."
+msgstr "Генериране…"
+
+#: lib/sshkey.tcl:86
+#, tcl-format
+msgid ""
+"Could not start ssh-keygen:\n"
+"\n"
+"%s"
+msgstr ""
+"Програмата „ssh-keygen“ не може да бъде стартирана:\n"
+"\n"
+"%s"
+
+#: lib/sshkey.tcl:113
+msgid "Generation failed."
+msgstr "Неуспешно генериране."
+
+#: lib/sshkey.tcl:120
+msgid "Generation succeeded, but no keys found."
+msgstr "Генерирането завърши успешно, а не са намерени ключове."
+
+#: lib/sshkey.tcl:123
+#, tcl-format
+msgid "Your key is in: %s"
+msgstr "Ключът ви е в „%s“"
+
+#: lib/branch_rename.tcl:15 lib/branch_rename.tcl:23
+msgid "Rename Branch"
+msgstr "Преименуване на клон"
+
+#: lib/branch_rename.tcl:28
+msgid "Rename"
+msgstr "Преименуване"
+
+#: lib/branch_rename.tcl:38
+msgid "Branch:"
+msgstr "Клон:"
+
+#: lib/branch_rename.tcl:46
+msgid "New Name:"
+msgstr "Ново име:"
+
+#: lib/branch_rename.tcl:81
+msgid "Please select a branch to rename."
+msgstr "Изберете клон за преименуване."
+
+#: lib/branch_rename.tcl:92 lib/branch_create.tcl:154
+msgid "Please supply a branch name."
+msgstr "Дайте име на клона."
+
+#: lib/branch_rename.tcl:102 lib/checkout_op.tcl:202
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "Клонът „%s“ вече съществува."
+
+#: lib/branch_rename.tcl:112 lib/branch_create.tcl:165
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "„%s“ не може да се използва за име на клон."
+
+#: lib/branch_rename.tcl:123
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "Неуспешно преименуване на „%s“."
+
+#: lib/choose_font.tcl:41
+msgid "Select"
+msgstr "Избор"
+
+#: lib/choose_font.tcl:55
+msgid "Font Family"
+msgstr "Шрифт"
+
+#: lib/choose_font.tcl:76
+msgid "Font Size"
+msgstr "Размер"
+
+#: lib/choose_font.tcl:93
+msgid "Font Example"
+msgstr "Мостра"
+
+#: lib/choose_font.tcl:105
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+"Това е примерен текст.\n"
+"Ако ви харесва как изглежда, изберете този шрифт."
+
+#: lib/option.tcl:11
+#, tcl-format
+msgid "Invalid global encoding '%s'"
+msgstr "Неправилно глобално кодиране „%s“"
+
+#: lib/option.tcl:19
+#, tcl-format
+msgid "Invalid repo encoding '%s'"
+msgstr "Неправилно кодиране „%s“ на хранилището"
+
+#: lib/option.tcl:119
+msgid "Restore Defaults"
+msgstr "Стандартни настройки"
+
+#: lib/option.tcl:123
+msgid "Save"
+msgstr "Запазване"
+
+#: lib/option.tcl:133
+#, tcl-format
+msgid "%s Repository"
+msgstr "Хранилище „%s“"
+
+#: lib/option.tcl:134
+msgid "Global (All Repositories)"
+msgstr "Глобално (за всички хранилища)"
+
+#: lib/option.tcl:140
+msgid "User Name"
+msgstr "Потребителско име"
+
+#: lib/option.tcl:141
+msgid "Email Address"
+msgstr "Адрес на е-поща"
+
+#: lib/option.tcl:143
+msgid "Summarize Merge Commits"
+msgstr "Обобщаване на подаванията при сливане"
+
+#: lib/option.tcl:144
+msgid "Merge Verbosity"
+msgstr "Подробности при сливанията"
+
+#: lib/option.tcl:145
+msgid "Show Diffstat After Merge"
+msgstr "Извеждане на статистика след сливанията"
+
+#: lib/option.tcl:146
+msgid "Use Merge Tool"
+msgstr "Използване на програма за сливане"
+
+#: lib/option.tcl:148
+msgid "Trust File Modification Timestamps"
+msgstr "Доверие във времето на промяна на файловете"
+
+#: lib/option.tcl:149
+msgid "Prune Tracking Branches During Fetch"
+msgstr "Окастряне на следящите клонове при доставяне"
+
+#: lib/option.tcl:150
+msgid "Match Tracking Branches"
+msgstr "Напасване на следящите клонове"
+
+#: lib/option.tcl:151
+msgid "Use Textconv For Diffs and Blames"
+msgstr "Използване на „textconv“ за разликите и анотациите"
+
+#: lib/option.tcl:152
+msgid "Blame Copy Only On Changed Files"
+msgstr "Анотиране на копието само по променените файлове"
+
+#: lib/option.tcl:153
+msgid "Maximum Length of Recent Repositories List"
+msgstr "Максимален брой скоро ползвани хранилища"
+
+#: lib/option.tcl:154
+msgid "Minimum Letters To Blame Copy On"
+msgstr "Минимален брой знаци за анотиране на копието"
+
+#: lib/option.tcl:155
+msgid "Blame History Context Radius (days)"
+msgstr "Исторически обхват за анотиране в дни"
+
+#: lib/option.tcl:156
+msgid "Number of Diff Context Lines"
+msgstr "Брой редове за контекста при извеждане на разликите"
+
+#: lib/option.tcl:157
+msgid "Additional Diff Parameters"
+msgstr "Допълнителни параметри за разликите"
+
+#: lib/option.tcl:158
+msgid "Commit Message Text Width"
+msgstr "Широчина на текста на съобщението при подаване"
+
+#: lib/option.tcl:159
+msgid "New Branch Name Template"
+msgstr "Шаблон за името на новите клони"
+
+#: lib/option.tcl:160
+msgid "Default File Contents Encoding"
+msgstr "Стандартно кодиране на файловете"
+
+#: lib/option.tcl:161
+msgid "Warn before committing to a detached head"
+msgstr "Предупреждение при подаване към несвързан връх"
+
+#: lib/option.tcl:162
+msgid "Staging of untracked files"
+msgstr "Добавяне на неследените файлове към индекса"
+
+#: lib/option.tcl:163
+msgid "Show untracked files"
+msgstr "Показване на неследените файлове"
+
+#: lib/option.tcl:209
+msgid "Change"
+msgstr "Смяна"
+
+#: lib/option.tcl:253
+msgid "Spelling Dictionary:"
+msgstr "Правописен речник:"
+
+#: lib/option.tcl:283
+msgid "Change Font"
+msgstr "Смяна на шрифта"
+
+#: lib/option.tcl:287
+#, tcl-format
+msgid "Choose %s"
+msgstr "Избор на „%s“"
+
+#: lib/option.tcl:293
+msgid "pt."
+msgstr "тчк."
+
+#: lib/option.tcl:307
+msgid "Preferences"
+msgstr "Настройки"
+
+#: lib/option.tcl:344
+msgid "Failed to completely save options:"
+msgstr "Неуспешно запазване на настройките:"
+
+#: lib/mergetool.tcl:8
+msgid "Force resolution to the base version?"
+msgstr "Да се използва базовата версия"
+
+#: lib/mergetool.tcl:9
+msgid "Force resolution to this branch?"
+msgstr "Да се използва версията от този клон"
+
+#: lib/mergetool.tcl:10
+msgid "Force resolution to the other branch?"
+msgstr "Да се използва версията от другия клон"
+
+#: lib/mergetool.tcl:14
+#, tcl-format
+msgid ""
+"Note that the diff shows only conflicting changes.\n"
+"\n"
+"%s will be overwritten.\n"
+"\n"
+"This operation can be undone only by restarting the merge."
+msgstr ""
+"Разликата показва само разликите с конфликт.\n"
+"\n"
+"Файлът „%s“ ще бъде презаписан.\n"
+"\n"
+"Тази операция може да бъде отменена само чрез започване на сливането наново."
+
+#: lib/mergetool.tcl:45
+#, tcl-format
+msgid "File %s seems to have unresolved conflicts, still stage?"
+msgstr ""
+"Изглежда, че във файла „%s“ все още има некоригирани конфликти. Да се добави "
+"ли файлът към индекса?"
+
+#: lib/mergetool.tcl:60
+#, tcl-format
+msgid "Adding resolution for %s"
+msgstr "Добавяне на корекция на конфликтите в „%s“"
+
+#: lib/mergetool.tcl:141
+msgid "Cannot resolve deletion or link conflicts using a tool"
+msgstr ""
+"Конфликтите при символни връзки или изтриване не могат да бъдат коригирани с "
+"външна програма."
+
+#: lib/mergetool.tcl:146
+msgid "Conflict file does not exist"
+msgstr "Файлът, в който е конфликтът, не съществува"
+
+#: lib/mergetool.tcl:246
+#, tcl-format
+msgid "Not a GUI merge tool: '%s'"
+msgstr "Това не е графична програма за сливане: „%s“"
+
+#: lib/mergetool.tcl:275
+#, tcl-format
+msgid "Unsupported merge tool '%s'"
+msgstr "Неподдържана програма за сливане: „%s“"
+
+#: lib/mergetool.tcl:310
+msgid "Merge tool is already running, terminate it?"
+msgstr "Програмата за сливане вече е стартирана. Да бъде ли изключена?"
+
+#: lib/mergetool.tcl:330
+#, tcl-format
+msgid ""
+"Error retrieving versions:\n"
+"%s"
+msgstr ""
+"Грешка при изтеглянето на версии:\n"
+"%s"
+
+#: lib/mergetool.tcl:350
+#, tcl-format
+msgid ""
+"Could not start the merge tool:\n"
+"\n"
+"%s"
+msgstr ""
+"Програмата за сливане не може да бъде стартирана:\n"
+"\n"
+"%s"
+
+#: lib/mergetool.tcl:354
+msgid "Running merge tool..."
+msgstr "Стартиране на програмата за сливане…"
+
+#: lib/mergetool.tcl:382 lib/mergetool.tcl:390
+msgid "Merge tool failed."
+msgstr "Грешка в програмата за сливане."
+
+#: lib/tools_dlg.tcl:22
+msgid "Add Tool"
+msgstr "Добавяне на команда"
+
+#: lib/tools_dlg.tcl:28
+msgid "Add New Tool Command"
+msgstr "Добавяне на команда"
+
+#: lib/tools_dlg.tcl:34
+msgid "Add globally"
+msgstr "Глобално добавяне"
+
+#: lib/tools_dlg.tcl:46
+msgid "Tool Details"
+msgstr "Подробности за командата"
+
+#: lib/tools_dlg.tcl:49
+msgid "Use '/' separators to create a submenu tree:"
+msgstr "За създаване на подменюта използвайте за разделител знака „/“:"
+
+#: lib/tools_dlg.tcl:60
+msgid "Command:"
+msgstr "Команда:"
+
+#: lib/tools_dlg.tcl:71
+msgid "Show a dialog before running"
+msgstr "Преди изпълнение да се извежда диалогов прозорец"
+
+#: lib/tools_dlg.tcl:77
+msgid "Ask the user to select a revision (sets $REVISION)"
+msgstr "Потребителят да укаже версия (задаване на променливата $REVISION)"
+
+#: lib/tools_dlg.tcl:82
+msgid "Ask the user for additional arguments (sets $ARGS)"
+msgstr ""
+"Потребителят да укаже допълнителни аргументи (задаване на променливата $ARGS)"
+
+#: lib/tools_dlg.tcl:89
+msgid "Don't show the command output window"
+msgstr "Без показване на прозорец с изхода от командата"
+
+#: lib/tools_dlg.tcl:94
+msgid "Run only if a diff is selected ($FILENAME not empty)"
+msgstr ""
+"Стартиране само след избор на разлика (променливата $FILENAME не е празна)"
+
+#: lib/tools_dlg.tcl:118
+msgid "Please supply a name for the tool."
+msgstr "Задайте име за командата."
+
+#: lib/tools_dlg.tcl:126
+#, tcl-format
+msgid "Tool '%s' already exists."
+msgstr "Командата „%s“ вече съществува."
+
+#: lib/tools_dlg.tcl:148
+#, tcl-format
+msgid ""
+"Could not add tool:\n"
+"%s"
+msgstr ""
+"Командата не може да бъде добавена:\n"
+"%s"
+
+#: lib/tools_dlg.tcl:187
+msgid "Remove Tool"
+msgstr "Премахване на команда"
+
+#: lib/tools_dlg.tcl:193
+msgid "Remove Tool Commands"
+msgstr "Премахване на команди"
+
+#: lib/tools_dlg.tcl:198
+msgid "Remove"
+msgstr "Премахване"
+
+#: lib/tools_dlg.tcl:231
+msgid "(Blue denotes repository-local tools)"
+msgstr "(команди към локалното хранилище са обозначени в синьо)"
+
+#: lib/tools_dlg.tcl:292
+#, tcl-format
+msgid "Run Command: %s"
+msgstr "Изпълнение на командата „%s“"
+
+#: lib/tools_dlg.tcl:306
+msgid "Arguments"
+msgstr "Аргументи"
+
+#: lib/tools_dlg.tcl:336 lib/checkout_op.tcl:567 lib/merge.tcl:166
+msgid "Visualize"
+msgstr "Визуализация"
+
+#: lib/tools_dlg.tcl:341
+msgid "OK"
+msgstr "Добре"
+
+#: lib/search.tcl:48
+msgid "Find:"
+msgstr "Търсене:"
+
+#: lib/search.tcl:50
+msgid "Next"
+msgstr "Следваща поява"
+
+#: lib/search.tcl:51
+msgid "Prev"
+msgstr "Предишна поява"
+
+#: lib/search.tcl:52
+msgid "RegExp"
+msgstr "Рег. изр."
+
+#: lib/search.tcl:54
+msgid "Case"
+msgstr "Регистър"
+
+#: lib/shortcut.tcl:21 lib/shortcut.tcl:62
+msgid "Cannot write shortcut:"
+msgstr "Клавишната комбинация не може да бъде запазена:"
+
+#: lib/shortcut.tcl:137
+msgid "Cannot write icon:"
+msgstr "Иконата не може да бъде запазена:"
+
+#: lib/diff.tcl:64
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"Не са открити разлики.\n"
+"\n"
+"Няма промени в „%s“.\n"
+"\n"
+"Времето на промяна на файла е бил зададен от друга програма, но съдържанието "
+"му не е променено.\n"
+"\n"
+"Автоматично ще започне нова проверка дали няма други файлове в това "
+"състояние."
+
+#: lib/diff.tcl:104
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "Зареждане на разликите в „%s“…"
+
+#: lib/diff.tcl:125
+msgid ""
+"LOCAL: deleted\n"
+"REMOTE:\n"
+msgstr ""
+"ЛОКАЛНО: изтрит\n"
+"ОТДАЛЕЧЕНО:\n"
+
+#: lib/diff.tcl:130
+msgid ""
+"REMOTE: deleted\n"
+"LOCAL:\n"
+msgstr ""
+"ОТДАЛЕЧЕНО: изтрит\n"
+"ЛОКАЛНО:\n"
+
+#: lib/diff.tcl:137
+msgid "LOCAL:\n"
+msgstr "ЛОКАЛНО:\n"
+
+#: lib/diff.tcl:140
+msgid "REMOTE:\n"
+msgstr "ОТДАЛЕЧЕНО:\n"
+
+#: lib/diff.tcl:202 lib/diff.tcl:337
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "Не може да бъде показан файлът „%s“"
+
+#: lib/diff.tcl:203
+msgid "Error loading file:"
+msgstr "Грешка при зареждане на файл:"
+
+#: lib/diff.tcl:210
+msgid "Git Repository (subproject)"
+msgstr "Хранилище на Git (подпроект)"
+
+#: lib/diff.tcl:222
+msgid "* Binary file (not showing content)."
+msgstr "⁃ Двоичен файл (съдържанието не се показва)."
+
+#: lib/diff.tcl:227
+#, tcl-format
+msgid ""
+"* Untracked file is %d bytes.\n"
+"* Showing only first %d bytes.\n"
+msgstr ""
+"⁃ Неследеният файл е %d байта.\n"
+"⁃ Показват се само първите %d байта.\n"
+
+#: lib/diff.tcl:233
+#, tcl-format
+msgid ""
+"\n"
+"* Untracked file clipped here by %s.\n"
+"* To see the entire file, use an external editor.\n"
+msgstr ""
+"\n"
+"⁃ Неследеният файл е отрязан дотук %s.\n"
+"⁃ Използвайте външен редактор, за да видите целия файл.\n"
+
+#: lib/diff.tcl:338 lib/blame.tcl:1128
+msgid "Error loading diff:"
+msgstr "Грешка при зареждане на разлика:"
+
+#: lib/diff.tcl:557
+msgid "Failed to unstage selected hunk."
+msgstr "Избраното парче не може да бъде извадено от индекса."
+
+#: lib/diff.tcl:564
+msgid "Failed to stage selected hunk."
+msgstr "Избраното парче не може да бъде добавен към индекса."
+
+#: lib/diff.tcl:643
+msgid "Failed to unstage selected line."
+msgstr "Избраният ред не може да бъде изваден от индекса."
+
+#: lib/diff.tcl:651
+msgid "Failed to stage selected line."
+msgstr "Избраният ред не може да бъде добавен към индекса."
+
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Branch Remotely"
+msgstr "Изтриване на отдалечения клон"
+
+#: lib/remote_branch_delete.tcl:48
+msgid "From Repository"
+msgstr "От хранилище"
+
+#: lib/remote_branch_delete.tcl:88
+msgid "Branches"
+msgstr "Клонове"
+
+#: lib/remote_branch_delete.tcl:110
+msgid "Delete Only If"
+msgstr "Изтриване, само ако"
+
+#: lib/remote_branch_delete.tcl:112
+msgid "Merged Into:"
+msgstr "Слят в:"
+
+#: lib/remote_branch_delete.tcl:120 lib/branch_delete.tcl:53
+msgid "Always (Do not perform merge checks)"
+msgstr "Винаги (без проверка за сливане)"
+
+#: lib/remote_branch_delete.tcl:153
+msgid "A branch is required for 'Merged Into'."
+msgstr "За данните „Слят в“ е необходимо да зададете клон."
+
+#: lib/remote_branch_delete.tcl:185
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+"Следните клони не са слети напълно в „%s“:\n"
+"\n"
+" ⁃ %s"
+
+#: lib/remote_branch_delete.tcl:190
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits.  Try fetching from %s first."
+msgstr ""
+"Поне една от пробите за сливане е неуспешна, защото не сте доставили всички "
+"необходими подавания. Пробвайте първо да доставите подаванията от „%s“."
+
+#: lib/remote_branch_delete.tcl:208
+msgid "Please select one or more branches to delete."
+msgstr "Изберете поне един клон за изтриване."
+
+#: lib/remote_branch_delete.tcl:218 lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"Възстановяването на изтрити клони може да е трудно.\n"
+"\n"
+"Сигурни ли сте, че искате да триете?"
+
+#: lib/remote_branch_delete.tcl:227
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr "Изтриване на клони от „%s“"
+
+#: lib/remote_branch_delete.tcl:300
+msgid "No repository selected."
+msgstr "Не е избрано хранилище."
+
+#: lib/remote_branch_delete.tcl:305
+#, tcl-format
+msgid "Scanning %s..."
+msgstr "Претърсване на „%s“…"
+
+#: lib/choose_repository.tcl:32
+msgid "Git Gui"
+msgstr "ГПИ на Git"
+
+#: lib/choose_repository.tcl:91 lib/choose_repository.tcl:396
+msgid "Create New Repository"
+msgstr "Създаване на ново хранилище"
+
+#: lib/choose_repository.tcl:97
+msgid "New..."
+msgstr "Ново…"
+
+#: lib/choose_repository.tcl:104 lib/choose_repository.tcl:480
+msgid "Clone Existing Repository"
+msgstr "Клониране на съществуващо хранилище"
+
+#: lib/choose_repository.tcl:115
+msgid "Clone..."
+msgstr "Клониране…"
+
+#: lib/choose_repository.tcl:122 lib/choose_repository.tcl:1019
+msgid "Open Existing Repository"
+msgstr "Отваряне на съществуващо хранилище"
+
+#: lib/choose_repository.tcl:128
+msgid "Open..."
+msgstr "Отваряне…"
+
+#: lib/choose_repository.tcl:141
+msgid "Recent Repositories"
+msgstr "Скоро ползвани"
+
+#: lib/choose_repository.tcl:147
+msgid "Open Recent Repository:"
+msgstr "Отваряне на хранилище ползвано наскоро:"
+
+#: lib/choose_repository.tcl:315 lib/choose_repository.tcl:322
+#: lib/choose_repository.tcl:329
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "Неуспешно създаване на хранилището „%s“:"
+
+#: lib/choose_repository.tcl:391 lib/branch_create.tcl:33
+msgid "Create"
+msgstr "Създаване"
+
+#: lib/choose_repository.tcl:401
+msgid "Directory:"
+msgstr "Директория:"
+
+#: lib/choose_repository.tcl:431 lib/choose_repository.tcl:552
+#: lib/choose_repository.tcl:1053
+msgid "Git Repository"
+msgstr "Хранилище на Git"
+
+#: lib/choose_repository.tcl:456
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "Вече съществува директория „%s“."
+
+#: lib/choose_repository.tcl:460
+#, tcl-format
+msgid "File %s already exists."
+msgstr "Вече съществува файл „%s“."
+
+#: lib/choose_repository.tcl:475
+msgid "Clone"
+msgstr "Клониране"
+
+#: lib/choose_repository.tcl:488
+msgid "Source Location:"
+msgstr "Адрес на източника:"
+
+#: lib/choose_repository.tcl:497
+msgid "Target Directory:"
+msgstr "Целева директория:"
+
+#: lib/choose_repository.tcl:507
+msgid "Clone Type:"
+msgstr "Вид клониране:"
+
+#: lib/choose_repository.tcl:512
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr "Стандартно (бързо, частично споделяне на файлове, твърди връзки)"
+
+#: lib/choose_repository.tcl:517
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr "Пълно (бавно, пълноценно резервно копие)"
+
+#: lib/choose_repository.tcl:522
+msgid "Shared (Fastest, Not Recommended, No Backup)"
+msgstr "Споделено (най-бързо, не се препоръчва, не прави резервно копие)"
+
+#: lib/choose_repository.tcl:558 lib/choose_repository.tcl:605
+#: lib/choose_repository.tcl:751 lib/choose_repository.tcl:821
+#: lib/choose_repository.tcl:1059 lib/choose_repository.tcl:1067
+#, tcl-format
+msgid "Not a Git repository: %s"
+msgstr "Това не е хранилище на Git: %s"
+
+#: lib/choose_repository.tcl:594
+msgid "Standard only available for local repository."
+msgstr "Само локални хранилища могат да се клонират стандартно"
+
+#: lib/choose_repository.tcl:598
+msgid "Shared only available for local repository."
+msgstr "Само локални хранилища могат да се клонират споделено"
+
+#: lib/choose_repository.tcl:619
+#, tcl-format
+msgid "Location %s already exists."
+msgstr "Вече съществува местоположението „%s“."
+
+#: lib/choose_repository.tcl:630
+msgid "Failed to configure origin"
+msgstr "Неуспешно настройване на хранилището-източник"
+
+#: lib/choose_repository.tcl:642
+msgid "Counting objects"
+msgstr "Преброяване на обекти"
+
+#: lib/choose_repository.tcl:643
+msgid "buckets"
+msgstr "клетки"
+
+#: lib/choose_repository.tcl:667
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr "Обектите/информацията/синонимите не могат да бъдат копирани: %s"
+
+#: lib/choose_repository.tcl:703
+#, tcl-format
+msgid "Nothing to clone from %s."
+msgstr "Няма какво да се клонира от „%s“."
+
+#: lib/choose_repository.tcl:705 lib/choose_repository.tcl:919
+#: lib/choose_repository.tcl:931
+msgid "The 'master' branch has not been initialized."
+msgstr "Основният клон — „master“ не е инициализиран."
+
+#: lib/choose_repository.tcl:718
+msgid "Hardlinks are unavailable.  Falling back to copying."
+msgstr "Не се поддържат твърди връзки. Преминава се към копиране."
+
+#: lib/choose_repository.tcl:730
+#, tcl-format
+msgid "Cloning from %s"
+msgstr "Клониране на „%s“"
+
+#: lib/choose_repository.tcl:761
+msgid "Copying objects"
+msgstr "Копиране на обекти"
+
+#: lib/choose_repository.tcl:762
+msgid "KiB"
+msgstr "KiB"
+
+#: lib/choose_repository.tcl:786
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr "Неуспешно копиране на обект: %s"
+
+#: lib/choose_repository.tcl:796
+msgid "Linking objects"
+msgstr "Създаване на връзки към обектите"
+
+#: lib/choose_repository.tcl:797
+msgid "objects"
+msgstr "обекти"
+
+#: lib/choose_repository.tcl:805
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr "Неуспешно създаване на твърда връзка към обект: %s"
+
+#: lib/choose_repository.tcl:860
+msgid "Cannot fetch branches and objects.  See console output for details."
+msgstr ""
+"Клоните и обектите не могат да бъдат изтеглени. За повече информация "
+"погледнете изхода на конзолата."
+
+#: lib/choose_repository.tcl:871
+msgid "Cannot fetch tags.  See console output for details."
+msgstr ""
+"Етикетите не могат да бъдат изтеглени. За повече информация погледнете "
+"изхода на конзолата."
+
+#: lib/choose_repository.tcl:895
+msgid "Cannot determine HEAD.  See console output for details."
+msgstr ""
+"Върхът HEAD не може да бъде определен. За повече информация погледнете "
+"изхода на конзолата."
+
+#: lib/choose_repository.tcl:904
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr "Не може да се зачисти „%s“"
+
+#: lib/choose_repository.tcl:910
+msgid "Clone failed."
+msgstr "Неуспешно клониране."
+
+#: lib/choose_repository.tcl:917
+msgid "No default branch obtained."
+msgstr "Не е получен клон по подразбиране."
+
+#: lib/choose_repository.tcl:928
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr "Няма подаване отговарящо на „%s“."
+
+#: lib/choose_repository.tcl:940
+msgid "Creating working directory"
+msgstr "Създаване на работната директория"
+
+#: lib/choose_repository.tcl:941 lib/index.tcl:70 lib/index.tcl:136
+#: lib/index.tcl:207
+msgid "files"
+msgstr "файлове"
+
+#: lib/choose_repository.tcl:970
+msgid "Initial file checkout failed."
+msgstr "Неуспешно първоначално изтегляне."
+
+#: lib/choose_repository.tcl:1014
+msgid "Open"
+msgstr "Отваряне"
+
+#: lib/choose_repository.tcl:1024
+msgid "Repository:"
+msgstr "Хранилище:"
+
+#: lib/choose_repository.tcl:1073
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "Неуспешно отваряне на хранилището „%s“:"
+
+#: lib/about.tcl:26
+msgid "git-gui - a graphical user interface for Git."
+msgstr "git-gui — графичен интерфейс за Git."
+
+#: lib/checkout_op.tcl:85
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr "Доставяне на „%s“ от „%s“"
+
+#: lib/checkout_op.tcl:133
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr "фатална грешка: „%s“ не може да се открие"
+
+#: lib/checkout_op.tcl:175
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr "Клонът „%s“ не съществува."
+
+#: lib/checkout_op.tcl:194
+#, tcl-format
+msgid "Failed to configure simplified git-pull for '%s'."
+msgstr "Неуспешно настройване на опростен git-pull за „%s“."
+
+#: lib/checkout_op.tcl:229
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+"Клонът „%s“ съществува.\n"
+"\n"
+"Той не може да бъде тривиално превъртян до %s.\n"
+"Необходимо е сливане."
+
+#: lib/checkout_op.tcl:243
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr "Стратегия за сливане  „%s“ не се поддържа."
+
+#: lib/checkout_op.tcl:262
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr "Неуспешно обновяване на „%s“."
+
+#: lib/checkout_op.tcl:274
+msgid "Staging area (index) is already locked."
+msgstr "Индексът вече е заключен."
+
+#: lib/checkout_op.tcl:289
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan.  A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Състоянието при последната проверка не отговаря на състоянието на "
+"хранилището.\n"
+"\n"
+"Някой друг процес за Git е променил хранилището междувременно. Състоянието "
+"трябва да бъде проверено, преди да се премине към нов клон.\n"
+"\n"
+"Автоматично ще започне нова проверка.\n"
+
+#: lib/checkout_op.tcl:345
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr "Работната директория се привежда към „%s“…"
+
+#: lib/checkout_op.tcl:346
+msgid "files checked out"
+msgstr "файла са изтеглени"
+
+#: lib/checkout_op.tcl:376
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr ""
+"Преустановяване на изтеглянето на „%s“ (необходимо е пофайлово сливане)."
+
+#: lib/checkout_op.tcl:377
+msgid "File level merge required."
+msgstr "Необходимо е пофайлово сливане."
+
+#: lib/checkout_op.tcl:381
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr "Оставане върху клона „%s“."
+
+#: lib/checkout_op.tcl:452
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+"Вече не сте на локален клон.\n"
+"\n"
+"Ако искате да сте на клон, създайте базиран на „Това несвързано изтегляне“."
+
+#: lib/checkout_op.tcl:503 lib/checkout_op.tcl:507
+#, tcl-format
+msgid "Checked out '%s'."
+msgstr "„%s“ е изтеглен."
+
+#: lib/checkout_op.tcl:535
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr ""
+"Зануляването на „%s“ към „%s“ ще доведе до загубването на следните подавания:"
+
+#: lib/checkout_op.tcl:557
+msgid "Recovering lost commits may not be easy."
+msgstr "Възстановяването на загубените подавания може да е трудно."
+
+#: lib/checkout_op.tcl:562
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr "Зануляване на „%s“?"
+
+#: lib/checkout_op.tcl:571 lib/branch_create.tcl:85
+msgid "Reset"
+msgstr "Отначало"
+
+#: lib/checkout_op.tcl:635
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched.  We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred.  %s will now close and give up."
+msgstr ""
+"Неуспешно задаване на текущия клон.\n"
+"\n"
+"Работната директория е само частично обновена: файловете са обновени "
+"успешно, но някой от вътрешните, служебни файлове на Git не е бил.\n"
+"\n"
+"Това състояние е аварийно и не трябва да се случва. Програмата „%s“ ще "
+"преустанови работа."
+
+#: lib/branch_create.tcl:23
+msgid "Create Branch"
+msgstr "Създаване на клон"
+
+#: lib/branch_create.tcl:28
+msgid "Create New Branch"
+msgstr "Създаване на нов клон"
+
+#: lib/branch_create.tcl:42
+msgid "Branch Name"
+msgstr "Име на клона"
+
+#: lib/branch_create.tcl:57
+msgid "Match Tracking Branch Name"
+msgstr "Съвпадане по името на следения клон"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "Начална версия"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "Обновяване на съществуващ клон:"
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "Не"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "Само тривиално превъртащо сливане"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "Преминаване към клона след създаването му"
+
+#: lib/branch_create.tcl:132
+msgid "Please select a tracking branch."
+msgstr "Изберете клон за следени."
+
+#: lib/branch_create.tcl:141
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr "Клонът, който се следи „%s“ не съществува в отдалеченото хранилище."
+
+#: lib/console.tcl:59
+msgid "Working... please wait..."
+msgstr "В момента се извършва действие, изчакайте…"
+
+#: lib/console.tcl:186
+msgid "Success"
+msgstr "Успех"
+
+#: lib/console.tcl:200
+msgid "Error: Command Failed"
+msgstr "Грешка: неуспешно изпълнение на команда"
+
+#: lib/choose_rev.tcl:52
+msgid "This Detached Checkout"
+msgstr "Това несвързано изтегляне"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "Израз за версия"
+
+#: lib/choose_rev.tcl:72
+msgid "Local Branch"
+msgstr "Локален клон"
+
+#: lib/choose_rev.tcl:77
+msgid "Tracking Branch"
+msgstr "Следящ клон"
+
+#: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544
+msgid "Tag"
+msgstr "Етикет"
+
+#: lib/choose_rev.tcl:321
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "Неправилна версия: %s"
+
+#: lib/choose_rev.tcl:342
+msgid "No revision selected."
+msgstr "Не е избрана версия."
+
+#: lib/choose_rev.tcl:350
+msgid "Revision expression is empty."
+msgstr "Изразът за версия е празен."
+
+#: lib/choose_rev.tcl:537
+msgid "Updated"
+msgstr "Обновен"
+
+#: lib/choose_rev.tcl:565
+msgid "URL"
+msgstr "Адрес"
+
+#: lib/line.tcl:17
+msgid "Goto Line:"
+msgstr "Към ред:"
+
+#: lib/line.tcl:23
+msgid "Go"
+msgstr "Придвижване"
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit.  There is no commit before this "
+"to amend.\n"
+msgstr ""
+"Няма какво да се поправи.\n"
+"\n"
+"Ще създадете първоначалното подаване. Преди него няма други подавания, които "
+"да поправите.\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed.  You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"По време на сливане не може да поправяте.\n"
+"\n"
+"В момента все още не сте завършили операция по сливане. Не може да поправите "
+"предишното подаване, освен ако първо не преустановите текущото сливане.\n"
+
+#: lib/commit.tcl:48
+msgid "Error loading commit data for amend:"
+msgstr "Грешка при зареждане на данните от подаване, които да се поправят:"
+
+#: lib/commit.tcl:75
+msgid "Unable to obtain your identity:"
+msgstr "Идентификацията ви не може да бъде определена:"
+
+#: lib/commit.tcl:80
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "Неправилно поле GIT_COMMITTER_IDENT:"
+
+#: lib/commit.tcl:129
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr "предупреждение: Tcl не поддържа кодирането „%s“."
+
+#: lib/commit.tcl:149
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan.  A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Състоянието при последната проверка не отговаря на състоянието на "
+"хранилището.\n"
+"\n"
+"Някой друг процес за Git е променил хранилището междувременно. Състоянието "
+"трябва да бъде проверено преди ново подаване.\n"
+"\n"
+"Автоматично ще започне нова проверка.\n"
+
+#: lib/commit.tcl:173
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts.  You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"Неслетите файлове не могат да бъдат подавани.\n"
+"\n"
+"Във файла „%s“ има конфликти при сливане. За да го подадете, трябва първо да "
+"коригирате конфликтите и да добавите файла към индекса за подаване.\n"
+
+#: lib/commit.tcl:181
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"Непознато състояние на файл „%s“.\n"
+"\n"
+"Файлът „%s“ не може да бъде подаден чрез текущата програма.\n"
+
+#: lib/commit.tcl:189
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"Няма промени за подаване.\n"
+"\n"
+"Трябва да добавите поне 1 файл към индекса, преди да подадете.\n"
+
+#: lib/commit.tcl:204
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentence what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"Задайте добро съобщение при подаване.\n"
+"\n"
+"Използвайте следния формат:\n"
+"\n"
+"⁃ Първи ред: описание в едно изречение на промяната.\n"
+"⁃ Втори ред: празен.\n"
+"⁃ Останалите редове: опишете защо се налага тази промяна.\n"
+
+#: lib/commit.tcl:235
+msgid "Calling pre-commit hook..."
+msgstr "Изпълняване на куката преди подаване…"
+
+#: lib/commit.tcl:250
+msgid "Commit declined by pre-commit hook."
+msgstr "Подаването е отхвърлено от куката преди подаване."
+
+#: lib/commit.tcl:269
+msgid ""
+"You are about to commit on a detached head. This is a potentially dangerous "
+"thing to do because if you switch to another branch you will lose your "
+"changes and it can be difficult to retrieve them later from the reflog. You "
+"should probably cancel this commit and create a new branch to continue.\n"
+" \n"
+" Do you really want to proceed with your Commit?"
+msgstr ""
+"Ще подадете към несвързан връх. Това действие е опасно, защото при "
+"преминаването към който и да е клон ще загубите промените си и не е сигурно, "
+"че ще можете по-късно да ги възстановите чрез журнала на указателите. Най-"
+"вероятно трябва първо да създадете клон базиран на текущото състояние и да "
+"подадете към него.\n"
+" \n"
+"Сигурни ли сте, че искате да подадете точно сега?"
+
+#: lib/commit.tcl:290
+msgid "Calling commit-msg hook..."
+msgstr "Изпълняване на куката за съобщението при подаване…"
+
+#: lib/commit.tcl:305
+msgid "Commit declined by commit-msg hook."
+msgstr "Подаването е отхвърлено от куката за съобщението при подаване."
+
+#: lib/commit.tcl:318
+msgid "Committing changes..."
+msgstr "Подаване на промените."
+
+#: lib/commit.tcl:334
+msgid "write-tree failed:"
+msgstr "неуспешно запазване на дървото (write-tree):"
+
+#: lib/commit.tcl:335 lib/commit.tcl:379 lib/commit.tcl:400
+msgid "Commit failed."
+msgstr "Неуспешно подаване."
+
+#: lib/commit.tcl:352
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr "Подаването „%s“ изглежда повредено"
+
+#: lib/commit.tcl:357
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+"Няма промени за подаване.\n"
+"\n"
+"В това подаване не са променяни никакви файлове, а и не е подаване със "
+"сливане.\n"
+"\n"
+"Автоматично ще започне нова проверка.\n"
+
+#: lib/commit.tcl:364
+msgid "No changes to commit."
+msgstr "Няма промени за подаване."
+
+#: lib/commit.tcl:378
+msgid "commit-tree failed:"
+msgstr "неуспешно подаване на дървото (commit-tree):"
+
+#: lib/commit.tcl:399
+msgid "update-ref failed:"
+msgstr "неуспешно обновяване на указателите (update-ref):"
+
+#: lib/commit.tcl:492
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr "Успешно подаване %s: %s"
+
+#: lib/branch_delete.tcl:16
+msgid "Delete Branch"
+msgstr "Изтриване на клон"
+
+#: lib/branch_delete.tcl:21
+msgid "Delete Local Branch"
+msgstr "Изтриване на локален клон"
+
+#: lib/branch_delete.tcl:39
+msgid "Local Branches"
+msgstr "Локални клони"
+
+#: lib/branch_delete.tcl:51
+msgid "Delete Only If Merged Into"
+msgstr "Изтриване, само ако промените са слети и другаде"
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr "Не всички промени в клоните са слети в %s:"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+"Неуспешно триене на клони:\n"
+"%s"
+
+#: lib/blame.tcl:73
+msgid "File Viewer"
+msgstr "Преглед на файлове"
+
+#: lib/blame.tcl:79
+msgid "Commit:"
+msgstr "Подаване:"
+
+#: lib/blame.tcl:280
+msgid "Copy Commit"
+msgstr "Копиране на подаване"
+
+#: lib/blame.tcl:284
+msgid "Find Text..."
+msgstr "Търсене на текст…"
+
+#: lib/blame.tcl:288
+msgid "Goto Line..."
+msgstr "Към ред…"
+
+#: lib/blame.tcl:297
+msgid "Do Full Copy Detection"
+msgstr "Пълно търсене на копиране"
+
+#: lib/blame.tcl:301
+msgid "Show History Context"
+msgstr "Показване на контекста от историята"
+
+#: lib/blame.tcl:304
+msgid "Blame Parent Commit"
+msgstr "Анотиране на родителското подаване"
+
+#: lib/blame.tcl:466
+#, tcl-format
+msgid "Reading %s..."
+msgstr "%s се чете…"
+
+#: lib/blame.tcl:594
+msgid "Loading copy/move tracking annotations..."
+msgstr "Зареждане на анотациите за проследяване на копирането/преместването…"
+
+#: lib/blame.tcl:614
+msgid "lines annotated"
+msgstr "реда анотирани"
+
+#: lib/blame.tcl:806
+msgid "Loading original location annotations..."
+msgstr "Зареждане на анотациите за първоначалното местоположение…"
+
+#: lib/blame.tcl:809
+msgid "Annotation complete."
+msgstr "Анотирането завърши."
+
+#: lib/blame.tcl:839
+msgid "Busy"
+msgstr "Операцията не е завършила"
+
+#: lib/blame.tcl:840
+msgid "Annotation process is already running."
+msgstr "В момента тече процес на анотиране."
+
+#: lib/blame.tcl:879
+msgid "Running thorough copy detection..."
+msgstr "Изпълнява се цялостен процес на откриване на копиране…"
+
+#: lib/blame.tcl:947
+msgid "Loading annotation..."
+msgstr "Зареждане на анотации…"
+
+#: lib/blame.tcl:1000
+msgid "Author:"
+msgstr "Автор:"
+
+#: lib/blame.tcl:1004
+msgid "Committer:"
+msgstr "Подал:"
+
+#: lib/blame.tcl:1009
+msgid "Original File:"
+msgstr "Първоначален файл:"
+
+#: lib/blame.tcl:1057
+msgid "Cannot find HEAD commit:"
+msgstr "Подаването за връх HEAD не може да се открие:"
+
+#: lib/blame.tcl:1112
+msgid "Cannot find parent commit:"
+msgstr "Родителското подаване не може да бъде открито"
+
+#: lib/blame.tcl:1127
+msgid "Unable to display parent"
+msgstr "Родителят не може да бъде показан"
+
+#: lib/blame.tcl:1269
+msgid "Originally By:"
+msgstr "Първоначално от:"
+
+#: lib/blame.tcl:1275
+msgid "In File:"
+msgstr "Във файл:"
+
+#: lib/blame.tcl:1280
+msgid "Copied Or Moved Here By:"
+msgstr "Копирано или преместено тук от:"
+
+#: lib/index.tcl:6
+msgid "Unable to unlock the index."
+msgstr "Индексът не може да бъде отключен."
+
+#: lib/index.tcl:17
+msgid "Index Error"
+msgstr "Грешка в индекса"
+
+#: lib/index.tcl:19
+msgid ""
+"Updating the Git index failed.  A rescan will be automatically started to "
+"resynchronize git-gui."
+msgstr ""
+"Неуспешно обновяване на индекса на Git. Автоматично ще започне нова проверка "
+"за синхронизирането на git-gui."
+
+#: lib/index.tcl:30
+msgid "Continue"
+msgstr "Продължаване"
+
+#: lib/index.tcl:33
+msgid "Unlock Index"
+msgstr "Отключване на индекса"
+
+#: lib/index.tcl:298
+#, tcl-format
+msgid "Unstaging %s from commit"
+msgstr "Изваждане на %s от подаването"
+
+#: lib/index.tcl:337
+msgid "Ready to commit."
+msgstr "Готовност за подаване."
+
+#: lib/index.tcl:350
+#, tcl-format
+msgid "Adding %s"
+msgstr "Добавяне на „%s“"
+
+#: lib/index.tcl:380
+#, tcl-format
+msgid "Stage %d untracked files?"
+msgstr "Да се добавят ли %d на брой неследени файла към индекса?"
+
+#: lib/index.tcl:428
+#, tcl-format
+msgid "Revert changes in file %s?"
+msgstr "Да се махнат ли промените във файла „%s“?"
+
+#: lib/index.tcl:430
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr "Да се махнат ли промените в тези %i файла?"
+
+#: lib/index.tcl:438
+msgid "Any unstaged changes will be permanently lost by the revert."
+msgstr ""
+"Всички промени, които не са били вкарани в индекса, ще бъдат безвъзвратно "
+"загубени."
+
+#: lib/index.tcl:441
+msgid "Do Nothing"
+msgstr "Нищо да не се прави"
+
+#: lib/index.tcl:459
+msgid "Reverting selected files"
+msgstr "Махане на промените в избраните файлове"
+
+#: lib/index.tcl:463
+#, tcl-format
+msgid "Reverting %s"
+msgstr "Махане на промените в „%s“"
+
+#: lib/encoding.tcl:443
+msgid "Default"
+msgstr "Стандартното"
+
+#: lib/encoding.tcl:448
+#, tcl-format
+msgid "System (%s)"
+msgstr "Системното (%s)"
+
+#: lib/encoding.tcl:459 lib/encoding.tcl:465
+msgid "Other"
+msgstr "Друго"
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Неправилни данни от Git: %s"
+
+#: lib/database.tcl:42
+msgid "Number of loose objects"
+msgstr "Брой непакетирани обекти"
+
+#: lib/database.tcl:43
+msgid "Disk space used by loose objects"
+msgstr "Дисково пространство заето от непакетирани обекти"
+
+#: lib/database.tcl:44
+msgid "Number of packed objects"
+msgstr "Брой пакетирани обекти"
+
+#: lib/database.tcl:45
+msgid "Number of packs"
+msgstr "Брой пакети"
+
+#: lib/database.tcl:46
+msgid "Disk space used by packed objects"
+msgstr "Дисково пространство заето от пакетирани обекти"
+
+#: lib/database.tcl:47
+msgid "Packed objects waiting for pruning"
+msgstr "Пакетирани обекти за окастряне"
+
+#: lib/database.tcl:48
+msgid "Garbage files"
+msgstr "Файлове за боклука"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "Компресиране на базата с данни за обектите"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "Проверка на базата с данни за обектите с програмата fsck-objects"
+
+#: lib/database.tcl:107
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+"В това хранилище в момента има към %i непакетирани обекти.\n"
+"\n"
+"Зd добра производителност се препоръчва да компресирате базата с данни за "
+"обектите.\n"
+"\n"
+"Да се започне ли компресирането?"
+
+#: lib/error.tcl:20 lib/error.tcl:116
+msgid "error"
+msgstr "грешка"
+
+#: lib/error.tcl:36
+msgid "warning"
+msgstr "предупреждение"
+
+#: lib/error.tcl:96
+msgid "You must correct the above errors before committing."
+msgstr "Преди да можете да подадете, оправете горните грешки."
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"По време на поправяне не може да сливане.\n"
+"\n"
+"Трябва да завършите поправянето на текущото подаване, преди да започнете "
+"сливане.\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan.  A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Последно установеното състояние не отговаря на това в хранилището.\n"
+"\n"
+"Някой друг процес за Git е променил хранилището междувременно. Състоянието "
+"трябва да бъде проверено, преди да се извърши сливане.\n"
+"\n"
+"Автоматично ще започне нова проверка.\n"
+"\n"
+
+#: lib/merge.tcl:45
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge.  Only then can you begin another merge.\n"
+msgstr ""
+"В момента тече сливане, но има конфликти.\n"
+"\n"
+"Погледнете файла „%s“.\n"
+"\n"
+"Трябва да коригирате конфликтите в него, да го добавите към индекса и да "
+"завършите текущото сливане чрез подаване. Чак тогава може да започнете ново "
+"сливане.\n"
+
+#: lib/merge.tcl:55
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge.  Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"В момента тече подаване.\n"
+"\n"
+"Файлът „%s“ е променен.\n"
+"\n"
+"Трябва да завършите текущото подаване, преди да започнете сливане. Така ще "
+"можете лесно да преустановите сливането, ако възникне нужда.\n"
+
+#: lib/merge.tcl:108
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s от общо %s"
+
+#: lib/merge.tcl:122
+#, tcl-format
+msgid "Merging %s and %s..."
+msgstr "Сливане на „%s“ и „%s“…"
+
+#: lib/merge.tcl:133
+msgid "Merge completed successfully."
+msgstr "Сливането завърши успешно."
+
+#: lib/merge.tcl:135
+msgid "Merge failed.  Conflict resolution is required."
+msgstr "Неуспешно сливане — има конфликти за коригиране."
+
+#: lib/merge.tcl:160
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "Сливане в „%s“"
+
+#: lib/merge.tcl:179
+msgid "Revision To Merge"
+msgstr "Версия за сливане"
+
+#: lib/merge.tcl:214
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"Поправянето не може да бъде преустановено.\n"
+"\n"
+"Трябва да завършите поправката на това подаване.\n"
+
+#: lib/merge.tcl:224
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"Да се преустанови ли сливането?\n"
+"\n"
+"В такъв случай *ВСИЧКИ* неподадени промени ще бъдат безвъзвратно загубени.\n"
+"\n"
+"Наистина ли да се преустанови сливането?"
+
+#: lib/merge.tcl:230
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"Да се занулят ли промените?\n"
+"\n"
+"В такъв случай *ВСИЧКИ* неподадени промени ще бъдат безвъзвратно загубени.\n"
+"\n"
+"Наистина ли да се занулят промените?"
+
+#: lib/merge.tcl:241
+msgid "Aborting"
+msgstr "Преустановяване"
+
+#: lib/merge.tcl:241
+msgid "files reset"
+msgstr "файла със занулени промени"
+
+#: lib/merge.tcl:269
+msgid "Abort failed."
+msgstr "Неуспешно преустановяване."
+
+#: lib/merge.tcl:271
+msgid "Abort completed.  Ready."
+msgstr "Успешно преустановяване. Готовност за следващо действие."
diff --git a/git-gui/po/glossary/bg.po b/git-gui/po/glossary/bg.po
new file mode 100644
index 0000000..8b71fad
--- /dev/null
+++ b/git-gui/po/glossary/bg.po
@@ -0,0 +1,287 @@
+# Bulgarian translation of git-gui-glossary po-file.
+# Copyright (C) 2012, 2013, 2014 Alexander Shopov <ash@kambanaria.org>.
+# This file is distributed under the same license as the git package.
+# Alexander Shopov <ash@kambanaria.org>, 2012, 2013, 2014.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui-glossary master\n"
+"POT-Creation-Date: 2014-01-13 21:39+0200\n"
+"PO-Revision-Date: 2014-01-13 21:39+0200\n"
+"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
+"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
+"Language: bg\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+msgid ""
+"English Term (Dear translator: This file will never be visible to the user!)"
+msgstr "Термин"
+
+#. ""
+msgid "amend"
+msgstr "поправям"
+
+#. ""
+msgid "annotate"
+msgstr "анотирам"
+
+#. "A 'branch' is an active line of development."
+msgid "branch [noun]"
+msgstr "клон, разклонение [съществително]"
+
+#. ""
+msgid "branch [verb]"
+msgstr "разклонявам [глагол]"
+
+#. ""
+msgid "checkout [noun]"
+msgstr "изтегляне [съществително]"
+
+#. "The action of updating the working tree to a revision which was stored in the object database."
+msgid "checkout [verb]"
+msgstr "изтегляне [глагол]"
+
+#. ""
+msgid "clone [verb]"
+msgstr "клонирам [глагол]"
+
+#. "A single point in the git history."
+msgid "commit [noun]"
+msgstr "подаване [съществително]"
+
+#. "The action of storing a new snapshot of the project's state in the git history."
+msgid "commit [verb]"
+msgstr "подавам [съществително]"
+
+#. ""
+msgid "diff [noun]"
+msgstr "разлика/промени [съществително]"
+
+#. ""
+msgid "diff [verb]"
+msgstr "изчислявам разлика/промени [глагол]"
+
+#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+msgid "fast forward merge"
+msgstr "превъртащо/директно/тривиално сливане"
+
+#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+msgid "fetch"
+msgstr "доставяне"
+
+#. "One context of consecutive lines in a whole patch, which consists of many such hunks"
+msgid "hunk"
+msgstr "парче"
+
+#. "A collection of files. The index is a stored version of your working tree."
+msgid "index (in git-gui: staging area)"
+msgstr "скеле/индекс/изба"
+
+#. "A successful merge results in the creation of a new commit representing the result of the merge."
+msgid "merge [noun]"
+msgstr "сливане/обединяване [съществително]"
+
+#. "To bring the contents of another branch into the current branch."
+msgid "merge [verb]"
+msgstr "сливам/обединявам [глагол]"
+
+#. ""
+msgid "message"
+msgstr "съобщение"
+
+#. "Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in 'remotes/<name>'."
+msgid "prune"
+msgstr "окастрям"
+
+#. "Pulling a branch means to fetch it and merge it."
+msgid "pull"
+msgstr "издърпвам"
+
+#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+msgid "push"
+msgstr "изтласквам"
+
+#. ""
+msgid "redo"
+msgstr "повтарям/правя наново"
+
+#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
+msgid "remote"
+msgstr "отдалечено хранилище"
+
+#. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)"
+msgid "repository"
+msgstr "хранилище"
+
+#. ""
+msgid "reset"
+msgstr "занулявам/отменям"
+
+#. ""
+msgid "revert"
+msgstr "връщам/отменям"
+
+#. "A particular state of files and directories which was stored in the object database."
+msgid "revision"
+msgstr "версия"
+
+#. ""
+msgid "sign off"
+msgstr "подписвам"
+
+#. ""
+msgid "staging area"
+msgstr "скеле/индекс/изба"
+
+#. ""
+msgid "status"
+msgstr "състояние"
+
+#. "A ref pointing to a tag or commit object"
+msgid "tag [noun]"
+msgstr "етикет [съществително]"
+
+#. ""
+msgid "tag [verb]"
+msgstr "задавам етикет [глагол]"
+
+#. "A regular git branch that is used to follow changes from another repository."
+msgid "tracking branch"
+msgstr "следящ клон"
+
+#. ""
+msgid "undo"
+msgstr "отменям"
+
+#. ""
+msgid "update"
+msgstr "обновявам"
+
+#. ""
+msgid "verify"
+msgstr "проверявам"
+
+#. "The tree of actual checked out files."
+msgid "working copy, working tree"
+msgstr "работно копие/работно дърво"
+
+#. "a commit that succeeds the current one in git's graph of commits (not necessarily directly)"
+msgid "ancestor"
+msgstr "предшественик"
+
+#. "prematurely stop and abandon an operation"
+msgid "abort"
+msgstr "преустановявам"
+
+#. "a repository with only .git directory, without working directory"
+msgid "bare repository"
+msgstr "голо хранилище"
+
+#. "a parent version of the current file"
+msgid "base"
+msgstr "родителска версия"
+
+#. "get the authors responsible for each line in a file"
+msgid "blame"
+msgstr "анотирам/анотиране"
+
+#. "to select and apply a single commit without merging"
+msgid "cherry-pick"
+msgstr "отбирам"
+
+#. "a commit that directly succeeds the current one in git's graph of commits"
+msgid "child"
+msgstr "дете"
+
+#. "clean the state of the git repository, often after manually stopped operation"
+msgid "cleanup"
+msgstr "зачиствам"
+
+#. "a message that gets attached with any commit"
+msgid "commit message"
+msgstr "съобщение при подаване"
+
+#. "a commit that precedes the current one in git's graph of commits (not necessarily directly)"
+msgid "descendant"
+msgstr "наследник"
+
+#. "checkout of a revision rather than a some head"
+msgid "detached checkout"
+msgstr "несвързано изтегляне"
+
+#. "any merge strategy that works on a file by file basis"
+msgid "file level merging"
+msgstr "пофайлово сливане"
+
+#. "the last revision in a branch"
+msgid "head"
+msgstr "глава/връх (на клон, разработка)"
+
+#. "script that gets executed automatically on some event"
+msgid "hook"
+msgstr "кука/автоматичен скрипт"
+
+#. "the first checkout during a clone operation"
+msgid "initial checkout"
+msgstr "първоначално изтегляне"
+
+#. "a branch that resides in the local git repository"
+msgid "local branch"
+msgstr "локален клон"
+
+#. "a Git object that is not part of any pack"
+msgid "loose object"
+msgstr "непакетиран обект"
+
+#. "a branch called by convention 'master' that exists in a newly created git repository"
+msgid "master branch"
+msgstr "основен клон"
+
+#. "a remote called by convention 'origin' that the current git repository has been cloned from"
+msgid "origin"
+msgstr "хранилище-източник"
+
+#. "a file containing many git objects packed together"
+msgid "pack [noun]"
+msgstr "етикет"
+
+#. "a Git object part of some pack"
+msgid "packed object"
+msgstr "пакетиран обект"
+
+#. "a commit that directly precedes the current one in git's graph of commits"
+msgid "parent"
+msgstr "родител"
+
+#. "the log file containing all states of the HEAD reference (in other words past pristine states of the working copy)"
+msgid "reflog"
+msgstr "журнал на указателите"
+
+#. "decide which changes from alternative versions of a file should persist in Git"
+msgid "resolve (a conflict)"
+msgstr "коригирам (конфликт)"
+
+#. "abandon changes and go to pristine version"
+msgid "revert changes"
+msgstr "връщане на оригинала"
+
+#. "expression that signifies a revision in git"
+msgid "revision expression"
+msgstr "израз за версия"
+
+#. "add some content of files and directories to the staging area in preparation for a commit"
+msgid "stage/unstage"
+msgstr "(добавяне) към скелето за подаване/изваждане от скелето за подаване"
+
+#. "temporarily save changes in a stack without committing"
+msgid "stash"
+msgstr "скатавам промени"
+
+#. "file whose content is tracked/not tracked by git"
+msgid "tracked/untracked"
+msgstr "следен/неследен"
diff --git a/git-gui/po/glossary/git-gui-glossary.txt b/git-gui/po/glossary/git-gui-glossary.txt
index 9b31f69..4093046 100644
--- a/git-gui/po/glossary/git-gui-glossary.txt
+++ b/git-gui/po/glossary/git-gui-glossary.txt
@@ -36,3 +36,32 @@
 "update"	""
 "verify"	""
 "working copy, working tree"	"The tree of actual checked out files."
+"ancestor"	"a commit that succeeds the current one in git's graph of commits (not necessarily directly)"
+"abort"	"prematurely stop and abandon an operation"
+"bare repository"	"a repository with only .git directory, without working directory"
+"base"	"a parent version of the current file"
+"blame"	"get the authors responsible for each line in a file"
+"cherry-pick"	"to select and apply a single commit without merging"
+"child"	"a commit that directly succeeds the current one in git's graph of commits"
+"cleanup"	"clean the state of the git repository, often after manually stopped operation"
+"commit message"	"a message that gets attached with any commit"
+"descendant"	"a commit that precedes the current one in git's graph of commits (not necessarily directly)"
+"detached checkout"	"checkout of a revision rather than a some head"
+"file level merging"	"any merge strategy that works on a file by file basis"
+"head"	"the last revision in a branch"
+"hook"	"script that gets executed automatically on some event"
+"initial checkout"	"the first checkout during a clone operation"
+"local branch"	"a branch that resides in the local git repository"
+"loose object"	"a Git object that is not part of any pack"
+"master branch"	"a branch called by convention 'master' that exists in a newly created git repository"
+"origin"	"a remote called by convention 'origin' that the current git repository has been cloned from"
+"pack [noun]"	"a file containing many git objects packed together"
+"packed object"	"a Git object part of some pack"
+"parent"	"a commit that directly precedes the current one in git's graph of commits"
+"reflog"	"the log file containing all states of the HEAD reference (in other words past pristine states of the working copy)"
+"resolve (a conflict)"	"decide which changes from alternative versions of a file should persist in Git"
+"revert changes"	"abandon changes and go to pristine version"
+"revision expression"	"expression that signifies a revision in git"
+"stage/unstage"	"add some content of files and directories to the staging area in preparation for a commit"
+"stash"	"temporarily save changes in a stack without committing"
+"tracked/untracked"	"file whose content is tracked/not tracked by git"
diff --git a/git-gui/po/po2msg.sh b/git-gui/po/po2msg.sh
old mode 100644
new mode 100755
diff --git a/git-gui/windows/git-gui.sh b/git-gui/windows/git-gui.sh
old mode 100644
new mode 100755
diff --git a/git-instaweb.sh b/git-instaweb.sh
index 01a1b05..e93a238 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -581,7 +581,7 @@
 
 gitweb_conf() {
 	cat > "$fqgitdir/gitweb/gitweb_config.perl" <<EOF
-#!/usr/bin/perl
+#!@@PERL@@
 our \$projectroot = "$(dirname "$fqgitdir")";
 our \$git_temp = "$fqgitdir/gitweb/tmp";
 our \$projects_list = \$projectroot;
diff --git a/git-lost-found.sh b/git-lost-found.sh
deleted file mode 100755
index 0b3e8c7..0000000
--- a/git-lost-found.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-USAGE=''
-SUBDIRECTORY_OK='Yes'
-OPTIONS_SPEC=
-. git-sh-setup
-
-echo "WARNING: '$0' is deprecated in favor of 'git fsck --lost-found'" >&2
-
-if [ "$#" != "0" ]
-then
-    usage
-fi
-
-laf="$GIT_DIR/lost-found"
-rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit
-
-git fsck --full --no-reflogs |
-while read dangling type sha1
-do
-	case "$dangling" in
-	dangling)
-		if git rev-parse -q --verify "$sha1^0" >/dev/null
-		then
-			dir="$laf/commit"
-			git show-branch "$sha1"
-		else
-			dir="$laf/other"
-		fi
-		echo "$sha1" >"$dir/$sha1"
-		;;
-	esac
-done
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index feee6a4..c45a020 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -1,5 +1,4 @@
-#!/bin/sh
-# git-mergetool--lib is a library for common merge tool functions
+# git-mergetool--lib is a shell library for common merge tool functions
 
 : ${MERGE_TOOLS_DIR=$(git --exec-path)/mergetools}
 
@@ -250,7 +249,8 @@
 		else
 			tools="opendiff kdiff3 tkdiff xxdiff meld $tools"
 		fi
-		tools="$tools gvimdiff diffuse ecmerge p4merge araxis bc3 codecompare"
+		tools="$tools gvimdiff diffuse diffmerge ecmerge"
+		tools="$tools p4merge araxis bc3 codecompare"
 	fi
 	case "${VISUAL:-$EDITOR}" in
 	*vim*)
@@ -263,7 +263,7 @@
 }
 
 show_tool_help () {
-	tool_opt="'git ${TOOL_MODE}tool --tool-<tool>'"
+	tool_opt="'git ${TOOL_MODE}tool --tool=<tool>'"
 
 	tab='	'
 	LF='
diff --git a/git-p4.py b/git-p4.py
index 31e71ff..cdfa2df 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -310,8 +310,8 @@
 #
 # return the raw p4 type of a file (text, text+ko, etc)
 #
-def p4_type(file):
-    results = p4CmdList(["fstat", "-T", "headType", file])
+def p4_type(f):
+    results = p4CmdList(["fstat", "-T", "headType", wildcard_encode(f)])
     return results[0]['headType']
 
 #
@@ -780,11 +780,14 @@
     # dictionary of all client parameters
     entry = specList[0]
 
+    # the //client/ name
+    client_name = entry["Client"]
+
     # just the keys that start with "View"
     view_keys = [ k for k in entry.keys() if k.startswith("View") ]
 
     # hold this new View
-    view = View()
+    view = View(client_name)
 
     # append the lines, in order, to the view
     for view_num in range(len(view_keys)):
@@ -1217,7 +1220,7 @@
             editor = os.environ.get("P4EDITOR")
         else:
             editor = read_pipe("git var GIT_EDITOR").strip()
-        system(editor + " " + template_file)
+        system([editor, template_file])
 
         # If the file was not saved, prompt to see if this patch should
         # be skipped.  But skip this verification step if configured so.
@@ -1308,7 +1311,7 @@
             else:
                 die("unknown modifier %s for %s" % (modifier, path))
 
-        diffcmd = "git format-patch -k --stdout \"%s^\"..\"%s\"" % (id, id)
+        diffcmd = "git diff-tree -p \"%s\"" % (id)
         patchcmd = diffcmd + " | git apply "
         tryPatchCmd = patchcmd + "--check -"
         applyPatchCmd = patchcmd + "--check --apply -"
@@ -1555,8 +1558,8 @@
             for b in body:
                 labelTemplate += "\t" + b + "\n"
             labelTemplate += "View:\n"
-            for mapping in clientSpec.mappings:
-                labelTemplate += "\t%s\n" % mapping.depot_side.path
+            for depot_side in clientSpec.mappings:
+                labelTemplate += "\t%s\n" % depot_side
 
             if self.dry_run:
                 print "Would create p4 label %s for tag" % name
@@ -1568,7 +1571,7 @@
 
                 # Use the label
                 p4_system(["tag", "-l", name] +
-                          ["%s@%s" % (mapping.depot_side.path, changelist) for mapping in clientSpec.mappings])
+                          ["%s@%s" % (depot_side, changelist) for depot_side in clientSpec.mappings])
 
                 if verbose:
                     print "created p4 label for tag %s" % name
@@ -1796,117 +1799,16 @@
     """Represent a p4 view ("p4 help views"), and map files in a
        repo according to the view."""
 
-    class Path(object):
-        """A depot or client path, possibly containing wildcards.
-           The only one supported is ... at the end, currently.
-           Initialize with the full path, with //depot or //client."""
-
-        def __init__(self, path, is_depot):
-            self.path = path
-            self.is_depot = is_depot
-            self.find_wildcards()
-            # remember the prefix bit, useful for relative mappings
-            m = re.match("(//[^/]+/)", self.path)
-            if not m:
-                die("Path %s does not start with //prefix/" % self.path)
-            prefix = m.group(1)
-            if not self.is_depot:
-                # strip //client/ on client paths
-                self.path = self.path[len(prefix):]
-
-        def find_wildcards(self):
-            """Make sure wildcards are valid, and set up internal
-               variables."""
-
-            self.ends_triple_dot = False
-            # There are three wildcards allowed in p4 views
-            # (see "p4 help views").  This code knows how to
-            # handle "..." (only at the end), but cannot deal with
-            # "%%n" or "*".  Only check the depot_side, as p4 should
-            # validate that the client_side matches too.
-            if re.search(r'%%[1-9]', self.path):
-                die("Can't handle %%n wildcards in view: %s" % self.path)
-            if self.path.find("*") >= 0:
-                die("Can't handle * wildcards in view: %s" % self.path)
-            triple_dot_index = self.path.find("...")
-            if triple_dot_index >= 0:
-                if triple_dot_index != len(self.path) - 3:
-                    die("Can handle only single ... wildcard, at end: %s" %
-                        self.path)
-                self.ends_triple_dot = True
-
-        def ensure_compatible(self, other_path):
-            """Make sure the wildcards agree."""
-            if self.ends_triple_dot != other_path.ends_triple_dot:
-                 die("Both paths must end with ... if either does;\n" +
-                     "paths: %s %s" % (self.path, other_path.path))
-
-        def match_wildcards(self, test_path):
-            """See if this test_path matches us, and fill in the value
-               of the wildcards if so.  Returns a tuple of
-               (True|False, wildcards[]).  For now, only the ... at end
-               is supported, so at most one wildcard."""
-            if self.ends_triple_dot:
-                dotless = self.path[:-3]
-                if test_path.startswith(dotless):
-                    wildcard = test_path[len(dotless):]
-                    return (True, [ wildcard ])
-            else:
-                if test_path == self.path:
-                    return (True, [])
-            return (False, [])
-
-        def match(self, test_path):
-            """Just return if it matches; don't bother with the wildcards."""
-            b, _ = self.match_wildcards(test_path)
-            return b
-
-        def fill_in_wildcards(self, wildcards):
-            """Return the relative path, with the wildcards filled in
-               if there are any."""
-            if self.ends_triple_dot:
-                return self.path[:-3] + wildcards[0]
-            else:
-                return self.path
-
-    class Mapping(object):
-        def __init__(self, depot_side, client_side, overlay, exclude):
-            # depot_side is without the trailing /... if it had one
-            self.depot_side = View.Path(depot_side, is_depot=True)
-            self.client_side = View.Path(client_side, is_depot=False)
-            self.overlay = overlay  # started with "+"
-            self.exclude = exclude  # started with "-"
-            assert not (self.overlay and self.exclude)
-            self.depot_side.ensure_compatible(self.client_side)
-
-        def __str__(self):
-            c = " "
-            if self.overlay:
-                c = "+"
-            if self.exclude:
-                c = "-"
-            return "View.Mapping: %s%s -> %s" % \
-                   (c, self.depot_side.path, self.client_side.path)
-
-        def map_depot_to_client(self, depot_path):
-            """Calculate the client path if using this mapping on the
-               given depot path; does not consider the effect of other
-               mappings in a view.  Even excluded mappings are returned."""
-            matches, wildcards = self.depot_side.match_wildcards(depot_path)
-            if not matches:
-                return ""
-            client_path = self.client_side.fill_in_wildcards(wildcards)
-            return client_path
-
-    #
-    # View methods
-    #
-    def __init__(self):
+    def __init__(self, client_name):
         self.mappings = []
+        self.client_prefix = "//%s/" % client_name
+        # cache results of "p4 where" to lookup client file locations
+        self.client_spec_path_cache = {}
 
     def append(self, view_line):
         """Parse a view line, splitting it into depot and client
-           sides.  Append to self.mappings, preserving order."""
+           sides.  Append to self.mappings, preserving order.  This
+           is only needed for tag creation."""
 
         # Split the view line into exactly two words.  P4 enforces
         # structure on these lines that simplifies this quite a bit.
@@ -1934,76 +1836,62 @@
             depot_side = view_line[0:space_index]
             rhs_index = space_index + 1
 
-        if view_line[rhs_index] == '"':
-            # Second word is double quoted.  Make sure there is a
-            # double quote at the end too.
-            if not view_line.endswith('"'):
-                die("View line with rhs quote should end with one: %s" %
-                    view_line)
-            # skip the quotes
-            client_side = view_line[rhs_index+1:-1]
-        else:
-            client_side = view_line[rhs_index:]
-
         # prefix + means overlay on previous mapping
-        overlay = False
         if depot_side.startswith("+"):
-            overlay = True
             depot_side = depot_side[1:]
 
-        # prefix - means exclude this path
+        # prefix - means exclude this path, leave out of mappings
         exclude = False
         if depot_side.startswith("-"):
             exclude = True
             depot_side = depot_side[1:]
 
-        m = View.Mapping(depot_side, client_side, overlay, exclude)
-        self.mappings.append(m)
+        if not exclude:
+            self.mappings.append(depot_side)
+
+    def convert_client_path(self, clientFile):
+        # chop off //client/ part to make it relative
+        if not clientFile.startswith(self.client_prefix):
+            die("No prefix '%s' on clientFile '%s'" %
+                (self.client_prefix, clientFile))
+        return clientFile[len(self.client_prefix):]
+
+    def update_client_spec_path_cache(self, files):
+        """ Caching file paths by "p4 where" batch query """
+
+        # List depot file paths exclude that already cached
+        fileArgs = [f['path'] for f in files if f['path'] not in self.client_spec_path_cache]
+
+        if len(fileArgs) == 0:
+            return  # All files in cache
+
+        where_result = p4CmdList(["-x", "-", "where"], stdin=fileArgs)
+        for res in where_result:
+            if "code" in res and res["code"] == "error":
+                # assume error is "... file(s) not in client view"
+                continue
+            if "clientFile" not in res:
+                die("No clientFile in 'p4 where' output")
+            if "unmap" in res:
+                # it will list all of them, but only one not unmap-ped
+                continue
+            self.client_spec_path_cache[res['depotFile']] = self.convert_client_path(res["clientFile"])
+
+        # not found files or unmap files set to ""
+        for depotFile in fileArgs:
+            if depotFile not in self.client_spec_path_cache:
+                self.client_spec_path_cache[depotFile] = ""
 
     def map_in_client(self, depot_path):
         """Return the relative location in the client where this
            depot file should live.  Returns "" if the file should
            not be mapped in the client."""
 
-        paths_filled = []
-        client_path = ""
+        if depot_path in self.client_spec_path_cache:
+            return self.client_spec_path_cache[depot_path]
 
-        # look at later entries first
-        for m in self.mappings[::-1]:
-
-            # see where will this path end up in the client
-            p = m.map_depot_to_client(depot_path)
-
-            if p == "":
-                # Depot path does not belong in client.  Must remember
-                # this, as previous items should not cause files to
-                # exist in this path either.  Remember that the list is
-                # being walked from the end, which has higher precedence.
-                # Overlap mappings do not exclude previous mappings.
-                if not m.overlay:
-                    paths_filled.append(m.client_side)
-
-            else:
-                # This mapping matched; no need to search any further.
-                # But, the mapping could be rejected if the client path
-                # has already been claimed by an earlier mapping (i.e.
-                # one later in the list, which we are walking backwards).
-                already_mapped_in_client = False
-                for f in paths_filled:
-                    # this is View.Path.match
-                    if f.match(p):
-                        already_mapped_in_client = True
-                        break
-                if not already_mapped_in_client:
-                    # Include this file, unless it is from a line that
-                    # explicitly said to exclude it.
-                    if not m.exclude:
-                        client_path = p
-
-                # a match, even if rejected, always stops the search
-                break
-
-        return client_path
+        die( "Error: %s is not found in client spec path" % depot_path )
+        return ""
 
 class P4Sync(Command, P4UserMap):
     delete_actions = ( "delete", "move/delete", "purge" )
@@ -2130,6 +2018,10 @@
         """Look at each depotFile in the commit to figure out to what
            branch it belongs."""
 
+        if self.clientSpecDirs:
+            files = self.extractFilesFromCommit(commit)
+            self.clientSpecDirs.update_client_spec_path_cache(files)
+
         branches = {}
         fnum = 0
         while commit.has_key("depotFile%s" % fnum):
@@ -2180,9 +2072,20 @@
             git_mode = "100755"
         if type_base == "symlink":
             git_mode = "120000"
-            # p4 print on a symlink contains "target\n"; remove the newline
+            # p4 print on a symlink sometimes contains "target\n";
+            # if it does, remove the newline
             data = ''.join(contents)
-            contents = [data[:-1]]
+            if not data:
+                # Some version of p4 allowed creating a symlink that pointed
+                # to nothing.  This causes p4 errors when checking out such
+                # a change, and errors here too.  Work around it by ignoring
+                # the bad symlink; hopefully a future change fixes it.
+                print "\nIgnoring empty symlink in %s" % file['depotFile']
+                return
+            elif data[-1] == '\n':
+                contents = [data[:-1]]
+            else:
+                contents = [data]
 
         if type_base == "utf16":
             # p4 delivers different text in the python output to -G
@@ -2379,6 +2282,9 @@
             else:
                 sys.stderr.write("Ignoring file outside of prefix: %s\n" % f['path'])
 
+        if self.clientSpecDirs:
+            self.clientSpecDirs.update_client_spec_path_cache(files)
+
         self.gitStream.write("commit %s\n" % branch)
 #        gitStream.write("mark :%s\n" % details["change"])
         self.committedChanges.add(int(details["change"]))
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 0e87e09..55fe8d5 100644
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -1,4 +1,6 @@
-#!/bin/sh
+# This is a shell library to calculate the remote repository and
+# upstream branch that should be pulled by "git pull" from the current
+# branch.
 
 # git-ls-remote could be called from outside a git managed repository;
 # this would fail in that case and would issue an error message.
diff --git a/git-pull.sh b/git-pull.sh
index f0df41c..0a5aa2c 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -4,7 +4,7 @@
 #
 # Fetch one or more remote refs and merge it/them into the current HEAD.
 
-USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
+USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [--[no-]rebase|--rebase=preserve] [-s strategy]... [<fetch-options>] <repo> <head>...'
 LONG_USAGE='Fetch one or more remote refs and integrate it/them with the current HEAD.'
 SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
@@ -38,15 +38,19 @@
 test -z "$(git ls-files -u)" || die_conflict
 test -f "$GIT_DIR/MERGE_HEAD" && die_merge
 
+bool_or_string_config () {
+	git config --bool "$1" 2>/dev/null || git config "$1"
+}
+
 strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
 log_arg= verbosity= progress= recurse_submodules= verify_signatures=
-merge_args= edit=
+merge_args= edit= rebase_args=
 curr_branch=$(git symbolic-ref -q HEAD)
 curr_branch_short="${curr_branch#refs/heads/}"
-rebase=$(git config --bool branch.$curr_branch_short.rebase)
+rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
 if test -z "$rebase"
 then
-	rebase=$(git config --bool pull.rebase)
+	rebase=$(bool_or_string_config pull.rebase)
 fi
 dry_run=
 while :
@@ -110,6 +114,9 @@
 		esac
 		merge_args="$merge_args$xx "
 		;;
+	-r=*|--r=*|--re=*|--reb=*|--reba=*|--rebas=*|--rebase=*)
+		rebase="${1#*=}"
+		;;
 	-r|--r|--re|--reb|--reba|--rebas|--rebase)
 		rebase=true
 		;;
@@ -145,13 +152,27 @@
 	shift
 done
 
+case "$rebase" in
+preserve)
+	rebase=true
+	rebase_args=--preserve-merges
+	;;
+true|false|'')
+	;;
+*)
+	echo "Invalid value for --rebase, should be true, false, or preserve"
+	usage
+	exit 1
+	;;
+esac
+
 error_on_no_merge_candidates () {
 	exec >&2
 	for opt
 	do
 		case "$opt" in
 		-t|--t|--ta|--tag|--tags)
-			echo "Fetching tags only, you probably meant:"
+			echo "It doesn't make sense to pull all tags; you probably meant:"
 			echo "  git fetch --tags"
 			exit 1
 		esac
@@ -166,9 +187,8 @@
 		op_prep=with
 	fi
 
-	curr_branch=${curr_branch#refs/heads/}
-	upstream=$(git config "branch.$curr_branch.merge")
-	remote=$(git config "branch.$curr_branch.remote")
+	upstream=$(git config "branch.$curr_branch_short.merge")
+	remote=$(git config "branch.$curr_branch_short.remote")
 
 	if [ $# -gt 1 ]; then
 		if [ "$rebase" = true ]; then
@@ -209,15 +229,7 @@
 	test -n "$curr_branch" &&
 	. git-parse-remote &&
 	remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
-	oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
-	for reflog in $(git rev-list -g $remoteref 2>/dev/null)
-	do
-		if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
-		then
-			oldremoteref="$reflog"
-			break
-		fi
-	done
+	oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
 }
 orig_head=$(git rev-parse -q --verify HEAD)
 git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
@@ -292,7 +304,7 @@
 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
 case "$rebase" in
 true)
-	eval="git-rebase $diffstat $strategy_args $merge_args $verbosity"
+	eval="git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity"
 	eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
 	;;
 *)
diff --git a/git-rebase--am.sh b/git-rebase--am.sh
index 34e3102..a4f683a 100644
--- a/git-rebase--am.sh
+++ b/git-rebase--am.sh
@@ -1,4 +1,5 @@
-#!/bin/sh
+# This shell script fragment is sourced by git-rebase to implement
+# its default, fast, patch-based, non-interactive mode.
 #
 # Copyright (c) 2010 Junio C Hamano.
 #
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 10bf318..43c19e0 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -1,11 +1,8 @@
-#!/bin/sh
+# This shell script fragment is sourced by git-rebase to implement
+# its interactive mode.  "git rebase --interactive" makes it easy
+# to fix up commits in the middle of a series and rearrange commits.
 #
 # Copyright (c) 2006 Johannes E. Schindelin
-
-# SHORT DESCRIPTION
-#
-# This script makes it easy to fix up commits in the middle of a series,
-# and rearrange commits.
 #
 # The original idea comes from Eric W. Biederman, in
 # http://article.gmane.org/gmane.comp.version-control.git/22407
@@ -713,7 +710,7 @@
 }
 
 collapse_todo_ids() {
-	transform_todo_ids --short=7
+	transform_todo_ids --short
 }
 
 # Rearrange the todo list that has both "pick sha1 msg" and
diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh
index 16d1817..e7d96de 100644
--- a/git-rebase--merge.sh
+++ b/git-rebase--merge.sh
@@ -1,4 +1,6 @@
-#!/bin/sh
+# This shell script fragment is sourced by git-rebase to implement
+# its merge-based non-interactive mode that copes well with renamed
+# files.
 #
 # Copyright (c) 2010 Junio C Hamano.
 #
diff --git a/git-rebase.sh b/git-rebase.sh
index 226752f..8a3efa2 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -14,6 +14,7 @@
 v,verbose!         display a diffstat of what changed upstream
 q,quiet!           be quiet. implies --no-stat
 autostash!         automatically stash/stash pop before and after
+fork-point         use 'merge-base --fork-point' to refine upstream
 onto=!             rebase onto given branch instead of upstream
 p,preserve-merges! try to recreate merges instead of ignoring them
 s,strategy=!       use the given merge strategy
@@ -66,6 +67,7 @@
 diffstat=
 test "$(git config --bool rebase.stat)" = true && diffstat=t
 autostash="$(git config --bool rebase.autostash || echo false)"
+fork_point=auto
 git_am_opt=
 rebase_root=
 force_rebase=
@@ -260,6 +262,12 @@
 	--no-autosquash)
 		autosquash=
 		;;
+	--fork-point)
+		fork_point=t
+		;;
+	--no-fork-point)
+		fork_point=
+		;;
 	-M|-m)
 		do_merge=t
 		;;
@@ -437,6 +445,8 @@
 			error_on_missing_default_upstream "rebase" "rebase" \
 				"against" "git rebase <branch>"
 		fi
+
+		test "$fork_point" = auto && fork_point=t
 		;;
 	*)	upstream_name="$1"
 		shift
@@ -522,6 +532,16 @@
 	;;
 esac
 
+if test "$fork_point" = t
+then
+	new_upstream=$(git merge-base --fork-point "$upstream_name" \
+			"${switch_to:-HEAD}")
+	if test -n "$new_upstream"
+	then
+		upstream=$new_upstream
+	fi
+fi
+
 if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
 then
 	stash_sha1=$(git stash create "autostash") ||
diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh
index 2109070..6d2f282 100755
--- a/git-remote-testgit.sh
+++ b/git-remote-testgit.sh
@@ -38,6 +38,7 @@
 			echo "*export-marks $gitmarks"
 		fi
 		test -n "$GIT_REMOTE_TESTGIT_SIGNED_TAGS" && echo "signed-tags"
+		test -n "$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE" && echo "no-private-update"
 		echo
 		;;
 	list)
diff --git a/git-remote-testpy.py b/git-remote-testpy.py
deleted file mode 100644
index ca67899..0000000
--- a/git-remote-testpy.py
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/usr/bin/env python
-
-# This command is a simple remote-helper, that is used both as a
-# testcase for the remote-helper functionality, and as an example to
-# show remote-helper authors one possible implementation.
-#
-# This is a Git <-> Git importer/exporter, that simply uses git
-# fast-import and git fast-export to consume and produce fast-import
-# streams.
-#
-# To understand better the way things work, one can activate debug
-# traces by setting (to any value) the environment variables
-# GIT_TRANSPORT_HELPER_DEBUG and GIT_DEBUG_TESTGIT, to see messages
-# from the transport-helper side, or from this example remote-helper.
-
-# hashlib is only available in python >= 2.5
-try:
-    import hashlib
-    _digest = hashlib.sha1
-except ImportError:
-    import sha
-    _digest = sha.new
-import sys
-import os
-import time
-sys.path.insert(0, os.getenv("GITPYTHONLIB","."))
-
-from git_remote_helpers.util import die, debug, warn
-from git_remote_helpers.git.repo import GitRepo
-from git_remote_helpers.git.exporter import GitExporter
-from git_remote_helpers.git.importer import GitImporter
-from git_remote_helpers.git.non_local import NonLocalGit
-
-if sys.hexversion < 0x02000000:
-    # string.encode() is the limiter
-    sys.stderr.write("git-remote-testgit: requires Python 2.0 or later.\n")
-    sys.exit(1)
-
-
-def encode_filepath(path):
-    """Encodes a Unicode file path to a byte string.
-
-    On Python 2 this is a no-op; on Python 3 we encode the string as
-    suggested by [1] which allows an exact round-trip from the command line
-    to the filesystem.
-
-    [1] http://docs.python.org/3/c-api/unicode.html#file-system-encoding
-
-    """
-    if sys.hexversion < 0x03000000:
-        return path
-    return path.encode(sys.getfilesystemencoding(), 'surrogateescape')
-
-
-def get_repo(alias, url):
-    """Returns a git repository object initialized for usage.
-    """
-
-    repo = GitRepo(url)
-    repo.get_revs()
-    repo.get_head()
-
-    hasher = _digest()
-    hasher.update(encode_filepath(repo.path))
-    repo.hash = hasher.hexdigest()
-
-    repo.get_base_path = lambda base: os.path.join(
-        base, 'info', 'fast-import', repo.hash)
-
-    prefix = 'refs/testgit/%s/' % alias
-    debug("prefix: '%s'", prefix)
-
-    repo.gitdir = os.environ["GIT_DIR"]
-    repo.alias = alias
-    repo.prefix = prefix
-
-    repo.exporter = GitExporter(repo)
-    repo.importer = GitImporter(repo)
-    repo.non_local = NonLocalGit(repo)
-
-    return repo
-
-
-def local_repo(repo, path):
-    """Returns a git repository object initalized for usage.
-    """
-
-    local = GitRepo(path)
-
-    local.non_local = None
-    local.gitdir = repo.gitdir
-    local.alias = repo.alias
-    local.prefix = repo.prefix
-    local.hash = repo.hash
-    local.get_base_path = repo.get_base_path
-    local.exporter = GitExporter(local)
-    local.importer = GitImporter(local)
-
-    return local
-
-
-def do_capabilities(repo, args):
-    """Prints the supported capabilities.
-    """
-
-    print("import")
-    print("export")
-    print("refspec refs/heads/*:%s*" % repo.prefix)
-
-    dirname = repo.get_base_path(repo.gitdir)
-
-    if not os.path.exists(dirname):
-        os.makedirs(dirname)
-
-    path = os.path.join(dirname, 'git.marks')
-
-    print("*export-marks %s" % path)
-    if os.path.exists(path):
-        print("*import-marks %s" % path)
-
-    print('') # end capabilities
-
-
-def do_list(repo, args):
-    """Lists all known references.
-
-    Bug: This will always set the remote head to master for non-local
-    repositories, since we have no way of determining what the remote
-    head is at clone time.
-    """
-
-    for ref in repo.revs:
-        debug("? refs/heads/%s", ref)
-        print("? refs/heads/%s" % ref)
-
-    if repo.head:
-        debug("@refs/heads/%s HEAD" % repo.head)
-        print("@refs/heads/%s HEAD" % repo.head)
-    else:
-        debug("@refs/heads/master HEAD")
-        print("@refs/heads/master HEAD")
-
-    print('') # end list
-
-
-def update_local_repo(repo):
-    """Updates (or clones) a local repo.
-    """
-
-    if repo.local:
-        return repo
-
-    path = repo.non_local.clone(repo.gitdir)
-    repo.non_local.update(repo.gitdir)
-    repo = local_repo(repo, path)
-    return repo
-
-
-def do_import(repo, args):
-    """Exports a fast-import stream from testgit for git to import.
-    """
-
-    if len(args) != 1:
-        die("Import needs exactly one ref")
-
-    if not repo.gitdir:
-        die("Need gitdir to import")
-
-    ref = args[0]
-    refs = [ref]
-
-    while True:
-        line = sys.stdin.readline().decode()
-        if line == '\n':
-            break
-        if not line.startswith('import '):
-            die("Expected import line.")
-
-        # strip of leading 'import '
-        ref = line[7:].strip()
-        refs.append(ref)
-
-    print("feature done")
-
-    if os.environ.get("GIT_REMOTE_TESTGIT_FAILURE"):
-        die('Told to fail')
-
-    repo = update_local_repo(repo)
-    repo.exporter.export_repo(repo.gitdir, refs)
-
-    print("done")
-
-
-def do_export(repo, args):
-    """Imports a fast-import stream from git to testgit.
-    """
-
-    if not repo.gitdir:
-        die("Need gitdir to export")
-
-    if os.environ.get("GIT_REMOTE_TESTGIT_FAILURE"):
-        die('Told to fail')
-
-    update_local_repo(repo)
-    changed = repo.importer.do_import(repo.gitdir)
-
-    if not repo.local:
-        repo.non_local.push(repo.gitdir)
-
-    for ref in changed:
-        print("ok %s" % ref)
-    print('')
-
-
-COMMANDS = {
-    'capabilities': do_capabilities,
-    'list': do_list,
-    'import': do_import,
-    'export': do_export,
-}
-
-
-def sanitize(value):
-    """Cleans up the url.
-    """
-
-    if value.startswith('testgit::'):
-        value = value[9:]
-
-    return value
-
-
-def read_one_line(repo):
-    """Reads and processes one command.
-    """
-
-    sleepy = os.environ.get("GIT_REMOTE_TESTGIT_SLEEPY")
-    if sleepy:
-        debug("Sleeping %d sec before readline" % int(sleepy))
-        time.sleep(int(sleepy))
-
-    line = sys.stdin.readline()
-
-    cmdline = line.decode()
-
-    if not cmdline:
-        warn("Unexpected EOF")
-        return False
-
-    cmdline = cmdline.strip().split()
-    if not cmdline:
-        # Blank line means we're about to quit
-        return False
-
-    cmd = cmdline.pop(0)
-    debug("Got command '%s' with args '%s'", cmd, ' '.join(cmdline))
-
-    if cmd not in COMMANDS:
-        die("Unknown command, %s", cmd)
-
-    func = COMMANDS[cmd]
-    func(repo, cmdline)
-    sys.stdout.flush()
-
-    return True
-
-
-def main(args):
-    """Starts a new remote helper for the specified repository.
-    """
-
-    if len(args) != 3:
-        die("Expecting exactly three arguments.")
-        sys.exit(1)
-
-    if os.getenv("GIT_DEBUG_TESTGIT"):
-        import git_remote_helpers.util
-        git_remote_helpers.util.DEBUG = True
-
-    alias = sanitize(args[1])
-    url = sanitize(args[2])
-
-    if not alias.isalnum():
-        warn("non-alnum alias '%s'", alias)
-        alias = "tmp"
-
-    args[1] = alias
-    args[2] = url
-
-    repo = get_repo(alias, url)
-
-    debug("Got arguments %s", args[1:])
-
-    more = True
-
-    # Use binary mode since Python 3 does not permit unbuffered I/O in text
-    # mode.  Unbuffered I/O is required to avoid data that should be going
-    # to git-fast-import after an "export" command getting caught in our
-    # stdin buffer instead.
-    sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)
-    while (more):
-        more = read_one_line(repo)
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/git-request-pull.sh b/git-request-pull.sh
index ebf1269..fe21d5d 100755
--- a/git-request-pull.sh
+++ b/git-request-pull.sh
@@ -106,7 +106,7 @@
 	}
 '
 
-ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev" "$tag_name")
+ref=$(git ls-remote "$url" | @@PERL@@ -e "$find_matching_ref" "$head" "$headrev" "$tag_name")
 
 url=$(git ls-remote --get-url "$url")
 
diff --git a/git-send-email.perl b/git-send-email.perl
index 3782c3b..fdb0029 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -291,7 +291,7 @@
 		    "smtp-pass:s" => \$smtp_authpass,
 		    "smtp-ssl" => sub { $smtp_encryption = 'ssl' },
 		    "smtp-encryption=s" => \$smtp_encryption,
-		    "smtp-ssl-cert-path" => \$smtp_ssl_cert_path,
+		    "smtp-ssl-cert-path=s" => \$smtp_ssl_cert_path,
 		    "smtp-debug:i" => \$debug_net_smtp,
 		    "smtp-domain:s" => \$smtp_domain,
 		    "identity=s" => \$identity,
@@ -1095,7 +1095,8 @@
 	}
 
 	if (!defined $smtp_ssl_cert_path) {
-		$smtp_ssl_cert_path = "/etc/ssl/certs";
+		# use the OpenSSL defaults
+		return (SSL_verify_mode => SSL_VERIFY_PEER());
 	}
 
 	if ($smtp_ssl_cert_path eq "") {
@@ -1214,10 +1215,14 @@
 			$smtp_server_port ||= 465; # ssmtp
 			require Net::SMTP::SSL;
 			$smtp_domain ||= maildomain();
+			require IO::Socket::SSL;
+			# Net::SMTP::SSL->new() does not forward any SSL options
+			IO::Socket::SSL::set_client_defaults(
+				ssl_verify_params());
 			$smtp ||= Net::SMTP::SSL->new($smtp_server,
 						      Hello => $smtp_domain,
 						      Port => $smtp_server_port,
-						      ssl_verify_params());
+						      Debug => $debug_net_smtp);
 		}
 		else {
 			require Net::SMTP;
diff --git a/git-sh-i18n.sh b/git-sh-i18n.sh
index 6a27f68..e6c3116 100644
--- a/git-sh-i18n.sh
+++ b/git-sh-i18n.sh
@@ -1,9 +1,8 @@
-#!/bin/sh
+# This shell library is Git's interface to gettext.sh. See po/README
+# for usage instructions.
 #
 # Copyright (c) 2010 Ævar Arnfjörð Bjarmason
 #
-# This is Git's interface to gettext.sh. See po/README for usage
-# instructions.
 
 # Export the TEXTDOMAIN* data that we need for Git
 TEXTDOMAIN=git
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index e15be51..fffa3c7 100644
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -1,9 +1,6 @@
-#!/bin/sh
-#
-# This is included in commands that either have to be run from the toplevel
-# of the repository, or with GIT_DIR environment variable properly.
-# If the GIT_DIR does not look like the right correct git-repository,
-# it dies.
+# This shell scriplet is meant to be included by other shell scripts
+# to set up some variables pointing at the normal git directories and
+# a few helper shell functions.
 
 # Having this variable in your environment would break scripts because
 # you would cause "cd" to be taken to unexpected places.  If you
@@ -103,6 +100,40 @@
 	esac
 fi
 
+# Set the name of the end-user facing command in the reflog when the
+# script may update refs.  When GIT_REFLOG_ACTION is already set, this
+# will not overwrite it, so that a scripted Porcelain (e.g. "git
+# rebase") can set it to its own name (e.g. "rebase") and then call
+# another scripted Porcelain (e.g. "git am") and a call to this
+# function in the latter will keep the name of the end-user facing
+# program (e.g. "rebase") in GIT_REFLOG_ACTION, ensuring whatever it
+# does will be record as actions done as part of the end-user facing
+# operation (e.g. "rebase").
+#
+# NOTE NOTE NOTE: consequently, after assigning a specific message to
+# GIT_REFLOG_ACTION when calling a "git" command to record a custom
+# reflog message, do not leave that custom value in GIT_REFLOG_ACTION,
+# after you are done.  Other callers of "git" commands that rely on
+# writing the default "program name" in reflog expect the variable to
+# contain the value set by this function.
+#
+# To use a custom reflog message, do either one of these three:
+#
+# (a) use a single-shot export form:
+#     GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz" \
+#         git command-that-updates-a-ref
+#
+# (b) save the original away and restore:
+#     SAVED_ACTION=$GIT_REFLOG_ACTION
+#     GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz"
+#     git command-that-updates-a-ref
+#     GIT_REFLOG_ACITON=$SAVED_ACTION
+#
+# (c) assign the variable in a subshell:
+#     (
+#         GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz"
+#         git command-that-updates-a-ref
+#     )
 set_reflog_action() {
 	if [ -z "${GIT_REFLOG_ACTION:+set}" ]
 	then
@@ -128,7 +159,8 @@
 		GIT_PAGER=cat
 	fi
 	: ${LESS=-FRSX}
-	export LESS
+	: ${LV=-c}
+	export LESS LV
 
 	eval "$GIT_PAGER" '"$@"'
 }
diff --git a/git-stash.sh b/git-stash.sh
index 1e541a2..f0a94ab 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -358,7 +358,7 @@
 	i_tree=
 	u_tree=
 
-	REV=$(git rev-parse --no-flags --symbolic "$@") || exit 1
+	REV=$(git rev-parse --no-flags --symbolic --sq "$@") || exit 1
 
 	FLAGS=
 	for opt
@@ -376,7 +376,7 @@
 		esac
 	done
 
-	set -- $REV
+	eval set -- $REV
 
 	case $# in
 		0)
@@ -391,13 +391,13 @@
 		;;
 	esac
 
-	REV=$(git rev-parse --quiet --symbolic --verify $1 2>/dev/null) || {
+	REV=$(git rev-parse --quiet --symbolic --verify "$1" 2>/dev/null) || {
 		reference="$1"
 		die "$(eval_gettext "\$reference is not valid reference")"
 	}
 
-	i_commit=$(git rev-parse --quiet --verify $REV^2 2>/dev/null) &&
-	set -- $(git rev-parse $REV $REV^1 $REV: $REV^1: $REV^2: 2>/dev/null) &&
+	i_commit=$(git rev-parse --quiet --verify "$REV^2" 2>/dev/null) &&
+	set -- $(git rev-parse "$REV" "$REV^1" "$REV:" "$REV^1:" "$REV^2:" 2>/dev/null) &&
 	s=$1 &&
 	w_commit=$1 &&
 	b_commit=$2 &&
@@ -408,8 +408,8 @@
 	test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
 	IS_STASH_REF=t
 
-	u_commit=$(git rev-parse --quiet --verify $REV^3 2>/dev/null) &&
-	u_tree=$(git rev-parse $REV^3: 2>/dev/null)
+	u_commit=$(git rev-parse --quiet --verify "$REV^3" 2>/dev/null) &&
+	u_tree=$(git rev-parse "$REV^3:" 2>/dev/null)
 }
 
 is_stash_like()
diff --git a/git-submodule.sh b/git-submodule.sh
index 83917d8..4a30087 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -156,7 +156,7 @@
 		git ls-files -z --error-unmatch --stage -- "$@" ||
 		echo "unmatched pathspec exists"
 	) |
-	perl -e '
+	@@PERL@@ -e '
 	my %unmerged = ();
 	my ($null_sha1) = ("0" x 40);
 	my @out = ();
@@ -545,7 +545,12 @@
 				sm_path=$(relative_path "$sm_path") &&
 				# we make $path available to scripts ...
 				path=$sm_path &&
-				eval "$@" &&
+				if test $# -eq 1
+				then
+					eval "$1"
+				else
+					"$@"
+				fi &&
 				if test -n "$recursive"
 				then
 					cmd_foreach "--recursive" "$@"
@@ -617,7 +622,7 @@
 		   test -z "$(git config submodule."$name".update)"
 		then
 			case "$upd" in
-			rebase | merge | none)
+			checkout | rebase | merge | none)
 				;; # known modes of updating
 			*)
 				echo >&2 "warning: unknown update mode '$upd' suggested for submodule '$name'"
@@ -716,7 +721,6 @@
 cmd_update()
 {
 	# parse $args after "submodule ... update".
-	orig_flags=
 	while test $# -ne 0
 	do
 		case "$1" in
@@ -741,7 +745,6 @@
 		--reference)
 			case "$2" in '') usage ;; esac
 			reference="--reference=$2"
-			orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 			shift
 			;;
 		--reference=*)
@@ -775,7 +778,6 @@
 			break
 			;;
 		esac
-		orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 		shift
 	done
 
@@ -803,6 +805,17 @@
 			update_module=$update
 		else
 			update_module=$(git config submodule."$name".update)
+			case "$update_module" in
+			'')
+				;; # Unset update mode
+			checkout | rebase | merge | none)
+				;; # Known update modes
+			!*)
+				;; # Custom update command
+			*)
+				die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")"
+				;;
+			esac
 		fi
 
 		displaypath=$(relative_path "$prefix$sm_path")
@@ -919,7 +932,7 @@
 				prefix="$prefix$sm_path/"
 				clear_local_git_env
 				cd "$sm_path" &&
-				eval cmd_update "$orig_flags"
+				eval cmd_update
 			)
 			res=$?
 			if test $res -gt 0
@@ -1042,13 +1055,20 @@
 	# Get modified modules cared by user
 	modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
 		sane_egrep '^:([0-7]* )?160000' |
-		while read mod_src mod_dst sha1_src sha1_dst status name
+		while read mod_src mod_dst sha1_src sha1_dst status sm_path
 		do
 			# Always show modules deleted or type-changed (blob<->module)
-			test $status = D -o $status = T && echo "$name" && continue
+			test $status = D -o $status = T && echo "$sm_path" && continue
+			# Respect the ignore setting for --for-status.
+			if test -n "$for_status"
+			then
+				name=$(module_name "$sm_path")
+				ignore_config=$(get_submodule_config "$name" ignore none)
+				test $status != A -a $ignore_config = all && continue
+			fi
 			# Also show added or modified modules which are checked out
-			GIT_DIR="$name/.git" git-rev-parse --git-dir >/dev/null 2>&1 &&
-			echo "$name"
+			GIT_DIR="$sm_path/.git" git-rev-parse --git-dir >/dev/null 2>&1 &&
+			echo "$sm_path"
 		done
 	)
 
@@ -1159,18 +1179,7 @@
 			echo
 		fi
 		echo
-	done |
-	if test -n "$for_status"; then
-		if [ -n "$files" ]; then
-			gettextln "Submodules changed but not updated:" | git stripspace -c
-		else
-			gettextln "Submodule changes to be committed:" | git stripspace -c
-		fi
-		printf "\n" | git stripspace -c
-		git stripspace -c
-	else
-		cat
-	fi
+	done
 }
 #
 # List all submodules, prefixed with:
diff --git a/git-svn.perl b/git-svn.perl
index ff1ce3d..7349ffe 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1389,7 +1389,17 @@
 		usage(1);
 	}
 
-	$_prefix = '' unless defined $_prefix;
+	unless (defined $_prefix) {
+		$_prefix = '';
+		warn <<EOF
+WARNING: --prefix is not given, defaulting to empty prefix.
+         This is probably not what you want! In order to stay compatible
+         with regular remote-tracking refs, provide a prefix like
+         --prefix=origin/ (remember the trailing slash), which will cause
+         the SVN-tracking refs to be placed at refs/remotes/origin/*.
+NOTE: In Git v2.0, the default prefix will change from empty to 'origin/'.
+EOF
+	}
 	if (defined $url) {
 		$url = canonicalize_url($url);
 		init_subdir(@_);
@@ -1759,7 +1769,7 @@
 		my $msgbuf = "";
 		while (<$msg_fh>) {
 			if (!$in_msg) {
-				$in_msg = 1 if (/^\s*$/);
+				$in_msg = 1 if (/^$/);
 				$author = $1 if (/^author (.*>)/);
 			} elsif (/^git-svn-id: /) {
 				# skip this for now, we regenerate the
diff --git a/git-web--browse.sh b/git-web--browse.sh
index 1d72ec7..ebdfba6 100755
--- a/git-web--browse.sh
+++ b/git-web--browse.sh
@@ -34,7 +34,7 @@
 	firefox | iceweasel | seamonkey | iceape | \
 	chrome | google-chrome | chromium | chromium-browser | \
 	konqueror | opera | w3m | elinks | links | lynx | dillo | open | \
-	start | cygstart)
+	start | cygstart | xdg-open)
 		;; # happy
 	*)
 		valid_custom_tool "$1" || return 1
@@ -112,7 +112,7 @@
 
 if test -z "$browser" ; then
 	if test -n "$DISPLAY"; then
-		browser_candidates="firefox iceweasel google-chrome chrome chromium chromium-browser konqueror opera seamonkey iceape w3m elinks links lynx dillo"
+		browser_candidates="firefox iceweasel google-chrome chrome chromium chromium-browser konqueror opera seamonkey iceape w3m elinks links lynx dillo xdg-open"
 		if test "$KDE_FULL_SESSION" = "true"; then
 			browser_candidates="konqueror $browser_candidates"
 		fi
@@ -179,7 +179,7 @@
 		;;
 	esac
 	;;
-w3m|elinks|links|lynx|open|cygstart)
+w3m|elinks|links|lynx|open|cygstart|xdg-open)
 	"$browser_path" "$@"
 	;;
 start)
diff --git a/git.c b/git.c
index 2025f77..7cf2953 100644
--- a/git.c
+++ b/git.c
@@ -7,7 +7,7 @@
 #include "commit.h"
 
 const char git_usage_string[] =
-	"git [--version] [--help] [-c name=value]\n"
+	"git [--version] [--help] [-C <path>] [-c name=value]\n"
 	"           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
 	"           [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n"
 	"           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
@@ -54,7 +54,7 @@
 		/*
 		 * Check remaining flags.
 		 */
-		if (!prefixcmp(cmd, "--exec-path")) {
+		if (starts_with(cmd, "--exec-path")) {
 			cmd += 11;
 			if (*cmd == '=')
 				git_set_argv_exec_path(cmd + 1);
@@ -92,7 +92,7 @@
 				*envchanged = 1;
 			(*argv)++;
 			(*argc)--;
-		} else if (!prefixcmp(cmd, "--git-dir=")) {
+		} else if (starts_with(cmd, "--git-dir=")) {
 			setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
 			if (envchanged)
 				*envchanged = 1;
@@ -106,7 +106,7 @@
 				*envchanged = 1;
 			(*argv)++;
 			(*argc)--;
-		} else if (!prefixcmp(cmd, "--namespace=")) {
+		} else if (starts_with(cmd, "--namespace=")) {
 			setenv(GIT_NAMESPACE_ENVIRONMENT, cmd + 12, 1);
 			if (envchanged)
 				*envchanged = 1;
@@ -120,7 +120,7 @@
 				*envchanged = 1;
 			(*argv)++;
 			(*argc)--;
-		} else if (!prefixcmp(cmd, "--work-tree=")) {
+		} else if (starts_with(cmd, "--work-tree=")) {
 			setenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1);
 			if (envchanged)
 				*envchanged = 1;
@@ -147,12 +147,35 @@
 			setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1);
 			if (envchanged)
 				*envchanged = 1;
+		} else if (!strcmp(cmd, "--glob-pathspecs")) {
+			setenv(GIT_GLOB_PATHSPECS_ENVIRONMENT, "1", 1);
+			if (envchanged)
+				*envchanged = 1;
+		} else if (!strcmp(cmd, "--noglob-pathspecs")) {
+			setenv(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, "1", 1);
+			if (envchanged)
+				*envchanged = 1;
+		} else if (!strcmp(cmd, "--icase-pathspecs")) {
+			setenv(GIT_ICASE_PATHSPECS_ENVIRONMENT, "1", 1);
+			if (envchanged)
+				*envchanged = 1;
 		} else if (!strcmp(cmd, "--shallow-file")) {
 			(*argv)++;
 			(*argc)--;
-			set_alternate_shallow_file((*argv)[0]);
+			set_alternate_shallow_file((*argv)[0], 1);
 			if (envchanged)
 				*envchanged = 1;
+		} else if (!strcmp(cmd, "-C")) {
+			if (*argc < 2) {
+				fprintf(stderr, "No directory given for -C.\n" );
+				usage(git_usage_string);
+			}
+			if (chdir((*argv)[1]))
+				die_errno("Cannot change to '%s'", (*argv)[1]);
+			if (envchanged)
+				*envchanged = 1;
+			(*argv)++;
+			(*argc)--;
 		} else {
 			fprintf(stderr, "Unknown option: %s\n", cmd);
 			usage(git_usage_string);
@@ -309,126 +332,136 @@
 	return 0;
 }
 
-static void handle_internal_command(int argc, const char **argv)
+static struct cmd_struct commands[] = {
+	{ "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
+	{ "annotate", cmd_annotate, RUN_SETUP },
+	{ "apply", cmd_apply, RUN_SETUP_GENTLY },
+	{ "archive", cmd_archive },
+	{ "bisect--helper", cmd_bisect__helper, RUN_SETUP },
+	{ "blame", cmd_blame, RUN_SETUP },
+	{ "branch", cmd_branch, RUN_SETUP },
+	{ "bundle", cmd_bundle, RUN_SETUP_GENTLY },
+	{ "cat-file", cmd_cat_file, RUN_SETUP },
+	{ "check-attr", cmd_check_attr, RUN_SETUP },
+	{ "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
+	{ "check-mailmap", cmd_check_mailmap, RUN_SETUP },
+	{ "check-ref-format", cmd_check_ref_format },
+	{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
+	{ "checkout-index", cmd_checkout_index,
+		RUN_SETUP | NEED_WORK_TREE},
+	{ "cherry", cmd_cherry, RUN_SETUP },
+	{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+	{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
+	{ "clone", cmd_clone },
+	{ "column", cmd_column, RUN_SETUP_GENTLY },
+	{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
+	{ "commit-tree", cmd_commit_tree, RUN_SETUP },
+	{ "config", cmd_config, RUN_SETUP_GENTLY },
+	{ "count-objects", cmd_count_objects, RUN_SETUP },
+	{ "credential", cmd_credential, RUN_SETUP_GENTLY },
+	{ "describe", cmd_describe, RUN_SETUP },
+	{ "diff", cmd_diff },
+	{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
+	{ "diff-index", cmd_diff_index, RUN_SETUP },
+	{ "diff-tree", cmd_diff_tree, RUN_SETUP },
+	{ "fast-export", cmd_fast_export, RUN_SETUP },
+	{ "fetch", cmd_fetch, RUN_SETUP },
+	{ "fetch-pack", cmd_fetch_pack, RUN_SETUP },
+	{ "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
+	{ "for-each-ref", cmd_for_each_ref, RUN_SETUP },
+	{ "format-patch", cmd_format_patch, RUN_SETUP },
+	{ "fsck", cmd_fsck, RUN_SETUP },
+	{ "fsck-objects", cmd_fsck, RUN_SETUP },
+	{ "gc", cmd_gc, RUN_SETUP },
+	{ "get-tar-commit-id", cmd_get_tar_commit_id },
+	{ "grep", cmd_grep, RUN_SETUP_GENTLY },
+	{ "hash-object", cmd_hash_object },
+	{ "help", cmd_help },
+	{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
+	{ "init", cmd_init_db },
+	{ "init-db", cmd_init_db },
+	{ "log", cmd_log, RUN_SETUP },
+	{ "ls-files", cmd_ls_files, RUN_SETUP },
+	{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
+	{ "ls-tree", cmd_ls_tree, RUN_SETUP },
+	{ "mailinfo", cmd_mailinfo },
+	{ "mailsplit", cmd_mailsplit },
+	{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
+	{ "merge-base", cmd_merge_base, RUN_SETUP },
+	{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
+	{ "merge-index", cmd_merge_index, RUN_SETUP },
+	{ "merge-ours", cmd_merge_ours, RUN_SETUP },
+	{ "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
+	{ "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
+	{ "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
+	{ "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
+	{ "merge-tree", cmd_merge_tree, RUN_SETUP },
+	{ "mktag", cmd_mktag, RUN_SETUP },
+	{ "mktree", cmd_mktree, RUN_SETUP },
+	{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
+	{ "name-rev", cmd_name_rev, RUN_SETUP },
+	{ "notes", cmd_notes, RUN_SETUP },
+	{ "pack-objects", cmd_pack_objects, RUN_SETUP },
+	{ "pack-redundant", cmd_pack_redundant, RUN_SETUP },
+	{ "pack-refs", cmd_pack_refs, RUN_SETUP },
+	{ "patch-id", cmd_patch_id },
+	{ "pickaxe", cmd_blame, RUN_SETUP },
+	{ "prune", cmd_prune, RUN_SETUP },
+	{ "prune-packed", cmd_prune_packed, RUN_SETUP },
+	{ "push", cmd_push, RUN_SETUP },
+	{ "read-tree", cmd_read_tree, RUN_SETUP },
+	{ "receive-pack", cmd_receive_pack },
+	{ "reflog", cmd_reflog, RUN_SETUP },
+	{ "remote", cmd_remote, RUN_SETUP },
+	{ "remote-ext", cmd_remote_ext },
+	{ "remote-fd", cmd_remote_fd },
+	{ "repack", cmd_repack, RUN_SETUP },
+	{ "replace", cmd_replace, RUN_SETUP },
+	{ "rerere", cmd_rerere, RUN_SETUP },
+	{ "reset", cmd_reset, RUN_SETUP },
+	{ "rev-list", cmd_rev_list, RUN_SETUP },
+	{ "rev-parse", cmd_rev_parse },
+	{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
+	{ "rm", cmd_rm, RUN_SETUP },
+	{ "send-pack", cmd_send_pack, RUN_SETUP },
+	{ "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER },
+	{ "show", cmd_show, RUN_SETUP },
+	{ "show-branch", cmd_show_branch, RUN_SETUP },
+	{ "show-ref", cmd_show_ref, RUN_SETUP },
+	{ "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
+	{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
+	{ "stripspace", cmd_stripspace },
+	{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
+	{ "tag", cmd_tag, RUN_SETUP },
+	{ "unpack-file", cmd_unpack_file, RUN_SETUP },
+	{ "unpack-objects", cmd_unpack_objects, RUN_SETUP },
+	{ "update-index", cmd_update_index, RUN_SETUP },
+	{ "update-ref", cmd_update_ref, RUN_SETUP },
+	{ "update-server-info", cmd_update_server_info, RUN_SETUP },
+	{ "upload-archive", cmd_upload_archive },
+	{ "upload-archive--writer", cmd_upload_archive_writer },
+	{ "var", cmd_var, RUN_SETUP_GENTLY },
+	{ "verify-pack", cmd_verify_pack },
+	{ "verify-tag", cmd_verify_tag, RUN_SETUP },
+	{ "version", cmd_version },
+	{ "whatchanged", cmd_whatchanged, RUN_SETUP },
+	{ "write-tree", cmd_write_tree, RUN_SETUP },
+};
+
+int is_builtin(const char *s)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(commands); i++) {
+		struct cmd_struct *p = commands+i;
+		if (!strcmp(s, p->cmd))
+			return 1;
+	}
+	return 0;
+}
+
+static void handle_builtin(int argc, const char **argv)
 {
 	const char *cmd = argv[0];
-	static struct cmd_struct commands[] = {
-		{ "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
-		{ "annotate", cmd_annotate, RUN_SETUP },
-		{ "apply", cmd_apply, RUN_SETUP_GENTLY },
-		{ "archive", cmd_archive },
-		{ "bisect--helper", cmd_bisect__helper, RUN_SETUP },
-		{ "blame", cmd_blame, RUN_SETUP },
-		{ "branch", cmd_branch, RUN_SETUP },
-		{ "bundle", cmd_bundle, RUN_SETUP_GENTLY },
-		{ "cat-file", cmd_cat_file, RUN_SETUP },
-		{ "check-attr", cmd_check_attr, RUN_SETUP },
-		{ "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
-		{ "check-mailmap", cmd_check_mailmap, RUN_SETUP },
-		{ "check-ref-format", cmd_check_ref_format },
-		{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
-		{ "checkout-index", cmd_checkout_index,
-			RUN_SETUP | NEED_WORK_TREE},
-		{ "cherry", cmd_cherry, RUN_SETUP },
-		{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
-		{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
-		{ "clone", cmd_clone },
-		{ "column", cmd_column, RUN_SETUP_GENTLY },
-		{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
-		{ "commit-tree", cmd_commit_tree, RUN_SETUP },
-		{ "config", cmd_config, RUN_SETUP_GENTLY },
-		{ "count-objects", cmd_count_objects, RUN_SETUP },
-		{ "credential", cmd_credential, RUN_SETUP_GENTLY },
-		{ "describe", cmd_describe, RUN_SETUP },
-		{ "diff", cmd_diff },
-		{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
-		{ "diff-index", cmd_diff_index, RUN_SETUP },
-		{ "diff-tree", cmd_diff_tree, RUN_SETUP },
-		{ "fast-export", cmd_fast_export, RUN_SETUP },
-		{ "fetch", cmd_fetch, RUN_SETUP },
-		{ "fetch-pack", cmd_fetch_pack, RUN_SETUP },
-		{ "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
-		{ "for-each-ref", cmd_for_each_ref, RUN_SETUP },
-		{ "format-patch", cmd_format_patch, RUN_SETUP },
-		{ "fsck", cmd_fsck, RUN_SETUP },
-		{ "fsck-objects", cmd_fsck, RUN_SETUP },
-		{ "gc", cmd_gc, RUN_SETUP },
-		{ "get-tar-commit-id", cmd_get_tar_commit_id },
-		{ "grep", cmd_grep, RUN_SETUP_GENTLY },
-		{ "hash-object", cmd_hash_object },
-		{ "help", cmd_help },
-		{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
-		{ "init", cmd_init_db },
-		{ "init-db", cmd_init_db },
-		{ "log", cmd_log, RUN_SETUP },
-		{ "ls-files", cmd_ls_files, RUN_SETUP },
-		{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
-		{ "ls-tree", cmd_ls_tree, RUN_SETUP },
-		{ "mailinfo", cmd_mailinfo },
-		{ "mailsplit", cmd_mailsplit },
-		{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
-		{ "merge-base", cmd_merge_base, RUN_SETUP },
-		{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
-		{ "merge-index", cmd_merge_index, RUN_SETUP },
-		{ "merge-ours", cmd_merge_ours, RUN_SETUP },
-		{ "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-		{ "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-		{ "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-		{ "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-		{ "merge-tree", cmd_merge_tree, RUN_SETUP },
-		{ "mktag", cmd_mktag, RUN_SETUP },
-		{ "mktree", cmd_mktree, RUN_SETUP },
-		{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
-		{ "name-rev", cmd_name_rev, RUN_SETUP },
-		{ "notes", cmd_notes, RUN_SETUP },
-		{ "pack-objects", cmd_pack_objects, RUN_SETUP },
-		{ "pack-redundant", cmd_pack_redundant, RUN_SETUP },
-		{ "pack-refs", cmd_pack_refs, RUN_SETUP },
-		{ "patch-id", cmd_patch_id },
-		{ "peek-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
-		{ "pickaxe", cmd_blame, RUN_SETUP },
-		{ "prune", cmd_prune, RUN_SETUP },
-		{ "prune-packed", cmd_prune_packed, RUN_SETUP },
-		{ "push", cmd_push, RUN_SETUP },
-		{ "read-tree", cmd_read_tree, RUN_SETUP },
-		{ "receive-pack", cmd_receive_pack },
-		{ "reflog", cmd_reflog, RUN_SETUP },
-		{ "remote", cmd_remote, RUN_SETUP },
-		{ "remote-ext", cmd_remote_ext },
-		{ "remote-fd", cmd_remote_fd },
-		{ "replace", cmd_replace, RUN_SETUP },
-		{ "repo-config", cmd_repo_config, RUN_SETUP_GENTLY },
-		{ "rerere", cmd_rerere, RUN_SETUP },
-		{ "reset", cmd_reset, RUN_SETUP },
-		{ "rev-list", cmd_rev_list, RUN_SETUP },
-		{ "rev-parse", cmd_rev_parse },
-		{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
-		{ "rm", cmd_rm, RUN_SETUP },
-		{ "send-pack", cmd_send_pack, RUN_SETUP },
-		{ "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER },
-		{ "show", cmd_show, RUN_SETUP },
-		{ "show-branch", cmd_show_branch, RUN_SETUP },
-		{ "show-ref", cmd_show_ref, RUN_SETUP },
-		{ "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
-		{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
-		{ "stripspace", cmd_stripspace },
-		{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
-		{ "tag", cmd_tag, RUN_SETUP },
-		{ "tar-tree", cmd_tar_tree },
-		{ "unpack-file", cmd_unpack_file, RUN_SETUP },
-		{ "unpack-objects", cmd_unpack_objects, RUN_SETUP },
-		{ "update-index", cmd_update_index, RUN_SETUP },
-		{ "update-ref", cmd_update_ref, RUN_SETUP },
-		{ "update-server-info", cmd_update_server_info, RUN_SETUP },
-		{ "upload-archive", cmd_upload_archive },
-		{ "upload-archive--writer", cmd_upload_archive_writer },
-		{ "var", cmd_var, RUN_SETUP_GENTLY },
-		{ "verify-pack", cmd_verify_pack },
-		{ "verify-tag", cmd_verify_tag, RUN_SETUP },
-		{ "version", cmd_version },
-		{ "whatchanged", cmd_whatchanged, RUN_SETUP },
-		{ "write-tree", cmd_write_tree, RUN_SETUP },
-	};
 	int i;
 	static const char ext[] = STRIP_EXTENSION;
 
@@ -496,8 +529,8 @@
 	int done_alias = 0;
 
 	while (1) {
-		/* See if it's an internal command */
-		handle_internal_command(*argcp, *argv);
+		/* See if it's a builtin */
+		handle_builtin(*argcp, *argv);
 
 		/* .. then try the external ones */
 		execv_dashed_external(*argv);
@@ -542,14 +575,14 @@
 	 *  - cannot execute it externally (since it would just do
 	 *    the same thing over again)
 	 *
-	 * So we just directly call the internal command handler, and
-	 * die if that one cannot handle it.
+	 * So we just directly call the builtin handler, and die if
+	 * that one cannot handle it.
 	 */
-	if (!prefixcmp(cmd, "git-")) {
+	if (starts_with(cmd, "git-")) {
 		cmd += 4;
 		argv[0] = cmd;
-		handle_internal_command(argc, argv);
-		die("cannot handle %s internally", cmd);
+		handle_builtin(argc, argv);
+		die("cannot handle %s as a builtin", cmd);
 	}
 
 	/* Look for flags.. */
@@ -557,7 +590,7 @@
 	argc--;
 	handle_options(&argv, &argc, NULL);
 	if (argc > 0) {
-		if (!prefixcmp(argv[0], "--"))
+		if (starts_with(argv[0], "--"))
 			argv[0] += 2;
 	} else {
 		/* The user didn't specify a command; give them help */
diff --git a/git.rc b/git.rc
index bce6db9..33aafb7 100644
--- a/git.rc
+++ b/git.rc
@@ -1,6 +1,6 @@
 1 VERSIONINFO
-FILEVERSION     MAJOR,MINOR,PATCH,0
-PRODUCTVERSION  MAJOR,MINOR,PATCH,0
+FILEVERSION     MAJOR,MINOR,0,0
+PRODUCTVERSION  MAJOR,MINOR,0,0
 BEGIN
   BLOCK "StringFileInfo"
   BEGIN
diff --git a/git_remote_helpers/.gitignore b/git_remote_helpers/.gitignore
deleted file mode 100644
index cf040af..0000000
--- a/git_remote_helpers/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/GIT-PYTHON-VERSION
-/build
-/dist
diff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile
deleted file mode 100644
index 3d12232..0000000
--- a/git_remote_helpers/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Makefile for the git_remote_helpers python support modules
-#
-pysetupfile:=setup.py
-
-# Shell quote (do not use $(call) to accommodate ancient setups);
-DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
-
-ifndef PYTHON_PATH
-	ifeq ($(uname_S),FreeBSD)
-		PYTHON_PATH = /usr/local/bin/python
-	else
-		PYTHON_PATH = /usr/bin/python
-	endif
-endif
-ifndef prefix
-	prefix = $(HOME)
-endif
-ifndef V
-	QUIET = @
-	QUIETSETUP = --quiet
-endif
-
-PYLIBDIR=$(shell $(PYTHON_PATH) -c \
-	 "import sys; \
-	 print('lib/python%i.%i/site-packages' % sys.version_info[:2])")
-
-py_version=$(shell $(PYTHON_PATH) -c \
-	'import sys; print("%i.%i" % sys.version_info[:2])')
-
-all: $(pysetupfile)
-	$(QUIET)test "$$(cat GIT-PYTHON-VERSION 2>/dev/null)" = "$(py_version)" || \
-	flags=--force; \
-	$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build $$flags
-	$(QUIET)echo "$(py_version)" >GIT-PYTHON-VERSION
-
-install: $(pysetupfile)
-	$(PYTHON_PATH) $(pysetupfile) install --prefix $(DESTDIR_SQ)$(prefix)
-
-instlibdir: $(pysetupfile)
-	@echo "$(DESTDIR_SQ)$(prefix)/$(PYLIBDIR)"
-
-clean:
-	$(QUIET)$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) clean -a
-	$(RM) *.pyo *.pyc GIT-PYTHON-VERSION
diff --git a/git_remote_helpers/__init__.py b/git_remote_helpers/__init__.py
deleted file mode 100644
index 00f69cb..0000000
--- a/git_remote_helpers/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-
-"""Support library package for git remote helpers.
-
-Git remote helpers are helper commands that interfaces with a non-git
-repository to provide automatic import of non-git history into a Git
-repository.
-
-This package provides the support library needed by these helpers..
-The following modules are included:
-
-- git.git - Interaction with Git repositories
-
-- util - General utility functionality use by the other modules in
-         this package, and also used directly by the helpers.
-"""
diff --git a/git_remote_helpers/git/__init__.py b/git_remote_helpers/git/__init__.py
deleted file mode 100644
index 1dbb1b0..0000000
--- a/git_remote_helpers/git/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-import sys
-if sys.hexversion < 0x02040000:
-    # The limiter is the subprocess module
-    sys.stderr.write("git_remote_helpers: requires Python 2.4 or later.\n")
-    sys.exit(1)
diff --git a/git_remote_helpers/git/exporter.py b/git_remote_helpers/git/exporter.py
deleted file mode 100644
index 9ee5f96..0000000
--- a/git_remote_helpers/git/exporter.py
+++ /dev/null
@@ -1,58 +0,0 @@
-import os
-import subprocess
-import sys
-
-from git_remote_helpers.util import check_call
-
-
-class GitExporter(object):
-    """An exporter for testgit repositories.
-
-    The exporter simply delegates to git fast-export.
-    """
-
-    def __init__(self, repo):
-        """Creates a new exporter for the specified repo.
-        """
-
-        self.repo = repo
-
-    def export_repo(self, base, refs=None):
-        """Exports a fast-export stream for the given directory.
-
-        Simply delegates to git fast-epxort and pipes it through sed
-        to make the refs show up under the prefix rather than the
-        default refs/heads. This is to demonstrate how the export
-        data can be stored under it's own ref (using the refspec
-        capability).
-
-        If None, refs defaults to ["HEAD"].
-        """
-
-        if not refs:
-            refs = ["HEAD"]
-
-        dirname = self.repo.get_base_path(base)
-        path = os.path.abspath(os.path.join(dirname, 'testgit.marks'))
-
-        if not os.path.exists(dirname):
-            os.makedirs(dirname)
-
-        print "feature relative-marks"
-        if os.path.exists(os.path.join(dirname, 'git.marks')):
-            print "feature import-marks=%s/git.marks" % self.repo.hash
-        print "feature export-marks=%s/git.marks" % self.repo.hash
-        sys.stdout.flush()
-
-        args = ["git", "--git-dir=" + self.repo.gitpath, "fast-export", "--export-marks=" + path]
-
-        if os.path.exists(path):
-            args.append("--import-marks=" + path)
-
-        args.extend(refs)
-
-        p1 = subprocess.Popen(args, stdout=subprocess.PIPE)
-
-        args = ["sed", "s_refs/heads/_" + self.repo.prefix + "_g"]
-
-        check_call(args, stdin=p1.stdout)
diff --git a/git_remote_helpers/git/git.py b/git_remote_helpers/git/git.py
deleted file mode 100644
index 007a1bf..0000000
--- a/git_remote_helpers/git/git.py
+++ /dev/null
@@ -1,678 +0,0 @@
-#!/usr/bin/env python
-
-"""Functionality for interacting with Git repositories.
-
-This module provides classes for interfacing with a Git repository.
-"""
-
-import os
-import re
-import time
-from binascii import hexlify
-from cStringIO import StringIO
-import unittest
-
-from git_remote_helpers.util import debug, error, die, start_command, run_command
-
-
-def get_git_dir ():
-    """Return the path to the GIT_DIR for this repo."""
-    args = ("git", "rev-parse", "--git-dir")
-    exit_code, output, errors = run_command(args)
-    if exit_code:
-        die("Failed to retrieve git dir")
-    assert not errors
-    return output.strip()
-
-
-def parse_git_config ():
-    """Return a dict containing the parsed version of 'git config -l'."""
-    exit_code, output, errors = run_command(("git", "config", "-z", "-l"))
-    if exit_code:
-        die("Failed to retrieve git configuration")
-    assert not errors
-    return dict([e.split('\n', 1) for e in output.split("\0") if e])
-
-
-def git_config_bool (value):
-    """Convert the given git config string value to True or False.
-
-    Raise ValueError if the given string was not recognized as a
-    boolean value.
-
-    """
-    norm_value = str(value).strip().lower()
-    if norm_value in ("true", "1", "yes", "on", ""):
-        return True
-    if norm_value in ("false", "0", "no", "off", "none"):
-        return False
-    raise ValueError("Failed to parse '%s' into a boolean value" % (value))
-
-
-def valid_git_ref (ref_name):
-    """Return True iff the given ref name is a valid git ref name."""
-    # The following is a reimplementation of the git check-ref-format
-    # command.  The rules were derived from the git check-ref-format(1)
-    # manual page.  This code should be replaced by a call to
-    # check_refname_format() in the git library, when such is available.
-    if ref_name.endswith('/') or \
-       ref_name.startswith('.') or \
-       ref_name.count('/.') or \
-       ref_name.count('..') or \
-       ref_name.endswith('.lock'):
-        return False
-    for c in ref_name:
-        if ord(c) < 0x20 or ord(c) == 0x7f or c in " ~^:?*[":
-            return False
-    return True
-
-
-class GitObjectFetcher(object):
-
-    """Provide parsed access to 'git cat-file --batch'.
-
-    This provides a read-only interface to the Git object database.
-
-    """
-
-    def __init__ (self):
-        """Initiate a 'git cat-file --batch' session."""
-        self.queue = []  # List of object names to be submitted
-        self.in_transit = None  # Object name currently in transit
-
-        # 'git cat-file --batch' produces binary output which is likely
-        # to be corrupted by the default "rU"-mode pipe opened by
-        # start_command.  (Mode == "rU" does universal new-line
-        # conversion, which mangles carriage returns.) Therefore, we
-        # open an explicitly binary-safe pipe for transferring the
-        # output from 'git cat-file --batch'.
-        pipe_r_fd, pipe_w_fd = os.pipe()
-        pipe_r = os.fdopen(pipe_r_fd, "rb")
-        pipe_w = os.fdopen(pipe_w_fd, "wb")
-        self.proc = start_command(("git", "cat-file", "--batch"),
-                                  stdout = pipe_w)
-        self.f = pipe_r
-
-    def __del__ (self):
-        """Verify completed communication with 'git cat-file --batch'."""
-        assert not self.queue
-        assert self.in_transit is None
-        self.proc.stdin.close()
-        assert self.proc.wait() == 0  # Zero exit code
-        assert self.f.read() == ""  # No remaining output
-
-    def _submit_next_object (self):
-        """Submit queue items to the 'git cat-file --batch' process.
-
-        If there are items in the queue, and there is currently no item
-        currently in 'transit', then pop the first item off the queue,
-        and submit it.
-
-        """
-        if self.queue and self.in_transit is None:
-            self.in_transit = self.queue.pop(0)
-            print >> self.proc.stdin, self.in_transit[0]
-
-    def push (self, obj, callback):
-        """Push the given object name onto the queue.
-
-        The given callback function will at some point in the future
-        be called exactly once with the following arguments:
-        - self - this GitObjectFetcher instance
-        - obj  - the object name provided to push()
-        - sha1 - the SHA1 of the object, if 'None' obj is missing
-        - t    - the type of the object (tag/commit/tree/blob)
-        - size - the size of the object in bytes
-        - data - the object contents
-
-        """
-        self.queue.append((obj, callback))
-        self._submit_next_object()  # (Re)start queue processing
-
-    def process_next_entry (self):
-        """Read the next entry off the queue and invoke callback."""
-        obj, cb = self.in_transit
-        self.in_transit = None
-        header = self.f.readline()
-        if header == "%s missing\n" % (obj):
-            cb(self, obj, None, None, None, None)
-            return
-        sha1, t, size = header.split(" ")
-        assert len(sha1) == 40
-        assert t in ("tag", "commit", "tree", "blob")
-        assert size.endswith("\n")
-        size = int(size.strip())
-        data = self.f.read(size)
-        assert self.f.read(1) == "\n"
-        cb(self, obj, sha1, t, size, data)
-        self._submit_next_object()
-
-    def process (self):
-        """Process the current queue until empty."""
-        while self.in_transit is not None:
-            self.process_next_entry()
-
-    # High-level convenience methods:
-
-    def get_sha1 (self, objspec):
-        """Return the SHA1 of the object specified by 'objspec'.
-
-        Return None if 'objspec' does not specify an existing object.
-
-        """
-        class _ObjHandler(object):
-            """Helper class for getting the returned SHA1."""
-            def __init__ (self, parser):
-                self.parser = parser
-                self.sha1 = None
-
-            def __call__ (self, parser, obj, sha1, t, size, data):
-                # FIXME: Many unused arguments. Could this be cheaper?
-                assert parser == self.parser
-                self.sha1 = sha1
-
-        handler = _ObjHandler(self)
-        self.push(objspec, handler)
-        self.process()
-        return handler.sha1
-
-    def open_obj (self, objspec):
-        """Return a file object wrapping the contents of a named object.
-
-        The caller is responsible for calling .close() on the returned
-        file object.
-
-        Raise KeyError if 'objspec' does not exist in the repo.
-
-        """
-        class _ObjHandler(object):
-            """Helper class for parsing the returned git object."""
-            def __init__ (self, parser):
-                """Set up helper."""
-                self.parser = parser
-                self.contents = StringIO()
-                self.err = None
-
-            def __call__ (self, parser, obj, sha1, t, size, data):
-                """Git object callback (see GitObjectFetcher documentation)."""
-                assert parser == self.parser
-                if not sha1:  # Missing object
-                    self.err = "Missing object '%s'" % obj
-                else:
-                    assert size == len(data)
-                    self.contents.write(data)
-
-        handler = _ObjHandler(self)
-        self.push(objspec, handler)
-        self.process()
-        if handler.err:
-            raise KeyError(handler.err)
-        handler.contents.seek(0)
-        return handler.contents
-
-    def walk_tree (self, tree_objspec, callback, prefix = ""):
-        """Recursively walk the given Git tree object.
-
-        Recursively walk all subtrees of the given tree object, and
-        invoke the given callback passing three arguments:
-        (path, mode, data) with the path, permission bits, and contents
-        of all the blobs found in the entire tree structure.
-
-        """
-        class _ObjHandler(object):
-            """Helper class for walking a git tree structure."""
-            def __init__ (self, parser, cb, path, mode = None):
-                """Set up helper."""
-                self.parser = parser
-                self.cb = cb
-                self.path = path
-                self.mode = mode
-                self.err = None
-
-            def parse_tree (self, treedata):
-                """Parse tree object data, yield tree entries.
-
-                Each tree entry is a 3-tuple (mode, sha1, path)
-
-                self.path is prepended to all paths yielded
-                from this method.
-
-                """
-                while treedata:
-                    mode = int(treedata[:6], 10)
-                    # Turn 100xxx into xxx
-                    if mode > 100000:
-                        mode -= 100000
-                    assert treedata[6] == " "
-                    i = treedata.find("\0", 7)
-                    assert i > 0
-                    path = treedata[7:i]
-                    sha1 = hexlify(treedata[i + 1: i + 21])
-                    yield (mode, sha1, self.path + path)
-                    treedata = treedata[i + 21:]
-
-            def __call__ (self, parser, obj, sha1, t, size, data):
-                """Git object callback (see GitObjectFetcher documentation)."""
-                assert parser == self.parser
-                if not sha1:  # Missing object
-                    self.err = "Missing object '%s'" % (obj)
-                    return
-                assert size == len(data)
-                if t == "tree":
-                    if self.path:
-                        self.path += "/"
-                    # Recurse into all blobs and subtrees
-                    for m, s, p in self.parse_tree(data):
-                        parser.push(s,
-                                    self.__class__(self.parser, self.cb, p, m))
-                elif t == "blob":
-                    self.cb(self.path, self.mode, data)
-                else:
-                    raise ValueError("Unknown object type '%s'" % (t))
-
-        self.push(tree_objspec, _ObjHandler(self, callback, prefix))
-        self.process()
-
-
-class GitRefMap(object):
-
-    """Map Git ref names to the Git object names they currently point to.
-
-    Behaves like a dictionary of Git ref names -> Git object names.
-
-    """
-
-    def __init__ (self, obj_fetcher):
-        """Create a new Git ref -> object map."""
-        self.obj_fetcher = obj_fetcher
-        self._cache = {}  # dict: refname -> objname
-
-    def _load (self, ref):
-        """Retrieve the object currently bound to the given ref.
-
-        The name of the object pointed to by the given ref is stored
-        into this mapping, and also returned.
-
-        """
-        if ref not in self._cache:
-            self._cache[ref] = self.obj_fetcher.get_sha1(ref)
-        return self._cache[ref]
-
-    def __contains__ (self, refname):
-        """Return True if the given refname is present in this cache."""
-        return bool(self._load(refname))
-
-    def __getitem__ (self, refname):
-        """Return the git object name pointed to by the given refname."""
-        commit = self._load(refname)
-        if commit is None:
-            raise KeyError("Unknown ref '%s'" % (refname))
-        return commit
-
-    def get (self, refname, default = None):
-        """Return the git object name pointed to by the given refname."""
-        commit = self._load(refname)
-        if commit is None:
-            return default
-        return commit
-
-
-class GitFICommit(object):
-
-    """Encapsulate the data in a Git fast-import commit command."""
-
-    SHA1RE = re.compile(r'^[0-9a-f]{40}$')
-
-    @classmethod
-    def parse_mode (cls, mode):
-        """Verify the given git file mode, and return it as a string."""
-        assert mode in (644, 755, 100644, 100755, 120000)
-        return "%i" % (mode)
-
-    @classmethod
-    def parse_objname (cls, objname):
-        """Return the given object name (or mark number) as a string."""
-        if isinstance(objname, int):  # Object name is a mark number
-            assert objname > 0
-            return ":%i" % (objname)
-
-        # No existence check is done, only checks for valid format
-        assert cls.SHA1RE.match(objname)  # Object name is valid SHA1
-        return objname
-
-    @classmethod
-    def quote_path (cls, path):
-        """Return a quoted version of the given path."""
-        path = path.replace("\\", "\\\\")
-        path = path.replace("\n", "\\n")
-        path = path.replace('"', '\\"')
-        return '"%s"' % (path)
-
-    @classmethod
-    def parse_path (cls, path):
-        """Verify that the given path is valid, and quote it, if needed."""
-        assert not isinstance(path, int)  # Cannot be a mark number
-
-        # These checks verify the rules on the fast-import man page
-        assert not path.count("//")
-        assert not path.endswith("/")
-        assert not path.startswith("/")
-        assert not path.count("/./")
-        assert not path.count("/../")
-        assert not path.endswith("/.")
-        assert not path.endswith("/..")
-        assert not path.startswith("./")
-        assert not path.startswith("../")
-
-        if path.count('"') + path.count('\n') + path.count('\\'):
-            return cls.quote_path(path)
-        return path
-
-    def __init__ (self, name, email, timestamp, timezone, message):
-        """Create a new Git fast-import commit, with the given metadata."""
-        self.name = name
-        self.email = email
-        self.timestamp = timestamp
-        self.timezone = timezone
-        self.message = message
-        self.pathops = []  # List of path operations in this commit
-
-    def modify (self, mode, blobname, path):
-        """Add a file modification to this Git fast-import commit."""
-        self.pathops.append(("M",
-                             self.parse_mode(mode),
-                             self.parse_objname(blobname),
-                             self.parse_path(path)))
-
-    def delete (self, path):
-        """Add a file deletion to this Git fast-import commit."""
-        self.pathops.append(("D", self.parse_path(path)))
-
-    def copy (self, path, newpath):
-        """Add a file copy to this Git fast-import commit."""
-        self.pathops.append(("C",
-                             self.parse_path(path),
-                             self.parse_path(newpath)))
-
-    def rename (self, path, newpath):
-        """Add a file rename to this Git fast-import commit."""
-        self.pathops.append(("R",
-                             self.parse_path(path),
-                             self.parse_path(newpath)))
-
-    def note (self, blobname, commit):
-        """Add a note object to this Git fast-import commit."""
-        self.pathops.append(("N",
-                             self.parse_objname(blobname),
-                             self.parse_objname(commit)))
-
-    def deleteall (self):
-        """Delete all files in this Git fast-import commit."""
-        self.pathops.append("deleteall")
-
-
-class TestGitFICommit(unittest.TestCase):
-
-    """GitFICommit selftests."""
-
-    def test_basic (self):
-        """GitFICommit basic selftests."""
-
-        def expect_fail (method, data):
-            """Verify that the method(data) raises an AssertionError."""
-            try:
-                method(data)
-            except AssertionError:
-                return
-            raise AssertionError("Failed test for invalid data '%s(%s)'" %
-                                 (method.__name__, repr(data)))
-
-    def test_parse_mode (self):
-        """GitFICommit.parse_mode() selftests."""
-        self.assertEqual(GitFICommit.parse_mode(644), "644")
-        self.assertEqual(GitFICommit.parse_mode(755), "755")
-        self.assertEqual(GitFICommit.parse_mode(100644), "100644")
-        self.assertEqual(GitFICommit.parse_mode(100755), "100755")
-        self.assertEqual(GitFICommit.parse_mode(120000), "120000")
-        self.assertRaises(AssertionError, GitFICommit.parse_mode, 0)
-        self.assertRaises(AssertionError, GitFICommit.parse_mode, 123)
-        self.assertRaises(AssertionError, GitFICommit.parse_mode, 600)
-        self.assertRaises(AssertionError, GitFICommit.parse_mode, "644")
-        self.assertRaises(AssertionError, GitFICommit.parse_mode, "abc")
-
-    def test_parse_objname (self):
-        """GitFICommit.parse_objname() selftests."""
-        self.assertEqual(GitFICommit.parse_objname(1), ":1")
-        self.assertRaises(AssertionError, GitFICommit.parse_objname, 0)
-        self.assertRaises(AssertionError, GitFICommit.parse_objname, -1)
-        self.assertEqual(GitFICommit.parse_objname("0123456789" * 4),
-                         "0123456789" * 4)
-        self.assertEqual(GitFICommit.parse_objname("2468abcdef" * 4),
-                         "2468abcdef" * 4)
-        self.assertRaises(AssertionError, GitFICommit.parse_objname,
-                          "abcdefghij" * 4)
-
-    def test_parse_path (self):
-        """GitFICommit.parse_path() selftests."""
-        self.assertEqual(GitFICommit.parse_path("foo/bar"), "foo/bar")
-        self.assertEqual(GitFICommit.parse_path("path/with\n and \" in it"),
-                         '"path/with\\n and \\" in it"')
-        self.assertRaises(AssertionError, GitFICommit.parse_path, 1)
-        self.assertRaises(AssertionError, GitFICommit.parse_path, 0)
-        self.assertRaises(AssertionError, GitFICommit.parse_path, -1)
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "foo//bar")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "foo/bar/")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "/foo/bar")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "foo/./bar")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "foo/../bar")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "foo/bar/.")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "foo/bar/..")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "./foo/bar")
-        self.assertRaises(AssertionError, GitFICommit.parse_path, "../foo/bar")
-
-
-class GitFastImport(object):
-
-    """Encapsulate communication with git fast-import."""
-
-    def __init__ (self, f, obj_fetcher, last_mark = 0):
-        """Set up self to communicate with a fast-import process through f."""
-        self.f = f  # File object where fast-import stream is written
-        self.obj_fetcher = obj_fetcher  # GitObjectFetcher instance
-        self.next_mark = last_mark + 1  # Next mark number
-        self.refs = set()  # Keep track of the refnames we've seen
-
-    def comment (self, s):
-        """Write the given comment in the fast-import stream."""
-        assert "\n" not in s, "Malformed comment: '%s'" % (s)
-        self.f.write("# %s\n" % (s))
-
-    def commit (self, ref, commitdata):
-        """Make a commit on the given ref, with the given GitFICommit.
-
-        Return the mark number identifying this commit.
-
-        """
-        self.f.write("""\
-commit %(ref)s
-mark :%(mark)i
-committer %(name)s <%(email)s> %(timestamp)i %(timezone)s
-data %(msgLength)i
-%(msg)s
-""" % {
-    'ref': ref,
-    'mark': self.next_mark,
-    'name': commitdata.name,
-    'email': commitdata.email,
-    'timestamp': commitdata.timestamp,
-    'timezone': commitdata.timezone,
-    'msgLength': len(commitdata.message),
-    'msg': commitdata.message,
-})
-
-        if ref not in self.refs:
-            self.refs.add(ref)
-            parent = ref + "^0"
-            if self.obj_fetcher.get_sha1(parent):
-                self.f.write("from %s\n" % (parent))
-
-        for op in commitdata.pathops:
-            self.f.write(" ".join(op))
-            self.f.write("\n")
-        self.f.write("\n")
-        retval = self.next_mark
-        self.next_mark += 1
-        return retval
-
-    def blob (self, data):
-        """Import the given blob.
-
-        Return the mark number identifying this blob.
-
-        """
-        self.f.write("blob\nmark :%i\ndata %i\n%s\n" %
-                     (self.next_mark, len(data), data))
-        retval = self.next_mark
-        self.next_mark += 1
-        return retval
-
-    def reset (self, ref, objname):
-        """Reset the given ref to point at the given Git object."""
-        self.f.write("reset %s\nfrom %s\n\n" %
-                     (ref, GitFICommit.parse_objname(objname)))
-        if ref not in self.refs:
-            self.refs.add(ref)
-
-
-class GitNotes(object):
-
-    """Encapsulate access to Git notes.
-
-    Simulates a dictionary of object name (SHA1) -> Git note mappings.
-
-    """
-
-    def __init__ (self, notes_ref, obj_fetcher):
-        """Create a new Git notes interface, bound to the given notes ref."""
-        self.notes_ref = notes_ref
-        self.obj_fetcher = obj_fetcher  # Used to get objects from repo
-        self.imports = []  # list: (objname, note data blob name) tuples
-
-    def __del__ (self):
-        """Verify that self.commit_notes() was called before destruction."""
-        if self.imports:
-            error("Missing call to self.commit_notes().")
-            error("%i notes are not committed!", len(self.imports))
-
-    def _load (self, objname):
-        """Return the note data associated with the given git object.
-
-        The note data is returned in string form. If no note is found
-        for the given object, None is returned.
-
-        """
-        try:
-            f = self.obj_fetcher.open_obj("%s:%s" % (self.notes_ref, objname))
-            ret = f.read()
-            f.close()
-        except KeyError:
-            ret = None
-        return ret
-
-    def __getitem__ (self, objname):
-        """Return the note contents associated with the given object.
-
-        Raise KeyError if given object has no associated note.
-
-        """
-        blobdata = self._load(objname)
-        if blobdata is None:
-            raise KeyError("Object '%s' has no note" % (objname))
-        return blobdata
-
-    def get (self, objname, default = None):
-        """Return the note contents associated with the given object.
-
-        Return given default if given object has no associated note.
-
-        """
-        blobdata = self._load(objname)
-        if blobdata is None:
-            return default
-        return blobdata
-
-    def import_note (self, objname, data, gfi):
-        """Tell git fast-import to store data as a note for objname.
-
-        This method uses the given GitFastImport object to create a
-        blob containing the given note data.  Also an entry mapping the
-        given object name to the created blob is stored until
-        commit_notes() is called.
-
-        Note that this method only works if it is later followed by a
-        call to self.commit_notes() (which produces the note commit
-        that refers to the blob produced here).
-
-        """
-        if not data.endswith("\n"):
-            data += "\n"
-        gfi.comment("Importing note for object %s" % (objname))
-        mark = gfi.blob(data)
-        self.imports.append((objname, mark))
-
-    def commit_notes (self, gfi, author, message):
-        """Produce a git fast-import note commit for the imported notes.
-
-        This method uses the given GitFastImport object to create a
-        commit on the notes ref, introducing the notes previously
-        submitted to import_note().
-
-        """
-        if not self.imports:
-            return
-        commitdata = GitFICommit(author[0], author[1],
-                                 time.time(), "0000", message)
-        for objname, blobname in self.imports:
-            assert isinstance(objname, int) and objname > 0
-            assert isinstance(blobname, int) and blobname > 0
-            commitdata.note(blobname, objname)
-        gfi.commit(self.notes_ref, commitdata)
-        self.imports = []
-
-
-class GitCachedNotes(GitNotes):
-
-    """Encapsulate access to Git notes (cached version).
-
-    Only use this class if no caching is done at a higher level.
-
-    Simulates a dictionary of object name (SHA1) -> Git note mappings.
-
-    """
-
-    def __init__ (self, notes_ref, obj_fetcher):
-        """Set up a caching wrapper around GitNotes."""
-        GitNotes.__init__(self, notes_ref, obj_fetcher)
-        self._cache = {}  # Cache: object name -> note data
-
-    def __del__ (self):
-        """Verify that GitNotes' destructor is called."""
-        GitNotes.__del__(self)
-
-    def _load (self, objname):
-        """Extend GitNotes._load() with a local objname -> note cache."""
-        if objname not in self._cache:
-            self._cache[objname] = GitNotes._load(self, objname)
-        return self._cache[objname]
-
-    def import_note (self, objname, data, gfi):
-        """Extend GitNotes.import_note() with a local objname -> note cache."""
-        if not data.endswith("\n"):
-            data += "\n"
-        assert objname not in self._cache
-        self._cache[objname] = data
-        GitNotes.import_note(self, objname, data, gfi)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/git_remote_helpers/git/importer.py b/git_remote_helpers/git/importer.py
deleted file mode 100644
index d3f90e1..0000000
--- a/git_remote_helpers/git/importer.py
+++ /dev/null
@@ -1,69 +0,0 @@
-import os
-import subprocess
-
-from git_remote_helpers.util import check_call, check_output
-
-
-class GitImporter(object):
-    """An importer for testgit repositories.
-
-    This importer simply delegates to git fast-import.
-    """
-
-    def __init__(self, repo):
-        """Creates a new importer for the specified repo.
-        """
-
-        self.repo = repo
-
-    def get_refs(self, gitdir):
-        """Returns a dictionary with refs.
-
-        Note that the keys in the returned dictionary are byte strings as
-        read from git.
-        """
-        args = ["git", "--git-dir=" + gitdir, "for-each-ref", "refs/heads"]
-        lines = check_output(args).strip().split('\n'.encode('ascii'))
-        refs = {}
-        for line in lines:
-            value, name = line.split(' '.encode('ascii'))
-            name = name.strip('commit\t'.encode('ascii'))
-            refs[name] = value
-        return refs
-
-    def do_import(self, base):
-        """Imports a fast-import stream to the given directory.
-
-        Simply delegates to git fast-import.
-        """
-
-        dirname = self.repo.get_base_path(base)
-        if self.repo.local:
-            gitdir = self.repo.gitpath
-        else:
-            gitdir = os.path.abspath(os.path.join(dirname, '.git'))
-        path = os.path.abspath(os.path.join(dirname, 'testgit.marks'))
-
-        if not os.path.exists(dirname):
-            os.makedirs(dirname)
-
-        refs_before = self.get_refs(gitdir)
-
-        args = ["git", "--git-dir=" + gitdir, "fast-import", "--quiet", "--export-marks=" + path]
-
-        if os.path.exists(path):
-            args.append("--import-marks=" + path)
-
-        check_call(args)
-
-        refs_after = self.get_refs(gitdir)
-
-        changed = {}
-
-        for name, value in refs_after.iteritems():
-            if refs_before.get(name) == value:
-                continue
-
-            changed[name] = value
-
-        return changed
diff --git a/git_remote_helpers/git/non_local.py b/git_remote_helpers/git/non_local.py
deleted file mode 100644
index e700250..0000000
--- a/git_remote_helpers/git/non_local.py
+++ /dev/null
@@ -1,61 +0,0 @@
-import os
-import subprocess
-
-from git_remote_helpers.util import check_call, die, warn
-
-
-class NonLocalGit(object):
-    """Handler to interact with non-local repos.
-    """
-
-    def __init__(self, repo):
-        """Creates a new non-local handler for the specified repo.
-        """
-
-        self.repo = repo
-
-    def clone(self, base):
-        """Clones the non-local repo to base.
-
-        Does nothing if a clone already exists.
-        """
-
-        path = os.path.join(self.repo.get_base_path(base), '.git')
-
-        # already cloned
-        if os.path.exists(path):
-            return path
-
-        os.makedirs(path)
-        args = ["git", "clone", "--bare", "--quiet", self.repo.gitpath, path]
-
-        check_call(args)
-
-        return path
-
-    def update(self, base):
-        """Updates checkout of the non-local repo in base.
-        """
-
-        path = os.path.join(self.repo.get_base_path(base), '.git')
-
-        if not os.path.exists(path):
-            die("could not find repo at %s", path)
-
-        args = ["git", "--git-dir=" + path, "fetch", "--quiet", self.repo.gitpath]
-        check_call(args)
-
-        args = ["git", "--git-dir=" + path, "update-ref", "refs/heads/master", "FETCH_HEAD"]
-        child = check_call(args)
-
-    def push(self, base):
-        """Pushes from the non-local repo to base.
-        """
-
-        path = os.path.join(self.repo.get_base_path(base), '.git')
-
-        if not os.path.exists(path):
-            die("could not find repo at %s", path)
-
-        args = ["git", "--git-dir=" + path, "push", "--quiet", self.repo.gitpath, "--all"]
-        child = check_call(args)
diff --git a/git_remote_helpers/git/repo.py b/git_remote_helpers/git/repo.py
deleted file mode 100644
index acbf8d7..0000000
--- a/git_remote_helpers/git/repo.py
+++ /dev/null
@@ -1,76 +0,0 @@
-import os
-import subprocess
-
-from git_remote_helpers.util import check_call
-
-
-def sanitize(rev, sep='\t'):
-    """Converts a for-each-ref line to a name/value pair.
-    """
-
-    splitrev = rev.split(sep)
-    branchval = splitrev[0]
-    branchname = splitrev[1].strip()
-    if branchname.startswith("refs/heads/"):
-        branchname = branchname[11:]
-
-    return branchname, branchval
-
-def is_remote(url):
-    """Checks whether the specified value is a remote url.
-    """
-
-    prefixes = ["http", "file", "git"]
-
-    for prefix in prefixes:
-        if url.startswith(prefix):
-            return True
-    return False
-
-class GitRepo(object):
-    """Repo object representing a repo.
-    """
-
-    def __init__(self, path):
-        """Initializes a new repo at the given path.
-        """
-
-        self.path = path
-        self.head = None
-        self.revmap = {}
-        self.local = not is_remote(self.path)
-
-        if(self.path.endswith('.git')):
-            self.gitpath = self.path
-        else:
-            self.gitpath = os.path.join(self.path, '.git')
-
-        if self.local and not os.path.exists(self.gitpath):
-            os.makedirs(self.gitpath)
-
-    def get_revs(self):
-        """Fetches all revs from the remote.
-        """
-
-        args = ["git", "ls-remote", self.gitpath]
-        path = ".cached_revs"
-        ofile = open(path, "w")
-
-        check_call(args, stdout=ofile)
-        output = open(path).readlines()
-        self.revmap = dict(sanitize(i) for i in output)
-        if "HEAD" in self.revmap:
-            del self.revmap["HEAD"]
-        self.revs = self.revmap.keys()
-        ofile.close()
-
-    def get_head(self):
-        """Determines the head of a local repo.
-        """
-
-        if not self.local:
-            return
-
-        path = os.path.join(self.gitpath, "HEAD")
-        head = open(path).readline()
-        self.head, _ = sanitize(head, ' ')
diff --git a/git_remote_helpers/setup.cfg b/git_remote_helpers/setup.cfg
deleted file mode 100644
index 4bff887..0000000
--- a/git_remote_helpers/setup.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-[build]
-build_purelib = build/lib
-build_platlib = build/lib
diff --git a/git_remote_helpers/setup.py b/git_remote_helpers/setup.py
deleted file mode 100644
index 6de41de..0000000
--- a/git_remote_helpers/setup.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-"""Distutils build/install script for the git_remote_helpers package."""
-
-from distutils.core import setup
-
-# If building under Python3 we need to run 2to3 on the code, do this by
-# trying to import distutils' 2to3 builder, which is only available in
-# Python3.
-try:
-    from distutils.command.build_py import build_py_2to3 as build_py
-except ImportError:
-    # 2.x
-    from distutils.command.build_py import build_py
-
-setup(
-    name = 'git_remote_helpers',
-    version = '0.1.0',
-    description = 'Git remote helper program for non-git repositories',
-    license = 'GPLv2',
-    author = 'The Git Community',
-    author_email = 'git@vger.kernel.org',
-    url = 'http://www.git-scm.com/',
-    package_dir = {'git_remote_helpers': ''},
-    packages = ['git_remote_helpers', 'git_remote_helpers.git'],
-    cmdclass = {'build_py': build_py},
-)
diff --git a/git_remote_helpers/util.py b/git_remote_helpers/util.py
deleted file mode 100644
index fbbb01b..0000000
--- a/git_remote_helpers/util.py
+++ /dev/null
@@ -1,275 +0,0 @@
-#!/usr/bin/env python
-
-"""Misc. useful functionality used by the rest of this package.
-
-This module provides common functionality used by the other modules in
-this package.
-
-"""
-
-import sys
-import os
-import subprocess
-
-try:
-    from subprocess import CalledProcessError
-except ImportError:
-    # from python2.7:subprocess.py
-    # Exception classes used by this module.
-    class CalledProcessError(Exception):
-        """This exception is raised when a process run by check_call() returns
-        a non-zero exit status.  The exit status will be stored in the
-        returncode attribute."""
-        def __init__(self, returncode, cmd):
-            self.returncode = returncode
-            self.cmd = cmd
-        def __str__(self):
-            return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
-
-
-# Whether or not to show debug messages
-DEBUG = False
-
-def notify(msg, *args):
-    """Print a message to stderr."""
-    print >> sys.stderr, msg % args
-
-def debug (msg, *args):
-    """Print a debug message to stderr when DEBUG is enabled."""
-    if DEBUG:
-        print >> sys.stderr, msg % args
-
-def error (msg, *args):
-    """Print an error message to stderr."""
-    print >> sys.stderr, "ERROR:", msg % args
-
-def warn(msg, *args):
-    """Print a warning message to stderr."""
-    print >> sys.stderr, "warning:", msg % args
-
-def die (msg, *args):
-    """Print as error message to stderr and exit the program."""
-    error(msg, *args)
-    sys.exit(1)
-
-
-class ProgressIndicator(object):
-
-    """Simple progress indicator.
-
-    Displayed as a spinning character by default, but can be customized
-    by passing custom messages that overrides the spinning character.
-
-    """
-
-    States = ("|", "/", "-", "\\")
-
-    def __init__ (self, prefix = "", f = sys.stdout):
-        """Create a new ProgressIndicator, bound to the given file object."""
-        self.n = 0  # Simple progress counter
-        self.f = f  # Progress is written to this file object
-        self.prev_len = 0  # Length of previous msg (to be overwritten)
-        self.prefix = prefix  # Prefix prepended to each progress message
-        self.prefix_lens = [] # Stack of prefix string lengths
-
-    def pushprefix (self, prefix):
-        """Append the given prefix onto the prefix stack."""
-        self.prefix_lens.append(len(self.prefix))
-        self.prefix += prefix
-
-    def popprefix (self):
-        """Remove the last prefix from the prefix stack."""
-        prev_len = self.prefix_lens.pop()
-        self.prefix = self.prefix[:prev_len]
-
-    def __call__ (self, msg = None, lf = False):
-        """Indicate progress, possibly with a custom message."""
-        if msg is None:
-            msg = self.States[self.n % len(self.States)]
-        msg = self.prefix + msg
-        print >> self.f, "\r%-*s" % (self.prev_len, msg),
-        self.prev_len = len(msg.expandtabs())
-        if lf:
-            print >> self.f
-            self.prev_len = 0
-        self.n += 1
-
-    def finish (self, msg = "done", noprefix = False):
-        """Finalize progress indication with the given message."""
-        if noprefix:
-            self.prefix = ""
-        self(msg, True)
-
-
-def start_command (args, cwd = None, shell = False, add_env = None,
-                   stdin = subprocess.PIPE, stdout = subprocess.PIPE,
-                   stderr = subprocess.PIPE):
-    """Start the given command, and return a subprocess object.
-
-    This provides a simpler interface to the subprocess module.
-
-    """
-    env = None
-    if add_env is not None:
-        env = os.environ.copy()
-        env.update(add_env)
-    return subprocess.Popen(args, bufsize = 1, stdin = stdin, stdout = stdout,
-                            stderr = stderr, cwd = cwd, shell = shell,
-                            env = env, universal_newlines = True)
-
-
-def run_command (args, cwd = None, shell = False, add_env = None,
-                 flag_error = True):
-    """Run the given command to completion, and return its results.
-
-    This provides a simpler interface to the subprocess module.
-
-    The results are formatted as a 3-tuple: (exit_code, output, errors)
-
-    If flag_error is enabled, Error messages will be produced if the
-    subprocess terminated with a non-zero exit code and/or stderr
-    output.
-
-    The other arguments are passed on to start_command().
-
-    """
-    process = start_command(args, cwd, shell, add_env)
-    (output, errors) = process.communicate()
-    exit_code = process.returncode
-    if flag_error and errors:
-        error("'%s' returned errors:\n---\n%s---", " ".join(args), errors)
-    if flag_error and exit_code:
-        error("'%s' returned exit code %i", " ".join(args), exit_code)
-    return (exit_code, output, errors)
-
-
-# from python2.7:subprocess.py
-def call(*popenargs, **kwargs):
-    """Run command with arguments.  Wait for command to complete, then
-    return the returncode attribute.
-
-    The arguments are the same as for the Popen constructor.  Example:
-
-    retcode = call(["ls", "-l"])
-    """
-    return subprocess.Popen(*popenargs, **kwargs).wait()
-
-
-# from python2.7:subprocess.py
-def check_call(*popenargs, **kwargs):
-    """Run command with arguments.  Wait for command to complete.  If
-    the exit code was zero then return, otherwise raise
-    CalledProcessError.  The CalledProcessError object will have the
-    return code in the returncode attribute.
-
-    The arguments are the same as for the Popen constructor.  Example:
-
-    check_call(["ls", "-l"])
-    """
-    retcode = call(*popenargs, **kwargs)
-    if retcode:
-        cmd = kwargs.get("args")
-        if cmd is None:
-            cmd = popenargs[0]
-        raise CalledProcessError(retcode, cmd)
-    return 0
-
-
-# from python2.7:subprocess.py
-def check_output(*popenargs, **kwargs):
-    r"""Run command with arguments and return its output as a byte string.
-
-    If the exit code was non-zero it raises a CalledProcessError.  The
-    CalledProcessError object will have the return code in the returncode
-    attribute and output in the output attribute.
-
-    The arguments are the same as for the Popen constructor.  Example:
-
-    >>> check_output(["ls", "-l", "/dev/null"])
-    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
-
-    The stdout argument is not allowed as it is used internally.
-    To capture standard error in the result, use stderr=STDOUT.
-
-    >>> check_output(["/bin/sh", "-c",
-    ...               "ls -l non_existent_file ; exit 0"],
-    ...              stderr=STDOUT)
-    'ls: non_existent_file: No such file or directory\n'
-    """
-    if 'stdout' in kwargs:
-        raise ValueError('stdout argument not allowed, it will be overridden.')
-    process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
-    output, unused_err = process.communicate()
-    retcode = process.poll()
-    if retcode:
-        cmd = kwargs.get("args")
-        if cmd is None:
-            cmd = popenargs[0]
-        raise subprocess.CalledProcessError(retcode, cmd)
-    return output
-
-
-def file_reader_method (missing_ok = False):
-    """Decorator for simplifying reading of files.
-
-    If missing_ok is True, a failure to open a file for reading will
-    not raise the usual IOError, but instead the wrapped method will be
-    called with f == None.  The method must in this case properly
-    handle f == None.
-
-    """
-    def _wrap (method):
-        """Teach given method to handle both filenames and file objects.
-
-        The given method must take a file object as its second argument
-        (the first argument being 'self', of course).  This decorator
-        will take a filename given as the second argument and promote
-        it to a file object.
-
-        """
-        def _wrapped_method (self, filename, *args, **kwargs):
-            if isinstance(filename, file):
-                f = filename
-            else:
-                try:
-                    f = open(filename, 'r')
-                except IOError:
-                    if missing_ok:
-                        f = None
-                    else:
-                        raise
-            try:
-                return method(self, f, *args, **kwargs)
-            finally:
-                if not isinstance(filename, file) and f:
-                    f.close()
-        return _wrapped_method
-    return _wrap
-
-
-def file_writer_method (method):
-    """Decorator for simplifying writing of files.
-
-    Enables the given method to handle both filenames and file objects.
-
-    The given method must take a file object as its second argument
-    (the first argument being 'self', of course).  This decorator will
-    take a filename given as the second argument and promote it to a
-    file object.
-
-    """
-    def _new_method (self, filename, *args, **kwargs):
-        if isinstance(filename, file):
-            f = filename
-        else:
-            # Make sure the containing directory exists
-            parent_dir = os.path.dirname(filename)
-            if not os.path.isdir(parent_dir):
-                os.makedirs(parent_dir)
-            f = open(filename, 'w')
-        try:
-            return method(self, f, *args, **kwargs)
-        finally:
-            if not isinstance(filename, file):
-                f.close()
-    return _new_method
diff --git a/gitk-git/gitk b/gitk-git/gitk
index 5cd00d8..90764e8 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -2,7 +2,7 @@
 # Tcl ignores the next line -*- tcl -*- \
 exec wish "$0" -- "$@"
 
-# Copyright © 2005-2011 Paul Mackerras.  All rights reserved.
+# Copyright © 2005-2014 Paul Mackerras.  All rights reserved.
 # This program is free software; it may be used, copied, modified
 # and distributed under the terms of the GNU General Public Licence,
 # either version 2, or (at your option) any later version.
@@ -156,10 +156,12 @@
 
 proc parseviewargs {n arglist} {
     global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs env
+    global vinlinediff
     global worddiff git_version
 
     set vdatemode($n) 0
     set vmergeonly($n) 0
+    set vinlinediff($n) 0
     set glflags {}
     set diffargs {}
     set nextisval 0
@@ -227,12 +229,20 @@
 	    "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
 	    "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
 	    "--remove-empty" - "--first-parent" - "--cherry-pick" -
-	    "-S*" - "--pickaxe-all" - "--pickaxe-regex" -
+	    "-S*" - "-G*" - "--pickaxe-all" - "--pickaxe-regex" -
 	    "--simplify-by-decoration" {
 		# These mean that we get a subset of the commits
 		set filtered 1
 		lappend glflags $arg
 	    }
+	    "-L*" {
+		# Line-log with 'stuck' argument (unstuck form is
+		# not supported)
+		set filtered 1
+		set vinlinediff($n) 1
+		set allknown 0
+		lappend glflags $arg
+	    }
 	    "-n" {
 		# This appears to be the only one that has a value as a
 		# separate word following it
@@ -1704,8 +1714,17 @@
 	set comment $newcomment
     }
     set hasnote [string first "\nNotes:\n" $contents]
+    set diff ""
+    # If there is diff output shown in the git-log stream, split it
+    # out.  But get rid of the empty line that always precedes the
+    # diff.
+    set i [string first "\n\ndiff" $comment]
+    if {$i >= 0} {
+	set diff [string range $comment $i+1 end]
+	set comment [string range $comment 0 $i-1]
+    }
     set commitinfo($id) [list $headline $auname $audate \
-			     $comname $comdate $comment $hasnote]
+			     $comname $comdate $comment $hasnote $diff]
 }
 
 proc getcommit {id} {
@@ -2244,9 +2263,35 @@
 
     # build up the bottom bar of upper window
     ${NS}::label .tf.lbar.flabel -text "[mc "Find"] "
-    ${NS}::button .tf.lbar.fnext -text [mc "next"] -command {dofind 1 1}
-    ${NS}::button .tf.lbar.fprev -text [mc "prev"] -command {dofind -1 1}
+
+    set bm_down_data {
+	#define down_width 16
+	#define down_height 16
+	static unsigned char down_bits[] = {
+	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+	0x87, 0xe1, 0x8e, 0x71, 0x9c, 0x39, 0xb8, 0x1d,
+	0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01};
+    }
+    image create bitmap bm-down -data $bm_down_data -foreground $uifgcolor
+    ${NS}::button .tf.lbar.fnext -width 26 -command {dofind 1 1}
+    .tf.lbar.fnext configure -image bm-down
+
+    set bm_up_data {
+	#define up_width 16
+	#define up_height 16
+	static unsigned char up_bits[] = {
+	0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
+	0xb8, 0x1d, 0x9c, 0x39, 0x8e, 0x71, 0x87, 0xe1,
+	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01};
+    }
+    image create bitmap bm-up -data $bm_up_data -foreground $uifgcolor
+    ${NS}::button .tf.lbar.fprev -width 26 -command {dofind -1 1}
+    .tf.lbar.fprev configure -image bm-up
+
     ${NS}::label .tf.lbar.flab2 -text " [mc "commit"] "
+
     pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \
 	-side left -fill y
     set gdttype [mc "containing:"]
@@ -2384,7 +2429,8 @@
     $ctext tag conf msep -font textfontbold
     $ctext tag conf found -back $foundbgcolor
     $ctext tag conf currentsearchhit -back $currentsearchhitbgcolor
-    $ctext tag conf wwrap -wrap word
+    $ctext tag conf wwrap -wrap word -lmargin2 1c
+    $ctext tag conf bold -font textfontbold
 
     .pwbottom add .bleft
     if {!$use_ttk} {
@@ -2741,14 +2787,17 @@
     global linkfgcolor circleoutlinecolor
     global autoselect autosellen extdifftool perfile_attrs markbgcolor use_ttk
     global hideremotes want_ttk maxrefs
+    global config_file config_file_tmp
 
     if {$stuffsaved} return
     if {![winfo viewable .]} return
     catch {
-	if {[file exists ~/.gitk-new]} {file delete -force ~/.gitk-new}
-	set f [open "~/.gitk-new" w]
+	if {[file exists $config_file_tmp]} {
+	    file delete -force $config_file_tmp
+	}
+	set f [open $config_file_tmp w]
 	if {$::tcl_platform(platform) eq {windows}} {
-	    file attributes "~/.gitk-new" -hidden true
+	    file attributes $config_file_tmp -hidden true
 	}
 	puts $f [list set mainfont $mainfont]
 	puts $f [list set textfont $textfont]
@@ -2825,7 +2874,7 @@
 	}
 	puts $f "}"
 	close $f
-	file rename -force "~/.gitk-new" "~/.gitk"
+	file rename -force $config_file_tmp $config_file
     }
     set stuffsaved 1
 }
@@ -2927,7 +2976,7 @@
     message $w.m -text [mc "
 Gitk - a commit viewer for git
 
-Copyright \u00a9 2005-2011 Paul Mackerras
+Copyright \u00a9 2005-2014 Paul Mackerras
 
 Use and redistribute under the terms of the GNU General Public License"] \
 	    -justify center -aspect 400 -border 2 -bg white -relief groove
@@ -6387,6 +6436,25 @@
     $canv bind $t <Button-1> "lineclick %x %y $id 1"
 }
 
+proc graph_pane_width {} {
+    global use_ttk
+
+    if {$use_ttk} {
+	set g [.tf.histframe.pwclist sashpos 0]
+    } else {
+	set g [.tf.histframe.pwclist sash coord 0]
+    }
+    return [lindex $g 0]
+}
+
+proc totalwidth {l font extra} {
+    set tot 0
+    foreach str $l {
+	set tot [expr {$tot + [font measure $font $str] + $extra}]
+    }
+    return $tot
+}
+
 proc drawtags {id x xt y1} {
     global idtags idheads idotherrefs mainhead
     global linespc lthickness
@@ -6398,9 +6466,27 @@
     set marks {}
     set ntags 0
     set nheads 0
+    set singletag 0
+    set maxtags 3
+    set maxtagpct 25
+    set maxwidth [expr {[graph_pane_width] * $maxtagpct / 100}]
+    set delta [expr {int(0.5 * ($linespc - $lthickness))}]
+    set extra [expr {$delta + $lthickness + $linespc}]
+
     if {[info exists idtags($id)]} {
 	set marks $idtags($id)
 	set ntags [llength $marks]
+	if {$ntags > $maxtags ||
+	    [totalwidth $marks mainfont $extra] > $maxwidth} {
+	    # show just a single "n tags..." tag
+	    set singletag 1
+	    if {$ntags == 1} {
+		set marks [list "tag..."]
+	    } else {
+		set marks [list [format "%d tags..." $ntags]]
+	    }
+	    set ntags 1
+	}
     }
     if {[info exists idheads($id)]} {
 	set marks [concat $marks $idheads($id)]
@@ -6413,7 +6499,6 @@
 	return $xt
     }
 
-    set delta [expr {int(0.5 * ($linespc - $lthickness))}]
     set yt [expr {$y1 - 0.5 * $linespc}]
     set yb [expr {$yt + $linespc - 1}]
     set xvals {}
@@ -6428,7 +6513,7 @@
 	}
 	lappend xvals $xt
 	lappend wvals $wid
-	set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
+	set xt [expr {$xt + $wid + $extra}]
     }
     set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
 	       -width $lthickness -fill $reflinecolor -tags tag.$id]
@@ -6444,7 +6529,12 @@
 		       $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
 		       -width 1 -outline $tagoutlinecolor -fill $tagbgcolor \
 		       -tags tag.$id]
-	    $canv bind $t <1> [list showtag $tag_quoted 1]
+	    if {$singletag} {
+		set tagclick [list showtags $id 1]
+	    } else {
+		set tagclick [list showtag $tag_quoted 1]
+	    }
+	    $canv bind $t <1> $tagclick
 	    set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}]
 	} else {
 	    # draw a head or other ref
@@ -6471,7 +6561,7 @@
 	set t [$canv create text $xl $y1 -anchor w -text $tag -fill $headfgcolor \
 		   -font $font -tags [list tag.$id text]]
 	if {$ntags >= 0} {
-	    $canv bind $t <1> [list showtag $tag_quoted 1]
+	    $canv bind $t <1> $tagclick
 	} elseif {$nheads >= 0} {
 	    $canv bind $t $ctxbut [list headmenu %X %Y $id $tag_quoted]
 	}
@@ -7080,6 +7170,7 @@
     global cmitmode showneartags allcommits
     global targetrow targetid lastscrollrows
     global autoselect autosellen jump_to_here
+    global vinlinediff
 
     catch {unset pending_select}
     $canv delete hover
@@ -7221,6 +7312,8 @@
     init_flist [mc "Comments"]
     if {$cmitmode eq "tree"} {
 	gettree $id
+    } elseif {$vinlinediff($curview) == 1} {
+	showinlinediff $id
     } elseif {[llength $olds] <= 1} {
 	startdiff $id
     } else {
@@ -7557,6 +7650,39 @@
     }
 }
 
+proc showinlinediff {ids} {
+    global commitinfo commitdata ctext
+    global treediffs
+
+    set info $commitinfo($ids)
+    set diff [lindex $info 7]
+    set difflines [split $diff "\n"]
+
+    initblobdiffvars
+    set treediff {}
+
+    set inhdr 0
+    foreach line $difflines {
+	if {![string compare -length 5 "diff " $line]} {
+	    set inhdr 1
+	} elseif {$inhdr && ![string compare -length 4 "+++ " $line]} {
+	    # offset also accounts for the b/ prefix
+	    lappend treediff [string range $line 6 end]
+	    set inhdr 0
+	}
+    }
+
+    set treediffs($ids) $treediff
+    add_flist $treediff
+
+    $ctext conf -state normal
+    foreach line $difflines {
+	parseblobdiffline $ids $line
+    }
+    maybe_scroll_ctext 1
+    $ctext conf -state disabled
+}
+
 # If the filename (name) is under any of the passed filter paths
 # then return true to include the file in the listing.
 proc path_filter {filter name} {
@@ -7710,15 +7836,25 @@
     reselectline
 }
 
+proc initblobdiffvars {} {
+    global diffencoding targetline diffnparents
+    global diffinhdr currdiffsubmod diffseehere
+    set targetline {}
+    set diffnparents 0
+    set diffinhdr 0
+    set diffencoding [get_path_encoding {}]
+    set currdiffsubmod ""
+    set diffseehere -1
+}
+
 proc getblobdiffs {ids} {
     global blobdifffd diffids env
-    global diffinhdr treediffs
+    global treediffs
     global diffcontext
     global ignorespace
     global worddiff
     global limitdiffs vfilelimit curview
-    global diffencoding targetline diffnparents
-    global git_version currdiffsubmod
+    global git_version
 
     set textconv {}
     if {[package vcompare $git_version "1.6.1"] >= 0} {
@@ -7742,13 +7878,9 @@
 	error_popup [mc "Error getting diffs: %s" $err]
 	return
     }
-    set targetline {}
-    set diffnparents 0
-    set diffinhdr 0
-    set diffencoding [get_path_encoding {}]
     fconfigure $bdf -blocking 0 -encoding binary -eofchar {}
     set blobdifffd($ids) $bdf
-    set currdiffsubmod ""
+    initblobdiffvars
     filerun $bdf [list getblobdiffline $bdf $diffids]
 }
 
@@ -7814,13 +7946,17 @@
     set diffline 0
 }
 
+proc blobdiffmaybeseehere {ateof} {
+    global diffseehere
+    if {$diffseehere >= 0} {
+	mark_ctext_line [lindex [split $diffseehere .] 0]
+    }
+    maybe_scroll_ctext $ateof
+}
+
 proc getblobdiffline {bdf ids} {
-    global diffids blobdifffd ctext curdiffstart
-    global diffnexthead diffnextnote difffilestart
-    global ctext_file_names ctext_file_lines
-    global diffinhdr treediffs mergemax diffnparents
-    global diffencoding jump_to_here targetline diffline currdiffsubmod
-    global worddiff
+    global diffids blobdifffd
+    global ctext
 
     set nr 0
     $ctext conf -state normal
@@ -7829,207 +7965,10 @@
 	    catch {close $bdf}
 	    return 0
 	}
-	if {![string compare -length 5 "diff " $line]} {
-	    if {![regexp {^diff (--cc|--git) } $line m type]} {
-		set line [encoding convertfrom $line]
-		$ctext insert end "$line\n" hunksep
-		continue
-	    }
-	    # start of a new file
-	    set diffinhdr 1
-	    $ctext insert end "\n"
-	    set curdiffstart [$ctext index "end - 1c"]
-	    lappend ctext_file_names ""
-	    lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
-	    $ctext insert end "\n" filesep
-
-	    if {$type eq "--cc"} {
-		# start of a new file in a merge diff
-		set fname [string range $line 10 end]
-		if {[lsearch -exact $treediffs($ids) $fname] < 0} {
-		    lappend treediffs($ids) $fname
-		    add_flist [list $fname]
-		}
-
-	    } else {
-		set line [string range $line 11 end]
-		# If the name hasn't changed the length will be odd,
-		# the middle char will be a space, and the two bits either
-		# side will be a/name and b/name, or "a/name" and "b/name".
-		# If the name has changed we'll get "rename from" and
-		# "rename to" or "copy from" and "copy to" lines following
-		# this, and we'll use them to get the filenames.
-		# This complexity is necessary because spaces in the
-		# filename(s) don't get escaped.
-		set l [string length $line]
-		set i [expr {$l / 2}]
-		if {!(($l & 1) && [string index $line $i] eq " " &&
-		      [string range $line 2 [expr {$i - 1}]] eq \
-			  [string range $line [expr {$i + 3}] end])} {
-		    continue
-		}
-		# unescape if quoted and chop off the a/ from the front
-		if {[string index $line 0] eq "\""} {
-		    set fname [string range [lindex $line 0] 2 end]
-		} else {
-		    set fname [string range $line 2 [expr {$i - 1}]]
-		}
-	    }
-	    makediffhdr $fname $ids
-
-	} elseif {![string compare -length 16 "* Unmerged path " $line]} {
-	    set fname [encoding convertfrom [string range $line 16 end]]
-	    $ctext insert end "\n"
-	    set curdiffstart [$ctext index "end - 1c"]
-	    lappend ctext_file_names $fname
-	    lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
-	    $ctext insert end "$line\n" filesep
-	    set i [lsearch -exact $treediffs($ids) $fname]
-	    if {$i >= 0} {
-		setinlist difffilestart $i $curdiffstart
-	    }
-
-	} elseif {![string compare -length 2 "@@" $line]} {
-	    regexp {^@@+} $line ats
-	    set line [encoding convertfrom $diffencoding $line]
-	    $ctext insert end "$line\n" hunksep
-	    if {[regexp { \+(\d+),\d+ @@} $line m nl]} {
-		set diffline $nl
-	    }
-	    set diffnparents [expr {[string length $ats] - 1}]
-	    set diffinhdr 0
-
-	} elseif {![string compare -length 10 "Submodule " $line]} {
-	    # start of a new submodule
-	    if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
-		set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
-	    } else {
-		set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
-	    }
-	    if {$currdiffsubmod != $fname} {
-		$ctext insert end "\n";     # Add newline after commit message
-	    }
-	    set curdiffstart [$ctext index "end - 1c"]
-	    lappend ctext_file_names ""
-	    if {$currdiffsubmod != $fname} {
-		lappend ctext_file_lines $fname
-		makediffhdr $fname $ids
-		set currdiffsubmod $fname
-		$ctext insert end "\n$line\n" filesep
-	    } else {
-		$ctext insert end "$line\n" filesep
-	    }
-	} elseif {![string compare -length 3 "  >" $line]} {
-	    set $currdiffsubmod ""
-	    set line [encoding convertfrom $diffencoding $line]
-	    $ctext insert end "$line\n" dresult
-	} elseif {![string compare -length 3 "  <" $line]} {
-	    set $currdiffsubmod ""
-	    set line [encoding convertfrom $diffencoding $line]
-	    $ctext insert end "$line\n" d0
-	} elseif {$diffinhdr} {
-	    if {![string compare -length 12 "rename from " $line]} {
-		set fname [string range $line [expr 6 + [string first " from " $line] ] end]
-		if {[string index $fname 0] eq "\""} {
-		    set fname [lindex $fname 0]
-		}
-		set fname [encoding convertfrom $fname]
-		set i [lsearch -exact $treediffs($ids) $fname]
-		if {$i >= 0} {
-		    setinlist difffilestart $i $curdiffstart
-		}
-	    } elseif {![string compare -length 10 $line "rename to "] ||
-		      ![string compare -length 8 $line "copy to "]} {
-		set fname [string range $line [expr 4 + [string first " to " $line] ] end]
-		if {[string index $fname 0] eq "\""} {
-		    set fname [lindex $fname 0]
-		}
-		makediffhdr $fname $ids
-	    } elseif {[string compare -length 3 $line "---"] == 0} {
-		# do nothing
-		continue
-	    } elseif {[string compare -length 3 $line "+++"] == 0} {
-		set diffinhdr 0
-		continue
-	    }
-	    $ctext insert end "$line\n" filesep
-
-	} else {
-	    set line [string map {\x1A ^Z} \
-                          [encoding convertfrom $diffencoding $line]]
-	    # parse the prefix - one ' ', '-' or '+' for each parent
-	    set prefix [string range $line 0 [expr {$diffnparents - 1}]]
-	    set tag [expr {$diffnparents > 1? "m": "d"}]
-	    set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
-	    set words_pre_markup ""
-	    set words_post_markup ""
-	    if {[string trim $prefix " -+"] eq {}} {
-		# prefix only has " ", "-" and "+" in it: normal diff line
-		set num [string first "-" $prefix]
-		if {$dowords} {
-		    set line [string range $line 1 end]
-		}
-		if {$num >= 0} {
-		    # removed line, first parent with line is $num
-		    if {$num >= $mergemax} {
-			set num "max"
-		    }
-		    if {$dowords && $worddiff eq [mc "Markup words"]} {
-			$ctext insert end "\[-$line-\]" $tag$num
-		    } else {
-			$ctext insert end "$line" $tag$num
-		    }
-		    if {!$dowords} {
-			$ctext insert end "\n" $tag$num
-		    }
-		} else {
-		    set tags {}
-		    if {[string first "+" $prefix] >= 0} {
-			# added line
-			lappend tags ${tag}result
-			if {$diffnparents > 1} {
-			    set num [string first " " $prefix]
-			    if {$num >= 0} {
-				if {$num >= $mergemax} {
-				    set num "max"
-				}
-				lappend tags m$num
-			    }
-			}
-			set words_pre_markup "{+"
-			set words_post_markup "+}"
-		    }
-		    if {$targetline ne {}} {
-			if {$diffline == $targetline} {
-			    set seehere [$ctext index "end - 1 chars"]
-			    set targetline {}
-			} else {
-			    incr diffline
-			}
-		    }
-		    if {$dowords && $worddiff eq [mc "Markup words"]} {
-			$ctext insert end "$words_pre_markup$line$words_post_markup" $tags
-		    } else {
-			$ctext insert end "$line" $tags
-		    }
-		    if {!$dowords} {
-			$ctext insert end "\n" $tags
-		    }
-		}
-	    } elseif {$dowords && $prefix eq "~"} {
-		$ctext insert end "\n" {}
-	    } else {
-		# "\ No newline at end of file",
-		# or something else we don't recognize
-		$ctext insert end "$line\n" hunksep
-	    }
-	}
+	parseblobdiffline $ids $line
     }
-    if {[info exists seehere]} {
-	mark_ctext_line [lindex [split $seehere .] 0]
-    }
-    maybe_scroll_ctext [eof $bdf]
     $ctext conf -state disabled
+    blobdiffmaybeseehere [eof $bdf]
     if {[eof $bdf]} {
 	catch {close $bdf}
 	return 0
@@ -8037,6 +7976,211 @@
     return [expr {$nr >= 1000? 2: 1}]
 }
 
+proc parseblobdiffline {ids line} {
+    global ctext curdiffstart
+    global diffnexthead diffnextnote difffilestart
+    global ctext_file_names ctext_file_lines
+    global diffinhdr treediffs mergemax diffnparents
+    global diffencoding jump_to_here targetline diffline currdiffsubmod
+    global worddiff diffseehere
+
+    if {![string compare -length 5 "diff " $line]} {
+	if {![regexp {^diff (--cc|--git) } $line m type]} {
+	    set line [encoding convertfrom $line]
+	    $ctext insert end "$line\n" hunksep
+	    continue
+	}
+	# start of a new file
+	set diffinhdr 1
+	$ctext insert end "\n"
+	set curdiffstart [$ctext index "end - 1c"]
+	lappend ctext_file_names ""
+	lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
+	$ctext insert end "\n" filesep
+
+	if {$type eq "--cc"} {
+	    # start of a new file in a merge diff
+	    set fname [string range $line 10 end]
+	    if {[lsearch -exact $treediffs($ids) $fname] < 0} {
+		lappend treediffs($ids) $fname
+		add_flist [list $fname]
+	    }
+
+	} else {
+	    set line [string range $line 11 end]
+	    # If the name hasn't changed the length will be odd,
+	    # the middle char will be a space, and the two bits either
+	    # side will be a/name and b/name, or "a/name" and "b/name".
+	    # If the name has changed we'll get "rename from" and
+	    # "rename to" or "copy from" and "copy to" lines following
+	    # this, and we'll use them to get the filenames.
+	    # This complexity is necessary because spaces in the
+	    # filename(s) don't get escaped.
+	    set l [string length $line]
+	    set i [expr {$l / 2}]
+	    if {!(($l & 1) && [string index $line $i] eq " " &&
+		  [string range $line 2 [expr {$i - 1}]] eq \
+		      [string range $line [expr {$i + 3}] end])} {
+		return
+	    }
+	    # unescape if quoted and chop off the a/ from the front
+	    if {[string index $line 0] eq "\""} {
+		set fname [string range [lindex $line 0] 2 end]
+	    } else {
+		set fname [string range $line 2 [expr {$i - 1}]]
+	    }
+	}
+	makediffhdr $fname $ids
+
+    } elseif {![string compare -length 16 "* Unmerged path " $line]} {
+	set fname [encoding convertfrom [string range $line 16 end]]
+	$ctext insert end "\n"
+	set curdiffstart [$ctext index "end - 1c"]
+	lappend ctext_file_names $fname
+	lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
+	$ctext insert end "$line\n" filesep
+	set i [lsearch -exact $treediffs($ids) $fname]
+	if {$i >= 0} {
+	    setinlist difffilestart $i $curdiffstart
+	}
+
+    } elseif {![string compare -length 2 "@@" $line]} {
+	regexp {^@@+} $line ats
+	set line [encoding convertfrom $diffencoding $line]
+	$ctext insert end "$line\n" hunksep
+	if {[regexp { \+(\d+),\d+ @@} $line m nl]} {
+	    set diffline $nl
+	}
+	set diffnparents [expr {[string length $ats] - 1}]
+	set diffinhdr 0
+
+    } elseif {![string compare -length 10 "Submodule " $line]} {
+	# start of a new submodule
+	if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
+	    set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
+	} else {
+	    set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
+	}
+	if {$currdiffsubmod != $fname} {
+	    $ctext insert end "\n";     # Add newline after commit message
+	}
+	set curdiffstart [$ctext index "end - 1c"]
+	lappend ctext_file_names ""
+	if {$currdiffsubmod != $fname} {
+	    lappend ctext_file_lines $fname
+	    makediffhdr $fname $ids
+	    set currdiffsubmod $fname
+	    $ctext insert end "\n$line\n" filesep
+	} else {
+	    $ctext insert end "$line\n" filesep
+	}
+    } elseif {![string compare -length 3 "  >" $line]} {
+	set $currdiffsubmod ""
+	set line [encoding convertfrom $diffencoding $line]
+	$ctext insert end "$line\n" dresult
+    } elseif {![string compare -length 3 "  <" $line]} {
+	set $currdiffsubmod ""
+	set line [encoding convertfrom $diffencoding $line]
+	$ctext insert end "$line\n" d0
+    } elseif {$diffinhdr} {
+	if {![string compare -length 12 "rename from " $line]} {
+	    set fname [string range $line [expr 6 + [string first " from " $line] ] end]
+	    if {[string index $fname 0] eq "\""} {
+		set fname [lindex $fname 0]
+	    }
+	    set fname [encoding convertfrom $fname]
+	    set i [lsearch -exact $treediffs($ids) $fname]
+	    if {$i >= 0} {
+		setinlist difffilestart $i $curdiffstart
+	    }
+	} elseif {![string compare -length 10 $line "rename to "] ||
+		  ![string compare -length 8 $line "copy to "]} {
+	    set fname [string range $line [expr 4 + [string first " to " $line] ] end]
+	    if {[string index $fname 0] eq "\""} {
+		set fname [lindex $fname 0]
+	    }
+	    makediffhdr $fname $ids
+	} elseif {[string compare -length 3 $line "---"] == 0} {
+	    # do nothing
+	    return
+	} elseif {[string compare -length 3 $line "+++"] == 0} {
+	    set diffinhdr 0
+	    return
+	}
+	$ctext insert end "$line\n" filesep
+
+    } else {
+	set line [string map {\x1A ^Z} \
+		      [encoding convertfrom $diffencoding $line]]
+	# parse the prefix - one ' ', '-' or '+' for each parent
+	set prefix [string range $line 0 [expr {$diffnparents - 1}]]
+	set tag [expr {$diffnparents > 1? "m": "d"}]
+	set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
+	set words_pre_markup ""
+	set words_post_markup ""
+	if {[string trim $prefix " -+"] eq {}} {
+	    # prefix only has " ", "-" and "+" in it: normal diff line
+	    set num [string first "-" $prefix]
+	    if {$dowords} {
+		set line [string range $line 1 end]
+	    }
+	    if {$num >= 0} {
+		# removed line, first parent with line is $num
+		if {$num >= $mergemax} {
+		    set num "max"
+		}
+		if {$dowords && $worddiff eq [mc "Markup words"]} {
+		    $ctext insert end "\[-$line-\]" $tag$num
+		} else {
+		    $ctext insert end "$line" $tag$num
+		}
+		if {!$dowords} {
+		    $ctext insert end "\n" $tag$num
+		}
+	    } else {
+		set tags {}
+		if {[string first "+" $prefix] >= 0} {
+		    # added line
+		    lappend tags ${tag}result
+		    if {$diffnparents > 1} {
+			set num [string first " " $prefix]
+			if {$num >= 0} {
+			    if {$num >= $mergemax} {
+				set num "max"
+			    }
+			    lappend tags m$num
+			}
+		    }
+		    set words_pre_markup "{+"
+		    set words_post_markup "+}"
+		}
+		if {$targetline ne {}} {
+		    if {$diffline == $targetline} {
+			set diffseehere [$ctext index "end - 1 chars"]
+			set targetline {}
+		    } else {
+			incr diffline
+		    }
+		}
+		if {$dowords && $worddiff eq [mc "Markup words"]} {
+		    $ctext insert end "$words_pre_markup$line$words_post_markup" $tags
+		} else {
+		    $ctext insert end "$line" $tags
+		}
+		if {!$dowords} {
+		    $ctext insert end "\n" $tags
+		}
+	    }
+	} elseif {$dowords && $prefix eq "~"} {
+	    $ctext insert end "\n" {}
+	} else {
+	    # "\ No newline at end of file",
+	    # or something else we don't recognize
+	    $ctext insert end "$line\n" hunksep
+	}
+    }
+}
+
 proc changediffdisp {} {
     global ctext diffelide
 
@@ -10878,6 +11022,23 @@
     return [list $x $y $z]
 }
 
+proc add_tag_ctext {tag} {
+    global ctext cached_tagcontent tagids
+
+    if {![info exists cached_tagcontent($tag)]} {
+	catch {
+	    set cached_tagcontent($tag) [exec git cat-file -p $tag]
+	}
+    }
+    $ctext insert end "[mc "Tag"]: $tag\n" bold
+    if {[info exists cached_tagcontent($tag)]} {
+	set text $cached_tagcontent($tag)
+    } else {
+	set text "[mc "Id"]:  $tagids($tag)"
+    }
+    appendwithlinks $text {}
+}
+
 proc showtag {tag isnew} {
     global ctext cached_tagcontent tagids linknum tagobjid
 
@@ -10888,17 +11049,28 @@
     clear_ctext
     settabs 0
     set linknum 0
-    if {![info exists cached_tagcontent($tag)]} {
-	catch {
-           set cached_tagcontent($tag) [exec git cat-file -p $tag]
-	}
+    add_tag_ctext $tag
+    maybe_scroll_ctext 1
+    $ctext conf -state disabled
+    init_flist {}
+}
+
+proc showtags {id isnew} {
+    global idtags ctext linknum
+
+    if {$isnew} {
+	addtohistory [list showtags $id 0] savectextpos
     }
-    if {[info exists cached_tagcontent($tag)]} {
-	set text $cached_tagcontent($tag)
-    } else {
-	set text "[mc "Tag"]: $tag\n[mc "Id"]:  $tagids($tag)"
+    $ctext conf -state normal
+    clear_ctext
+    settabs 0
+    set linknum 0
+    set sep {}
+    foreach tag $idtags($id) {
+	$ctext insert end $sep
+	add_tag_ctext $tag
+	set sep "\n\n"
     }
-    appendwithlinks $text {}
     maybe_scroll_ctext 1
     $ctext conf -state disabled
     init_flist {}
@@ -11915,7 +12087,29 @@
 ## And eventually load the actual message catalog
 ::msgcat::mcload $gitk_msgsdir
 
-catch {source ~/.gitk}
+catch {
+    # follow the XDG base directory specification by default. See
+    # http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+    if {[info exists env(XDG_CONFIG_HOME)] && $env(XDG_CONFIG_HOME) ne ""} {
+	# XDG_CONFIG_HOME environment variable is set
+	set config_file [file join $env(XDG_CONFIG_HOME) git gitk]
+	set config_file_tmp [file join $env(XDG_CONFIG_HOME) git gitk-tmp]
+    } else {
+	# default XDG_CONFIG_HOME
+	set config_file "~/.config/git/gitk"
+	set config_file_tmp "~/.config/git/gitk-tmp"
+    }
+    if {![file exists $config_file]} {
+	# for backward compatibility use the old config file if it exists
+	if {[file exists "~/.gitk"]} {
+	    set config_file "~/.gitk"
+	    set config_file_tmp "~/.gitk-tmp"
+	} elseif {![file exists [file dirname $config_file]]} {
+	    file mkdir [file dirname $config_file]
+	}
+    }
+    source $config_file
+}
 
 parsefont mainfont $mainfont
 eval font create mainfont [fontflags mainfont]
diff --git a/gitk-git/po/bg.po b/gitk-git/po/bg.po
new file mode 100644
index 0000000..782397e
--- /dev/null
+++ b/gitk-git/po/bg.po
@@ -0,0 +1,1334 @@
+# Bulgarian translation of gitk po-file.
+# Copyright (C) 2014 Alexander Shopov <ash@kambanaria.org>.
+# This file is distributed under the same license as the git package.
+# Alexander Shopov <ash@kambanaria.org>, 2014.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gitk master\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-26 15:47-0800\n"
+"PO-Revision-Date: 2014-01-08 08:03+0200\n"
+"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
+"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
+"Language: bg\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: gitk:140
+msgid "Couldn't get list of unmerged files:"
+msgstr "Списъкът с неслети файлове не може да бъде получен:"
+
+#: gitk:212 gitk:2353
+msgid "Color words"
+msgstr "Оцветяване на думите"
+
+#: gitk:217 gitk:2353 gitk:8103 gitk:8136
+msgid "Markup words"
+msgstr "Отбелязване на думите"
+
+#: gitk:322
+msgid "Error parsing revisions:"
+msgstr "Грешка при разбор на версиите:"
+
+#: gitk:378
+msgid "Error executing --argscmd command:"
+msgstr "Грешка при изпълнение на командата с „--argscmd“."
+
+#: gitk:391
+msgid "No files selected: --merge specified but no files are unmerged."
+msgstr "Не са избрани файлове — указана е опцията „--merge“, но няма неслети файлове."
+
+#: gitk:394
+msgid ""
+"No files selected: --merge specified but no unmerged files are within file "
+"limit."
+msgstr "Не са избрани файлове — указана е опцията „--merge“, но няма неслети файлове в ограниченията."
+
+#: gitk:416 gitk:564
+msgid "Error executing git log:"
+msgstr "Грешка при изпълнение на „git log“:"
+
+#: gitk:434 gitk:580
+msgid "Reading"
+msgstr "Прочитане"
+
+#: gitk:494 gitk:4429
+msgid "Reading commits..."
+msgstr "Прочитане на подаванията…"
+
+#: gitk:497 gitk:1635 gitk:4432
+msgid "No commits selected"
+msgstr "Не са избрани подавания"
+
+#: gitk:1509
+msgid "Can't parse git log output:"
+msgstr "Изходът от „git log“ не може да се анализира:"
+
+#: gitk:1738
+msgid "No commit information available"
+msgstr "Липсва информация за подавания"
+
+#: gitk:1895
+msgid "mc"
+msgstr "mc"
+
+#: gitk:1930 gitk:4222 gitk:9552 gitk:11122 gitk:11401
+msgid "OK"
+msgstr "Добре"
+
+#: gitk:1932 gitk:4224 gitk:9079 gitk:9158 gitk:9274 gitk:9323 gitk:9554
+#: gitk:11123 gitk:11402
+msgid "Cancel"
+msgstr "Отказ"
+
+#: gitk:2067
+msgid "Update"
+msgstr "Обновяване"
+
+#: gitk:2068
+msgid "Reload"
+msgstr "Презареждане"
+
+#: gitk:2069
+msgid "Reread references"
+msgstr "Наново прочитане на настройките"
+
+#: gitk:2070
+msgid "List references"
+msgstr "Изброяване на указателите"
+
+#: gitk:2072
+msgid "Start git gui"
+msgstr "Стартиране на git gui"
+
+#: gitk:2074
+msgid "Quit"
+msgstr "Спиране на програмата"
+
+#: gitk:2066
+msgid "File"
+msgstr "Файл"
+
+#: gitk:2078
+msgid "Preferences"
+msgstr "Настройки"
+
+#: gitk:2077
+msgid "Edit"
+msgstr "Редактиране"
+
+#: gitk:2082
+msgid "New view..."
+msgstr "Нов изглед…"
+
+#: gitk:2083
+msgid "Edit view..."
+msgstr "Редактиране на изгледа…"
+
+#: gitk:2084
+msgid "Delete view"
+msgstr "Изтриване на изгледа"
+
+#: gitk:2086
+msgid "All files"
+msgstr "Всички файлове"
+
+#: gitk:2081 gitk:3975
+msgid "View"
+msgstr "Изглед"
+
+#: gitk:2091 gitk:2101 gitk:2945
+msgid "About gitk"
+msgstr "Относно gitk"
+
+#: gitk:2092 gitk:2106
+msgid "Key bindings"
+msgstr "Клавишни комбинации"
+
+#: gitk:2090 gitk:2105
+msgid "Help"
+msgstr "Помощ"
+
+#: gitk:2183 gitk:8535
+msgid "SHA1 ID:"
+msgstr "SHA1:"
+
+#: gitk:2227
+msgid "Row"
+msgstr "Ред"
+
+#: gitk:2265
+msgid "Find"
+msgstr "Търсене"
+
+#: gitk:2266
+msgid "next"
+msgstr "следващо"
+
+#: gitk:2267
+msgid "prev"
+msgstr "предишно"
+
+#: gitk:2268
+msgid "commit"
+msgstr "подаване"
+
+#: gitk:2271 gitk:2273 gitk:4590 gitk:4613 gitk:4637 gitk:6653 gitk:6725
+#: gitk:6810
+msgid "containing:"
+msgstr "съдържащо:"
+
+#: gitk:2274 gitk:3457 gitk:3462 gitk:4666
+msgid "touching paths:"
+msgstr "засягащо пътищата:"
+
+#: gitk:2275 gitk:4680
+msgid "adding/removing string:"
+msgstr "добавящо/премахващо низ"
+
+#: gitk:2276 gitk:4682
+msgid "changing lines matching:"
+msgstr "променящо редове напасващи:"
+
+#: gitk:2285 gitk:2287 gitk:4669
+msgid "Exact"
+msgstr "Точно"
+
+#: gitk:2287 gitk:4757 gitk:6621
+msgid "IgnCase"
+msgstr "Без регистър"
+
+#: gitk:2287 gitk:4639 gitk:4755 gitk:6617
+msgid "Regexp"
+msgstr "Рег. изр."
+
+#: gitk:2289 gitk:2290 gitk:4777 gitk:4807 gitk:4814 gitk:6746 gitk:6814
+msgid "All fields"
+msgstr "Всички полета"
+
+#: gitk:2290 gitk:4774 gitk:4807 gitk:6684
+msgid "Headline"
+msgstr "Първи ред"
+
+#: gitk:2291 gitk:4774 gitk:6684 gitk:6814 gitk:7283
+msgid "Comments"
+msgstr "Коментари"
+
+#: gitk:2291 gitk:4774 gitk:4779 gitk:4814 gitk:6684 gitk:7218 gitk:8713
+#: gitk:8728
+msgid "Author"
+msgstr "Автор"
+
+#: gitk:2291 gitk:4774 gitk:6684 gitk:7220
+msgid "Committer"
+msgstr "Подаващ"
+
+#: gitk:2322
+msgid "Search"
+msgstr "Търсене"
+
+#: gitk:2330
+msgid "Diff"
+msgstr "Разлики"
+
+#: gitk:2332
+msgid "Old version"
+msgstr "Стара версия"
+
+#: gitk:2334
+msgid "New version"
+msgstr "Нова версия"
+
+#: gitk:2336
+msgid "Lines of context"
+msgstr "Контекст в редове"
+
+#: gitk:2346
+msgid "Ignore space change"
+msgstr "Празните знаци без значение"
+
+#: gitk:2350 gitk:2352 gitk:7842 gitk:8089
+msgid "Line diff"
+msgstr "Поредови разлики"
+
+#: gitk:2417
+msgid "Patch"
+msgstr "Кръпка"
+
+#: gitk:2419
+msgid "Tree"
+msgstr "Дърво"
+
+#: gitk:2577 gitk:2597
+msgid "Diff this -> selected"
+msgstr "Разлики между това и избраното"
+
+#: gitk:2578 gitk:2598
+msgid "Diff selected -> this"
+msgstr "Разлики между избраното и това"
+
+#: gitk:2579 gitk:2599
+msgid "Make patch"
+msgstr "Създаване на кръпка"
+
+#: gitk:2580 gitk:9137
+msgid "Create tag"
+msgstr "Създаване на етикет"
+
+#: gitk:2581 gitk:9254
+msgid "Write commit to file"
+msgstr "Запазване на подаването във файл"
+
+#: gitk:2582 gitk:9311
+msgid "Create new branch"
+msgstr "Създаване на нов клон"
+
+#: gitk:2583
+msgid "Cherry-pick this commit"
+msgstr "Отбиране на това подаване"
+
+#: gitk:2584
+msgid "Reset HEAD branch to here"
+msgstr "Привеждане на върха на клона към текущото подаване"
+
+#: gitk:2585
+msgid "Mark this commit"
+msgstr "Отбелязване на това подаване"
+
+#: gitk:2586
+msgid "Return to mark"
+msgstr "Връщане към отбелязаното подаване"
+
+#: gitk:2587
+msgid "Find descendant of this and mark"
+msgstr "Откриване и отбелязване на наследниците"
+
+#: gitk:2588
+msgid "Compare with marked commit"
+msgstr "Сравнение с отбелязаното подаване"
+
+#: gitk:2589 gitk:2600
+msgid "Diff this -> marked commit"
+msgstr "Разлики между това и отбелязаното"
+
+#: gitk:2590 gitk:2601
+msgid "Diff marked commit -> this"
+msgstr "Разлики между отбелязаното и това"
+
+#: gitk:2591
+msgid "Revert this commit"
+msgstr "Отмяна на това подаване"
+
+#: gitk:2607
+msgid "Check out this branch"
+msgstr "Изтегляне на този клон"
+
+#: gitk:2608
+msgid "Remove this branch"
+msgstr "Изтриване на този клон"
+
+#: gitk:2615
+msgid "Highlight this too"
+msgstr "Отбелязване и на това"
+
+#: gitk:2616
+msgid "Highlight this only"
+msgstr "Отбелязване само на това"
+
+#: gitk:2617
+msgid "External diff"
+msgstr "Външна програма за разлики"
+
+#: gitk:2618
+msgid "Blame parent commit"
+msgstr "Анотиране на родителското подаване"
+
+#: gitk:2625
+msgid "Show origin of this line"
+msgstr "Показване на произхода на този ред"
+
+#: gitk:2626
+msgid "Run git gui blame on this line"
+msgstr "Изпълнение на „git gui blame“ върху този ред"
+
+#: gitk:2947
+msgid ""
+"\n"
+"Gitk - a commit viewer for git\n"
+"\n"
+"Copyright © 2005-2011 Paul Mackerras\n"
+"\n"
+"Use and redistribute under the terms of the GNU General Public License"
+msgstr ""
+"\n"
+"Gitk — визуализация на подаванията в Git\n"
+"\n"
+"Авторски права: © 2005-2011 Paul Mackerras\n"
+"\n"
+"Използвайте и разпространявайте при условията на ОПЛ на ГНУ"
+
+#: gitk:2955 gitk:3020 gitk:9738
+msgid "Close"
+msgstr "Затваряне"
+
+#: gitk:2976
+msgid "Gitk key bindings"
+msgstr "Клавишни комбинации"
+
+#: gitk:2979
+msgid "Gitk key bindings:"
+msgstr "Клавишни комбинации:"
+
+#: gitk:2981
+#, tcl-format
+msgid "<%s-Q>\t\tQuit"
+msgstr "<%s-Q>\t\tСпиране на програмата"
+
+#: gitk:2982
+#, tcl-format
+msgid "<%s-W>\t\tClose window"
+msgstr "<%s-W>\t\tЗатваряне на прозореца"
+
+#: gitk:2983
+msgid "<Home>\t\tMove to first commit"
+msgstr "<Home>\t\tКъм първото подаване"
+
+#: gitk:2984
+msgid "<End>\t\tMove to last commit"
+msgstr "<End>\t\tКъм последното подаване"
+
+#: gitk:2985
+msgid "<Up>, p, k\tMove up one commit"
+msgstr "<Up>, p, k\tЕдно подаване нагоре"
+
+#: gitk:2986
+msgid "<Down>, n, j\tMove down one commit"
+msgstr "<Down>, n, j\tЕдно подаване надолу"
+
+#: gitk:2987
+msgid "<Left>, z, h\tGo back in history list"
+msgstr "<Left>, z, h\tНазад в историята"
+
+#: gitk:2988
+msgid "<Right>, x, l\tGo forward in history list"
+msgstr "<Right>, x, l\tНапред в историята"
+
+#: gitk:2989
+msgid "<PageUp>\tMove up one page in commit list"
+msgstr "<PageUp>\tЕдна страница нагоре в списъка с подаванията"
+
+#: gitk:2990
+msgid "<PageDown>\tMove down one page in commit list"
+msgstr "<PageDown>\tЕдна страница надолу в списъка с подаванията"
+
+#: gitk:2991
+#, tcl-format
+msgid "<%s-Home>\tScroll to top of commit list"
+msgstr "<%s-Home>\tКъм началото на списъка с подаванията"
+
+#: gitk:2992
+#, tcl-format
+msgid "<%s-End>\tScroll to bottom of commit list"
+msgstr "<%s-End>\tКъм края на списъка с подаванията"
+
+#: gitk:2993
+#, tcl-format
+msgid "<%s-Up>\tScroll commit list up one line"
+msgstr "<%s-Up>\tПридвижване на списъка с подавания с един ред нагоре"
+
+#: gitk:2994
+#, tcl-format
+msgid "<%s-Down>\tScroll commit list down one line"
+msgstr "<%s-Down>\tПридвижване на списъка с подавания с един ред надолу"
+
+#: gitk:2995
+#, tcl-format
+msgid "<%s-PageUp>\tScroll commit list up one page"
+msgstr "<%s-PageUp>\tПридвижване на списъка с подавания с една страница нагоре"
+
+#: gitk:2996
+#, tcl-format
+msgid "<%s-PageDown>\tScroll commit list down one page"
+msgstr "<%s-PageDown>\tПридвижване на списъка с подавания с една страница надолу"
+
+#: gitk:2997
+msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
+msgstr "<Shift-Up>\tТърсене назад (визуално нагоре, исторически — последващи)"
+
+#: gitk:2998
+msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
+msgstr "<Shift-Down>\tТърсене напред (визуално надолу, исторически — предхождащи)"
+
+#: gitk:2999
+msgid "<Delete>, b\tScroll diff view up one page"
+msgstr "<Delete>, b\tПридвижване на изгледа за разлики една страница нагоре"
+
+#: gitk:3000
+msgid "<Backspace>\tScroll diff view up one page"
+msgstr "<Backspace>\tПридвижване на изгледа за разлики една страница нагоре"
+
+#: gitk:3001
+msgid "<Space>\t\tScroll diff view down one page"
+msgstr "<Space>\t\tПридвижване на изгледа за разлики една страница надолу"
+
+#: gitk:3002
+msgid "u\t\tScroll diff view up 18 lines"
+msgstr "u\t\tПридвижване на изгледа за разлики 18 реда нагоре"
+
+#: gitk:3003
+msgid "d\t\tScroll diff view down 18 lines"
+msgstr "d\t\tПридвижване на изгледа за разлики 18 реда надолу"
+
+#: gitk:3004
+#, tcl-format
+msgid "<%s-F>\t\tFind"
+msgstr "<%s-F>\t\tТърсене"
+
+#: gitk:3005
+#, tcl-format
+msgid "<%s-G>\t\tMove to next find hit"
+msgstr "<%s-G>\t\tКъм следващата поява"
+
+#: gitk:3006
+msgid "<Return>\tMove to next find hit"
+msgstr "<Return>\tКъм следващата поява"
+
+#: gitk:3007
+msgid "/\t\tFocus the search box"
+msgstr "/\t\tФокус върху полето за търсене"
+
+#: gitk:3008
+msgid "?\t\tMove to previous find hit"
+msgstr "?\t\tКъм предишната поява"
+
+#: gitk:3009
+msgid "f\t\tScroll diff view to next file"
+msgstr "f\t\tПридвижване на изгледа за разлики към следващия ред"
+
+#: gitk:3010
+#, tcl-format
+msgid "<%s-S>\t\tSearch for next hit in diff view"
+msgstr "<%s-S>\t\tТърсене на следващата поява в изгледа за разлики"
+
+#: gitk:3011
+#, tcl-format
+msgid "<%s-R>\t\tSearch for previous hit in diff view"
+msgstr "<%s-R>\t\tТърсене на предишната поява в изгледа за разлики"
+
+#: gitk:3012
+#, tcl-format
+msgid "<%s-KP+>\tIncrease font size"
+msgstr "<%s-KP+>\tПо-голям размер на шрифта"
+
+#: gitk:3013
+#, tcl-format
+msgid "<%s-plus>\tIncrease font size"
+msgstr "<%s-plus>\tПо-голям размер на шрифта"
+
+#: gitk:3014
+#, tcl-format
+msgid "<%s-KP->\tDecrease font size"
+msgstr "<%s-KP->\tПо-малък размер на шрифта"
+
+#: gitk:3015
+#, tcl-format
+msgid "<%s-minus>\tDecrease font size"
+msgstr "<%s-minus>\tПо-малък размер на шрифта"
+
+#: gitk:3016
+msgid "<F5>\t\tUpdate"
+msgstr "<F5>\t\tОбновяване"
+
+#: gitk:3471 gitk:3480
+#, tcl-format
+msgid "Error creating temporary directory %s:"
+msgstr "Грешка при създаването на временната директория „%s“:"
+
+#: gitk:3493
+#, tcl-format
+msgid "Error getting \"%s\" from %s:"
+msgstr "Грешка при получаването на „%s“ от %s:"
+
+#: gitk:3556
+msgid "command failed:"
+msgstr "неуспешно изпълнение на команда:"
+
+#: gitk:3705
+msgid "No such commit"
+msgstr "Такова подаване няма"
+
+#: gitk:3719
+msgid "git gui blame: command failed:"
+msgstr "git gui blame: неуспешно изпълнение на команда:"
+
+#: gitk:3750
+#, tcl-format
+msgid "Couldn't read merge head: %s"
+msgstr "Върхът за сливане не може да бъде прочетен: %s"
+
+#: gitk:3758
+#, tcl-format
+msgid "Error reading index: %s"
+msgstr "Грешка при прочитане на индекса: %s"
+
+#: gitk:3783
+#, tcl-format
+msgid "Couldn't start git blame: %s"
+msgstr "Командата „git blame“ не може да бъде стартирана: %s"
+
+#: gitk:3786 gitk:6652
+msgid "Searching"
+msgstr "Търсене"
+
+#: gitk:3818
+#, tcl-format
+msgid "Error running git blame: %s"
+msgstr "Грешка при изпълнението на „git blame“: %s"
+
+#: gitk:3846
+#, tcl-format
+msgid "That line comes from commit %s,  which is not in this view"
+msgstr "Този ред идва от подаването %s,  което не е в изгледа"
+
+#: gitk:3860
+msgid "External diff viewer failed:"
+msgstr "Неуспешно изпълнение на външната програма за разлики:"
+
+#: gitk:3978
+msgid "Gitk view definition"
+msgstr "Дефиниция на изглед в Gitk"
+
+#: gitk:3982
+msgid "Remember this view"
+msgstr "Запазване на този изглед"
+
+#: gitk:3983
+msgid "References (space separated list):"
+msgstr "Указатели (списък с разделител интервал):"
+
+#: gitk:3984
+msgid "Branches & tags:"
+msgstr "Клони и етикети:"
+
+#: gitk:3985
+msgid "All refs"
+msgstr "Всички указатели"
+
+#: gitk:3986
+msgid "All (local) branches"
+msgstr "Всички (локални) клони"
+
+#: gitk:3987
+msgid "All tags"
+msgstr "Всички етикети"
+
+#: gitk:3988
+msgid "All remote-tracking branches"
+msgstr "Всички следящи клони"
+
+#: gitk:3989
+msgid "Commit Info (regular expressions):"
+msgstr "Информация за подаване (рег. изр.):"
+
+#: gitk:3990
+msgid "Author:"
+msgstr "Автор:"
+
+#: gitk:3991
+msgid "Committer:"
+msgstr "Подал:"
+
+#: gitk:3992
+msgid "Commit Message:"
+msgstr "Съобщение при подаване:"
+
+#: gitk:3993
+msgid "Matches all Commit Info criteria"
+msgstr "Съвпадение по коя да е информация за подаването"
+
+#: gitk:3994
+msgid "Changes to Files:"
+msgstr "Промени по файловете:"
+
+#: gitk:3995
+msgid "Fixed String"
+msgstr "Дословен низ"
+
+#: gitk:3996
+msgid "Regular Expression"
+msgstr "Регулярен израз"
+
+#: gitk:3997
+msgid "Search string:"
+msgstr "Низ за търсене:"
+
+#: gitk:3998
+msgid ""
+"Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 "
+"15:27:38\"):"
+msgstr "Дата на подаване („2 weeks ago“ (преди 2 седмици), „2009-03-17 15:27:38“, „March 17, 2009 15:27:38“):"
+
+#: gitk:3999
+msgid "Since:"
+msgstr "От:"
+
+#: gitk:4000
+msgid "Until:"
+msgstr "До:"
+
+#: gitk:4001
+msgid "Limit and/or skip a number of revisions (positive integer):"
+msgstr "Ограничаване и/или прескачане на определен брой версии (неотрицателно цяло число):"
+
+#: gitk:4002
+msgid "Number to show:"
+msgstr "Брой показани:"
+
+#: gitk:4003
+msgid "Number to skip:"
+msgstr "Брой прескочени:"
+
+#: gitk:4004
+msgid "Miscellaneous options:"
+msgstr "Разни:"
+
+#: gitk:4005
+msgid "Strictly sort by date"
+msgstr "Подреждане по дата"
+
+#: gitk:4006
+msgid "Mark branch sides"
+msgstr "Отбелязване на страните по клона"
+
+#: gitk:4007
+msgid "Limit to first parent"
+msgstr "Само първият родител"
+
+#: gitk:4008
+msgid "Simple history"
+msgstr "Опростена история"
+
+#: gitk:4009
+msgid "Additional arguments to git log:"
+msgstr "Допълнителни аргументи към „git log“:"
+
+#: gitk:4010
+msgid "Enter files and directories to include, one per line:"
+msgstr "Въведете файловете и директориите за включване, по елемент на ред"
+
+#: gitk:4011
+msgid "Command to generate more commits to include:"
+msgstr "Команда за генерирането на допълнителни подавания, които да бъдат включени:"
+
+#: gitk:4135
+msgid "Gitk: edit view"
+msgstr "Gitk: редактиране на изглед"
+
+#: gitk:4143
+msgid "-- criteria for selecting revisions"
+msgstr "— критерии за избор на версии"
+
+#: gitk:4148
+msgid "View Name"
+msgstr "Име на изглед"
+
+#: gitk:4223
+msgid "Apply (F5)"
+msgstr "Прилагане (F5)"
+
+#: gitk:4261
+msgid "Error in commit selection arguments:"
+msgstr "Грешка в аргументите за избор на подавания:"
+
+#: gitk:4314 gitk:4366 gitk:4827 gitk:4841 gitk:6107 gitk:12184 gitk:12185
+msgid "None"
+msgstr "Няма"
+
+#: gitk:4924 gitk:4929
+msgid "Descendant"
+msgstr "Наследник"
+
+#: gitk:4925
+msgid "Not descendant"
+msgstr "Не е наследник"
+
+#: gitk:4932 gitk:4937
+msgid "Ancestor"
+msgstr "Предшественик"
+
+#: gitk:4933
+msgid "Not ancestor"
+msgstr "Не е предшественик"
+
+#: gitk:5223
+msgid "Local changes checked in to index but not committed"
+msgstr "Локални промени добавени към индекса, но неподадени"
+
+#: gitk:5259
+msgid "Local uncommitted changes, not checked in to index"
+msgstr "Локални промени извън индекса"
+
+#: gitk:7032
+msgid "and many more"
+msgstr "и още много"
+
+#: gitk:7035
+msgid "many"
+msgstr "много"
+
+#: gitk:7222
+msgid "Tags:"
+msgstr "Етикети:"
+
+#: gitk:7239 gitk:7245 gitk:8708
+msgid "Parent"
+msgstr "Родител"
+
+#: gitk:7250
+msgid "Child"
+msgstr "Дете"
+
+#: gitk:7259
+msgid "Branch"
+msgstr "Клон"
+
+#: gitk:7262
+msgid "Follows"
+msgstr "Следва"
+
+#: gitk:7265
+msgid "Precedes"
+msgstr "Предшества"
+
+#: gitk:7849
+#, tcl-format
+msgid "Error getting diffs: %s"
+msgstr "Грешка при получаването на разликите: %s"
+
+#: gitk:8533
+msgid "Goto:"
+msgstr "Към ред:"
+
+#: gitk:8554
+#, tcl-format
+msgid "Short SHA1 id %s is ambiguous"
+msgstr "Съкратената SHA1 %s не е еднозначна"
+
+#: gitk:8561
+#, tcl-format
+msgid "Revision %s is not known"
+msgstr "Непозната версия %s"
+
+#: gitk:8571
+#, tcl-format
+msgid "SHA1 id %s is not known"
+msgstr "Непозната SHA1 %s"
+
+#: gitk:8573
+#, tcl-format
+msgid "Revision %s is not in the current view"
+msgstr "Версия %s не е в текущия изглед"
+
+#: gitk:8715 gitk:8730
+msgid "Date"
+msgstr "Дата"
+
+#: gitk:8718
+msgid "Children"
+msgstr "Деца"
+
+#: gitk:8781
+#, tcl-format
+msgid "Reset %s branch to here"
+msgstr "Зануляване на клона „%s“ към текущото подаване"
+
+#: gitk:8783
+msgid "Detached head: can't reset"
+msgstr "Несвързан връх: невъзможно зануляване"
+
+#: gitk:8888 gitk:8894
+msgid "Skipping merge commit "
+msgstr "Пропускане на подаването на сливането"
+
+#: gitk:8903 gitk:8908
+msgid "Error getting patch ID for "
+msgstr "Грешка при получаването на идентификатора на "
+
+#: gitk:8904 gitk:8909
+msgid " - stopping\n"
+msgstr " — спиране\n"
+
+#: gitk:8914 gitk:8917 gitk:8925 gitk:8939 gitk:8948
+msgid "Commit "
+msgstr "Подаване"
+
+#: gitk:8918
+msgid ""
+" is the same patch as\n"
+"       "
+msgstr ""
+" е същата кръпка като\n"
+"       "
+
+#: gitk:8926
+msgid ""
+" differs from\n"
+"       "
+msgstr ""
+" се различава от\n"
+"       "
+
+#: gitk:8928
+msgid ""
+"Diff of commits:\n"
+"\n"
+msgstr "Разлика между подаванията:\n\n"
+
+#: gitk:8940 gitk:8949
+#, tcl-format
+msgid " has %s children - stopping\n"
+msgstr " има %s деца — спиране\n"
+
+#: gitk:8968
+#, tcl-format
+msgid "Error writing commit to file: %s"
+msgstr "Грешка при запазването на подаването във файл: %s"
+
+#: gitk:8974
+#, tcl-format
+msgid "Error diffing commits: %s"
+msgstr "Грешка при изчисляването на разликите между подаванията: %s"
+
+#: gitk:9020
+msgid "Top"
+msgstr "Най-горе"
+
+#: gitk:9021
+msgid "From"
+msgstr "От"
+
+#: gitk:9026
+msgid "To"
+msgstr "До"
+
+#: gitk:9050
+msgid "Generate patch"
+msgstr "Генериране на кръпка"
+
+#: gitk:9052
+msgid "From:"
+msgstr "От:"
+
+#: gitk:9061
+msgid "To:"
+msgstr "До:"
+
+#: gitk:9070
+msgid "Reverse"
+msgstr "Обръщане"
+
+#: gitk:9072 gitk:9268
+msgid "Output file:"
+msgstr "Запазване във файла:"
+
+#: gitk:9078
+msgid "Generate"
+msgstr "Генериране"
+
+#: gitk:9116
+msgid "Error creating patch:"
+msgstr "Грешка при създаването на кръпка:"
+
+#: gitk:9139 gitk:9256 gitk:9313
+msgid "ID:"
+msgstr "Идентификатор:"
+
+#: gitk:9148
+msgid "Tag name:"
+msgstr "Име на етикет:"
+
+#: gitk:9151
+msgid "Tag message is optional"
+msgstr "Съобщението за етикет е незадължително"
+
+#: gitk:9153
+msgid "Tag message:"
+msgstr "Съобщение за етикет:"
+
+#: gitk:9157 gitk:9322
+msgid "Create"
+msgstr "Създаване"
+
+#: gitk:9175
+msgid "No tag name specified"
+msgstr "Липсва име на етикет"
+
+#: gitk:9179
+#, tcl-format
+msgid "Tag \"%s\" already exists"
+msgstr "Етикетът „%s“ вече съществува"
+
+#: gitk:9189
+msgid "Error creating tag:"
+msgstr "Грешка при създаването на етикет:"
+
+#: gitk:9265
+msgid "Command:"
+msgstr "Команда:"
+
+#: gitk:9273
+msgid "Write"
+msgstr "Pdmdpldke"
+
+#: gitk:9291
+msgid "Error writing commit:"
+msgstr "Грешка при запазването на подаването:"
+
+#: gitk:9318
+msgid "Name:"
+msgstr "Име:"
+
+#: gitk:9341
+msgid "Please specify a name for the new branch"
+msgstr "Укажете име за новия клон"
+
+#: gitk:9346
+#, tcl-format
+msgid "Branch '%s' already exists. Overwrite?"
+msgstr "Клонът „%s“ вече съществува. Да бъде ли презаписан?"
+
+#: gitk:9413
+#, tcl-format
+msgid "Commit %s is already included in branch %s -- really re-apply it?"
+msgstr "Подаването „%s“ вече е включено в клона „%s“ — да бъде ли приложено отново?"
+
+#: gitk:9418
+msgid "Cherry-picking"
+msgstr "Отбиране"
+
+#: gitk:9427
+#, tcl-format
+msgid ""
+"Cherry-pick failed because of local changes to file '%s'.\n"
+"Please commit, reset or stash your changes and try again."
+msgstr ""
+"Неуспешно отбиране, защото във файла „%s“ има локални промени.\n"
+"Подайте, занулете или ги скатайте и пробвайте отново."
+
+#: gitk:9433
+msgid ""
+"Cherry-pick failed because of merge conflict.\n"
+"Do you wish to run git citool to resolve it?"
+msgstr ""
+"Неуспешно отбиране поради конфликти при сливане.\n"
+"Искате ли да ги коригирате чрез „git citool“?"
+
+#: gitk:9449 gitk:9507
+msgid "No changes committed"
+msgstr "Не са подадени промени"
+
+#: gitk:9476
+#, tcl-format
+msgid "Commit %s is not included in branch %s -- really revert it?"
+msgstr "Подаването „%s“ не е включено в клона „%s“. Да бъде ли отменено?"
+
+#: gitk:9481
+msgid "Reverting"
+msgstr "Отмяна"
+
+#: gitk:9489
+#, tcl-format
+msgid ""
+"Revert failed because of local changes to the following files:%s Please "
+"commit, reset or stash  your changes and try again."
+msgstr ""
+"Неуспешна отмяна, защото във файла „%s“ има локални промени.\n"
+"Подайте, занулете или ги скатайте и пробвайте отново.<"
+
+#: gitk:9493
+msgid ""
+"Revert failed because of merge conflict.\n"
+" Do you wish to run git citool to resolve it?"
+msgstr ""
+"Неуспешно отмяна поради конфликти при сливане.\n"
+"Искате ли да ги коригирате чрез „git citool“?"
+
+#: gitk:9536
+msgid "Confirm reset"
+msgstr "Потвърждаване на зануляването"
+
+#: gitk:9538
+#, tcl-format
+msgid "Reset branch %s to %s?"
+msgstr "Да се занули ли клона „%s“ към „%s“?"
+
+#: gitk:9540
+msgid "Reset type:"
+msgstr "Вид зануляване:"
+
+#: gitk:9543
+msgid "Soft: Leave working tree and index untouched"
+msgstr "Слабо: работното дърво и индекса остават същите"
+
+#: gitk:9546
+msgid "Mixed: Leave working tree untouched, reset index"
+msgstr "Смесено: работното дърво остава същото, индексът се занулява"
+
+#: gitk:9549
+msgid ""
+"Hard: Reset working tree and index\n"
+"(discard ALL local changes)"
+msgstr ""
+"Силно: зануляване и на работното дърво, и на индекса\n"
+"(*ВСИЧКИ* локални промени ще бъдат безвъзвратно загубени)"
+
+#: gitk:9566
+msgid "Resetting"
+msgstr "Зануляване"
+
+#: gitk:9626
+msgid "Checking out"
+msgstr "Изтегляне"
+
+#: gitk:9679
+msgid "Cannot delete the currently checked-out branch"
+msgstr "Текущо изтегленият клон не може да бъде изтрит"
+
+#: gitk:9685
+#, tcl-format
+msgid ""
+"The commits on branch %s aren't on any other branch.\n"
+"Really delete branch %s?"
+msgstr ""
+"Подаванията на клона „%s“ не са на никой друг клон.\n"
+"Наистина ли да се изтрие клона „%s“?"
+
+#: gitk:9716
+#, tcl-format
+msgid "Tags and heads: %s"
+msgstr "Етикети и върхове: %s"
+
+#: gitk:9731
+msgid "Filter"
+msgstr "Филтриране"
+
+#: gitk:10027
+msgid ""
+"Error reading commit topology information; branch and preceding/following "
+"tag information will be incomplete."
+msgstr "Грешка при прочитането на топологията на подаванията. Информацията за клона и предшестващите/следващите етикети ще е непълна."
+
+#: gitk:11004
+msgid "Tag"
+msgstr "Етикет"
+
+#: gitk:11008
+msgid "Id"
+msgstr "Идентификатор"
+
+#: gitk:11091
+msgid "Gitk font chooser"
+msgstr "Избор на шрифт за Gitk"
+
+#: gitk:11108
+msgid "B"
+msgstr "Ч"
+
+#: gitk:11111
+msgid "I"
+msgstr "К"
+
+#: gitk:11229
+msgid "Commit list display options"
+msgstr "Настройки на списъка с подавания"
+
+#: gitk:11232
+msgid "Maximum graph width (lines)"
+msgstr "Максимална широчина на графа (в редове)"
+
+#: gitk:11235
+#, tcl-format
+msgid "Maximum graph width (% of pane)"
+msgstr "Максимална широчина на графа (% от панела)"
+
+#: gitk:11238
+msgid "Show local changes"
+msgstr "Показване на локалните промени"
+
+#: gitk:11241
+msgid "Auto-select SHA1 (length)"
+msgstr "Автоматично избиране на SHA1 (дължина)"
+
+#: gitk:11245
+msgid "Hide remote refs"
+msgstr "Скриване на отдалечените указатели"
+
+#: gitk:11249
+msgid "Diff display options"
+msgstr "Настройки на показването на разликите"
+
+#: gitk:11251
+msgid "Tab spacing"
+msgstr "Широчина на табулатора"
+
+#: gitk:11254
+msgid "Display nearby tags/heads"
+msgstr "Извеждане на близките етикети и върхове"
+
+#: gitk:11257
+msgid "Maximum # tags/heads to show"
+msgstr "Максимален брой етикети/върхове за показване"
+
+#: gitk:11260
+msgid "Limit diffs to listed paths"
+msgstr "Разлика само в избраните пътища"
+
+#: gitk:11263
+msgid "Support per-file encodings"
+msgstr "Поддръжка на различни кодирания за всеки файл"
+
+#: gitk:11269 gitk:11416
+msgid "External diff tool"
+msgstr "Външен инструмент за разлики"
+
+#: gitk:11270
+msgid "Choose..."
+msgstr "Избор…"
+
+#: gitk:11275
+msgid "General options"
+msgstr "Общи настройки"
+
+#: gitk:11278
+msgid "Use themed widgets"
+msgstr "Използване на тема за графичните обекти"
+
+#: gitk:11280
+msgid "(change requires restart)"
+msgstr "(промяната изисква рестартиране на Gitk)"
+
+#: gitk:11282
+msgid "(currently unavailable)"
+msgstr "(в момента недостъпно)"
+
+#: gitk:11293
+msgid "Colors: press to choose"
+msgstr "Цветове: избира се с натискане"
+
+#: gitk:11296
+msgid "Interface"
+msgstr "Интерфейс"
+
+#: gitk:11297
+msgid "interface"
+msgstr "интерфейс"
+
+#: gitk:11300
+msgid "Background"
+msgstr "Фон"
+
+#: gitk:11301 gitk:11331
+msgid "background"
+msgstr "Фон"
+
+#: gitk:11304
+msgid "Foreground"
+msgstr "Знаци"
+
+#: gitk:11305
+msgid "foreground"
+msgstr "знаци"
+
+#: gitk:11308
+msgid "Diff: old lines"
+msgstr "Разлика: стари редове"
+
+#: gitk:11309
+msgid "diff old lines"
+msgstr "разлика, стари редове"
+
+#: gitk:11313
+msgid "Diff: new lines"
+msgstr "Разлика: нови редове"
+
+#: gitk:11314
+msgid "diff new lines"
+msgstr "разлика, нови редове"
+
+#: gitk:11318
+msgid "Diff: hunk header"
+msgstr "Разлика: начало на парче"
+
+#: gitk:11320
+msgid "diff hunk header"
+msgstr "разлика, начало на парче"
+
+#: gitk:11324
+msgid "Marked line bg"
+msgstr "Фон на отбелязан ред"
+
+#: gitk:11326
+msgid "marked line background"
+msgstr "Фон на отбелязан ред"
+
+#: gitk:11330
+msgid "Select bg"
+msgstr "Избор на фон"
+
+#: gitk:11339
+msgid "Fonts: press to choose"
+msgstr "Шрифтове: избира се с натискане"
+
+#: gitk:11341
+msgid "Main font"
+msgstr "Основен шрифт"
+
+#: gitk:11342
+msgid "Diff display font"
+msgstr "Шрифт за разликите"
+
+#: gitk:11343
+msgid "User interface font"
+msgstr "Шрифт на интерфейса"
+
+#: gitk:11365
+msgid "Gitk preferences"
+msgstr "Настройки на Gitk"
+
+#: gitk:11374
+msgid "General"
+msgstr "Общи"
+
+#: gitk:11375
+msgid "Colors"
+msgstr "Цветове"
+
+#: gitk:11376
+msgid "Fonts"
+msgstr "Шрифтове"
+
+#: gitk:11426
+#, tcl-format
+msgid "Gitk: choose color for %s"
+msgstr "Gitk: избор на цвят на %s"
+
+#: gitk:12080
+msgid "Cannot find a git repository here."
+msgstr "Тук липсва хранилище на Git."
+
+#: gitk:12127
+#, tcl-format
+msgid "Ambiguous argument '%s': both revision and filename"
+msgstr "Нееднозначен аргумент „%s“: има и такава версия, и такъв файл"
+
+#: gitk:12139
+msgid "Bad arguments to gitk:"
+msgstr "Неправилни аргументи на gitk:"
+
+#: gitk:12242
+msgid "Command line"
+msgstr "Команден ред"
diff --git a/gitk-git/po/po2msg.sh b/gitk-git/po/po2msg.sh
old mode 100644
new mode 100755
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f429f75..3bc0f0b 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -548,6 +548,20 @@
 		'sub' => sub { feature_bool('remote_heads', @_) },
 		'override' => 0,
 		'default' => [0]},
+
+	# Enable showing branches under other refs in addition to heads
+
+	# To set system wide extra branch refs have in $GITWEB_CONFIG
+	# $feature{'extra-branch-refs'}{'default'} = ['dirs', 'of', 'choice'];
+	# To have project specific config enable override in $GITWEB_CONFIG
+	# $feature{'extra-branch-refs'}{'override'} = 1;
+	# and in project config gitweb.extrabranchrefs = dirs of choice
+	# Every directory is separated with whitespace.
+
+	'extra-branch-refs' => {
+		'sub' => \&feature_extra_branch_refs,
+		'override' => 0,
+		'default' => []},
 );
 
 sub gitweb_get_feature {
@@ -626,6 +640,21 @@
 	return @val ? @val : @_;
 }
 
+sub feature_extra_branch_refs {
+	my (@branch_refs) = @_;
+	my $values = git_get_project_config('extrabranchrefs');
+
+	if ($values) {
+		$values = config_to_multi ($values);
+		@branch_refs = ();
+		foreach my $value (@{$values}) {
+			push @branch_refs, split /\s+/, $value;
+		}
+	}
+
+	return @branch_refs;
+}
+
 # checking HEAD file with -e is fragile if the repository was
 # initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed
 # and then pruned.
@@ -656,6 +685,18 @@
 		!$known_snapshot_formats{$_}{'disabled'}} @fmts;
 }
 
+sub filter_and_validate_refs {
+	my @refs = @_;
+	my %unique_refs = ();
+
+	foreach my $ref (@refs) {
+		die_error(500, "Invalid ref '$ref' in 'extra-branch-refs' feature") unless (is_valid_ref_format($ref));
+		# 'heads' are added implicitly in get_branch_refs().
+		$unique_refs{$ref} = 1 if ($ref ne 'heads');
+	}
+	return sort keys %unique_refs;
+}
+
 # If it is set to code reference, it is code that it is to be run once per
 # request, allowing updating configurations that change with each request,
 # while running other code in config file only once.
@@ -994,7 +1035,7 @@
 sub evaluate_and_validate_params {
 	our $action = $input_params{'action'};
 	if (defined $action) {
-		if (!validate_action($action)) {
+		if (!is_valid_action($action)) {
 			die_error(400, "Invalid action parameter");
 		}
 	}
@@ -1002,7 +1043,7 @@
 	# parameters which are pathnames
 	our $project = $input_params{'project'};
 	if (defined $project) {
-		if (!validate_project($project)) {
+		if (!is_valid_project($project)) {
 			undef $project;
 			die_error(404, "No such project");
 		}
@@ -1010,21 +1051,21 @@
 
 	our $project_filter = $input_params{'project_filter'};
 	if (defined $project_filter) {
-		if (!validate_pathname($project_filter)) {
+		if (!is_valid_pathname($project_filter)) {
 			die_error(404, "Invalid project_filter parameter");
 		}
 	}
 
 	our $file_name = $input_params{'file_name'};
 	if (defined $file_name) {
-		if (!validate_pathname($file_name)) {
+		if (!is_valid_pathname($file_name)) {
 			die_error(400, "Invalid file parameter");
 		}
 	}
 
 	our $file_parent = $input_params{'file_parent'};
 	if (defined $file_parent) {
-		if (!validate_pathname($file_parent)) {
+		if (!is_valid_pathname($file_parent)) {
 			die_error(400, "Invalid file parent parameter");
 		}
 	}
@@ -1032,21 +1073,21 @@
 	# parameters which are refnames
 	our $hash = $input_params{'hash'};
 	if (defined $hash) {
-		if (!validate_refname($hash)) {
+		if (!is_valid_refname($hash)) {
 			die_error(400, "Invalid hash parameter");
 		}
 	}
 
 	our $hash_parent = $input_params{'hash_parent'};
 	if (defined $hash_parent) {
-		if (!validate_refname($hash_parent)) {
+		if (!is_valid_refname($hash_parent)) {
 			die_error(400, "Invalid hash parent parameter");
 		}
 	}
 
 	our $hash_base = $input_params{'hash_base'};
 	if (defined $hash_base) {
-		if (!validate_refname($hash_base)) {
+		if (!is_valid_refname($hash_base)) {
 			die_error(400, "Invalid hash base parameter");
 		}
 	}
@@ -1066,7 +1107,7 @@
 
 	our $hash_parent_base = $input_params{'hash_parent_base'};
 	if (defined $hash_parent_base) {
-		if (!validate_refname($hash_parent_base)) {
+		if (!is_valid_refname($hash_parent_base)) {
 			die_error(400, "Invalid hash parent base parameter");
 		}
 	}
@@ -1113,7 +1154,7 @@
 	our $git_dir = "$projectroot/$project" if $project;
 }
 
-our (@snapshot_fmts, $git_avatar);
+our (@snapshot_fmts, $git_avatar, @extra_branch_refs);
 sub configure_gitweb_features {
 	# list of supported snapshot formats
 	our @snapshot_fmts = gitweb_get_feature('snapshot');
@@ -1131,6 +1172,13 @@
 	} else {
 		$git_avatar = '';
 	}
+
+	our @extra_branch_refs = gitweb_get_feature('extra-branch-refs');
+	@extra_branch_refs = filter_and_validate_refs (@extra_branch_refs);
+}
+
+sub get_branch_refs {
+	return ('heads', @extra_branch_refs);
 }
 
 # custom error handler: 'die <message>' is Internal Server Error
@@ -1418,27 +1466,30 @@
 ## ======================================================================
 ## validation, quoting/unquoting and escaping
 
-sub validate_action {
-	my $input = shift || return undef;
+sub is_valid_action {
+	my $input = shift;
 	return undef unless exists $actions{$input};
-	return $input;
+	return 1;
 }
 
-sub validate_project {
-	my $input = shift || return undef;
-	if (!validate_pathname($input) ||
+sub is_valid_project {
+	my $input = shift;
+
+	return unless defined $input;
+	if (!is_valid_pathname($input) ||
 		!(-d "$projectroot/$input") ||
 		!check_export_ok("$projectroot/$input") ||
 		($strict_export && !project_in_list($input))) {
 		return undef;
 	} else {
-		return $input;
+		return 1;
 	}
 }
 
-sub validate_pathname {
-	my $input = shift || return undef;
+sub is_valid_pathname {
+	my $input = shift;
 
+	return undef unless defined $input;
 	# no '.' or '..' as elements of path, i.e. no '.' nor '..'
 	# at the beginning, at the end, and between slashes.
 	# also this catches doubled slashes
@@ -1449,24 +1500,33 @@
 	if ($input =~ m!\0!) {
 		return undef;
 	}
-	return $input;
+	return 1;
 }
 
-sub validate_refname {
-	my $input = shift || return undef;
+sub is_valid_ref_format {
+	my $input = shift;
 
-	# textual hashes are O.K.
-	if ($input =~ m/^[0-9a-fA-F]{40}$/) {
-		return $input;
-	}
-	# it must be correct pathname
-	$input = validate_pathname($input)
-		or return undef;
+	return undef unless defined $input;
 	# restrictions on ref name according to git-check-ref-format
 	if ($input =~ m!(/\.|\.\.|[\000-\040\177 ~^:?*\[]|/$)!) {
 		return undef;
 	}
-	return $input;
+	return 1;
+}
+
+sub is_valid_refname {
+	my $input = shift;
+
+	return undef unless defined $input;
+	# textual hashes are O.K.
+	if ($input =~ m/^[0-9a-fA-F]{40}$/) {
+		return 1;
+	}
+	# it must be correct pathname
+	is_valid_pathname($input) or return undef;
+	# check git-check-ref-format restrictions
+	is_valid_ref_format($input) or return undef;
+	return 1;
 }
 
 # decode sequences of octets in utf8 into Perl's internal form,
@@ -2515,6 +2575,7 @@
 sub get_feed_info {
 	my $format = shift || 'Atom';
 	my %res = (action => lc($format));
+	my $matched_ref = 0;
 
 	# feed links are possible only for project views
 	return unless (defined $project);
@@ -2522,12 +2583,17 @@
 	# or don't have specific feed yet (so they should use generic)
 	return if (!$action || $action =~ /^(?:tags|heads|forks|tag|search)$/x);
 
-	my $branch;
-	# branches refs uses 'refs/heads/' prefix (fullname) to differentiate
-	# from tag links; this also makes possible to detect branch links
-	if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) ||
-	    (defined $hash      && $hash      =~ m!^refs/heads/(.*)$!)) {
-		$branch = $1;
+	my $branch = undef;
+	# branches refs uses 'refs/' + $get_branch_refs()[x] + '/' prefix
+	# (fullname) to differentiate from tag links; this also makes
+	# possible to detect branch links
+	for my $ref (get_branch_refs()) {
+		if ((defined $hash_base && $hash_base =~ m!^refs/\Q$ref\E/(.*)$!) ||
+		    (defined $hash      && $hash      =~ m!^refs/\Q$ref\E/(.*)$!)) {
+			$branch = $1;
+			$matched_ref = $ref;
+			last;
+		}
 	}
 	# find log type for feed description (title)
 	my $type = 'log';
@@ -2540,7 +2606,7 @@
 	}
 
 	$res{-title} = $type;
-	$res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef);
+	$res{'hash'} = (defined $branch ? "refs/$matched_ref/$branch" : undef);
 	$res{'file_name'} = $file_name;
 
 	return %res;
@@ -3193,7 +3259,7 @@
 	     '--format=%(committer)',
 	     '--sort=-committerdate',
 	     '--count=1',
-	     'refs/heads') or return;
+	     map { "refs/$_" } get_branch_refs ()) or return;
 	my $most_recent = <$fd>;
 	close $fd or return;
 	if (defined $most_recent &&
@@ -3644,7 +3710,7 @@
 
 sub git_get_heads_list {
 	my ($limit, @classes) = @_;
-	@classes = ('heads') unless @classes;
+	@classes = get_branch_refs() unless @classes;
 	my @patterns = map { "refs/$_" } @classes;
 	my @headslist;
 
@@ -3662,9 +3728,16 @@
 		my ($committer, $epoch, $tz) =
 			($committerinfo =~ /^(.*) ([0-9]+) (.*)$/);
 		$ref_item{'fullname'}  = $name;
-		$name =~ s!^refs/(?:head|remote)s/!!;
+		my $strip_refs = join '|', map { quotemeta } get_branch_refs();
+		$name =~ s!^refs/($strip_refs|remotes)/!!;
+		$ref_item{'name'} = $name;
+		# for refs neither in 'heads' nor 'remotes' we want to
+		# show their ref dir
+		my $ref_dir = (defined $1) ? $1 : '';
+		if ($ref_dir ne '' and $ref_dir ne 'heads' and $ref_dir ne 'remotes') {
+		    $ref_item{'name'} .= ' (' . $ref_dir . ')';
+		}
 
-		$ref_item{'name'}  = $name;
 		$ref_item{'id'}    = $hash;
 		$ref_item{'title'} = $title || '(no commit message)';
 		$ref_item{'epoch'} = $epoch;
@@ -4035,8 +4108,8 @@
 	      $cgi->input({-name=>"h", -value=>$search_hash, -type=>"hidden"}) . "\n" .
 	      $cgi->popup_menu(-name => 'st', -default => 'commit',
 	                       -values => ['commit', 'grep', 'author', 'committer', 'pickaxe']) .
-	      $cgi->sup($cgi->a({-href => href(action=>"search_help")}, "?")) .
-	      " search:\n",
+	      " " . $cgi->a({-href => href(action=>"search_help"),
+			     -title => "search help" }, "?") . " search:\n",
 	      $cgi->textfield(-name => "s", -value => $searchtext, -override => 1) . "\n" .
 	      "<span title=\"Extended regular expression\">" .
 	      $cgi->checkbox(-name => 'sr', -value => 1, -label => 're',
@@ -6468,7 +6541,7 @@
 	print "<div class=\"title\">&nbsp;</div>\n";
 	print "<table class=\"projects_list\">\n" .
 	      "<tr id=\"metadata_desc\"><td>description</td><td>" . esc_html($descr) . "</td></tr>\n";
-        unless ($omit_owner) {
+        if ($owner and not $omit_owner) {
 	        print  "<tr id=\"metadata_owner\"><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
         }
 	if (defined $cd{'rfc2822'}) {
@@ -6631,6 +6704,7 @@
 			$hash_base, '--', $file_name
 			or die_error(500, "Open git-blame --porcelain failed");
 	}
+	binmode $fd, ':utf8';
 
 	# incremental blame data returns early
 	if ($format eq 'data') {
@@ -7155,6 +7229,15 @@
 	git_footer_html();
 }
 
+sub sanitize_for_filename {
+    my $name = shift;
+
+    $name =~ s!/!-!g;
+    $name =~ s/[^[:alnum:]_.-]//g;
+
+    return $name;
+}
+
 sub snapshot_name {
 	my ($project, $hash) = @_;
 
@@ -7162,9 +7245,7 @@
 	# path/to/project/.git -> project
 	my $name = to_utf8($project);
 	$name =~ s,([^/])/*\.git$,$1,;
-	$name = basename($name);
-	# sanitize name
-	$name =~ s/[[:cntrl:]]/?/g;
+	$name = sanitize_for_filename(basename($name));
 
 	my $ver = $hash;
 	if ($hash =~ /^[0-9a-fA-F]+$/) {
@@ -7178,13 +7259,25 @@
 		$ver = $1;
 	} else {
 		# branches and other need shortened SHA-1 hash
-		if ($hash =~ m!^refs/(?:heads|remotes)/(.*)$!) {
-			$ver = $1;
+		my $strip_refs = join '|', map { quotemeta } get_branch_refs();
+		if ($hash =~ m!^refs/($strip_refs|remotes)/(.*)$!) {
+			my $ref_dir = (defined $1) ? $1 : '';
+			$ver = $2;
+
+			$ref_dir = sanitize_for_filename($ref_dir);
+			# for refs neither in heads nor remotes we want to
+			# add a ref dir to archive name
+			if ($ref_dir ne '' and $ref_dir ne 'heads' and $ref_dir ne 'remotes') {
+				$ver = $ref_dir . '-' . $ver;
+			}
 		}
 		$ver .= '-' . git_get_short_hash($project, $hash);
 	}
+	# special case of sanitization for filename - we change
+	# slashes to dots instead of dashes
 	# in case of hierarchical branch names
 	$ver =~ s!/!.!g;
+	$ver =~ s/[^[:alnum:]_.-]//g;
 
 	# name = project-version_string
 	$name = "$name-$ver";
diff --git a/gitweb/static/gitweb.css b/gitweb/static/gitweb.css
index cb86d2d..3b4d833 100644
--- a/gitweb/static/gitweb.css
+++ b/gitweb/static/gitweb.css
@@ -68,12 +68,13 @@
 }
 
 div.page_footer {
-	height: 17px;
+	height: 22px;
 	padding: 4px 8px;
 	background-color: #d9d8d1;
 }
 
 div.page_footer_text {
+	line-height: 22px;
 	float: left;
 	color: #555555;
 	font-style: italic;
@@ -548,8 +549,7 @@
 
 a.rss_logo {
 	float: right;
-	padding: 3px 0px;
-	width: 35px;
+	padding: 3px 5px;
 	line-height: 10px;
 	border: 1px solid;
 	border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
diff --git a/grep.c b/grep.c
index bb548ca..c668034 100644
--- a/grep.c
+++ b/grep.c
@@ -2,6 +2,8 @@
 #include "grep.h"
 #include "userdiff.h"
 #include "xdiff-interface.h"
+#include "diff.h"
+#include "diffcore.h"
 
 static int grep_source_load(struct grep_source *gs);
 static int grep_source_is_binary(struct grep_source *gs);
@@ -1322,6 +1324,58 @@
 	fwrite(buf, size, 1, stdout);
 }
 
+static int fill_textconv_grep(struct userdiff_driver *driver,
+			      struct grep_source *gs)
+{
+	struct diff_filespec *df;
+	char *buf;
+	size_t size;
+
+	if (!driver || !driver->textconv)
+		return grep_source_load(gs);
+
+	/*
+	 * The textconv interface is intimately tied to diff_filespecs, so we
+	 * have to pretend to be one. If we could unify the grep_source
+	 * and diff_filespec structs, this mess could just go away.
+	 */
+	df = alloc_filespec(gs->path);
+	switch (gs->type) {
+	case GREP_SOURCE_SHA1:
+		fill_filespec(df, gs->identifier, 1, 0100644);
+		break;
+	case GREP_SOURCE_FILE:
+		fill_filespec(df, null_sha1, 0, 0100644);
+		break;
+	default:
+		die("BUG: attempt to textconv something without a path?");
+	}
+
+	/*
+	 * fill_textconv is not remotely thread-safe; it may load objects
+	 * behind the scenes, and it modifies the global diff tempfile
+	 * structure.
+	 */
+	grep_read_lock();
+	size = fill_textconv(driver, df, &buf);
+	grep_read_unlock();
+	free_filespec(df);
+
+	/*
+	 * The normal fill_textconv usage by the diff machinery would just keep
+	 * the textconv'd buf separate from the diff_filespec. But much of the
+	 * grep code passes around a grep_source and assumes that its "buf"
+	 * pointer is the beginning of the thing we are searching. So let's
+	 * install our textconv'd version into the grep_source, taking care not
+	 * to leak any existing buffer.
+	 */
+	grep_source_clear_data(gs);
+	gs->buf = buf;
+	gs->size = size;
+
+	return 0;
+}
+
 static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits)
 {
 	char *bol;
@@ -1332,6 +1386,7 @@
 	unsigned count = 0;
 	int try_lookahead = 0;
 	int show_function = 0;
+	struct userdiff_driver *textconv = NULL;
 	enum grep_context ctx = GREP_CONTEXT_HEAD;
 	xdemitconf_t xecfg;
 
@@ -1353,19 +1408,36 @@
 	}
 	opt->last_shown = 0;
 
-	switch (opt->binary) {
-	case GREP_BINARY_DEFAULT:
-		if (grep_source_is_binary(gs))
-			binary_match_only = 1;
-		break;
-	case GREP_BINARY_NOMATCH:
-		if (grep_source_is_binary(gs))
-			return 0; /* Assume unmatch */
-		break;
-	case GREP_BINARY_TEXT:
-		break;
-	default:
-		die("bug: unknown binary handling mode");
+	if (opt->allow_textconv) {
+		grep_source_load_driver(gs);
+		/*
+		 * We might set up the shared textconv cache data here, which
+		 * is not thread-safe.
+		 */
+		grep_attr_lock();
+		textconv = userdiff_get_textconv(gs->driver);
+		grep_attr_unlock();
+	}
+
+	/*
+	 * We know the result of a textconv is text, so we only have to care
+	 * about binary handling if we are not using it.
+	 */
+	if (!textconv) {
+		switch (opt->binary) {
+		case GREP_BINARY_DEFAULT:
+			if (grep_source_is_binary(gs))
+				binary_match_only = 1;
+			break;
+		case GREP_BINARY_NOMATCH:
+			if (grep_source_is_binary(gs))
+				return 0; /* Assume unmatch */
+			break;
+		case GREP_BINARY_TEXT:
+			break;
+		default:
+			die("bug: unknown binary handling mode");
+		}
 	}
 
 	memset(&xecfg, 0, sizeof(xecfg));
@@ -1373,7 +1445,7 @@
 
 	try_lookahead = should_lookahead(opt);
 
-	if (grep_source_load(gs) < 0)
+	if (fill_textconv_grep(textconv, gs) < 0)
 		return 0;
 
 	bol = gs->buf;
diff --git a/grep.h b/grep.h
index e4a1df5..eaaced1 100644
--- a/grep.h
+++ b/grep.h
@@ -107,6 +107,7 @@
 #define GREP_BINARY_NOMATCH	1
 #define GREP_BINARY_TEXT	2
 	int binary;
+	int allow_textconv;
 	int extended;
 	int use_reflog_filter;
 	int pcre;
diff --git a/help.c b/help.c
index f068925..df7d16d 100644
--- a/help.c
+++ b/help.c
@@ -148,7 +148,7 @@
 	while ((de = readdir(dir)) != NULL) {
 		int entlen;
 
-		if (prefixcmp(de->d_name, prefix))
+		if (!starts_with(de->d_name, prefix))
 			continue;
 
 		strbuf_setlen(&buf, len);
@@ -255,7 +255,7 @@
 	if (!strcmp(var, "help.autocorrect"))
 		autocorrect = git_config_int(var,value);
 	/* Also use aliases for command lookup */
-	if (!prefixcmp(var, "alias."))
+	if (starts_with(var, "alias."))
 		add_cmdname(&aliases, var + 6, strlen(var + 6));
 
 	return git_default_config(var, value, cb);
@@ -329,7 +329,7 @@
 		if ((n < ARRAY_SIZE(common_cmds)) && !cmp) {
 			/* Yes, this is one of the common commands */
 			n++; /* use the entry from common_cmds[] */
-			if (!prefixcmp(candidate, cmd)) {
+			if (starts_with(candidate, cmd)) {
 				/* Give prefix match a very good score */
 				main_cmds.names[i]->len = 0;
 				continue;
@@ -414,7 +414,7 @@
 	struct similar_ref_cb *cb = (struct similar_ref_cb *)(cb_data);
 	char *branch = strrchr(refname, '/') + 1;
 	/* A remote branch of the same name is deemed similar */
-	if (!prefixcmp(refname, "refs/remotes/") &&
+	if (starts_with(refname, "refs/remotes/") &&
 	    !strcmp(branch, cb->base_ref))
 		string_list_append(cb->similar_refs,
 				   refname + strlen("refs/remotes/"));
diff --git a/http-backend.c b/http-backend.c
index 8c464bd..d2c0a62 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -226,7 +226,7 @@
 		return 0;
 	}
 
-	if (!prefixcmp(var, "http.")) {
+	if (starts_with(var, "http.")) {
 		int i;
 
 		for (i = 0; i < ARRAY_SIZE(rpc_service); i++) {
@@ -247,7 +247,7 @@
 	struct rpc_service *svc = NULL;
 	int i;
 
-	if (prefixcmp(name, "git-"))
+	if (!starts_with(name, "git-"))
 		forbidden("Unsupported service: '%s'", name);
 
 	for (i = 0; i < ARRAY_SIZE(rpc_service); i++) {
diff --git a/http-push.c b/http-push.c
index b1e74d2..d4b40c9 100644
--- a/http-push.c
+++ b/http-push.c
@@ -771,7 +771,7 @@
 			lock->owner = xmalloc(strlen(ctx->cdata) + 1);
 			strcpy(lock->owner, ctx->cdata);
 		} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
-			if (!prefixcmp(ctx->cdata, "Second-"))
+			if (starts_with(ctx->cdata, "Second-"))
 				lock->timeout =
 					strtol(ctx->cdata + 7, NULL, 10);
 		} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
@@ -1330,8 +1330,7 @@
 			break;
 		}
 
-	free(tree->buffer);
-	tree->buffer = NULL;
+	free_tree_buffer(tree);
 	return p;
 }
 
@@ -1580,7 +1579,7 @@
 		return;
 
 	/* If it's a symref, set the refname; otherwise try for a sha1 */
-	if (!prefixcmp((char *)buffer.buf, "ref: ")) {
+	if (starts_with((char *)buffer.buf, "ref: ")) {
 		*symref = xmemdupz((char *)buffer.buf + 5, buffer.len - 6);
 	} else {
 		get_sha1_hex(buffer.buf, sha1);
diff --git a/http.c b/http.c
index 3447945..70eaa26 100644
--- a/http.c
+++ b/http.c
@@ -3,6 +3,7 @@
 #include "sideband.h"
 #include "run-command.h"
 #include "url.h"
+#include "urlmatch.h"
 #include "credential.h"
 #include "version.h"
 #include "pkt-line.h"
@@ -45,6 +46,7 @@
 static int curl_ftp_no_epsv;
 static const char *curl_http_proxy;
 static const char *curl_cookie_file;
+static int curl_save_cookies;
 struct credential http_auth = CREDENTIAL_INIT;
 static int http_proactive_auth;
 static const char *user_agent;
@@ -160,8 +162,7 @@
 	if (!strcmp("http.sslcainfo", var))
 		return git_config_string(&ssl_cainfo, var, value);
 	if (!strcmp("http.sslcertpasswordprotected", var)) {
-		if (git_config_bool(var, value))
-			ssl_cert_password_required = 1;
+		ssl_cert_password_required = git_config_bool(var, value);
 		return 0;
 	}
 	if (!strcmp("http.ssltry", var)) {
@@ -200,6 +201,10 @@
 
 	if (!strcmp("http.cookiefile", var))
 		return git_config_string(&curl_cookie_file, var, value);
+	if (!strcmp("http.savecookies", var)) {
+		curl_save_cookies = git_config_bool(var, value);
+		return 0;
+	}
 
 	if (!strcmp("http.postbuffer", var)) {
 		http_post_buffer = git_config_int(var, value);
@@ -255,6 +260,42 @@
 	return 1;
 }
 
+#if LIBCURL_VERSION_NUM >= 0x071900
+static void set_curl_keepalive(CURL *c)
+{
+	curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1);
+}
+
+#elif LIBCURL_VERSION_NUM >= 0x071000
+static int sockopt_callback(void *client, curl_socket_t fd, curlsocktype type)
+{
+	int ka = 1;
+	int rc;
+	socklen_t len = (socklen_t)sizeof(ka);
+
+	if (type != CURLSOCKTYPE_IPCXN)
+		return 0;
+
+	rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&ka, len);
+	if (rc < 0)
+		warning("unable to set SO_KEEPALIVE on socket %s",
+			strerror(errno));
+
+	return 0; /* CURL_SOCKOPT_OK only exists since curl 7.21.5 */
+}
+
+static void set_curl_keepalive(CURL *c)
+{
+	curl_easy_setopt(c, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
+}
+
+#else
+static void set_curl_keepalive(CURL *c)
+{
+	/* not supported on older curl versions */
+}
+#endif
+
 static CURL *get_curl_handle(void)
 {
 	CURL *result = curl_easy_init();
@@ -327,6 +368,8 @@
 		curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
 	}
 
+	set_curl_keepalive(result);
+
 	return result;
 }
 
@@ -341,10 +384,20 @@
 {
 	char *low_speed_limit;
 	char *low_speed_time;
+	char *normalized_url;
+	struct urlmatch_config config = { STRING_LIST_INIT_DUP };
+
+	config.section = "http";
+	config.key = NULL;
+	config.collect_fn = http_options;
+	config.cascade_fn = git_default_config;
+	config.cb = NULL;
 
 	http_is_verbose = 0;
+	normalized_url = url_normalize(url, &config.url);
 
-	git_config(http_options, NULL);
+	git_config(urlmatch_config_entry, &config);
+	free(normalized_url);
 
 	curl_global_init(CURL_GLOBAL_ALL);
 
@@ -407,7 +460,7 @@
 		credential_from_url(&http_auth, url);
 		if (!ssl_cert_password_required &&
 		    getenv("GIT_SSL_CERT_PASSWORD_PROTECTED") &&
-		    !prefixcmp(url, "https://"))
+		    starts_with(url, "https://"))
 			ssl_cert_password_required = 1;
 	}
 
@@ -513,6 +566,8 @@
 	slot->callback_data = NULL;
 	slot->callback_func = NULL;
 	curl_easy_setopt(slot->curl, CURLOPT_COOKIEFILE, curl_cookie_file);
+	if (curl_save_cookies)
+		curl_easy_setopt(slot->curl, CURLOPT_COOKIEJAR, curl_cookie_file);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header);
 	curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, NULL);
@@ -706,6 +761,12 @@
 	if (slot->results != NULL) {
 		slot->results->curl_result = slot->curl_result;
 		slot->results->http_code = slot->http_code;
+#if LIBCURL_VERSION_NUM >= 0x070a08
+		curl_easy_getinfo(slot->curl, CURLINFO_HTTPAUTH_AVAIL,
+				  &slot->results->auth_avail);
+#else
+		slot->results->auth_avail = 0;
+#endif
 	}
 
 	/* Run callback if appropriate */
@@ -939,7 +1000,7 @@
 	if (!strcmp(asked, got->buf))
 		return 0;
 
-	if (prefixcmp(asked, base->buf))
+	if (!starts_with(asked, base->buf))
 		die("BUG: update_url_from_redirect: %s is not a superset of %s",
 		    asked, base->buf);
 
@@ -1045,7 +1106,7 @@
 		strbuf_rtrim(&buffer);
 		if (buffer.len == 40)
 			ret = get_sha1_hex(buffer.buf, ref->old_sha1);
-		else if (!prefixcmp(buffer.buf, "ref: ")) {
+		else if (starts_with(buffer.buf, "ref: ")) {
 			ref->symref = xstrdup(buffer.buf + 5);
 			ret = 0;
 		}
@@ -1146,8 +1207,8 @@
 		case 'P':
 			i++;
 			if (i + 52 <= buf.len &&
-			    !prefixcmp(data + i, " pack-") &&
-			    !prefixcmp(data + i + 46, ".pack\n")) {
+			    starts_with(data + i, " pack-") &&
+			    starts_with(data + i + 46, ".pack\n")) {
 				get_sha1_hex(data + i + 6, sha1);
 				fetch_and_setup_pack_index(packs_head, sha1,
 						      base_url);
diff --git a/http.h b/http.h
index 12ca5c8..cd37d58 100644
--- a/http.h
+++ b/http.h
@@ -54,6 +54,7 @@
 struct slot_results {
 	CURLcode curl_result;
 	long http_code;
+	long auth_avail;
 };
 
 struct active_request_slot {
diff --git a/imap-send.c b/imap-send.c
index d6b65e2..0bc6f7f 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -28,20 +28,6 @@
 #include "prompt.h"
 #ifdef NO_OPENSSL
 typedef void *SSL;
-#else
-#ifdef APPLE_COMMON_CRYPTO
-#include <CommonCrypto/CommonHMAC.h>
-#define HMAC_CTX CCHmacContext
-#define HMAC_Init(hmac, key, len, algo) CCHmacInit(hmac, algo, key, len)
-#define HMAC_Update CCHmacUpdate
-#define HMAC_Final(hmac, hash, ptr) CCHmacFinal(hmac, hash)
-#define HMAC_CTX_cleanup(ignore)
-#define EVP_md5() kCCHmacAlgMD5
-#else
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#endif
-#include <openssl/x509v3.h>
 #endif
 
 static const char imap_send_usage[] = "git imap-send < <mbox>";
@@ -1277,7 +1263,7 @@
 	char *p = all_msgs->buf;
 
 	while (1) {
-		if (!prefixcmp(p, "From ")) {
+		if (starts_with(p, "From ")) {
 			p = strstr(p+5, "\nFrom: ");
 			if (!p) break;
 			p = strstr(p+7, "\nDate: ");
@@ -1311,7 +1297,7 @@
 	data = &all_msgs->buf[*ofs];
 	len = all_msgs->len - *ofs;
 
-	if (len < 5 || prefixcmp(data, "From "))
+	if (len < 5 || !starts_with(data, "From "))
 		return 0;
 
 	p = strchr(data, '\n');
@@ -1353,13 +1339,13 @@
 	if (!strcmp("folder", key)) {
 		imap_folder = xstrdup(val);
 	} else if (!strcmp("host", key)) {
-		if (!prefixcmp(val, "imap:"))
+		if (starts_with(val, "imap:"))
 			val += 5;
-		else if (!prefixcmp(val, "imaps:")) {
+		else if (starts_with(val, "imaps:")) {
 			val += 6;
 			server.use_ssl = 1;
 		}
-		if (!prefixcmp(val, "//"))
+		if (starts_with(val, "//"))
 			val += 2;
 		server.host = xstrdup(val);
 	} else if (!strcmp("user", key))
diff --git a/line-log.c b/line-log.c
index c2d01dc..717638b 100644
--- a/line-log.c
+++ b/line-log.c
@@ -23,7 +23,7 @@
 /* Either initialization would be fine */
 #define RANGE_SET_INIT {0}
 
-static void range_set_init(struct range_set *rs, size_t prealloc)
+void range_set_init(struct range_set *rs, size_t prealloc)
 {
 	rs->alloc = rs->nr = 0;
 	rs->ranges = NULL;
@@ -31,7 +31,7 @@
 		range_set_grow(rs, prealloc);
 }
 
-static void range_set_release(struct range_set *rs)
+void range_set_release(struct range_set *rs)
 {
 	free(rs->ranges);
 	rs->alloc = rs->nr = 0;
@@ -56,7 +56,7 @@
 }
 
 /* tack on a _new_ range _at the end_ */
-static void range_set_append_unsafe(struct range_set *rs, long a, long b)
+void range_set_append_unsafe(struct range_set *rs, long a, long b)
 {
 	assert(a <= b);
 	range_set_grow(rs, 1);
@@ -65,7 +65,7 @@
 	rs->nr++;
 }
 
-static void range_set_append(struct range_set *rs, long a, long b)
+void range_set_append(struct range_set *rs, long a, long b)
 {
 	assert(rs->nr == 0 || rs->ranges[rs->nr-1].end <= a);
 	range_set_append_unsafe(rs, a, b);
@@ -107,7 +107,7 @@
  * In-place pass of sorting and merging the ranges in the range set,
  * to establish the invariants when we get the ranges from the user
  */
-static void sort_and_merge_range_set(struct range_set *rs)
+void sort_and_merge_range_set(struct range_set *rs)
 {
 	int i;
 	int o = 0; /* output cursor */
@@ -291,7 +291,6 @@
 
 	if (p) {
 		range_set_append_unsafe(&p->ranges, begin, end);
-		sort_and_merge_range_set(&p->ranges);
 		free(path);
 		return;
 	}
@@ -299,7 +298,6 @@
 	p = xcalloc(1, sizeof(struct line_log_data));
 	p->path = path;
 	range_set_append(&p->ranges, begin, end);
-	sort_and_merge_range_set(&p->ranges);
 	if (ip) {
 		p->next = ip->next;
 		ip->next = p;
@@ -566,12 +564,14 @@
 	struct nth_line_cb cb_data;
 	struct string_list_item *item;
 	struct line_log_data *ranges = NULL;
+	struct line_log_data *p;
 
 	for_each_string_list_item(item, args) {
 		const char *name_part, *range_part;
 		char *full_name;
 		struct diff_filespec *spec;
 		long begin = 0, end = 0;
+		long anchor;
 
 		name_part = skip_range_arg(item->string);
 		if (!name_part || *name_part != ':' || !name_part[1])
@@ -590,17 +590,23 @@
 		cb_data.lines = lines;
 		cb_data.line_ends = ends;
 
+		p = search_line_log_data(ranges, full_name, NULL);
+		if (p && p->ranges.nr)
+			anchor = p->ranges.ranges[p->ranges.nr - 1].end + 1;
+		else
+			anchor = 1;
+
 		if (parse_range_arg(range_part, nth_line, &cb_data,
-				    lines, &begin, &end,
+				    lines, anchor, &begin, &end,
 				    full_name))
 			die("malformed -L argument '%s'", range_part);
+		if (lines < end || ((lines || begin) && lines < begin))
+			die("file %s has only %lu lines", name_part, lines);
 		if (begin < 1)
 			begin = 1;
 		if (end < 1)
 			end = lines;
 		begin--;
-		if (lines < end || lines < begin)
-			die("file %s has only %ld lines", name_part, lines);
 		line_log_data_insert(&ranges, full_name, begin, end);
 
 		free_filespec(spec);
@@ -608,6 +614,9 @@
 		ends = NULL;
 	}
 
+	for (p = ranges; p; p = p->next)
+		sort_and_merge_range_set(&p->ranges);
+
 	return ranges;
 }
 
@@ -751,7 +760,8 @@
 			r = r->next;
 		}
 		paths[count] = NULL;
-		init_pathspec(&rev->diffopt.pathspec, paths);
+		parse_pathspec(&rev->diffopt.pathspec, 0,
+			       PATHSPEC_PREFER_FULL, "", paths);
 		free(paths);
 	}
 }
diff --git a/line-log.h b/line-log.h
index 8bea45f..a9212d8 100644
--- a/line-log.h
+++ b/line-log.h
@@ -25,6 +25,18 @@
 	struct range_set target;
 };
 
+extern void range_set_init(struct range_set *, size_t prealloc);
+extern void range_set_release(struct range_set *);
+/* Range includes start; excludes end */
+extern void range_set_append_unsafe(struct range_set *, long start, long end);
+/* New range must begin at or after end of last added range */
+extern void range_set_append(struct range_set *, long start, long end);
+/*
+ * In-place pass of sorting and merging the ranges in the range set,
+ * to sort and make the ranges disjoint.
+ */
+extern void sort_and_merge_range_set(struct range_set *);
+
 /* Linked list of interesting files and their associated ranges.  The
  * list must be kept sorted by path.
  *
diff --git a/line-range.c b/line-range.c
index 3942475..de4e32f 100644
--- a/line-range.c
+++ b/line-range.c
@@ -6,6 +6,18 @@
 
 /*
  * Parse one item in the -L option
+ *
+ * 'begin' is applicable only to relative range anchors. Absolute anchors
+ * ignore this value.
+ *
+ * When parsing "-L A,B", parse_loc() is called once for A and once for B.
+ *
+ * When parsing A, 'begin' must be a negative number, the absolute value of
+ * which is the line at which relative start-of-range anchors should be
+ * based. Beginning of file is represented by -1.
+ *
+ * When parsing B, 'begin' must be the positive line number immediately
+ * following the line computed for 'A'.
  */
 static const char *parse_loc(const char *spec, nth_line_fn_t nth_line,
 			     void *data, long lines, long begin, long *ret)
@@ -21,11 +33,13 @@
 	 * for 20 lines, or "-L <something>,-5" for 5 lines ending at
 	 * <something>.
 	 */
-	if (1 < begin && (spec[0] == '+' || spec[0] == '-')) {
+	if (1 <= begin && (spec[0] == '+' || spec[0] == '-')) {
 		num = strtol(spec + 1, &term, 10);
 		if (term != spec + 1) {
 			if (!ret)
 				return term;
+			if (num == 0)
+				die("-L invalid empty range");
 			if (spec[0] == '-')
 				num = 0 - num;
 			if (0 < num)
@@ -40,10 +54,23 @@
 	}
 	num = strtol(spec, &term, 10);
 	if (term != spec) {
-		if (ret)
+		if (ret) {
+			if (num <= 0)
+				die("-L invalid line number: %ld", num);
 			*ret = num;
+		}
 		return term;
 	}
+
+	if (begin < 0) {
+		if (spec[0] != '^')
+			begin = -begin;
+		else {
+			begin = 1;
+			spec++;
+		}
+	}
+
 	if (spec[0] != '/')
 		return spec;
 
@@ -83,7 +110,8 @@
 	else {
 		char errbuf[1024];
 		regerror(reg_error, &regexp, errbuf, 1024);
-		die("-L parameter '%s': %s", spec + 1, errbuf);
+		die("-L parameter '%s' starting at line %ld: %s",
+		    spec + 1, begin + 1, errbuf);
 	}
 }
 
@@ -136,7 +164,7 @@
 }
 
 static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_cb,
-					void *cb_data, long lines, long *begin, long *end,
+					void *cb_data, long lines, long anchor, long *begin, long *end,
 					const char *path)
 {
 	char *pattern;
@@ -148,6 +176,11 @@
 	int reg_error;
 	regex_t regexp;
 
+	if (*arg == '^') {
+		anchor = 1;
+		arg++;
+	}
+
 	assert(*arg == ':');
 	term = arg+1;
 	while (*term && *term != ':') {
@@ -162,7 +195,8 @@
 
 	pattern = xstrndup(arg+1, term-(arg+1));
 
-	start = nth_line_cb(cb_data, 0);
+	anchor--; /* input is in human terms */
+	start = nth_line_cb(cb_data, anchor);
 
 	drv = userdiff_find_by_path(path);
 	if (drv && drv->funcname.pattern) {
@@ -180,7 +214,8 @@
 
 	p = find_funcname_matching_regexp(xecfg, (char*) start, &regexp);
 	if (!p)
-		die("-L parameter '%s': no match", pattern);
+		die("-L parameter '%s' starting at line %ld: no match",
+		    pattern, anchor + 1);
 	*begin = 0;
 	while (p > nth_line_cb(cb_data, *begin))
 		(*begin)++;
@@ -208,19 +243,24 @@
 }
 
 int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
-		    void *cb_data, long lines, long *begin, long *end,
-		    const char *path)
+		    void *cb_data, long lines, long anchor,
+		    long *begin, long *end, const char *path)
 {
 	*begin = *end = 0;
 
-	if (*arg == ':') {
-		arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, begin, end, path);
+	if (anchor < 1)
+		anchor = 1;
+	if (anchor > lines)
+		anchor = lines + 1;
+
+	if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':')) {
+		arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, anchor, begin, end, path);
 		if (!arg || *arg)
 			return -1;
 		return 0;
 	}
 
-	arg = parse_loc(arg, nth_line_cb, cb_data, lines, 1, begin);
+	arg = parse_loc(arg, nth_line_cb, cb_data, lines, -anchor, begin);
 
 	if (*arg == ',')
 		arg = parse_loc(arg + 1, nth_line_cb, cb_data, lines, *begin + 1, end);
@@ -238,8 +278,8 @@
 
 const char *skip_range_arg(const char *arg)
 {
-	if (*arg == ':')
-		return parse_range_funcname(arg, NULL, NULL, 0, NULL, NULL, NULL);
+	if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':'))
+		return parse_range_funcname(arg, NULL, NULL, 0, 0, NULL, NULL, NULL);
 
 	arg = parse_loc(arg, NULL, NULL, 0, -1, NULL);
 
diff --git a/line-range.h b/line-range.h
index ae3d012..83ba3c2 100644
--- a/line-range.h
+++ b/line-range.h
@@ -9,6 +9,9 @@
  * line 'lno' inside the 'cb_data'.  The caller is expected to already
  * have a suitable map at hand to make this a constant-time lookup.
  *
+ * 'anchor' is the 1-based line at which relative range specifications
+ * should be anchored. Absolute ranges are unaffected by this value.
+ *
  * Returns 0 in case of success and -1 if there was an error.  The
  * actual range is stored in *begin and *end.  The counting starts
  * at 1!  In case of error, the caller should show usage message.
@@ -18,7 +21,7 @@
 
 extern int parse_range_arg(const char *arg,
 			   nth_line_fn_t nth_line_cb,
-			   void *cb_data, long lines,
+			   void *cb_data, long lines, long anchor,
 			   long *begin, long *end,
 			   const char *path);
 
diff --git a/list-objects.c b/list-objects.c
index 05c8c5c..206816f 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -123,8 +123,7 @@
 				     cb_data);
 	}
 	strbuf_setlen(base, baselen);
-	free(tree->buffer);
-	tree->buffer = NULL;
+	free_tree_buffer(tree);
 }
 
 static void mark_edge_parents_uninteresting(struct commit *commit,
@@ -163,15 +162,17 @@
 		}
 		mark_edge_parents_uninteresting(commit, revs, show_edge);
 	}
-	for (i = 0; i < revs->cmdline.nr; i++) {
-		struct object *obj = revs->cmdline.rev[i].item;
-		struct commit *commit = (struct commit *)obj;
-		if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING))
-			continue;
-		mark_tree_uninteresting(commit->tree);
-		if (revs->edge_hint && !(obj->flags & SHOWN)) {
-			obj->flags |= SHOWN;
-			show_edge(commit);
+	if (revs->edge_hint) {
+		for (i = 0; i < revs->cmdline.nr; i++) {
+			struct object *obj = revs->cmdline.rev[i].item;
+			struct commit *commit = (struct commit *)obj;
+			if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING))
+				continue;
+			mark_tree_uninteresting(commit->tree);
+			if (!(obj->flags & SHOWN)) {
+				obj->flags |= SHOWN;
+				show_edge(commit);
+			}
 		}
 	}
 }
diff --git a/log-tree.c b/log-tree.c
index 8534d91..08970bf 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -98,7 +98,7 @@
 	struct object *obj;
 	enum decoration_type type = DECORATION_NONE;
 
-	if (!prefixcmp(refname, "refs/replace/")) {
+	if (starts_with(refname, "refs/replace/")) {
 		unsigned char original_sha1[20];
 		if (!read_replace_refs)
 			return 0;
@@ -116,11 +116,11 @@
 	if (!obj)
 		return 0;
 
-	if (!prefixcmp(refname, "refs/heads/"))
+	if (starts_with(refname, "refs/heads/"))
 		type = DECORATION_REF_LOCAL;
-	else if (!prefixcmp(refname, "refs/remotes/"))
+	else if (starts_with(refname, "refs/remotes/"))
 		type = DECORATION_REF_REMOTE;
-	else if (!prefixcmp(refname, "refs/tags/"))
+	else if (starts_with(refname, "refs/tags/"))
 		type = DECORATION_REF_TAG;
 	else if (!strcmp(refname, "refs/stash"))
 		type = DECORATION_REF_STASH;
@@ -134,6 +134,8 @@
 		obj = ((struct tag *)obj)->tagged;
 		if (!obj)
 			break;
+		if (!obj->parsed)
+			parse_object(obj->sha1);
 		add_name_decoration(DECORATION_REF_TAG, refname, obj);
 	}
 	return 0;
@@ -734,7 +736,7 @@
 	if (!opt->diff && !DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS))
 		return 0;
 
-	parse_commit(commit);
+	parse_commit_or_die(commit);
 	sha1 = commit->tree->object.sha1;
 
 	/* Root commit? */
@@ -759,7 +761,7 @@
 			 * parent, showing summary diff of the others
 			 * we merged _in_.
 			 */
-			parse_commit(parents->item);
+			parse_commit_or_die(parents->item);
 			diff_tree_sha1(parents->item->tree->object.sha1,
 				       sha1, "", &opt->diffopt);
 			log_tree_diff_flush(opt);
@@ -774,7 +776,7 @@
 	for (;;) {
 		struct commit *parent = parents->item;
 
-		parse_commit(parent);
+		parse_commit_or_die(parent);
 		diff_tree_sha1(parent->tree->object.sha1,
 			       sha1, "", &opt->diffopt);
 		log_tree_diff_flush(opt);
diff --git a/mailmap.c b/mailmap.c
index 3061434..81890a6 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -52,6 +52,20 @@
 	string_list_clear_func(&me->namemap, free_mailmap_info);
 }
 
+/*
+ * On some systems (e.g. MinGW 4.0), string.h has _only_ inline
+ * definition of strcasecmp and no non-inline implementation is
+ * supplied anywhere, which is, eh, "unusual"; we cannot take an
+ * address of such a function to store it in namemap.cmp.  This is
+ * here as a workaround---do not assign strcasecmp directly to
+ * namemap.cmp until we know no systems that matter have such an
+ * "unusual" string.h.
+ */
+static int namemap_cmp(const char *a, const char *b)
+{
+	return strcasecmp(a, b);
+}
+
 static void add_mapping(struct string_list *map,
 			char *new_name, char *new_email,
 			char *old_name, char *old_email)
@@ -75,7 +89,7 @@
 		item = string_list_insert_at_index(map, index, old_email);
 		me = xcalloc(1, sizeof(struct mailmap_entry));
 		me->namemap.strdup_strings = 1;
-		me->namemap.cmp = strcasecmp;
+		me->namemap.cmp = namemap_cmp;
 		item->util = me;
 	}
 
@@ -153,8 +167,7 @@
 		if (!strncmp(buffer, abbrev, abblen)) {
 			char *cp;
 
-			if (repo_abbrev)
-				free(*repo_abbrev);
+			free(*repo_abbrev);
 			*repo_abbrev = xmalloc(len);
 
 			for (cp = buffer + abblen; isspace(*cp); cp++)
@@ -238,7 +251,7 @@
 	int err = 0;
 
 	map->strdup_strings = 1;
-	map->cmp = strcasecmp;
+	map->cmp = namemap_cmp;
 
 	if (!git_mailmap_blob && is_bare_repository())
 		git_mailmap_blob = "HEAD:.mailmap";
diff --git a/merge-recursive.c b/merge-recursive.c
index fc2f001..8400a8e 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -298,7 +298,7 @@
 {
 	int n;
 	struct pathspec match_all;
-	init_pathspec(&match_all, NULL);
+	memset(&match_all, 0, sizeof(match_all));
 	if (read_tree_recursive(tree, "", 0, 0, &match_all, save_files_dirs, o))
 		return 0;
 	n = o->current_file_set.nr + o->current_directory_set.nr;
@@ -693,7 +693,7 @@
 	/* Make sure leading directories are created */
 	status = safe_create_leading_directories_const(path);
 	if (status) {
-		if (status == -3) {
+		if (status == SCLD_EXISTS) {
 			/* something else exists */
 			error(msg, path, _(": perhaps a D/F conflict?"));
 			return -1;
@@ -2063,13 +2063,13 @@
 		o->recursive_variant = MERGE_RECURSIVE_THEIRS;
 	else if (!strcmp(s, "subtree"))
 		o->subtree_shift = "";
-	else if (!prefixcmp(s, "subtree="))
+	else if (starts_with(s, "subtree="))
 		o->subtree_shift = s + strlen("subtree=");
 	else if (!strcmp(s, "patience"))
 		o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF);
 	else if (!strcmp(s, "histogram"))
 		o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF);
-	else if (!prefixcmp(s, "diff-algorithm=")) {
+	else if (starts_with(s, "diff-algorithm=")) {
 		long value = parse_algorithm_value(s + strlen("diff-algorithm="));
 		if (value < 0)
 			return -1;
@@ -2088,7 +2088,7 @@
 		o->renormalize = 1;
 	else if (!strcmp(s, "no-renormalize"))
 		o->renormalize = 0;
-	else if (!prefixcmp(s, "rename-threshold=")) {
+	else if (starts_with(s, "rename-threshold=")) {
 		const char *score = s + strlen("rename-threshold=");
 		if ((o->rename_score = parse_rename_score(&score)) == -1 || *score != 0)
 			return -1;
diff --git a/mergetools/diffmerge b/mergetools/diffmerge
new file mode 100644
index 0000000..85ac720
--- /dev/null
+++ b/mergetools/diffmerge
@@ -0,0 +1,15 @@
+diff_cmd () {
+	"$merge_tool_path" "$LOCAL" "$REMOTE" >/dev/null 2>&1
+}
+
+merge_cmd () {
+	if $base_present
+	then
+		"$merge_tool_path" --merge --result="$MERGED" \
+			"$LOCAL" "$BASE" "$REMOTE"
+	else
+		"$merge_tool_path" --merge \
+			--result="$MERGED" "$LOCAL" "$REMOTE"
+	fi
+	status=$?
+}
diff --git a/name-hash.c b/name-hash.c
index 617c86c..e5b6e1a 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -58,9 +58,9 @@
 {
 	/*
 	 * Throw each directory component in the hash for quick lookup
-	 * during a git status. Directory components are stored with their
+	 * during a git status. Directory components are stored without their
 	 * closing slash.  Despite submodules being a directory, they never
-	 * reach this point, because they are stored without a closing slash
+	 * reach this point, because they are stored
 	 * in index_state.name_hash (as ordinary cache_entries).
 	 *
 	 * Note that the cache_entry stored with the dir_entry merely
@@ -78,6 +78,7 @@
 		namelen--;
 	if (namelen <= 0)
 		return NULL;
+	namelen--;
 
 	/* lookup existing entry for that directory */
 	dir = find_dir_entry(istate, ce->name, namelen);
@@ -97,7 +98,7 @@
 		}
 
 		/* recursively add missing parent directories */
-		dir->parent = hash_dir_entry(istate, ce, namelen - 1);
+		dir->parent = hash_dir_entry(istate, ce, namelen);
 	}
 	return dir;
 }
@@ -222,7 +223,29 @@
 	return slow_same_name(name, namelen, ce->name, len);
 }
 
-struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase)
+struct cache_entry *index_dir_exists(struct index_state *istate, const char *name, int namelen)
+{
+	struct cache_entry *ce;
+	struct dir_entry *dir;
+
+	lazy_init_name_hash(istate);
+	dir = find_dir_entry(istate, name, namelen);
+	if (dir && dir->nr)
+		return dir->ce;
+
+	/*
+	 * It might be a submodule. Unlike plain directories, which are stored
+	 * in the dir-hash, submodules are stored in the name-hash, so check
+	 * there, as well.
+	 */
+	ce = index_file_exists(istate, name, namelen, 1);
+	if (ce && S_ISGITLINK(ce->ce_mode))
+		return ce;
+
+	return NULL;
+}
+
+struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase)
 {
 	unsigned int hash = hash_name(name, namelen);
 	struct cache_entry *ce;
@@ -237,32 +260,16 @@
 		}
 		ce = ce->next;
 	}
-
-	/*
-	 * When looking for a directory (trailing '/'), it might be a
-	 * submodule or a directory. Despite submodules being directories,
-	 * they are stored in the name hash without a closing slash.
-	 * When ignore_case is 1, directories are stored in a separate hash
-	 * table *with* their closing slash.
-	 *
-	 * The side effect of this storage technique is we have need to
-	 * lookup the directory in a separate hash table, and if not found
-	 * remove the slash from name and perform the lookup again without
-	 * the slash.  If a match is made, S_ISGITLINK(ce->mode) will be
-	 * true.
-	 */
-	if (icase && name[namelen - 1] == '/') {
-		struct dir_entry *dir = find_dir_entry(istate, name, namelen);
-		if (dir && dir->nr)
-			return dir->ce;
-
-		ce = index_name_exists(istate, name, namelen - 1, icase);
-		if (ce && S_ISGITLINK(ce->ce_mode))
-			return ce;
-	}
 	return NULL;
 }
 
+struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase)
+{
+	if (namelen > 0 && name[namelen - 1] == '/')
+		return index_dir_exists(istate, name, namelen - 1);
+	return index_file_exists(istate, name, namelen, icase);
+}
+
 static int free_dir_entry(void *entry, void *unused)
 {
 	struct dir_entry *dir = entry;
diff --git a/notes-merge.c b/notes-merge.c
index ab18857..94a1a8a 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -170,7 +170,7 @@
 		       sha1_to_hex(mp->remote));
 	}
 	diff_flush(&opt);
-	diff_tree_release_paths(&opt);
+	free_pathspec(&opt.pathspec);
 
 	*num_changes = len;
 	return changes;
@@ -256,7 +256,7 @@
 		       sha1_to_hex(mp->local));
 	}
 	diff_flush(&opt);
-	diff_tree_release_paths(&opt);
+	free_pathspec(&opt.pathspec);
 }
 
 static void check_notes_merge_worktree(struct notes_merge_options *o)
diff --git a/notes-utils.c b/notes-utils.c
index 9107c37..2975dcd 100644
--- a/notes-utils.c
+++ b/notes-utils.c
@@ -18,7 +18,7 @@
 		unsigned char parent_sha1[20];
 		if (!read_ref(t->ref, parent_sha1)) {
 			struct commit *parent = lookup_commit(parent_sha1);
-			if (!parent || parse_commit(parent))
+			if (parse_commit(parent))
 				die("Failed to find/parse commit %s", t->ref);
 			commit_list_insert(parent, &parents);
 		}
@@ -70,7 +70,7 @@
 static int notes_rewrite_config(const char *k, const char *v, void *cb)
 {
 	struct notes_rewrite_cfg *c = cb;
-	if (!prefixcmp(k, "notes.rewrite.") && !strcmp(k+14, c->cmd)) {
+	if (starts_with(k, "notes.rewrite.") && !strcmp(k+14, c->cmd)) {
 		c->enabled = git_config_bool(k, v);
 		return 0;
 	} else if (!c->mode_from_env && !strcmp(k, "notes.rewritemode")) {
@@ -85,7 +85,7 @@
 	} else if (!c->refs_from_env && !strcmp(k, "notes.rewriteref")) {
 		/* note that a refs/ prefix is implied in the
 		 * underlying for_each_glob_ref */
-		if (!prefixcmp(v, "refs/notes/"))
+		if (starts_with(v, "refs/notes/"))
 			string_list_add_refs_by_glob(c->refs, v);
 		else
 			warning(_("Refusing to rewrite notes in %s"
diff --git a/notes-utils.h b/notes-utils.h
index b4cb1bf..564e30c 100644
--- a/notes-utils.h
+++ b/notes-utils.h
@@ -9,7 +9,7 @@
  * Properties of the created commit:
  * - tree: the result of converting t to a tree object with write_notes_tree().
  * - parents: the given parents OR (if NULL) the commit referenced by t->ref.
- * - author/committer: the default determined by commmit_tree().
+ * - author/committer: the default determined by commit_tree().
  * - commit message: msg
  *
  * The resulting commit SHA1 is stored in result_sha1.
diff --git a/notes.c b/notes.c
index b69c0b8..5f07c0b 100644
--- a/notes.c
+++ b/notes.c
@@ -1243,9 +1243,9 @@
 		if (!ref || !strcmp(ref, GIT_NOTES_DEFAULT_REF)) {
 			strbuf_addstr(sb, "\nNotes:\n");
 		} else {
-			if (!prefixcmp(ref, "refs/"))
+			if (starts_with(ref, "refs/"))
 				ref += 5;
-			if (!prefixcmp(ref, "notes/"))
+			if (starts_with(ref, "notes/"))
 				ref += 6;
 			strbuf_addf(sb, "\nNotes (%s):\n", ref);
 		}
@@ -1293,9 +1293,9 @@
 
 void expand_notes_ref(struct strbuf *sb)
 {
-	if (!prefixcmp(sb->buf, "refs/notes/"))
+	if (starts_with(sb->buf, "refs/notes/"))
 		return; /* we're happy */
-	else if (!prefixcmp(sb->buf, "notes/"))
+	else if (starts_with(sb->buf, "notes/"))
 		strbuf_insert(sb, 0, "refs/", 5);
 	else
 		strbuf_insert(sb, 0, "refs/notes/", 11);
diff --git a/object.c b/object.c
index d8a4b1f..584f7ac 100644
--- a/object.c
+++ b/object.c
@@ -43,16 +43,17 @@
 	die("invalid object type \"%s\"", str);
 }
 
-static unsigned int hash_obj(struct object *obj, unsigned int n)
+static unsigned int hash_obj(const unsigned char *sha1, unsigned int n)
 {
 	unsigned int hash;
-	memcpy(&hash, obj->sha1, sizeof(unsigned int));
-	return hash % n;
+	memcpy(&hash, sha1, sizeof(unsigned int));
+	/* Assumes power-of-2 hash sizes in grow_object_hash */
+	return hash & (n - 1);
 }
 
 static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size)
 {
-	unsigned int j = hash_obj(obj, size);
+	unsigned int j = hash_obj(obj->sha1, size);
 
 	while (hash[j]) {
 		j++;
@@ -62,13 +63,6 @@
 	hash[j] = obj;
 }
 
-static unsigned int hashtable_index(const unsigned char *sha1)
-{
-	unsigned int i;
-	memcpy(&i, sha1, sizeof(unsigned int));
-	return i % obj_hash_size;
-}
-
 struct object *lookup_object(const unsigned char *sha1)
 {
 	unsigned int i, first;
@@ -77,7 +71,7 @@
 	if (!obj_hash)
 		return NULL;
 
-	first = i = hashtable_index(sha1);
+	first = i = hash_obj(sha1, obj_hash_size);
 	while ((obj = obj_hash[i]) != NULL) {
 		if (!hashcmp(sha1, obj->sha1))
 			break;
@@ -101,6 +95,10 @@
 static void grow_object_hash(void)
 {
 	int i;
+	/*
+	 * Note that this size must always be power-of-2 to match hash_obj
+	 * above.
+	 */
 	int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size;
 	struct object **new_hash;
 
@@ -264,18 +262,16 @@
 	return 0;
 }
 
-void add_object_array(struct object *obj, const char *name, struct object_array *array)
-{
-	add_object_array_with_mode(obj, name, array, S_IFINVALID);
-}
-
 /*
  * A zero-length string to which object_array_entry::name can be
  * initialized without requiring a malloc/free.
  */
 static char object_array_slopbuf[1];
 
-void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode)
+static void add_object_array_with_mode_context(struct object *obj, const char *name,
+					       struct object_array *array,
+					       unsigned mode,
+					       struct object_context *context)
 {
 	unsigned nr = array->nr;
 	unsigned alloc = array->alloc;
@@ -298,9 +294,28 @@
 	else
 		entry->name = xstrdup(name);
 	entry->mode = mode;
+	entry->context = context;
 	array->nr = ++nr;
 }
 
+void add_object_array(struct object *obj, const char *name, struct object_array *array)
+{
+	add_object_array_with_mode(obj, name, array, S_IFINVALID);
+}
+
+void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode)
+{
+	add_object_array_with_mode_context(obj, name, array, mode, NULL);
+}
+
+void add_object_array_with_context(struct object *obj, const char *name, struct object_array *array, struct object_context *context)
+{
+	if (context)
+		add_object_array_with_mode_context(obj, name, array, context->mode, context);
+	else
+		add_object_array_with_mode_context(obj, name, array, S_IFINVALID, context);
+}
+
 void object_array_filter(struct object_array *array,
 			 object_array_each_func_t want, void *cb_data)
 {
diff --git a/object.h b/object.h
index 2ff68c5..dc5df8c 100644
--- a/object.h
+++ b/object.h
@@ -19,6 +19,7 @@
 		 */
 		char *name;
 		unsigned mode;
+		struct object_context *context;
 	} *objects;
 };
 
@@ -91,6 +92,7 @@
 /* Object array handling .. */
 void add_object_array(struct object *obj, const char *name, struct object_array *array);
 void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode);
+void add_object_array_with_context(struct object *obj, const char *name, struct object_array *array, struct object_context *context);
 
 typedef int (*object_array_each_func_t)(struct object_array_entry *, void *);
 
diff --git a/pack-write.c b/pack-write.c
index ca9e63b..605d01b 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -44,14 +44,13 @@
  */
 const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects,
 			   int nr_objects, const struct pack_idx_option *opts,
-			   unsigned char *sha1)
+			   const unsigned char *sha1)
 {
 	struct sha1file *f;
 	struct pack_idx_entry **sorted_by_sha, **list, **last;
 	off_t last_obj_offset = 0;
 	uint32_t array[256];
 	int i, fd;
-	git_SHA_CTX ctx;
 	uint32_t index_version;
 
 	if (nr_objects) {
@@ -114,9 +113,6 @@
 	}
 	sha1write(f, array, 256 * 4);
 
-	/* compute the SHA1 hash of sorted object names. */
-	git_SHA1_Init(&ctx);
-
 	/*
 	 * Write the actual SHA1 entries..
 	 */
@@ -128,7 +124,6 @@
 			sha1write(f, &offset, 4);
 		}
 		sha1write(f, obj->sha1, 20);
-		git_SHA1_Update(&ctx, obj->sha1, 20);
 		if ((opts->flags & WRITE_IDX_STRICT) &&
 		    (i && !hashcmp(list[-2]->sha1, obj->sha1)))
 			die("The same object %s appears twice in the pack",
@@ -178,7 +173,6 @@
 	sha1write(f, sha1, 20);
 	sha1close(f, NULL, ((opts->flags & WRITE_IDX_VERIFY)
 			    ? CSUM_CLOSE : CSUM_FSYNC));
-	git_SHA1_Final(sha1, &ctx);
 	return index_name;
 }
 
@@ -189,8 +183,7 @@
 	hdr.hdr_signature = htonl(PACK_SIGNATURE);
 	hdr.hdr_version = htonl(PACK_VERSION);
 	hdr.hdr_entries = htonl(nr_entries);
-	if (sha1write(f, &hdr, sizeof(hdr)))
-		return 0;
+	sha1write(f, &hdr, sizeof(hdr));
 	return sizeof(hdr);
 }
 
diff --git a/pack.h b/pack.h
index aa6ee7d..12d9516 100644
--- a/pack.h
+++ b/pack.h
@@ -76,7 +76,7 @@
 struct progress;
 typedef int (*verify_fn)(const unsigned char*, enum object_type, unsigned long, void*, int*);
 
-extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *, unsigned char *sha1);
+extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *, const unsigned char *sha1);
 extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
 extern int verify_pack_index(struct packed_git *);
 extern int verify_pack(struct packed_git *, verify_fn fn, struct progress *, uint32_t);
diff --git a/pager.c b/pager.c
index c1ecf65..0cc75a8 100644
--- a/pager.c
+++ b/pager.c
@@ -54,7 +54,7 @@
 		pager = getenv("PAGER");
 	if (!pager)
 		pager = DEFAULT_PAGER;
-	else if (!*pager || !strcmp(pager, "cat"))
+	if (!*pager || !strcmp(pager, "cat"))
 		pager = NULL;
 
 	return pager;
@@ -80,8 +80,15 @@
 	pager_process.use_shell = 1;
 	pager_process.argv = pager_argv;
 	pager_process.in = -1;
-	if (!getenv("LESS")) {
-		static const char *env[] = { "LESS=FRSX", NULL };
+	if (!getenv("LESS") || !getenv("LV")) {
+		static const char *env[3];
+		int i = 0;
+
+		if (!getenv("LESS"))
+			env[i++] = "LESS=FRSX";
+		if (!getenv("LV"))
+			env[i++] = "LV=-c";
+		env[i] = NULL;
 		pager_process.env = env;
 	}
 	if (start_command(&pager_process))
@@ -151,7 +158,7 @@
 static int pager_command_config(const char *var, const char *value, void *data)
 {
 	struct pager_config *c = data;
-	if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) {
+	if (starts_with(var, "pager.") && !strcmp(var + 6, c->cmd)) {
 		int b = git_config_maybe_bool(var, value);
 		if (b >= 0)
 			c->want = b;
diff --git a/parse-options.c b/parse-options.c
index c2cbca2..7b8d3fa 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -43,8 +43,42 @@
 	*file = xstrdup(prefix_filename(prefix, strlen(prefix), *file));
 }
 
+static int opt_command_mode_error(const struct option *opt,
+				  const struct option *all_opts,
+				  int flags)
+{
+	const struct option *that;
+	struct strbuf message = STRBUF_INIT;
+	struct strbuf that_name = STRBUF_INIT;
+
+	/*
+	 * Find the other option that was used to set the variable
+	 * already, and report that this is not compatible with it.
+	 */
+	for (that = all_opts; that->type != OPTION_END; that++) {
+		if (that == opt ||
+		    that->type != OPTION_CMDMODE ||
+		    that->value != opt->value ||
+		    that->defval != *(int *)opt->value)
+			continue;
+
+		if (that->long_name)
+			strbuf_addf(&that_name, "--%s", that->long_name);
+		else
+			strbuf_addf(&that_name, "-%c", that->short_name);
+		strbuf_addf(&message, ": incompatible with %s", that_name.buf);
+		strbuf_release(&that_name);
+		opterror(opt, message.buf, flags);
+		strbuf_release(&message);
+		return -1;
+	}
+	return opterror(opt, ": incompatible with something else", flags);
+}
+
 static int get_value(struct parse_opt_ctx_t *p,
-		     const struct option *opt, int flags)
+		     const struct option *opt,
+		     const struct option *all_opts,
+		     int flags)
 {
 	const char *s, *arg;
 	const int unset = flags & OPT_UNSET;
@@ -83,6 +117,16 @@
 		*(int *)opt->value = unset ? 0 : opt->defval;
 		return 0;
 
+	case OPTION_CMDMODE:
+		/*
+		 * Giving the same mode option twice, although is unnecessary,
+		 * is not a grave error, so let it pass.
+		 */
+		if (*(int *)opt->value && *(int *)opt->value != opt->defval)
+			return opt_command_mode_error(opt, all_opts, flags);
+		*(int *)opt->value = opt->defval;
+		return 0;
+
 	case OPTION_SET_PTR:
 		*(void **)opt->value = unset ? NULL : (void *)opt->defval;
 		return 0;
@@ -143,12 +187,13 @@
 
 static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
 {
+	const struct option *all_opts = options;
 	const struct option *numopt = NULL;
 
 	for (; options->type != OPTION_END; options++) {
 		if (options->short_name == *p->opt) {
 			p->opt = p->opt[1] ? p->opt + 1 : NULL;
-			return get_value(p, options, OPT_SHORT);
+			return get_value(p, options, all_opts, OPT_SHORT);
 		}
 
 		/*
@@ -177,6 +222,7 @@
 static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
                           const struct option *options)
 {
+	const struct option *all_opts = options;
 	const char *arg_end = strchr(arg, '=');
 	const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
 	int abbrev_flags = 0, ambiguous_flags = 0;
@@ -227,13 +273,13 @@
 			if (options->flags & PARSE_OPT_NONEG)
 				continue;
 			/* negated and abbreviated very much? */
-			if (!prefixcmp("no-", arg)) {
+			if (starts_with("no-", arg)) {
 				flags |= OPT_UNSET;
 				goto is_abbreviated;
 			}
 			/* negated? */
-			if (prefixcmp(arg, "no-")) {
-				if (!prefixcmp(long_name, "no-")) {
+			if (!starts_with(arg, "no-")) {
+				if (starts_with(long_name, "no-")) {
 					long_name += 3;
 					opt_flags |= OPT_UNSET;
 					goto again;
@@ -243,7 +289,7 @@
 			flags |= OPT_UNSET;
 			rest = skip_prefix(arg + 3, long_name);
 			/* abbreviated and negated? */
-			if (!rest && !prefixcmp(long_name, arg + 3))
+			if (!rest && starts_with(long_name, arg + 3))
 				goto is_abbreviated;
 			if (!rest)
 				continue;
@@ -253,7 +299,7 @@
 				continue;
 			p->opt = rest + 1;
 		}
-		return get_value(p, options, flags ^ opt_flags);
+		return get_value(p, options, all_opts, flags ^ opt_flags);
 	}
 
 	if (ambiguous_option)
@@ -265,18 +311,20 @@
 			(abbrev_flags & OPT_UNSET) ?  "no-" : "",
 			abbrev_option->long_name);
 	if (abbrev_option)
-		return get_value(p, abbrev_option, abbrev_flags);
+		return get_value(p, abbrev_option, all_opts, abbrev_flags);
 	return -2;
 }
 
 static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg,
 			    const struct option *options)
 {
+	const struct option *all_opts = options;
+
 	for (; options->type != OPTION_END; options++) {
 		if (!(options->flags & PARSE_OPT_NODASH))
 			continue;
 		if (options->short_name == arg[0] && arg[1] == '\0')
-			return get_value(p, options, OPT_SHORT);
+			return get_value(p, options, all_opts, OPT_SHORT);
 	}
 	return -2;
 }
@@ -286,7 +334,7 @@
 	if (strlen(arg) < 3)
 		return;
 
-	if (!prefixcmp(arg, "no-")) {
+	if (starts_with(arg, "no-")) {
 		error ("did you mean `--%s` (with two dashes ?)", arg);
 		exit(129);
 	}
@@ -294,7 +342,7 @@
 	for (; options->type != OPTION_END; options++) {
 		if (!options->long_name)
 			continue;
-		if (!prefixcmp(options->long_name, arg)) {
+		if (starts_with(options->long_name, arg)) {
 			error ("did you mean `--%s` (with two dashes ?)", arg);
 			exit(129);
 		}
diff --git a/parse-options.h b/parse-options.h
index 9b94596..d670cb9 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -13,6 +13,7 @@
 	OPTION_COUNTUP,
 	OPTION_SET_INT,
 	OPTION_SET_PTR,
+	OPTION_CMDMODE,
 	/* options with arguments (usually) */
 	OPTION_STRING,
 	OPTION_INTEGER,
@@ -21,9 +22,6 @@
 	OPTION_FILENAME
 };
 
-/* Deprecated synonym */
-#define OPTION_BOOLEAN OPTION_COUNTUP
-
 enum parse_opt_flags {
 	PARSE_OPT_KEEP_DASHDASH = 1,
 	PARSE_OPT_STOP_AT_NON_OPTION = 2,
@@ -128,8 +126,12 @@
 #define OPT_SET_INT(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG, NULL, (i) }
 #define OPT_BOOL(s, l, v, h)        OPT_SET_INT(s, l, v, h, 1)
+#define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
+				      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
 #define OPT_SET_PTR(s, l, v, h, p)  { OPTION_SET_PTR, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG, NULL, (p) }
+#define OPT_CMDMODE(s, l, v, h, i) { OPTION_CMDMODE, (s), (l), (v), NULL, \
+				      (h), PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, (i) }
 #define OPT_INTEGER(s, l, v, h)     { OPTION_INTEGER, (s), (l), (v), N_("n"), (h) }
 #define OPT_STRING(s, l, v, a, h)   { OPTION_STRING,  (s), (l), (v), (a), (h) }
 #define OPT_STRING_LIST(s, l, v, a, h) \
@@ -159,9 +161,6 @@
 	  N_("no-op (backward compatibility)"),		\
 	  PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb }
 
-/* Deprecated synonym */
-#define OPT_BOOLEAN OPT_COUNTUP
-
 /* parse_options() will filter out the processed options and leave the
  * non-option arguments in argv[]. usagestr strings should be marked
  * for translation with N_().
@@ -230,15 +229,15 @@
 extern int parse_opt_string_list(const struct option *, const char *, int);
 extern int parse_opt_noop_cb(const struct option *, const char *, int);
 
-#define OPT__VERBOSE(var, h)  OPT_BOOLEAN('v', "verbose", (var), (h))
-#define OPT__QUIET(var, h)    OPT_BOOLEAN('q', "quiet",   (var), (h))
+#define OPT__VERBOSE(var, h)  OPT_COUNTUP('v', "verbose", (var), (h))
+#define OPT__QUIET(var, h)    OPT_COUNTUP('q', "quiet",   (var), (h))
 #define OPT__VERBOSITY(var) \
 	{ OPTION_CALLBACK, 'v', "verbose", (var), NULL, N_("be more verbose"), \
 	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \
 	{ OPTION_CALLBACK, 'q', "quiet", (var), NULL, N_("be more quiet"), \
 	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }
-#define OPT__DRY_RUN(var, h)  OPT_BOOLEAN('n', "dry-run", (var), (h))
-#define OPT__FORCE(var, h)    OPT_BOOLEAN('f', "force",   (var), (h))
+#define OPT__DRY_RUN(var, h)  OPT_BOOL('n', "dry-run", (var), (h))
+#define OPT__FORCE(var, h)    OPT_COUNTUP('f', "force",   (var), (h))
 #define OPT__ABBREV(var)  \
 	{ OPTION_CALLBACK, 0, "abbrev", (var), N_("n"),	\
 	  N_("use <n> digits to display SHA-1s"),	\
diff --git a/path.c b/path.c
index 3d244d3..24594c4 100644
--- a/path.c
+++ b/path.c
@@ -434,6 +434,16 @@
 	return 0;
 }
 
+static int have_same_root(const char *path1, const char *path2)
+{
+	int is_abs1, is_abs2;
+
+	is_abs1 = is_absolute_path(path1);
+	is_abs2 = is_absolute_path(path2);
+	return (is_abs1 && is_abs2 && tolower(path1[0]) == tolower(path2[0])) ||
+	       (!is_abs1 && !is_abs2);
+}
+
 /*
  * Give path as relative to prefix.
  *
@@ -454,6 +464,16 @@
 	else if (!prefix_len)
 		return in;
 
+	if (have_same_root(in, prefix)) {
+		/* bypass dos_drive, for "c:" is identical to "C:" */
+		if (has_dos_drive_prefix(in)) {
+			i = 2;
+			j = 2;
+		}
+	} else {
+		return in;
+	}
+
 	while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
 		if (is_dir_sep(prefix[i])) {
 			while (is_dir_sep(prefix[i]))
@@ -531,6 +551,51 @@
 }
 
 /*
+ * A simpler implementation of relative_path
+ *
+ * Get relative path by removing "prefix" from "in". This function
+ * first appears in v1.5.6-1-g044bbbc, and makes git_dir shorter
+ * to increase performance when traversing the path to work_tree.
+ */
+const char *remove_leading_path(const char *in, const char *prefix)
+{
+	static char buf[PATH_MAX + 1];
+	int i = 0, j = 0;
+
+	if (!prefix || !prefix[0])
+		return in;
+	while (prefix[i]) {
+		if (is_dir_sep(prefix[i])) {
+			if (!is_dir_sep(in[j]))
+				return in;
+			while (is_dir_sep(prefix[i]))
+				i++;
+			while (is_dir_sep(in[j]))
+				j++;
+			continue;
+		} else if (in[j] != prefix[i]) {
+			return in;
+		}
+		i++;
+		j++;
+	}
+	if (
+	    /* "/foo" is a prefix of "/foo" */
+	    in[j] &&
+	    /* "/foo" is not a prefix of "/foobar" */
+	    !is_dir_sep(prefix[i-1]) && !is_dir_sep(in[j])
+	   )
+		return in;
+	while (is_dir_sep(in[j]))
+		j++;
+	if (!in[j])
+		strcpy(buf, ".");
+	else
+		strcpy(buf, in + j);
+	return buf;
+}
+
+/*
  * It is okay if dst == src, but they should not overlap otherwise.
  *
  * Performs the following normalizations on src, storing the result in dst:
@@ -543,8 +608,14 @@
  *
  * Note that this function is purely textual.  It does not follow symlinks,
  * verify the existence of the path, or make any system calls.
+ *
+ * prefix_len != NULL is for a specific case of prefix_pathspec():
+ * assume that src == dst and src[0..prefix_len-1] is already
+ * normalized, any time "../" eats up to the prefix_len part,
+ * prefix_len is reduced. In the end prefix_len is the remaining
+ * prefix that has not been overridden by user pathspec.
  */
-int normalize_path_copy(char *dst, const char *src)
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
 {
 	char *dst0;
 
@@ -619,11 +690,18 @@
 		/* Windows: dst[-1] cannot be backslash anymore */
 		while (dst0 < dst && dst[-1] != '/')
 			dst--;
+		if (prefix_len && *prefix_len > dst - dst0)
+			*prefix_len = dst - dst0;
 	}
 	*dst = '\0';
 	return 0;
 }
 
+int normalize_path_copy(char *dst, const char *src)
+{
+	return normalize_path_copy_len(dst, src, NULL);
+}
+
 /*
  * path = Canonical absolute path
  * prefixes = string_list containing normalized, absolute paths without
diff --git a/pathspec.c b/pathspec.c
index 6ea0867..6cb9fd3 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -15,8 +15,8 @@
  * If seen[] has not already been written to, it may make sense
  * to use find_pathspecs_matching_against_index() instead.
  */
-void add_pathspec_matches_against_index(const char **pathspec,
-					char *seen, int specs)
+void add_pathspec_matches_against_index(const struct pathspec *pathspec,
+					char *seen)
 {
 	int num_unmatched = 0, i;
 
@@ -26,14 +26,14 @@
 	 * mistakenly think that the user gave a pathspec that did not match
 	 * anything.
 	 */
-	for (i = 0; i < specs; i++)
+	for (i = 0; i < pathspec->nr; i++)
 		if (!seen[i])
 			num_unmatched++;
 	if (!num_unmatched)
 		return;
 	for (i = 0; i < active_nr; i++) {
 		const struct cache_entry *ce = active_cache[i];
-		match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);
+		match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);
 	}
 }
 
@@ -45,57 +45,452 @@
  * nature of the "closest" (i.e. most specific) matches which each of the
  * given pathspecs achieves against all items in the index.
  */
-char *find_pathspecs_matching_against_index(const char **pathspec)
+char *find_pathspecs_matching_against_index(const struct pathspec *pathspec)
 {
-	char *seen;
-	int i;
-
-	for (i = 0; pathspec[i];  i++)
-		; /* just counting */
-	seen = xcalloc(i, 1);
-	add_pathspec_matches_against_index(pathspec, seen, i);
+	char *seen = xcalloc(pathspec->nr, 1);
+	add_pathspec_matches_against_index(pathspec, seen);
 	return seen;
 }
 
 /*
- * Check the index to see whether path refers to a submodule, or
- * something inside a submodule.  If the former, returns the path with
- * any trailing slash stripped.  If the latter, dies with an error
- * message.
+ * Magic pathspec
+ *
+ * Possible future magic semantics include stuff like:
+ *
+ *	{ PATHSPEC_RECURSIVE, '*', "recursive" },
+ *	{ PATHSPEC_REGEXP, '\0', "regexp" },
+ *
  */
-const char *check_path_for_gitlink(const char *path)
+
+static struct pathspec_magic {
+	unsigned bit;
+	char mnemonic; /* this cannot be ':'! */
+	const char *name;
+} pathspec_magic[] = {
+	{ PATHSPEC_FROMTOP, '/', "top" },
+	{ PATHSPEC_LITERAL,   0, "literal" },
+	{ PATHSPEC_GLOB,   '\0', "glob" },
+	{ PATHSPEC_ICASE,  '\0', "icase" },
+	{ PATHSPEC_EXCLUDE, '!', "exclude" },
+};
+
+static void prefix_short_magic(struct strbuf *sb, int prefixlen,
+			       unsigned short_magic)
 {
-	int i, path_len = strlen(path);
-	for (i = 0; i < active_nr; i++) {
-		const struct cache_entry *ce = active_cache[i];
-		if (S_ISGITLINK(ce->ce_mode)) {
-			int ce_len = ce_namelen(ce);
-			if (path_len <= ce_len || path[ce_len] != '/' ||
-			    memcmp(ce->name, path, ce_len))
-				/* path does not refer to this
-				 * submodule or anything inside it */
-				continue;
-			if (path_len == ce_len + 1) {
-				/* path refers to submodule;
-				 * strip trailing slash */
-				return xstrndup(ce->name, ce_len);
-			} else {
-				die (_("Path '%s' is in submodule '%.*s'"),
-				     path, ce_len, ce->name);
-			}
+	int i;
+	strbuf_addstr(sb, ":(");
+	for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
+		if (short_magic & pathspec_magic[i].bit) {
+			if (sb->buf[sb->len - 1] != '(')
+				strbuf_addch(sb, ',');
+			strbuf_addstr(sb, pathspec_magic[i].name);
 		}
-	}
-	return path;
+	strbuf_addf(sb, ",prefix:%d)", prefixlen);
 }
 
 /*
- * Dies if the given path refers to a file inside a symlinked
- * directory in the index.
+ * Take an element of a pathspec and check for magic signatures.
+ * Append the result to the prefix. Return the magic bitmap.
+ *
+ * For now, we only parse the syntax and throw out anything other than
+ * "top" magic.
+ *
+ * NEEDSWORK: This needs to be rewritten when we start migrating
+ * get_pathspec() users to use the "struct pathspec" interface.  For
+ * example, a pathspec element may be marked as case-insensitive, but
+ * the prefix part must always match literally, and a single stupid
+ * string cannot express such a case.
  */
-void die_if_path_beyond_symlink(const char *path, const char *prefix)
+static unsigned prefix_pathspec(struct pathspec_item *item,
+				unsigned *p_short_magic,
+				const char **raw, unsigned flags,
+				const char *prefix, int prefixlen,
+				const char *elt)
 {
-	if (has_symlink_leading_path(path, strlen(path))) {
-		int len = prefix ? strlen(prefix) : 0;
-		die(_("'%s' is beyond a symbolic link"), path + len);
+	static int literal_global = -1;
+	static int glob_global = -1;
+	static int noglob_global = -1;
+	static int icase_global = -1;
+	unsigned magic = 0, short_magic = 0, global_magic = 0;
+	const char *copyfrom = elt, *long_magic_end = NULL;
+	char *match;
+	int i, pathspec_prefix = -1;
+
+	if (literal_global < 0)
+		literal_global = git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT, 0);
+	if (literal_global)
+		global_magic |= PATHSPEC_LITERAL;
+
+	if (glob_global < 0)
+		glob_global = git_env_bool(GIT_GLOB_PATHSPECS_ENVIRONMENT, 0);
+	if (glob_global)
+		global_magic |= PATHSPEC_GLOB;
+
+	if (noglob_global < 0)
+		noglob_global = git_env_bool(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, 0);
+
+	if (glob_global && noglob_global)
+		die(_("global 'glob' and 'noglob' pathspec settings are incompatible"));
+
+
+	if (icase_global < 0)
+		icase_global = git_env_bool(GIT_ICASE_PATHSPECS_ENVIRONMENT, 0);
+	if (icase_global)
+		global_magic |= PATHSPEC_ICASE;
+
+	if ((global_magic & PATHSPEC_LITERAL) &&
+	    (global_magic & ~PATHSPEC_LITERAL))
+		die(_("global 'literal' pathspec setting is incompatible "
+		      "with all other global pathspec settings"));
+
+	if (flags & PATHSPEC_LITERAL_PATH)
+		global_magic = 0;
+
+	if (elt[0] != ':' || literal_global ||
+	    (flags & PATHSPEC_LITERAL_PATH)) {
+		; /* nothing to do */
+	} else if (elt[1] == '(') {
+		/* longhand */
+		const char *nextat;
+		for (copyfrom = elt + 2;
+		     *copyfrom && *copyfrom != ')';
+		     copyfrom = nextat) {
+			size_t len = strcspn(copyfrom, ",)");
+			if (copyfrom[len] == ',')
+				nextat = copyfrom + len + 1;
+			else
+				/* handle ')' and '\0' */
+				nextat = copyfrom + len;
+			if (!len)
+				continue;
+			for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
+				if (strlen(pathspec_magic[i].name) == len &&
+				    !strncmp(pathspec_magic[i].name, copyfrom, len)) {
+					magic |= pathspec_magic[i].bit;
+					break;
+				}
+				if (starts_with(copyfrom, "prefix:")) {
+					char *endptr;
+					pathspec_prefix = strtol(copyfrom + 7,
+								 &endptr, 10);
+					if (endptr - copyfrom != len)
+						die(_("invalid parameter for pathspec magic 'prefix'"));
+					/* "i" would be wrong, but it does not matter */
+					break;
+				}
+			}
+			if (ARRAY_SIZE(pathspec_magic) <= i)
+				die(_("Invalid pathspec magic '%.*s' in '%s'"),
+				    (int) len, copyfrom, elt);
+		}
+		if (*copyfrom != ')')
+			die(_("Missing ')' at the end of pathspec magic in '%s'"), elt);
+		long_magic_end = copyfrom;
+		copyfrom++;
+	} else {
+		/* shorthand */
+		for (copyfrom = elt + 1;
+		     *copyfrom && *copyfrom != ':';
+		     copyfrom++) {
+			char ch = *copyfrom;
+
+			if (!is_pathspec_magic(ch))
+				break;
+			for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
+				if (pathspec_magic[i].mnemonic == ch) {
+					short_magic |= pathspec_magic[i].bit;
+					break;
+				}
+			if (ARRAY_SIZE(pathspec_magic) <= i)
+				die(_("Unimplemented pathspec magic '%c' in '%s'"),
+				    ch, elt);
+		}
+		if (*copyfrom == ':')
+			copyfrom++;
 	}
+
+	magic |= short_magic;
+	*p_short_magic = short_magic;
+
+	/* --noglob-pathspec adds :(literal) _unless_ :(glob) is specified */
+	if (noglob_global && !(magic & PATHSPEC_GLOB))
+		global_magic |= PATHSPEC_LITERAL;
+
+	/* --glob-pathspec is overridden by :(literal) */
+	if ((global_magic & PATHSPEC_GLOB) && (magic & PATHSPEC_LITERAL))
+		global_magic &= ~PATHSPEC_GLOB;
+
+	magic |= global_magic;
+
+	if (pathspec_prefix >= 0 &&
+	    (prefixlen || (prefix && *prefix)))
+		die("BUG: 'prefix' magic is supposed to be used at worktree's root");
+
+	if ((magic & PATHSPEC_LITERAL) && (magic & PATHSPEC_GLOB))
+		die(_("%s: 'literal' and 'glob' are incompatible"), elt);
+
+	if (pathspec_prefix >= 0) {
+		match = xstrdup(copyfrom);
+		prefixlen = pathspec_prefix;
+	} else if (magic & PATHSPEC_FROMTOP) {
+		match = xstrdup(copyfrom);
+		prefixlen = 0;
+	} else {
+		match = prefix_path_gently(prefix, prefixlen, &prefixlen, copyfrom);
+		if (!match)
+			die(_("%s: '%s' is outside repository"), elt, copyfrom);
+	}
+	*raw = item->match = match;
+	/*
+	 * Prefix the pathspec (keep all magic) and assign to
+	 * original. Useful for passing to another command.
+	 */
+	if (flags & PATHSPEC_PREFIX_ORIGIN) {
+		struct strbuf sb = STRBUF_INIT;
+		if (prefixlen && !literal_global) {
+			/* Preserve the actual prefix length of each pattern */
+			if (short_magic)
+				prefix_short_magic(&sb, prefixlen, short_magic);
+			else if (long_magic_end) {
+				strbuf_add(&sb, elt, long_magic_end - elt);
+				strbuf_addf(&sb, ",prefix:%d)", prefixlen);
+			} else
+				strbuf_addf(&sb, ":(prefix:%d)", prefixlen);
+		}
+		strbuf_addstr(&sb, match);
+		item->original = strbuf_detach(&sb, NULL);
+	} else
+		item->original = elt;
+	item->len = strlen(item->match);
+	item->prefix = prefixlen;
+
+	if ((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) &&
+	    (item->len >= 1 && item->match[item->len - 1] == '/') &&
+	    (i = cache_name_pos(item->match, item->len - 1)) >= 0 &&
+	    S_ISGITLINK(active_cache[i]->ce_mode)) {
+		item->len--;
+		match[item->len] = '\0';
+	}
+
+	if (flags & PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE)
+		for (i = 0; i < active_nr; i++) {
+			struct cache_entry *ce = active_cache[i];
+			int ce_len = ce_namelen(ce);
+
+			if (!S_ISGITLINK(ce->ce_mode))
+				continue;
+
+			if (item->len <= ce_len || match[ce_len] != '/' ||
+			    memcmp(ce->name, match, ce_len))
+				continue;
+			if (item->len == ce_len + 1) {
+				/* strip trailing slash */
+				item->len--;
+				match[item->len] = '\0';
+			} else
+				die (_("Pathspec '%s' is in submodule '%.*s'"),
+				     elt, ce_len, ce->name);
+		}
+
+	if (magic & PATHSPEC_LITERAL)
+		item->nowildcard_len = item->len;
+	else {
+		item->nowildcard_len = simple_length(item->match);
+		if (item->nowildcard_len < prefixlen)
+			item->nowildcard_len = prefixlen;
+	}
+	item->flags = 0;
+	if (magic & PATHSPEC_GLOB) {
+		/*
+		 * FIXME: should we enable ONESTAR in _GLOB for
+		 * pattern "* * / * . c"?
+		 */
+	} else {
+		if (item->nowildcard_len < item->len &&
+		    item->match[item->nowildcard_len] == '*' &&
+		    no_wildcard(item->match + item->nowildcard_len + 1))
+			item->flags |= PATHSPEC_ONESTAR;
+	}
+
+	/* sanity checks, pathspec matchers assume these are sane */
+	assert(item->nowildcard_len <= item->len &&
+	       item->prefix         <= item->len);
+	return magic;
+}
+
+static int pathspec_item_cmp(const void *a_, const void *b_)
+{
+	struct pathspec_item *a, *b;
+
+	a = (struct pathspec_item *)a_;
+	b = (struct pathspec_item *)b_;
+	return strcmp(a->match, b->match);
+}
+
+static void NORETURN unsupported_magic(const char *pattern,
+				       unsigned magic,
+				       unsigned short_magic)
+{
+	struct strbuf sb = STRBUF_INIT;
+	int i, n;
+	for (n = i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
+		const struct pathspec_magic *m = pathspec_magic + i;
+		if (!(magic & m->bit))
+			continue;
+		if (sb.len)
+			strbuf_addstr(&sb, " ");
+		if (short_magic & m->bit)
+			strbuf_addf(&sb, "'%c'", m->mnemonic);
+		else
+			strbuf_addf(&sb, "'%s'", m->name);
+		n++;
+	}
+	/*
+	 * We may want to substitute "this command" with a command
+	 * name. E.g. when add--interactive dies when running
+	 * "checkout -p"
+	 */
+	die(_("%s: pathspec magic not supported by this command: %s"),
+	    pattern, sb.buf);
+}
+
+/*
+ * Given command line arguments and a prefix, convert the input to
+ * pathspec. die() if any magic in magic_mask is used.
+ */
+void parse_pathspec(struct pathspec *pathspec,
+		    unsigned magic_mask, unsigned flags,
+		    const char *prefix, const char **argv)
+{
+	struct pathspec_item *item;
+	const char *entry = argv ? *argv : NULL;
+	int i, n, prefixlen, nr_exclude = 0;
+
+	memset(pathspec, 0, sizeof(*pathspec));
+
+	if (flags & PATHSPEC_MAXDEPTH_VALID)
+		pathspec->magic |= PATHSPEC_MAXDEPTH;
+
+	/* No arguments, no prefix -> no pathspec */
+	if (!entry && !prefix)
+		return;
+
+	if ((flags & PATHSPEC_PREFER_CWD) &&
+	    (flags & PATHSPEC_PREFER_FULL))
+		die("BUG: PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible");
+
+	/* No arguments with prefix -> prefix pathspec */
+	if (!entry) {
+		static const char *raw[2];
+
+		if (flags & PATHSPEC_PREFER_FULL)
+			return;
+
+		if (!(flags & PATHSPEC_PREFER_CWD))
+			die("BUG: PATHSPEC_PREFER_CWD requires arguments");
+
+		pathspec->items = item = xmalloc(sizeof(*item));
+		memset(item, 0, sizeof(*item));
+		item->match = prefix;
+		item->original = prefix;
+		item->nowildcard_len = item->len = strlen(prefix);
+		item->prefix = item->len;
+		raw[0] = prefix;
+		raw[1] = NULL;
+		pathspec->nr = 1;
+		pathspec->_raw = raw;
+		return;
+	}
+
+	n = 0;
+	while (argv[n])
+		n++;
+
+	pathspec->nr = n;
+	pathspec->items = item = xmalloc(sizeof(*item) * n);
+	pathspec->_raw = argv;
+	prefixlen = prefix ? strlen(prefix) : 0;
+
+	for (i = 0; i < n; i++) {
+		unsigned short_magic;
+		entry = argv[i];
+
+		item[i].magic = prefix_pathspec(item + i, &short_magic,
+						argv + i, flags,
+						prefix, prefixlen, entry);
+		if ((flags & PATHSPEC_LITERAL_PATH) &&
+		    !(magic_mask & PATHSPEC_LITERAL))
+			item[i].magic |= PATHSPEC_LITERAL;
+		if (item[i].magic & PATHSPEC_EXCLUDE)
+			nr_exclude++;
+		if (item[i].magic & magic_mask)
+			unsupported_magic(entry,
+					  item[i].magic & magic_mask,
+					  short_magic);
+
+		if ((flags & PATHSPEC_SYMLINK_LEADING_PATH) &&
+		    has_symlink_leading_path(item[i].match, item[i].len)) {
+			die(_("pathspec '%s' is beyond a symbolic link"), entry);
+		}
+
+		if (item[i].nowildcard_len < item[i].len)
+			pathspec->has_wildcard = 1;
+		pathspec->magic |= item[i].magic;
+	}
+
+	if (nr_exclude == n)
+		die(_("There is nothing to exclude from by :(exclude) patterns.\n"
+		      "Perhaps you forgot to add either ':/' or '.' ?"));
+
+
+	if (pathspec->magic & PATHSPEC_MAXDEPTH) {
+		if (flags & PATHSPEC_KEEP_ORDER)
+			die("BUG: PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible");
+		qsort(pathspec->items, pathspec->nr,
+		      sizeof(struct pathspec_item), pathspec_item_cmp);
+	}
+}
+
+/*
+ * N.B. get_pathspec() is deprecated in favor of the "struct pathspec"
+ * based interface - see pathspec.c:parse_pathspec().
+ *
+ * Arguments:
+ *  - prefix - a path relative to the root of the working tree
+ *  - pathspec - a list of paths underneath the prefix path
+ *
+ * Iterates over pathspec, prepending each path with prefix,
+ * and return the resulting list.
+ *
+ * If pathspec is empty, return a singleton list containing prefix.
+ *
+ * If pathspec and prefix are both empty, return an empty list.
+ *
+ * This is typically used by built-in commands such as add.c, in order
+ * to normalize argv arguments provided to the built-in into a list of
+ * paths to process, all relative to the root of the working tree.
+ */
+const char **get_pathspec(const char *prefix, const char **pathspec)
+{
+	struct pathspec ps;
+	parse_pathspec(&ps,
+		       PATHSPEC_ALL_MAGIC &
+		       ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
+		       PATHSPEC_PREFER_CWD,
+		       prefix, pathspec);
+	return ps._raw;
+}
+
+void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
+{
+	*dst = *src;
+	dst->items = xmalloc(sizeof(struct pathspec_item) * dst->nr);
+	memcpy(dst->items, src->items,
+	       sizeof(struct pathspec_item) * dst->nr);
+}
+
+void free_pathspec(struct pathspec *pathspec)
+{
+	free(pathspec->items);
+	pathspec->items = NULL;
 }
diff --git a/pathspec.h b/pathspec.h
index db0184a..0c11262 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -1,8 +1,101 @@
 #ifndef PATHSPEC_H
 #define PATHSPEC_H
 
-extern char *find_pathspecs_matching_against_index(const char **pathspec);
-extern void add_pathspec_matches_against_index(const char **pathspec, char *seen, int specs);
+/* Pathspec magic */
+#define PATHSPEC_FROMTOP	(1<<0)
+#define PATHSPEC_MAXDEPTH	(1<<1)
+#define PATHSPEC_LITERAL	(1<<2)
+#define PATHSPEC_GLOB		(1<<3)
+#define PATHSPEC_ICASE		(1<<4)
+#define PATHSPEC_EXCLUDE	(1<<5)
+#define PATHSPEC_ALL_MAGIC	  \
+	(PATHSPEC_FROMTOP	| \
+	 PATHSPEC_MAXDEPTH	| \
+	 PATHSPEC_LITERAL	| \
+	 PATHSPEC_GLOB		| \
+	 PATHSPEC_ICASE		| \
+	 PATHSPEC_EXCLUDE)
+
+#define PATHSPEC_ONESTAR 1	/* the pathspec pattern satisfies GFNM_ONESTAR */
+
+struct pathspec {
+	const char **_raw; /* get_pathspec() result, not freed by free_pathspec() */
+	int nr;
+	unsigned int has_wildcard:1;
+	unsigned int recursive:1;
+	unsigned magic;
+	int max_depth;
+	struct pathspec_item {
+		const char *match;
+		const char *original;
+		unsigned magic;
+		int len, prefix;
+		int nowildcard_len;
+		int flags;
+	} *items;
+};
+
+#define GUARD_PATHSPEC(ps, mask) \
+	do { \
+		if ((ps)->magic & ~(mask))	       \
+			die("BUG:%s:%d: unsupported magic %x",	\
+			    __FILE__, __LINE__, (ps)->magic & ~(mask)); \
+	} while (0)
+
+/* parse_pathspec flags */
+#define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */
+#define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */
+#define PATHSPEC_MAXDEPTH_VALID (1<<2) /* max_depth field is valid */
+/* strip the trailing slash if the given path is a gitlink */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (1<<3)
+/* die if a symlink is part of the given path's directory */
+#define PATHSPEC_SYMLINK_LEADING_PATH (1<<4)
+/*
+ * This is like a combination of ..LEADING_PATH and .._SLASH_CHEAP
+ * (but not the same): it strips the trailing slash if the given path
+ * is a gitlink but also checks and dies if gitlink is part of the
+ * leading path (i.e. the given path goes beyond a submodule). It's
+ * safer than _SLASH_CHEAP and also more expensive.
+ */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (1<<5)
+#define PATHSPEC_PREFIX_ORIGIN (1<<6)
+#define PATHSPEC_KEEP_ORDER (1<<7)
+/*
+ * For the callers that just need pure paths from somewhere else, not
+ * from command line. Global --*-pathspecs options are ignored. No
+ * magic is parsed in each pathspec either. If PATHSPEC_LITERAL is
+ * allowed, then it will automatically set for every pathspec.
+ */
+#define PATHSPEC_LITERAL_PATH (1<<8)
+
+extern void parse_pathspec(struct pathspec *pathspec,
+			   unsigned magic_mask,
+			   unsigned flags,
+			   const char *prefix,
+			   const char **args);
+extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
+extern void free_pathspec(struct pathspec *);
+
+static inline int ps_strncmp(const struct pathspec_item *item,
+			     const char *s1, const char *s2, size_t n)
+{
+	if (item->magic & PATHSPEC_ICASE)
+		return strncasecmp(s1, s2, n);
+	else
+		return strncmp(s1, s2, n);
+}
+
+static inline int ps_strcmp(const struct pathspec_item *item,
+			    const char *s1, const char *s2)
+{
+	if (item->magic & PATHSPEC_ICASE)
+		return strcasecmp(s1, s2);
+	else
+		return strcmp(s1, s2);
+}
+
+extern char *find_pathspecs_matching_against_index(const struct pathspec *pathspec);
+extern void add_pathspec_matches_against_index(const struct pathspec *pathspec, char *seen);
 extern const char *check_path_for_gitlink(const char *path);
 extern void die_if_path_beyond_symlink(const char *path, const char *prefix);
 
diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm
index 5273ee8..6e804a2 100644
--- a/perl/Git/SVN.pm
+++ b/perl/Git/SVN.pm
@@ -1599,6 +1599,7 @@
 		my %lookup_svn_merge_cache;
 		my %check_cherry_pick_cache;
 		my %has_no_changes_cache;
+		my %_rev_list_cache;
 
 		tie_for_persistent_memoization(\%lookup_svn_merge_cache,
 		    "$cache_path/lookup_svn_merge");
@@ -1620,6 +1621,14 @@
 			SCALAR_CACHE => ['HASH' => \%has_no_changes_cache],
 			LIST_CACHE => 'FAULT',
 		;
+
+		tie_for_persistent_memoization(\%_rev_list_cache,
+		    "$cache_path/_rev_list");
+		memoize '_rev_list',
+			SCALAR_CACHE => 'FAULT',
+			LIST_CACHE => ['HASH' => \%_rev_list_cache],
+		;
+
 	}
 
 	sub unmemoize_svn_mergeinfo_functions {
@@ -1629,6 +1638,7 @@
 		Memoize::unmemoize 'lookup_svn_merge';
 		Memoize::unmemoize 'check_cherry_pick';
 		Memoize::unmemoize 'has_no_changes';
+		Memoize::unmemoize '_rev_list';
 	}
 
 	sub clear_memoized_mergeinfo_caches {
@@ -1959,11 +1969,25 @@
 	unlink $path or croak "unlink: $!";
 }
 
+#define a global associate map to record rebuild status
+my %rebuild_status;
+#define a global associate map to record rebuild verify status
+my %rebuild_verify_status;
+
 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');
+	my $verify_key = $self->refname.'^0';
+	if (!$rebuild_verify_status{$verify_key}) {
+		my $verify_result = ::verify_ref($verify_key);
+		if ($verify_result) {
+			$rebuild_verify_status{$verify_key} = 1;
+		}
+	}
+	if (!$rebuild_verify_status{$verify_key}) {
+		return;
+	}
 	if (!$partial && ($self->use_svm_props || $self->no_metadata)) {
 		my $rev_db = $self->rev_db_path;
 		$self->rebuild_from_rev_db($rev_db);
@@ -1977,10 +2001,21 @@
 	print "Rebuilding $map_path ...\n" if (!$partial);
 	my ($base_rev, $head) = ($partial ? $self->rev_map_max_norebuild(1) :
 		(undef, undef));
+	my $key_value = ($head ? "$head.." : "") . $self->refname;
+	if (exists $rebuild_status{$key_value}) {
+		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;
+		return;
+	}
 	my ($log, $ctx) =
-	    command_output_pipe(qw/rev-list --pretty=raw --reverse/,
-				($head ? "$head.." : "") . $self->refname,
+		command_output_pipe(qw/rev-list --pretty=raw --reverse/,
+				$key_value,
 				'--');
+	$rebuild_status{$key_value} = 1;
 	my $metadata_url = $self->metadata_url;
 	remove_username($metadata_url);
 	my $svn_uuid = $self->rewrite_uuid || $self->ra_uuid;
diff --git a/perl/Git/SVN/Editor.pm b/perl/Git/SVN/Editor.pm
index b3bcd47..34e8af9 100644
--- a/perl/Git/SVN/Editor.pm
+++ b/perl/Git/SVN/Editor.pm
@@ -304,8 +304,12 @@
 	my ($self, $m, $deletions) = @_;
 	my ($dir, $file) = split_path($m->{file_b});
 	my $pbat = $self->ensure_path($dir, $deletions);
+	# workaround for a bug in svn serf backend (v1.8.5 and below):
+	# store third argument to ->add_file() in a local variable, to make it
+	# have the same lifetime as $fbat
+	my $upa = $self->url_path($m->{file_a});
 	my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
-				$self->url_path($m->{file_a}), $self->{r});
+				$upa, $self->{r});
 	print "\tC\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
 	$self->chg_file($fbat, $m);
 	$self->close_file($fbat,undef,$self->{pool});
@@ -323,8 +327,10 @@
 	my ($self, $m, $deletions) = @_;
 	my ($dir, $file) = split_path($m->{file_b});
 	my $pbat = $self->ensure_path($dir, $deletions);
+	# workaround for a bug in svn serf backend, see comment in C() above
+	my $upa = $self->url_path($m->{file_a});
 	my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
-				$self->url_path($m->{file_a}), $self->{r});
+				$upa, $self->{r});
 	print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
 	$self->apply_autoprops($file, $fbat);
 	$self->chg_file($fbat, $m);
diff --git a/perl/Git/SVN/Log.pm b/perl/Git/SVN/Log.pm
index 3f8350a..34f2869 100644
--- a/perl/Git/SVN/Log.pm
+++ b/perl/Git/SVN/Log.pm
@@ -117,6 +117,7 @@
 	}
 	open STDIN, '<&', $rfd or fatal "Can't redirect stdin: $!";
 	$ENV{LESS} ||= 'FRSX';
+	$ENV{LV} ||= '-c';
 	exec $pager or fatal "Can't run pager: $! ($pager)";
 }
 
diff --git a/perl/Git/SVN/Ra.pm b/perl/Git/SVN/Ra.pm
index 75ecc42..a7b0119 100644
--- a/perl/Git/SVN/Ra.pm
+++ b/perl/Git/SVN/Ra.pm
@@ -32,6 +32,14 @@
 	}
 }
 
+# serf has a bug that leads to a coredump upon termination if the
+# remote access object is left around (not fixed yet in serf 1.3.1).
+# Explicitly free it to work around the issue.
+END {
+	$RA = undef;
+	$ra_invalid = 1;
+}
+
 sub _auth_providers () {
 	my @rv = (
 	  SVN::Client::get_simple_provider(),
diff --git a/pkt-line.c b/pkt-line.c
index 70f1950..bc63b3b 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -24,8 +24,8 @@
 	strbuf_addf(&out, "packet: %12s%c ",
 		    packet_trace_prefix, write ? '>' : '<');
 
-	if ((len >= 4 && !prefixcmp(buf, "PACK")) ||
-	    (len >= 5 && !prefixcmp(buf+1, "PACK"))) {
+	if ((len >= 4 && starts_with(buf, "PACK")) ||
+	    (len >= 5 && starts_with(buf+1, "PACK"))) {
 		strbuf_addstr(&out, "PACK ...");
 		unsetenv(trace_key);
 	}
diff --git a/po/TEAMS b/po/TEAMS
index 107aa59..f9a99ed 100644
--- a/po/TEAMS
+++ b/po/TEAMS
@@ -8,7 +8,7 @@
 Language:	de (German)
 Repository:	https://github.com/ralfth/git-po-de
 Leader:		Ralf Thielow <ralf.thielow@googlemail.com>
-Members:	Thomas Rast <trast@student.ethz.ch>
+Members:	Thomas Rast <tr@thomasrast.ch>
 		Jan Krüger <jk@jk.gs>
 		Christian Stimming <stimming@tuhh.de>
 
diff --git a/po/da.po b/po/da.po
index 20a88ea..898b18d 100644
--- a/po/da.po
+++ b/po/da.po
@@ -1674,7 +1674,7 @@
 msgstr ""
 
 #: builtin/describe.c:482
-msgid "--dirty is incompatible with committishes"
+msgid "--dirty is incompatible with commit-ishes"
 msgstr ""
 
 #: builtin/diff.c:77
diff --git a/po/de.po b/po/de.po
index f4076fb..c0bbb65 100644
--- a/po/de.po
+++ b/po/de.po
@@ -5,9 +5,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git 1.8.4\n"
+"Project-Id-Version: git 1.8.5\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2013-08-06 14:10+0800\n"
+"POT-Creation-Date: 2013-11-02 08:06+0800\n"
 "PO-Revision-Date: 2013-07-28 18:42+0200\n"
 "Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n"
 "Language-Team: German <>\n"
@@ -57,71 +57,76 @@
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <Repository> [--exec <Programm>] --list"
 
-#: archive.c:323
+#: archive.c:242 builtin/add.c:240 builtin/add.c:556 builtin/rm.c:328
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr "Pfadspezifikation '%s' stimmt mit keinen Dateien überein"
+
+#: archive.c:327
 msgid "fmt"
 msgstr "Format"
 
-#: archive.c:323
+#: archive.c:327
 msgid "archive format"
 msgstr "Archivformat"
 
-#: archive.c:324 builtin/log.c:1173
+#: archive.c:328 builtin/log.c:1193
 msgid "prefix"
-msgstr "Prefix"
+msgstr "Präfix"
 
-#: archive.c:325
+#: archive.c:329
 msgid "prepend prefix to each pathname in the archive"
 msgstr "stellt einen Präfix vor jeden Pfadnamen in dem Archiv"
 
-#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2292
-#: builtin/blame.c:2293 builtin/config.c:56 builtin/fast-export.c:673
-#: builtin/fast-export.c:675 builtin/grep.c:714 builtin/hash-object.c:77
-#: builtin/ls-files.c:496 builtin/ls-files.c:499 builtin/notes.c:408
-#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:152
+#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2264
+#: builtin/blame.c:2265 builtin/config.c:58 builtin/fast-export.c:680
+#: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77
+#: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408
+#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154
 msgid "file"
 msgstr "Datei"
 
-#: archive.c:327 builtin/archive.c:89
+#: archive.c:331 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "schreibt das Archiv in diese Datei"
 
-#: archive.c:329
+#: archive.c:333
 msgid "read .gitattributes in working directory"
 msgstr "liest .gitattributes aus dem Arbeitsverzeichnis"
 
-#: archive.c:330
+#: archive.c:334
 msgid "report archived files on stderr"
 msgstr "gibt archivierte Dateien in der Standard-Fehlerausgabe aus"
 
-#: archive.c:331
+#: archive.c:335
 msgid "store only"
 msgstr "nur speichern"
 
-#: archive.c:332
+#: archive.c:336
 msgid "compress faster"
 msgstr "schneller komprimieren"
 
-#: archive.c:340
+#: archive.c:344
 msgid "compress better"
 msgstr "besser komprimieren"
 
-#: archive.c:343
+#: archive.c:347
 msgid "list supported archive formats"
 msgstr "listet unterstützte Archivformate auf"
 
-#: archive.c:345 builtin/archive.c:90 builtin/clone.c:85
+#: archive.c:349 builtin/archive.c:90 builtin/clone.c:84
 msgid "repo"
 msgstr "Repository"
 
-#: archive.c:346 builtin/archive.c:91
+#: archive.c:350 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "ruft das Archiv von Remote-Repository <Repository> ab"
 
-#: archive.c:347 builtin/archive.c:92 builtin/notes.c:487
+#: archive.c:351 builtin/archive.c:92 builtin/notes.c:487
 msgid "command"
 msgstr "Programm"
 
-#: archive.c:348 builtin/archive.c:93
+#: archive.c:352 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "Pfad zum externen \"git-upload-archive\"-Programm"
 
@@ -207,19 +212,19 @@
 msgid "Cannot force update the current branch."
 msgstr "Kann Aktualisierung des aktuellen Branches nicht erzwingen."
 
-#: branch.c:216
+#: branch.c:215
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
 "Kann Tracking-Informationen nicht einrichten; Startpunkt '%s' ist kein "
 "Branch."
 
-#: branch.c:218
+#: branch.c:217
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "der angeforderte Upstream-Branch '%s' existiert nicht"
 
-#: branch.c:220
+#: branch.c:219
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -240,26 +245,26 @@
 "\"git push -u\" verwenden, um den Upstream-Branch beim \"push\"\n"
 "zu konfigurieren."
 
-#: branch.c:265
+#: branch.c:264
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Ungültiger Objekt-Name: '%s'"
 
-#: branch.c:285
+#: branch.c:284
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "mehrdeutiger Objekt-Name: '%s'"
 
-#: branch.c:290
+#: branch.c:289
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Ungültiger Branchpunkt: '%s'"
 
-#: branch.c:296
+#: branch.c:295
 msgid "Failed to lock ref for update"
 msgstr "Fehler beim Sperren der Referenz zur Aktualisierung."
 
-#: branch.c:314
+#: branch.c:313
 msgid "Failed to write ref"
 msgstr "Fehler beim Schreiben der Referenz."
 
@@ -273,7 +278,7 @@
 msgid "unrecognized header: %s%s (%d)"
 msgstr "nicht erkannter Kopfbereich: %s%s (%d)"
 
-#: bundle.c:89 builtin/commit.c:697
+#: bundle.c:89 builtin/commit.c:706
 #, c-format
 msgid "could not open '%s'"
 msgstr "Konnte '%s' nicht öffnen"
@@ -282,9 +287,9 @@
 msgid "Repository lacks these prerequisite commits:"
 msgstr "Dem Repository fehlen folgende vorausgesetzte Commits:"
 
-#: bundle.c:164 sequencer.c:661 sequencer.c:1111 builtin/log.c:331
-#: builtin/log.c:801 builtin/log.c:1399 builtin/log.c:1625 builtin/merge.c:364
-#: builtin/shortlog.c:156
+#: bundle.c:164 sequencer.c:662 sequencer.c:1112 builtin/log.c:332
+#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:364
+#: builtin/shortlog.c:158
 msgid "revision walk setup failed"
 msgstr "Einrichtung des Revisionsgangs fehlgeschlagen"
 
@@ -310,7 +315,7 @@
 msgid "rev-list died"
 msgstr "\"rev-list\" abgebrochen"
 
-#: bundle.c:300 builtin/log.c:1310 builtin/shortlog.c:259
+#: bundle.c:300 builtin/log.c:1329 builtin/shortlog.c:261
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "nicht erkanntes Argument: %s"
@@ -461,7 +466,7 @@
 "Fehler in 'diff.dirstat' Konfigurationsvariable gefunden:\n"
 "%s"
 
-#: diff.c:3487
+#: diff.c:3490
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -470,7 +475,7 @@
 "Fehler beim Parsen des --dirstat/-X Optionsparameters:\n"
 "%s"
 
-#: diff.c:3501
+#: diff.c:3504
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Fehler beim Parsen des --submodule Optionsparameters: '%s'"
@@ -497,17 +502,17 @@
 msgid "failed writing detached signature to '%s': %s"
 msgstr "Fehler beim Schreiben der Signatur nach '%s': %s"
 
-#: grep.c:1623
+#: grep.c:1695
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "'%s': konnte nicht lesen %s"
 
-#: grep.c:1640
+#: grep.c:1712
 #, c-format
 msgid "'%s': %s"
 msgstr "'%s': %s"
 
-#: grep.c:1651
+#: grep.c:1723
 #, c-format
 msgid "'%s': short read %s"
 msgstr "'%s': read() zu kurz %s"
@@ -580,8 +585,8 @@
 msgid "failed to read the cache"
 msgstr "Lesen des Zwischenspeichers fehlgeschlagen"
 
-#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566
-#: builtin/clone.c:656
+#: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559
+#: builtin/clone.c:655
 msgid "unable to write new index file"
 msgstr "Konnte neue Staging-Area-Datei nicht schreiben."
 
@@ -630,7 +635,7 @@
 msgid "blob expected for %s '%s'"
 msgstr "Blob erwartet für %s '%s'"
 
-#: merge-recursive.c:774 builtin/clone.c:312
+#: merge-recursive.c:774 builtin/clone.c:311
 #, c-format
 msgid "failed to open '%s'"
 msgstr "Fehler beim Öffnen von '%s'"
@@ -767,7 +772,7 @@
 msgid "Auto-merging %s"
 msgstr "automatischer Merge von %s"
 
-#: merge-recursive.c:1634 git-submodule.sh:1118
+#: merge-recursive.c:1634 git-submodule.sh:1125
 msgid "submodule"
 msgstr "Submodul"
 
@@ -866,58 +871,122 @@
 msgid "Bad %s value: '%s'"
 msgstr "Ungültiger %s Wert: '%s'"
 
-#: object.c:204
+#: object.c:202
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "Konnte Objekt '%s' nicht parsen."
 
-#: parse-options.c:489
+#: parse-options.c:537
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:507
+#: parse-options.c:555
 #, c-format
 msgid "usage: %s"
 msgstr "Verwendung: %s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:511
+#: parse-options.c:559
 #, c-format
 msgid "   or: %s"
 msgstr "      oder: %s"
 
-#: parse-options.c:514
+#: parse-options.c:562
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:548
+#: parse-options.c:596
 msgid "-NUM"
 msgstr "-NUM"
 
-#: pathspec.c:83
-#, c-format
-msgid "Path '%s' is in submodule '%.*s'"
-msgstr "Pfad '%s' befindet sich in Submodul '%.*s'"
+#: pathspec.c:118
+msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
+msgstr "Globale Einstellungen zur Pfadspezifikation 'glob' und 'noglob' sind inkompatibel."
 
-#: pathspec.c:99
-#, c-format
-msgid "'%s' is beyond a symbolic link"
-msgstr "'%s' ist hinter einem symbolischen Verweis"
+#: pathspec.c:128
+msgid ""
+"global 'literal' pathspec setting is incompatible with all other global "
+"pathspec settings"
+msgstr "Globale Einstellung zur Pfadspezifikation 'literal' ist inkompatibel\n"
+"mit allen anderen Optionen."
 
-#: remote.c:1788
+#: pathspec.c:158
+msgid "invalid parameter for pathspec magic 'prefix'"
+msgstr "ungültiger Parameter für Pfadspezifikationsangabe 'prefix'"
+
+#: pathspec.c:164
+#, c-format
+msgid "Invalid pathspec magic '%.*s' in '%s'"
+msgstr "ungültige Pfadspezifikationsangabe '%.*s' in '%s'"
+
+#: pathspec.c:168
+#, c-format
+msgid "Missing ')' at the end of pathspec magic in '%s'"
+msgstr "Fehlendes ')' am Ende der Pfadspezifikationsangabe in '%s'"
+
+#: pathspec.c:186
+#, c-format
+msgid "Unimplemented pathspec magic '%c' in '%s'"
+msgstr "nicht unterstützte Pfadspezifikationsangabe '%c' in '%s'"
+
+#: pathspec.c:211
+#, c-format
+msgid "%s: 'literal' and 'glob' are incompatible"
+msgstr "%s: 'literal' und 'glob' sind inkompatibel"
+
+#: pathspec.c:222
+#, c-format
+msgid "%s: '%s' is outside repository"
+msgstr "%s: '%s' liegt außerhalb des Repositories"
+
+#: pathspec.c:278
+#, c-format
+msgid "Pathspec '%s' is in submodule '%.*s'"
+msgstr "Pfadspezifikation '%s' befindet sich in Submodul '%.*s'"
+
+#.
+#. * We may want to substitute "this command" with a command
+#. * name. E.g. when add--interactive dies when running
+#. * "checkout -p"
+#.
+#: pathspec.c:340
+#, c-format
+msgid "%s: pathspec magic not supported by this command: %s"
+msgstr "%s: Pfadspezifikationsangabe wird von diesem Kommando nicht unterstützt: %s"
+
+#: pathspec.c:415
+#, c-format
+msgid "pathspec '%s' is beyond a symbolic link"
+msgstr "Pfadspezifikation '%s' ist hinter einem symbolischen Verweis"
+
+#: remote.c:1833
+#, c-format
+msgid "Your branch is based on '%s', but the upstream is gone.\n"
+msgstr "Ihr Branch basiert auf '%s', aber Upstream-Branch wurde entfernt.\n"
+
+#: remote.c:1837
+msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
+msgstr "  (benutzen Sie \"git branch --unset-upstream\" zum Beheben)\n"
+
+#: remote.c:1840
+#, c-format
+msgid "Your branch is up-to-date with '%s'.\n"
+msgstr "Ihr Branch ist auf dem selben Stand wie '%s'.\n"
+
+#: remote.c:1844
 #, 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] "Ihr Branch ist vor '%s' um %d Commit.\n"
 msgstr[1] "Ihr Branch ist vor '%s' um %d Commits.\n"
 
-#: remote.c:1794
+#: remote.c:1850
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (benutzen Sie \"git push\" um lokale Commits zu publizieren)\n"
 
-#: remote.c:1797
+#: remote.c:1853
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -927,12 +996,12 @@
 msgstr[1] ""
 "Ihr Branch ist zu '%s' um %d Commits hinterher, und kann vorgespult werden.\n"
 
-#: remote.c:1805
+#: remote.c:1861
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr ""
 "  (benutzen Sie \"git pull\" um Ihren lokalen Branch zu aktualisieren)\n"
 
-#: remote.c:1808
+#: remote.c:1864
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -947,7 +1016,7 @@
 "Ihr Branch und '%s' sind divergiert,\n"
 "und haben jeweils %d und %d unterschiedliche Commits.\n"
 
-#: remote.c:1818
+#: remote.c:1874
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr ""
 "  (benutzen Sie \"git pull\" um Ihren Branch mit dem Remote-Branch "
@@ -992,7 +1061,7 @@
 "mit 'git add <Pfade>' oder 'git rm <Pfade>'und tragen Sie das Ergebnis mit\n"
 "'git commit' ein"
 
-#: sequencer.c:245 sequencer.c:869 sequencer.c:952
+#: sequencer.c:245 sequencer.c:870 sequencer.c:953
 #, c-format
 msgid "Could not write to %s"
 msgstr "Konnte nicht nach %s schreiben"
@@ -1017,197 +1086,197 @@
 "Tragen Sie Ihre Änderungen ein oder benutzen Sie \"stash\" um fortzufahren."
 
 #. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:324
+#: sequencer.c:325
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: Konnte neue Staging-Area-Datei nicht schreiben"
 
-#: sequencer.c:355
+#: sequencer.c:356
 msgid "Could not resolve HEAD commit\n"
 msgstr "Konnte Commit von HEAD nicht auflösen\n"
 
-#: sequencer.c:377
+#: sequencer.c:378
 msgid "Unable to update cache tree\n"
 msgstr "Konnte Cache-Verzeichnis nicht aktualisieren\n"
 
-#: sequencer.c:422
+#: sequencer.c:423
 #, c-format
 msgid "Could not parse commit %s\n"
 msgstr "Konnte Commit %s nicht parsen\n"
 
-#: sequencer.c:427
+#: sequencer.c:428
 #, c-format
 msgid "Could not parse parent commit %s\n"
 msgstr "Konnte Eltern-Commit %s nicht parsen\n"
 
-#: sequencer.c:493
+#: sequencer.c:494
 msgid "Your index file is unmerged."
 msgstr "Ihre Staging-Area-Datei ist nicht zusammengeführt."
 
-#: sequencer.c:512
+#: sequencer.c:513
 #, c-format
 msgid "Commit %s is a merge but no -m option was given."
 msgstr "Commit %s ist ein Merge, aber die Option -m wurde nicht angegeben."
 
-#: sequencer.c:520
+#: sequencer.c:521
 #, c-format
 msgid "Commit %s does not have parent %d"
 msgstr "Commit %s hat keinen Elternteil %d"
 
-#: sequencer.c:524
+#: sequencer.c:525
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
 msgstr "Hauptlinie wurde spezifiziert, aber Commit %s ist kein Merge."
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
-#: sequencer.c:537
+#: sequencer.c:538
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: kann Eltern-Commit %s nicht parsen"
 
-#: sequencer.c:541
+#: sequencer.c:542
 #, c-format
 msgid "Cannot get commit message for %s"
 msgstr "Kann keine Commit-Beschreibung für %s bekommen"
 
-#: sequencer.c:627
+#: sequencer.c:628
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "Konnte \"revert\" nicht auf %s ausführen... %s"
 
-#: sequencer.c:628
+#: sequencer.c:629
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "Konnte %s nicht anwenden... %s"
 
-#: sequencer.c:664
+#: sequencer.c:665
 msgid "empty commit set passed"
 msgstr "leere Menge von Commits übergeben"
 
-#: sequencer.c:672
+#: sequencer.c:673
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: Fehler beim Lesen der Staging-Area"
 
-#: sequencer.c:677
+#: sequencer.c:678
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s: Fehler beim Aktualisieren der Staging-Area"
 
-#: sequencer.c:735
+#: sequencer.c:736
 #, c-format
 msgid "Cannot %s during a %s"
 msgstr "Kann %s nicht während eines %s durchführen"
 
-#: sequencer.c:757
+#: sequencer.c:758
 #, c-format
 msgid "Could not parse line %d."
 msgstr "Konnte Zeile %d nicht parsen."
 
-#: sequencer.c:762
+#: sequencer.c:763
 msgid "No commits parsed."
 msgstr "Keine Commits geparst."
 
-#: sequencer.c:775
+#: sequencer.c:776
 #, c-format
 msgid "Could not open %s"
 msgstr "Konnte %s nicht öffnen"
 
-#: sequencer.c:779
+#: sequencer.c:780
 #, c-format
 msgid "Could not read %s."
 msgstr "Konnte %s nicht lesen."
 
-#: sequencer.c:786
+#: sequencer.c:787
 #, c-format
 msgid "Unusable instruction sheet: %s"
 msgstr "Unbenutzbares Instruktionsblatt: %s"
 
-#: sequencer.c:814
+#: sequencer.c:815
 #, c-format
 msgid "Invalid key: %s"
 msgstr "Ungültiger Schlüssel: %s"
 
-#: sequencer.c:817
+#: sequencer.c:818
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Ungültiger Wert für %s: %s"
 
-#: sequencer.c:829
+#: sequencer.c:830
 #, c-format
 msgid "Malformed options sheet: %s"
 msgstr "Fehlerhaftes Optionsblatt: %s"
 
-#: sequencer.c:850
+#: sequencer.c:851
 msgid "a cherry-pick or revert is already in progress"
 msgstr "\"cherry-pick\" oder \"revert\" ist bereits im Gang"
 
-#: sequencer.c:851
+#: sequencer.c:852
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "versuchen Sie \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:855
+#: sequencer.c:856
 #, c-format
 msgid "Could not create sequencer directory %s"
 msgstr "Konnte \"sequencer\"-Verzeichnis %s nicht erstellen"
 
-#: sequencer.c:871 sequencer.c:956
+#: sequencer.c:872 sequencer.c:957
 #, c-format
 msgid "Error wrapping up %s."
 msgstr "Fehler beim Einpacken von %s."
 
-#: sequencer.c:890 sequencer.c:1024
+#: sequencer.c:891 sequencer.c:1025
 msgid "no cherry-pick or revert in progress"
 msgstr "kein \"cherry-pick\" oder \"revert\" im Gang"
 
-#: sequencer.c:892
+#: sequencer.c:893
 msgid "cannot resolve HEAD"
 msgstr "kann HEAD nicht auflösen"
 
-#: sequencer.c:894
+#: sequencer.c:895
 msgid "cannot abort from a branch yet to be born"
 msgstr "kann nicht abbrechen: bin auf einem Branch, der noch geboren wird"
 
-#: sequencer.c:916 builtin/apply.c:4061
+#: sequencer.c:917 builtin/apply.c:4061
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "Kann %s nicht öffnen: %s"
 
-#: sequencer.c:919
+#: sequencer.c:920
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "Kann %s nicht lesen: %s"
 
-#: sequencer.c:920
+#: sequencer.c:921
 msgid "unexpected end of file"
 msgstr "Unerwartetes Dateiende"
 
-#: sequencer.c:926
+#: sequencer.c:927
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "gespeicherte \"pre-cherry-pick\" HEAD Datei '%s' ist beschädigt"
 
-#: sequencer.c:949
+#: sequencer.c:950
 #, c-format
 msgid "Could not format %s."
 msgstr "Konnte %s nicht formatieren."
 
-#: sequencer.c:1092
+#: sequencer.c:1093
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: %s kann nicht in \"cherry-pick\" benutzt werden"
 
-#: sequencer.c:1095
+#: sequencer.c:1096
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: ungültiger Commit"
 
-#: sequencer.c:1129
+#: sequencer.c:1130
 msgid "Can't revert as initial commit"
 msgstr "Kann nicht als allerersten Commit einen Revert ausführen."
 
-#: sequencer.c:1130
+#: sequencer.c:1131
 msgid "Can't cherry-pick into empty head"
 msgstr "Kann nicht als allerersten Commit einen Cherry-Pick ausführen."
 
@@ -1236,275 +1305,368 @@
 "indem Sie \"git config advice.objectNameWarning false\"\n"
 "ausführen."
 
-#: sha1_name.c:1097
+#: sha1_name.c:1112
 msgid "HEAD does not point to a branch"
 msgstr "HEAD zeigt auf keinen Branch"
 
-#: sha1_name.c:1100
+#: sha1_name.c:1115
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "Kein solcher Branch '%s'"
 
-#: sha1_name.c:1102
+#: sha1_name.c:1117
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "Kein Upstream-Branch für Branch '%s' konfiguriert."
 
-#: sha1_name.c:1106
+#: sha1_name.c:1121
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "Upstream-Branch '%s' ist nicht als Remote-Tracking-Branch gespeichert"
 
-#: wrapper.c:408
+#: submodule.c:64 submodule.c:98
+msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
+msgstr "Kann nicht zusammengeführte .gitmodules-Datei nicht ändern, lösen\n"
+"Sie zuerst die Konflikte auf"
+
+#: submodule.c:68 submodule.c:102
+#, c-format
+msgid "Could not find section in .gitmodules where path=%s"
+msgstr "Konnte keine Sektion in .gitmodules mit Pfad \"%s\" finden"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:76
+#, c-format
+msgid "Could not update .gitmodules entry %s"
+msgstr "Konnte Eintrag '%s' in .gitmodules nicht aktualisieren"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:109
+#, c-format
+msgid "Could not remove .gitmodules entry for %s"
+msgstr "Konnte Eintrag '%s' nicht aus .gitmodules entfernen"
+
+#: submodule.c:127
+msgid "could not find .gitmodules in index"
+msgstr "Konnte .gitmodules nicht in der Staging-Area finden"
+
+#: submodule.c:133
+msgid "reading updated .gitmodules failed"
+msgstr "Lesen der aktualisierten .gitmodules-Datei fehlgeschlagen"
+
+#: submodule.c:135
+msgid "unable to stat updated .gitmodules"
+msgstr "Konnte aktualisierte .gitmodules-Datei nicht lesen"
+
+#: submodule.c:139
+msgid "unable to remove .gitmodules from index"
+msgstr "Konnte .gitmodules nicht aus der Staging-Area entfernen"
+
+#: submodule.c:141
+msgid "adding updated .gitmodules failed"
+msgstr "Konnte aktualisierte .gitmodules-Datei nicht hinzufügen"
+
+#: submodule.c:143
+msgid "staging updated .gitmodules failed"
+msgstr "Konnte aktualisierte .gitmodules-Datei nicht zum Commit vormerken"
+
+#: submodule.c:1144 builtin/init-db.c:363
+#, c-format
+msgid "Could not create git link %s"
+msgstr "Konnte git-Verweis %s nicht erstellen"
+
+#: submodule.c:1155
+#, c-format
+msgid "Could not set core.worktree in %s"
+msgstr "Konnte core.worktree in '%s' nicht setzen."
+
+#: urlmatch.c:120
+msgid "invalid URL scheme name or missing '://' suffix"
+msgstr "Ungültiges URL-Schema oder Suffix '://' fehlt"
+
+#: urlmatch.c:144 urlmatch.c:297 urlmatch.c:356
+#, c-format
+msgid "invalid %XX escape sequence"
+msgstr "ungültige Escape-Sequenz %XX"
+
+#: urlmatch.c:172
+msgid "missing host and scheme is not 'file:'"
+msgstr "fehlender Host und Schema ist nicht 'file:'"
+
+#: urlmatch.c:189
+msgid "a 'file:' URL may not have a port number"
+msgstr "eine 'file:' URL darf keine Portnummer enthalten"
+
+#: urlmatch.c:199
+msgid "invalid characters in host name"
+msgstr "Hostname enthält ungültige Zeichen"
+
+#: urlmatch.c:244 urlmatch.c:255
+msgid "invalid port number"
+msgstr "ungültige Portnummer"
+
+#: urlmatch.c:322
+msgid "invalid '..' path segment"
+msgstr "ungültiges '..' Pfadsegment"
+
+#: wrapper.c:422
 #, c-format
 msgid "unable to access '%s': %s"
 msgstr "konnte nicht auf '%s' zugreifen: %s"
 
-#: wrapper.c:429
+#: wrapper.c:443
 #, c-format
 msgid "unable to access '%s'"
 msgstr "konnte nicht auf '%s' zugreifen"
 
-#: wrapper.c:440
+#: wrapper.c:454
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
 msgstr "konnte aktuellen Benutzer nicht in Passwort-Datei finden: %s"
 
-#: wrapper.c:441
+#: wrapper.c:455
 msgid "no such user"
 msgstr "kein solcher Benutzer"
 
-#: wt-status.c:141
+#: wt-status.c:146
 msgid "Unmerged paths:"
 msgstr "Nicht zusammengeführte Pfade:"
 
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:173 wt-status.c:200
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr ""
 "  (benutzen Sie \"git reset %s <Datei>...\" zum Entfernen aus der Staging-"
 "Area)"
 
-#: wt-status.c:170 wt-status.c:197
+#: wt-status.c:175 wt-status.c:202
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr ""
 "  (benutzen Sie \"git rm --cached <Datei>...\" zum Entfernen aus der Staging-"
 "Area)"
 
-#: wt-status.c:174
+#: wt-status.c:179
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr ""
 "  (benutzen Sie \"git add/rm <Datei>...\" um die Auflösung zu markieren)"
 
-#: wt-status.c:176 wt-status.c:180
+#: wt-status.c:181 wt-status.c:185
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 "  (benutzen Sie \"git add/rm <Datei>...\" um die Auflösung entsprechend zu "
 "markieren)"
 
-#: wt-status.c:178
+#: wt-status.c:183
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr ""
 "  (benutzen Sie \"git add/rm <Datei>...\" um die Auflösung zu markieren)"
 
-#: wt-status.c:189
+#: wt-status.c:194
 msgid "Changes to be committed:"
 msgstr "zum Commit vorgemerkte Änderungen:"
 
-#: wt-status.c:207
+#: wt-status.c:212
 msgid "Changes not staged for commit:"
 msgstr "Änderungen, die nicht zum Commit vorgemerkt sind:"
 
-#: wt-status.c:211
+#: wt-status.c:216
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 "  (benutzen Sie \"git add <Datei>...\" um die Änderungen zum Commit "
 "vorzumerken)"
 
-#: wt-status.c:213
+#: wt-status.c:218
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 "  (benutzen Sie \"git add/rm <Datei>...\" um die Änderungen zum Commit "
 "vorzumerken)"
 
-#: wt-status.c:214
+#: wt-status.c:219
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (benutzen Sie \"git checkout -- <Datei>...\" um die Änderungen im "
 "Arbeitsverzeichnis zu verwerfen)"
 
-#: wt-status.c:216
+#: wt-status.c:221
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (committen oder verwerfen Sie den unbeobachteten oder geänderten Inhalt in "
 "den Submodulen)"
 
-#: wt-status.c:228
+#: wt-status.c:233
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 "  (benutzen Sie \"git %s <Datei>...\" um die Änderungen zum Commit "
 "vorzumerken)"
 
-#: wt-status.c:245
+#: wt-status.c:250
 msgid "bug"
 msgstr "Fehler"
 
-#: wt-status.c:250
+#: wt-status.c:255
 msgid "both deleted:"
 msgstr "beide gelöscht:"
 
-#: wt-status.c:251
+#: wt-status.c:256
 msgid "added by us:"
 msgstr "von uns hinzugefügt:"
 
-#: wt-status.c:252
+#: wt-status.c:257
 msgid "deleted by them:"
 msgstr "von denen gelöscht:"
 
-#: wt-status.c:253
+#: wt-status.c:258
 msgid "added by them:"
 msgstr "von denen hinzugefügt:"
 
-#: wt-status.c:254
+#: wt-status.c:259
 msgid "deleted by us:"
 msgstr "von uns gelöscht:"
 
-#: wt-status.c:255
+#: wt-status.c:260
 msgid "both added:"
 msgstr "von beiden hinzugefügt:"
 
-#: wt-status.c:256
+#: wt-status.c:261
 msgid "both modified:"
 msgstr "von beiden geändert:"
 
-#: wt-status.c:286
+#: wt-status.c:291
 msgid "new commits, "
 msgstr "neue Commits, "
 
-#: wt-status.c:288
+#: wt-status.c:293
 msgid "modified content, "
 msgstr "geänderter Inhalt, "
 
-#: wt-status.c:290
+#: wt-status.c:295
 msgid "untracked content, "
 msgstr "unbeobachteter Inhalt, "
 
-#: wt-status.c:307
+#: wt-status.c:312
 #, c-format
 msgid "new file:   %s"
 msgstr "neue Datei:   %s"
 
-#: wt-status.c:310
+#: wt-status.c:315
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "kopiert:     %s -> %s"
 
-#: wt-status.c:313
+#: wt-status.c:318
 #, c-format
 msgid "deleted:    %s"
 msgstr "gelöscht:    %s"
 
-#: wt-status.c:316
+#: wt-status.c:321
 #, c-format
 msgid "modified:   %s"
 msgstr "geändert:   %s"
 
-#: wt-status.c:319
+#: wt-status.c:324
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "umbenannt:    %s -> %s"
 
-#: wt-status.c:322
+#: wt-status.c:327
 #, c-format
 msgid "typechange: %s"
 msgstr "Typänderung: %s"
 
-#: wt-status.c:325
+#: wt-status.c:330
 #, c-format
 msgid "unknown:    %s"
 msgstr "unbekannt:    %s"
 
-#: wt-status.c:328
+#: wt-status.c:333
 #, c-format
 msgid "unmerged:   %s"
 msgstr "nicht zusammengeführt:   %s"
 
-#: wt-status.c:331
+#: wt-status.c:336
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "Fehler: unbehandelter Differenz-Status %c"
 
-#: wt-status.c:803
+#: wt-status.c:703
+msgid "Submodules changed but not updated:"
+msgstr "Submodule geändert, aber nicht aktualisiert:"
+
+#: wt-status.c:705
+msgid "Submodule changes to be committed:"
+msgstr "Änderungen in Submodul zum Committen:"
+
+#: wt-status.c:848
 msgid "You have unmerged paths."
 msgstr "Sie haben nicht zusammengeführte Pfade."
 
-#: wt-status.c:806
+#: wt-status.c:851
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr " (beheben Sie die Konflikte und führen Sie \"git commit\" aus)"
 
-#: wt-status.c:809
+#: wt-status.c:854
 msgid "All conflicts fixed but you are still merging."
 msgstr "Alle Konflikte sind behoben, aber Sie sind immer noch beim Merge."
 
-#: wt-status.c:812
+#: wt-status.c:857
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (benutzen Sie \"git commit\" um den Merge abzuschließen)"
 
-#: wt-status.c:822
+#: wt-status.c:867
 msgid "You are in the middle of an am session."
 msgstr "Eine \"am\"-Sitzung ist im Gange."
 
-#: wt-status.c:825
+#: wt-status.c:870
 msgid "The current patch is empty."
 msgstr "Der aktuelle Patch ist leer."
 
-#: wt-status.c:829
+#: wt-status.c:874
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr ""
 "  (beheben Sie die Konflikte und führen Sie dann \"git am --continue\" aus)"
 
-#: wt-status.c:831
+#: wt-status.c:876
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (benutzen Sie \"git am --skip\" um diesen Patch auszulassen)"
 
-#: wt-status.c:833
+#: wt-status.c:878
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr ""
 "  (benutzen Sie \"git am --abort\" um den ursprünglichen Branch "
 "wiederherzustellen)"
 
-#: wt-status.c:893 wt-status.c:910
+#: wt-status.c:938 wt-status.c:955
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "Sie sind gerade beim Rebase von Branch '%s' auf '%s'."
 
-#: wt-status.c:898 wt-status.c:915
+#: wt-status.c:943 wt-status.c:960
 msgid "You are currently rebasing."
 msgstr "Sie sind gerade beim Rebase."
 
-#: wt-status.c:901
+#: wt-status.c:946
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr ""
 "  (beheben Sie die Konflikte und führen Sie dann \"git rebase --continue\" "
 "aus)"
 
-#: wt-status.c:903
+#: wt-status.c:948
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (benutzen Sie \"git rebase --skip\" um diesen Patch auszulassen)"
 
-#: wt-status.c:905
+#: wt-status.c:950
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr ""
 "  (benutzen Sie \"git rebase --abort\" um den ursprünglichen Branch "
 "auszuchecken)"
 
-#: wt-status.c:918
+#: wt-status.c:963
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (alle Konflikte behoben: führen Sie \"git rebase --continue\" aus)"
 
-#: wt-status.c:922
+#: wt-status.c:967
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
@@ -1512,128 +1674,129 @@
 "Sie teilen gerade einen Commit auf, während ein Rebase von Branch '%s' auf "
 "'%s' im Gange ist."
 
-#: wt-status.c:927
+#: wt-status.c:972
 msgid "You are currently splitting a commit during a rebase."
 msgstr "Sie teilen gerade einen Commit während eines Rebase auf."
 
-#: wt-status.c:930
+#: wt-status.c:975
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
 "  (Sobald Ihr Arbeitsverzeichnis unverändert ist, führen Sie \"git rebase --"
 "continue\" aus)"
 
-#: wt-status.c:934
+#: wt-status.c:979
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 "Sie editieren gerade einen Commit während eines Rebase von Branch '%s' auf "
 "'%s'."
 
-#: wt-status.c:939
+#: wt-status.c:984
 msgid "You are currently editing a commit during a rebase."
 msgstr "Sie editieren gerade einen Commit während eines Rebase."
 
-#: wt-status.c:942
+#: wt-status.c:987
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 "  (benutzen Sie \"git commit --amend\" um den aktuellen Commit nachzubessern)"
 
-#: wt-status.c:944
+#: wt-status.c:989
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 "  (benutzen Sie \"git rebase --continue\" sobald Ihre Änderungen "
 "abgeschlossen sind)"
 
-#: wt-status.c:954
-msgid "You are currently cherry-picking."
-msgstr "Sie führen gerade \"cherry-pick\" aus."
+#: wt-status.c:999
+#, c-format
+msgid "You are currently cherry-picking commit %s."
+msgstr "Sie führen gerade \"cherry-pick\" von Commit %s aus."
 
-#: wt-status.c:958
+#: wt-status.c:1004
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr ""
 "  (beheben Sie die Konflikte und führen Sie dann \"git cherry-pick --continue"
 "\" aus)"
 
-#: wt-status.c:961
+#: wt-status.c:1007
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 "  (alle Konflikte behoben: führen Sie \"git cherry-pick --continue\" aus)"
 
-#: wt-status.c:963
+#: wt-status.c:1009
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
 "  (benutzen Sie \"git cherry-pick --abort\" um die Cherry-Pick-Operation "
 "abzubrechen)"
 
-#: wt-status.c:972
+#: wt-status.c:1018
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "Sie sind gerade an einem Revert von Commit '%s'."
 
-#: wt-status.c:977
+#: wt-status.c:1023
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr ""
 "  (beheben Sie die Konflikte und führen Sie dann \"git revert --continue\" "
 "aus)"
 
-#: wt-status.c:980
+#: wt-status.c:1026
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (alle Konflikte behoben: führen Sie \"git revert --continue\" aus)"
 
-#: wt-status.c:982
+#: wt-status.c:1028
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr ""
 "  (benutzen Sie \"git revert --abort\" um die Revert-Operation abzubrechen)"
 
-#: wt-status.c:993
+#: wt-status.c:1039
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "Sie sind gerade bei einer binären Suche, gestartet von Branch '%s'."
 
-#: wt-status.c:997
+#: wt-status.c:1043
 msgid "You are currently bisecting."
 msgstr "Sie sind gerade bei einer binären Suche."
 
-#: wt-status.c:1000
+#: wt-status.c:1046
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
 "  (benutzen Sie \"git bisect reset\" um zum ursprünglichen Branch "
 "zurückzukehren)"
 
-#: wt-status.c:1173
+#: wt-status.c:1221
 msgid "On branch "
 msgstr "Auf Branch "
 
-#: wt-status.c:1180
+#: wt-status.c:1228
 msgid "rebase in progress; onto "
 msgstr "Rebase im Gange; auf "
 
-#: wt-status.c:1187
+#: wt-status.c:1235
 msgid "HEAD detached at "
 msgstr "HEAD losgelöst bei "
 
-#: wt-status.c:1189
+#: wt-status.c:1237
 msgid "HEAD detached from "
 msgstr "HEAD losgelöst von "
 
-#: wt-status.c:1192
+#: wt-status.c:1240
 msgid "Not currently on any branch."
 msgstr "Im Moment auf keinem Branch."
 
-#: wt-status.c:1209
+#: wt-status.c:1257
 msgid "Initial commit"
 msgstr "Initialer Commit"
 
-#: wt-status.c:1223
+#: wt-status.c:1271
 msgid "Untracked files"
 msgstr "Unbeobachtete Dateien"
 
-#: wt-status.c:1225
+#: wt-status.c:1273
 msgid "Ignored files"
 msgstr "Ignorierte Dateien"
 
-#: wt-status.c:1229
+#: wt-status.c:1277
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -1644,32 +1807,32 @@
 "'status -uno' könnte das beschleunigen, aber Sie müssen darauf achten,\n"
 "neue Dateien selbstständig hinzuzufügen (siehe 'git help status')."
 
-#: wt-status.c:1235
+#: wt-status.c:1283
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Unbeobachtete Dateien nicht aufgelistet%s"
 
-#: wt-status.c:1237
+#: wt-status.c:1285
 msgid " (use -u option to show untracked files)"
 msgstr " (benutzen Sie die Option -u um unbeobachteten Dateien anzuzeigen)"
 
-#: wt-status.c:1243
+#: wt-status.c:1291
 msgid "No changes"
 msgstr "Keine Änderungen"
 
-#: wt-status.c:1248
+#: wt-status.c:1296
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 "keine Änderungen zum Commit vorgemerkt (benutzen Sie \"git add\" und/oder "
 "\"git commit -a\")\n"
 
-#: wt-status.c:1251
+#: wt-status.c:1299
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "keine Änderungen zum Commit vorgemerkt\n"
 
-#: wt-status.c:1254
+#: wt-status.c:1302
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -1678,56 +1841,60 @@
 "nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien (benutzen "
 "Sie \"git add\" zum Beobachten)\n"
 
-#: wt-status.c:1257
+#: wt-status.c:1305
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr "nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien\n"
 
-#: wt-status.c:1260
+#: wt-status.c:1308
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 "nichts zu committen (Erstellen/Kopieren Sie Dateien und benutzen Sie \"git "
 "add\" zum Beobachten)\n"
 
-#: wt-status.c:1263 wt-status.c:1268
+#: wt-status.c:1311 wt-status.c:1316
 #, c-format
 msgid "nothing to commit\n"
 msgstr "nichts zu committen\n"
 
-#: wt-status.c:1266
+#: wt-status.c:1314
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
 "nichts zu committen (benutzen Sie die Option -u, um unbeobachtete Dateien "
 "anzuzeigen)\n"
 
-#: wt-status.c:1270
+#: wt-status.c:1318
 #, c-format
 msgid "nothing to commit, working directory clean\n"
 msgstr "nichts zu committen, Arbeitsverzeichnis unverändert\n"
 
-#: wt-status.c:1378
+#: wt-status.c:1427
 msgid "HEAD (no branch)"
 msgstr "HEAD (kein Branch)"
 
-#: wt-status.c:1384
+#: wt-status.c:1433
 msgid "Initial commit on "
 msgstr "Initialer Commit auf "
 
-#: wt-status.c:1399
+#: wt-status.c:1463
+msgid "gone"
+msgstr "entfernt"
+
+#: wt-status.c:1465
 msgid "behind "
 msgstr "hinterher "
 
-#: wt-status.c:1402 wt-status.c:1405
+#: wt-status.c:1468 wt-status.c:1471
 msgid "ahead "
 msgstr "voraus "
 
-#: wt-status.c:1407
+#: wt-status.c:1473
 msgid ", behind "
 msgstr ", hinterher "
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:351
+#: compat/precompose_utf8.c:55 builtin/clone.c:350
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "Konnte '%s' nicht entfernen."
@@ -1813,7 +1980,7 @@
 msgid "unexpected diff status %c"
 msgstr "unerwarteter Differenz-Status %c"
 
-#: builtin/add.c:149 builtin/commit.c:252
+#: builtin/add.c:149 builtin/commit.c:260
 msgid "updating files failed"
 msgstr "Aktualisierung der Dateien fehlgeschlagen"
 
@@ -1822,147 +1989,142 @@
 msgid "remove '%s'\n"
 msgstr "lösche '%s'\n"
 
-#: builtin/add.c:253
+#: builtin/add.c:237
 msgid "Unstaged changes after refreshing the index:"
 msgstr ""
 "Nicht zum Commit vorgemerkte Änderungen nach Aktualisierung der Staging-Area:"
 
-#: builtin/add.c:256 builtin/add.c:573 builtin/rm.c:337
-#, c-format
-msgid "pathspec '%s' did not match any files"
-msgstr "Pfadspezifikation '%s' stimmt mit keinen Dateien überein"
-
-#: builtin/add.c:339
+#: builtin/add.c:299
 msgid "Could not read the index"
 msgstr "Konnte die Staging-Area nicht lesen"
 
-#: builtin/add.c:350
+#: builtin/add.c:310
 #, c-format
 msgid "Could not open '%s' for writing."
 msgstr "Konnte '%s' nicht zum Schreiben öffnen."
 
-#: builtin/add.c:354
+#: builtin/add.c:314
 msgid "Could not write patch"
 msgstr "Konnte Patch nicht schreiben"
 
-#: builtin/add.c:359
+#: builtin/add.c:319
 #, c-format
 msgid "Could not stat '%s'"
 msgstr "Konnte Verzeichnis '%s' nicht lesen"
 
-#: builtin/add.c:361
+#: builtin/add.c:321
 msgid "Empty patch. Aborted."
 msgstr "Leerer Patch. Abgebrochen."
 
-#: builtin/add.c:367
+#: builtin/add.c:327
 #, c-format
 msgid "Could not apply '%s'"
 msgstr "Konnte '%s' nicht anwenden."
 
-#: builtin/add.c:377
+#: builtin/add.c:337
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
 "Die folgenden Pfade werden durch eine Ihrer \".gitignore\" Dateien "
 "ignoriert:\n"
 
-#: builtin/add.c:394 builtin/clean.c:875 builtin/fetch.c:78 builtin/mv.c:63
-#: builtin/prune-packed.c:73 builtin/push.c:451 builtin/remote.c:1253
-#: builtin/rm.c:268
+#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:92 builtin/mv.c:66
+#: builtin/prune-packed.c:73 builtin/push.c:459 builtin/remote.c:1253
+#: builtin/rm.c:269
 msgid "dry run"
 msgstr "Probelauf"
 
-#: builtin/add.c:395 builtin/apply.c:4410 builtin/check-ignore.c:19
-#: builtin/commit.c:1220 builtin/count-objects.c:95 builtin/fsck.c:613
-#: builtin/log.c:1573 builtin/mv.c:62 builtin/read-tree.c:113
+#: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19
+#: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612
+#: builtin/log.c:1592 builtin/mv.c:65 builtin/read-tree.c:113
 msgid "be verbose"
 msgstr "erweiterte Ausgaben"
 
-#: builtin/add.c:397
+#: builtin/add.c:357
 msgid "interactive picking"
 msgstr "interaktives Auswählen"
 
-#: builtin/add.c:398 builtin/checkout.c:1073 builtin/reset.c:261
+#: builtin/add.c:358 builtin/checkout.c:1109 builtin/reset.c:272
 msgid "select hunks interactively"
 msgstr "Blöcke interaktiv auswählen"
 
-#: builtin/add.c:399
+#: builtin/add.c:359
 msgid "edit current diff and apply"
 msgstr "aktuelle Unterschiede editieren und anwenden"
 
-#: builtin/add.c:400
+#: builtin/add.c:360
 msgid "allow adding otherwise ignored files"
 msgstr "erlaubt das Hinzufügen andernfalls ignorierter Dateien"
 
-#: builtin/add.c:401
+#: builtin/add.c:361
 msgid "update tracked files"
 msgstr "aktualisiert beobachtete Dateien"
 
-#: builtin/add.c:402
+#: builtin/add.c:362
 msgid "record only the fact that the path will be added later"
 msgstr "speichert nur, dass der Pfad später hinzugefügt werden soll"
 
-#: builtin/add.c:403
+#: builtin/add.c:363
 msgid "add changes from all tracked and untracked files"
 msgstr ""
 "fügt Änderungen von allen beobachteten und unbeobachteten Dateien hinzu"
 
 #. takes no arguments
-#: builtin/add.c:406
+#: builtin/add.c:366
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr "ignoriert gelöschte Pfade im Arbeitsverzeichnis (genau wie --no-all)"
 
-#: builtin/add.c:408
+#: builtin/add.c:368
 msgid "don't add, only refresh the index"
 msgstr "fügt nichts hinzu, aktualisiert nur die Staging-Area"
 
-#: builtin/add.c:409
+#: builtin/add.c:369
 msgid "just skip files which cannot be added because of errors"
 msgstr ""
 "überspringt Dateien, die aufgrund von Fehlern nicht hinzugefügt werden "
 "konnten"
 
-#: builtin/add.c:410
+#: builtin/add.c:370
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "prüft ob - auch fehlende - Dateien im Probelauf ignoriert werden"
 
-#: builtin/add.c:432
+#: builtin/add.c:392
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Verwenden Sie -f wenn Sie diese wirklich hinzufügen möchten.\n"
 
-#: builtin/add.c:433
+#: builtin/add.c:393
 msgid "no files added"
 msgstr "keine Dateien hinzugefügt"
 
-#: builtin/add.c:439
+#: builtin/add.c:399
 msgid "adding files failed"
 msgstr "Hinzufügen von Dateien fehlgeschlagen"
 
-#: builtin/add.c:478
+#: builtin/add.c:438
 msgid "-A and -u are mutually incompatible"
 msgstr "Die Optionen -A und -u sind zueinander inkompatibel."
 
-#: builtin/add.c:496
+#: builtin/add.c:456
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr ""
 "Die Option --ignore-missing kann nur zusammen mit --dry-run verwendet werden."
 
-#: builtin/add.c:526
+#: builtin/add.c:486
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Nichts spezifiziert, nichts hinzugefügt.\n"
 
-#: builtin/add.c:527
+#: builtin/add.c:487
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Wollten Sie vielleicht 'git add .' sagen?\n"
 
-#: builtin/add.c:533 builtin/check-ignore.c:161 builtin/clean.c:919
-#: builtin/commit.c:312 builtin/mv.c:82 builtin/rm.c:297
+#: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919
+#: builtin/commit.c:320 builtin/mv.c:86 builtin/reset.c:224 builtin/rm.c:299
 msgid "index file corrupt"
 msgstr "Staging-Area-Datei beschädigt"
 
-#: builtin/add.c:605 builtin/apply.c:4506 builtin/mv.c:229 builtin/rm.c:432
+#: builtin/add.c:589 builtin/apply.c:4506 builtin/mv.c:259 builtin/rm.c:432
 msgid "Unable to write new index file"
 msgstr "Konnte neue Staging-Area-Datei nicht schreiben."
 
@@ -2220,7 +2382,7 @@
 msgid "Checking patch %s..."
 msgstr "Prüfe Patch %s..."
 
-#: builtin/apply.c:3680 builtin/checkout.c:216 builtin/reset.c:127
+#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:127
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen"
@@ -2300,8 +2462,8 @@
 msgid "unable to read index file"
 msgstr "Konnte Staging-Area-Datei nicht lesen"
 
-#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:91
-#: builtin/fetch.c:63
+#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90
+#: builtin/fetch.c:77
 msgid "path"
 msgstr "Pfad"
 
@@ -2374,7 +2536,7 @@
 "erstellt eine temporäre Staging-Area basierend auf den integrierten Staging-"
 "Area-Informationen"
 
-#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:462
+#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:452
 msgid "paths are separated with NUL character"
 msgstr "Pfade sind getrennt durch NUL Zeichen"
 
@@ -2508,104 +2670,104 @@
 msgid "update BISECT_HEAD instead of checking out the current commit"
 msgstr "aktualisiert BISECT_HEAD, anstatt den aktuellen Commit auszuchecken"
 
-#: builtin/blame.c:26
+#: builtin/blame.c:27
 msgid "git blame [options] [rev-opts] [rev] [--] file"
 msgstr "git blame [Optionen] [rev-opts] [rev] [--] Datei"
 
-#: builtin/blame.c:31
+#: builtin/blame.c:32
 msgid "[rev-opts] are documented in git-rev-list(1)"
 msgstr "[rev-opts] sind dokumentiert in git-rev-list(1)"
 
-#: builtin/blame.c:2276
+#: builtin/blame.c:2248
 msgid "Show blame entries as we find them, incrementally"
 msgstr "Zeigt \"blame\"-Einträge schrittweise, während wir sie generieren"
 
-#: builtin/blame.c:2277
+#: builtin/blame.c:2249
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "Zeigt leere SHA-1 für Grenz-Commits (Standard: aus)"
 
-#: builtin/blame.c:2278
+#: builtin/blame.c:2250
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "Behandelt Ursprungs-Commit nicht als Grenzen (Standard: aus)"
 
-#: builtin/blame.c:2279
+#: builtin/blame.c:2251
 msgid "Show work cost statistics"
 msgstr "Zeigt Statistiken zum Arbeitsaufwand"
 
-#: builtin/blame.c:2280
+#: builtin/blame.c:2252
 msgid "Show output score for blame entries"
 msgstr "Zeigt Ausgabebewertung für \"blame\"-Einträge"
 
-#: builtin/blame.c:2281
+#: builtin/blame.c:2253
 msgid "Show original filename (Default: auto)"
 msgstr "Zeigt ursprünglichen Dateinamen (Standard: auto)"
 
-#: builtin/blame.c:2282
+#: builtin/blame.c:2254
 msgid "Show original linenumber (Default: off)"
 msgstr "Zeigt ursprüngliche Zeilennummer (Standard: aus)"
 
-#: builtin/blame.c:2283
+#: builtin/blame.c:2255
 msgid "Show in a format designed for machine consumption"
 msgstr "Anzeige in einem Format für maschinelle Auswertung"
 
-#: builtin/blame.c:2284
+#: builtin/blame.c:2256
 msgid "Show porcelain format with per-line commit information"
 msgstr ""
 "Anzeige in Format für Fremdprogramme mit Commit-Informationen pro Zeile"
 
-#: builtin/blame.c:2285
+#: builtin/blame.c:2257
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "Benutzt den gleichen Ausgabemodus wie \"git-annotate\" (Standard: aus)"
 
-#: builtin/blame.c:2286
+#: builtin/blame.c:2258
 msgid "Show raw timestamp (Default: off)"
 msgstr "Zeigt unbearbeiteten Zeitstempel (Standard: aus)"
 
-#: builtin/blame.c:2287
+#: builtin/blame.c:2259
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Zeigt langen Commit-SHA1 (Standard: aus)"
 
-#: builtin/blame.c:2288
+#: builtin/blame.c:2260
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Unterdrückt den Namen des Autors und den Zeitstempel (Standard: aus)"
 
-#: builtin/blame.c:2289
+#: builtin/blame.c:2261
 msgid "Show author email instead of name (Default: off)"
 msgstr "Zeigt anstatt des Namens die Email-Adresse des Autors (Standard: aus)"
 
-#: builtin/blame.c:2290
+#: builtin/blame.c:2262
 msgid "Ignore whitespace differences"
 msgstr "Ignoriert Unterschiede im Whitespace"
 
-#: builtin/blame.c:2291
+#: builtin/blame.c:2263
 msgid "Spend extra cycles to find better match"
 msgstr "arbeite länger, um bessere Übereinstimmungen zu finden"
 
-#: builtin/blame.c:2292
+#: builtin/blame.c:2264
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "Benutzt Commits von <Datei> anstatt \"git-rev-list\" aufzurufen"
 
-#: builtin/blame.c:2293
+#: builtin/blame.c:2265
 msgid "Use <file>'s contents as the final image"
 msgstr "Benutzt Inhalte der <Datei>en als entgültiges Abbild"
 
-#: builtin/blame.c:2294 builtin/blame.c:2295
+#: builtin/blame.c:2266 builtin/blame.c:2267
 msgid "score"
 msgstr "Bewertung"
 
-#: builtin/blame.c:2294
+#: builtin/blame.c:2266
 msgid "Find line copies within and across files"
 msgstr "Findet kopierte Zeilen innerhalb oder zwischen Dateien"
 
-#: builtin/blame.c:2295
+#: builtin/blame.c:2267
 msgid "Find line movements within and across files"
 msgstr "Findet verschobene Zeilen innerhalb oder zwischen Dateien"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "Process only line range n,m, counting from 1"
 msgstr "Verarbeitet nur Zeilen im Bereich n,m, gezählt von 1"
 
@@ -2713,240 +2875,250 @@
 
 #: builtin/branch.c:453
 #, c-format
+msgid "[%s: gone]"
+msgstr "[%s: entfernt]"
+
+#: builtin/branch.c:456
+#, c-format
+msgid "[%s]"
+msgstr "[%s]"
+
+#: builtin/branch.c:459
+#, c-format
 msgid "[%s: behind %d]"
 msgstr "[%s: %d hinterher]"
 
-#: builtin/branch.c:455
+#: builtin/branch.c:461
 #, c-format
 msgid "[behind %d]"
 msgstr "[%d hinterher]"
 
-#: builtin/branch.c:459
+#: builtin/branch.c:465
 #, c-format
 msgid "[%s: ahead %d]"
 msgstr "[%s: %d voraus]"
 
-#: builtin/branch.c:461
+#: builtin/branch.c:467
 #, c-format
 msgid "[ahead %d]"
 msgstr "[%d voraus]"
 
-#: builtin/branch.c:464
+#: builtin/branch.c:470
 #, c-format
 msgid "[%s: ahead %d, behind %d]"
 msgstr "[%s: %d voraus, %d hinterher]"
 
-#: builtin/branch.c:467
+#: builtin/branch.c:473
 #, c-format
 msgid "[ahead %d, behind %d]"
 msgstr "[%d voraus, %d hinterher]"
 
-#: builtin/branch.c:490
+#: builtin/branch.c:496
 msgid " **** invalid ref ****"
 msgstr " **** ungültige Referenz ****"
 
-#: builtin/branch.c:582
+#: builtin/branch.c:588
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(kein Branch, Rebase von Branch %s im Gange)"
 
-#: builtin/branch.c:585
+#: builtin/branch.c:591
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(kein Branch, binäre Suche begonnen bei %s)"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:594
 #, c-format
 msgid "(detached from %s)"
 msgstr "(losgelöst von %s)"
 
-#: builtin/branch.c:591
+#: builtin/branch.c:597
 msgid "(no branch)"
 msgstr "(kein Branch)"
 
-#: builtin/branch.c:637
+#: builtin/branch.c:643
 #, c-format
 msgid "object '%s' does not point to a commit"
 msgstr "Objekt '%s' zeigt auf keinen Commit"
 
-#: builtin/branch.c:669
+#: builtin/branch.c:675
 msgid "some refs could not be read"
 msgstr "Konnte einige Referenzen nicht lesen"
 
-#: builtin/branch.c:682
+#: builtin/branch.c:688
 msgid "cannot rename the current branch while not on any."
 msgstr ""
 "Kann aktuellen Branch nicht umbenennen, solange Sie sich auf keinem befinden."
 
-#: builtin/branch.c:692
+#: builtin/branch.c:698
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Ungültiger Branchname: '%s'"
 
-#: builtin/branch.c:707
+#: builtin/branch.c:713
 msgid "Branch rename failed"
 msgstr "Umbenennung des Branches fehlgeschlagen"
 
-#: builtin/branch.c:711
+#: builtin/branch.c:717
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "falsch benannten Branch '%s' umbenannt"
 
-#: builtin/branch.c:715
+#: builtin/branch.c:721
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "Branch umbenannt zu %s, aber HEAD ist nicht aktualisiert!"
 
-#: builtin/branch.c:722
+#: builtin/branch.c:728
 msgid "Branch is renamed, but update of config-file failed"
 msgstr ""
 "Branch ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist "
 "fehlgeschlagen."
 
-#: builtin/branch.c:737
+#: builtin/branch.c:743
 #, c-format
 msgid "malformed object name %s"
 msgstr "Missgebildeter Objektname %s"
 
-#: builtin/branch.c:761
+#: builtin/branch.c:767
 #, c-format
 msgid "could not write branch description template: %s"
 msgstr "Konnte Beschreibungsvorlage für Branch nicht schreiben: %s"
 
-#: builtin/branch.c:791
+#: builtin/branch.c:797
 msgid "Generic options"
 msgstr "Allgemeine Optionen"
 
-#: builtin/branch.c:793
+#: builtin/branch.c:799
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "Zeigt Hash und Betreff; -vv: zusätzlich Upstream-Branch"
 
-#: builtin/branch.c:794
+#: builtin/branch.c:800
 msgid "suppress informational messages"
 msgstr "unterdrückt Informationsmeldungen"
 
-#: builtin/branch.c:795
+#: builtin/branch.c:801
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "stellt den Übernahmemodus ein (siehe git-pull(1))"
 
-#: builtin/branch.c:797
+#: builtin/branch.c:803
 msgid "change upstream info"
 msgstr "ändert Informationen zum Upstream-Branch"
 
-#: builtin/branch.c:801
+#: builtin/branch.c:807
 msgid "use colored output"
 msgstr "verwendet farbliche Ausgaben"
 
-#: builtin/branch.c:802
+#: builtin/branch.c:808
 msgid "act on remote-tracking branches"
 msgstr "wirkt auf Remote-Tracking-Branches"
 
-#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832
-#: builtin/branch.c:838 builtin/commit.c:1433 builtin/commit.c:1434
-#: builtin/commit.c:1435 builtin/commit.c:1436 builtin/tag.c:468
+#: builtin/branch.c:811 builtin/branch.c:817 builtin/branch.c:838
+#: builtin/branch.c:844 builtin/commit.c:1460 builtin/commit.c:1461
+#: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468
 msgid "commit"
 msgstr "Commit"
 
-#: builtin/branch.c:806 builtin/branch.c:812
+#: builtin/branch.c:812 builtin/branch.c:818
 msgid "print only branches that contain the commit"
 msgstr "gibt nur Branches aus, welche diesen Commit beinhalten"
 
-#: builtin/branch.c:818
+#: builtin/branch.c:824
 msgid "Specific git-branch actions:"
 msgstr "spezifische Aktionen für \"git-branch\":"
 
-#: builtin/branch.c:819
+#: builtin/branch.c:825
 msgid "list both remote-tracking and local branches"
 msgstr "listet Remote-Tracking und lokale Branches auf"
 
-#: builtin/branch.c:821
+#: builtin/branch.c:827
 msgid "delete fully merged branch"
 msgstr "entfernt vollständig zusammengeführten Branch"
 
-#: builtin/branch.c:822
+#: builtin/branch.c:828
 msgid "delete branch (even if not merged)"
 msgstr "löscht Branch (auch wenn nicht zusammengeführt)"
 
-#: builtin/branch.c:823
+#: builtin/branch.c:829
 msgid "move/rename a branch and its reflog"
 msgstr "verschiebt/benennt einen Branch und dessen Reflog um"
 
-#: builtin/branch.c:824
+#: builtin/branch.c:830
 msgid "move/rename a branch, even if target exists"
 msgstr ""
 "verschiebt/benennt einen Branch um, auch wenn das Ziel bereits existiert"
 
-#: builtin/branch.c:825
+#: builtin/branch.c:831
 msgid "list branch names"
 msgstr "listet Branchnamen auf"
 
-#: builtin/branch.c:826
+#: builtin/branch.c:832
 msgid "create the branch's reflog"
 msgstr "erzeugt das Reflog des Branches"
 
-#: builtin/branch.c:828
+#: builtin/branch.c:834
 msgid "edit the description for the branch"
 msgstr "bearbeitet die Beschreibung für den Branch"
 
-#: builtin/branch.c:829
+#: builtin/branch.c:835
 msgid "force creation (when already exists)"
 msgstr "erzeuge auch, wenn der Branch bereits existiert"
 
-#: builtin/branch.c:832
+#: builtin/branch.c:838
 msgid "print only not merged branches"
 msgstr "gibt nur Branches aus, die nicht zusammengeführt sind"
 
-#: builtin/branch.c:838
+#: builtin/branch.c:844
 msgid "print only merged branches"
 msgstr "gibt nur Branches aus, die zusammengeführt sind"
 
-#: builtin/branch.c:842
+#: builtin/branch.c:848
 msgid "list branches in columns"
 msgstr "listet Branches in Spalten auf"
 
-#: builtin/branch.c:855
+#: builtin/branch.c:861
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Konnte HEAD nicht als gültige Referenz auflösen."
 
-#: builtin/branch.c:860 builtin/clone.c:630
+#: builtin/branch.c:866 builtin/clone.c:629
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD wurde nicht unter \"refs/heads\" gefunden!"
 
-#: builtin/branch.c:883
+#: builtin/branch.c:890
 msgid "--column and --verbose are incompatible"
 msgstr "Die Optionen --column und --verbose sind inkompatibel."
 
-#: builtin/branch.c:889 builtin/branch.c:928
+#: builtin/branch.c:896 builtin/branch.c:935
 msgid "branch name required"
 msgstr "Branchname erforderlich"
 
-#: builtin/branch.c:904
+#: builtin/branch.c:911
 msgid "Cannot give description to detached HEAD"
 msgstr "zu losgelöstem HEAD kann keine Beschreibung hinterlegt werden"
 
-#: builtin/branch.c:909
+#: builtin/branch.c:916
 msgid "cannot edit description of more than one branch"
 msgstr "Beschreibung von mehr als einem Branch kann nicht bearbeitet werden"
 
-#: builtin/branch.c:916
+#: builtin/branch.c:923
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Noch kein Commit in Branch '%s'."
 
-#: builtin/branch.c:919
+#: builtin/branch.c:926
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Branch '%s' nicht vorhanden."
 
-#: builtin/branch.c:934
+#: builtin/branch.c:941
 msgid "too many branches for a rename operation"
 msgstr "zu viele Branches für eine Umbenennen-Operation angegeben"
 
-#: builtin/branch.c:939
+#: builtin/branch.c:946
 msgid "too many branches to set new upstream"
 msgstr "zu viele Branches angegeben um Upstream-Branch zu setzen"
 
-#: builtin/branch.c:943
+#: builtin/branch.c:950
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
@@ -2954,43 +3126,43 @@
 "Konnte keinen neuen Upstream-Branch von HEAD zu %s setzen, da dieser auf\n"
 "keinen Branch zeigt."
 
-#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990
+#: builtin/branch.c:953 builtin/branch.c:975 builtin/branch.c:997
 #, c-format
 msgid "no such branch '%s'"
 msgstr "Kein solcher Branch '%s'"
 
-#: builtin/branch.c:950
+#: builtin/branch.c:957
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "Branch '%s' existiert nicht"
 
-#: builtin/branch.c:962
+#: builtin/branch.c:969
 msgid "too many branches to unset upstream"
 msgstr ""
 "zu viele Branches angegeben um Konfiguration zu Upstream-Branch zu entfernen"
 
-#: builtin/branch.c:966
+#: builtin/branch.c:973
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "Konnte Konfiguration zu Upstream-Branch von HEAD nicht entfernen, da dieser\n"
 "auf keinen Branch zeigt."
 
-#: builtin/branch.c:972
+#: builtin/branch.c:979
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "Branch '%s' hat keinen Upstream-Branch gesetzt"
 
-#: builtin/branch.c:987
+#: builtin/branch.c:994
 msgid "it does not make sense to create 'HEAD' manually"
 msgstr "'HEAD' darf nicht manuell erstellt werden"
 
-#: builtin/branch.c:993
+#: builtin/branch.c:1000
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "Die Optionen -a und -r bei 'git branch' können nicht gemeimsam mit einem "
 "Branchnamen verwendet werden."
 
-#: builtin/branch.c:996
+#: builtin/branch.c:1003
 #, c-format
 msgid ""
 "The --set-upstream flag is deprecated and will be removed. Consider using --"
@@ -2999,7 +3171,7 @@
 "Die --set-upstream Option ist veraltet und wird entfernt. Benutzen Sie --"
 "track oder --set-upstream-to\n"
 
-#: builtin/branch.c:1013
+#: builtin/branch.c:1020
 #, c-format
 msgid ""
 "\n"
@@ -3010,12 +3182,12 @@
 "Wenn Sie wollten, dass '%s' den Branch '%s' als Upstream-Branch hat, führen "
 "Sie aus:\n"
 
-#: builtin/branch.c:1014
+#: builtin/branch.c:1021
 #, c-format
 msgid "    git branch -d %s\n"
 msgstr "    git branch -d %s\n"
 
-#: builtin/branch.c:1015
+#: builtin/branch.c:1022
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
 msgstr "    git branch --set-upstream-to %s\n"
@@ -3033,45 +3205,45 @@
 msgid "Need a repository to unbundle."
 msgstr "Zum Entpacken wird ein Repository benötigt."
 
-#: builtin/cat-file.c:285
+#: builtin/cat-file.c:312
 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"
 msgstr "git cat-file (-t|-s|-e|-p|<Art>|--textconv) <Objekt>"
 
-#: builtin/cat-file.c:286
+#: builtin/cat-file.c:313
 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>"
 msgstr "git cat-file (--batch|--batch-check) < <Liste_von_Objekten>"
 
-#: builtin/cat-file.c:323
+#: builtin/cat-file.c:350
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<Art> kann sein: blob, tree, commit, tag"
 
-#: builtin/cat-file.c:324
+#: builtin/cat-file.c:351
 msgid "show object type"
 msgstr "zeigt Objektart"
 
-#: builtin/cat-file.c:325
+#: builtin/cat-file.c:352
 msgid "show object size"
 msgstr "zeigt Objektgröße"
 
-#: builtin/cat-file.c:327
+#: builtin/cat-file.c:354
 msgid "exit with zero when there's no error"
 msgstr "beendet mit Rückgabewert 0, wenn kein Fehler aufgetreten ist"
 
-#: builtin/cat-file.c:328
+#: builtin/cat-file.c:355
 msgid "pretty-print object's content"
 msgstr "ansprechende Anzeige des Objektinhaltes"
 
-#: builtin/cat-file.c:330
+#: builtin/cat-file.c:357
 msgid "for blob objects, run textconv on object's content"
 msgstr "führt eine Textkonvertierung auf den Inhalt von Blob-Objekten aus"
 
-#: builtin/cat-file.c:332
+#: builtin/cat-file.c:359
 msgid "show info and content of objects fed from the standard input"
 msgstr ""
 "Anzeige von Informationen und Inhalt von Objekten, gelesen von der Standard-"
 "Eingabe"
 
-#: builtin/cat-file.c:335
+#: builtin/cat-file.c:362
 msgid "show info about objects fed from the standard input"
 msgstr ""
 "Anzeige von Informationen über Objekte, gelesen von der Standard-Eingabe"
@@ -3098,10 +3270,10 @@
 msgstr "liest Dateinamen von der Standard-Eingabe"
 
 #: builtin/check-attr.c:23 builtin/check-ignore.c:24
-msgid "input paths are terminated by a null character"
-msgstr "Eingabepfade sind durch ein NUL Zeichen abgeschlossen"
+msgid "terminate input and output records by a NUL character"
+msgstr "schließt Einträge von Ein- und Ausgabe mit NUL-Zeichen ab"
 
-#: builtin/check-ignore.c:18 builtin/checkout.c:1054 builtin/gc.c:177
+#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:259
 msgid "suppress progress reporting"
 msgstr "unterdrückt Fortschrittsanzeige"
 
@@ -3109,28 +3281,32 @@
 msgid "show non-matching input paths"
 msgstr "zeigt Eingabe-Pfade ohne Übereinstimmungen"
 
-#: builtin/check-ignore.c:143
+#: builtin/check-ignore.c:28
+msgid "ignore index when checking"
+msgstr "ignoriert Staging-Area bei der Prüfung"
+
+#: builtin/check-ignore.c:154
 msgid "cannot specify pathnames with --stdin"
 msgstr "Angabe von Pfadnamen kann nicht gemeinsam mit --stdin verwendet werden"
 
-#: builtin/check-ignore.c:146
+#: builtin/check-ignore.c:157
 msgid "-z only makes sense with --stdin"
 msgstr "Die Option -z kann nur mit --stdin verwendet werden."
 
-#: builtin/check-ignore.c:148
+#: builtin/check-ignore.c:159
 msgid "no path specified"
 msgstr "kein Pfad angegeben"
 
-#: builtin/check-ignore.c:152
+#: builtin/check-ignore.c:163
 msgid "--quiet is only valid with a single pathname"
 msgstr "Die Option --quiet ist nur mit einem einzelnen Pfadnamen gültig."
 
-#: builtin/check-ignore.c:154
+#: builtin/check-ignore.c:165
 msgid "cannot have both --quiet and --verbose"
 msgstr ""
 "Die Optionen --quiet und --verbose können nicht gemeinsam verwendet werden."
 
-#: builtin/check-ignore.c:157
+#: builtin/check-ignore.c:168
 msgid "--non-matching is only valid with --verbose"
 msgstr "--non-matching ist nur mit --verbose zulässig"
 
@@ -3206,107 +3382,107 @@
 msgid "git checkout [options] [<branch>] -- <file>..."
 msgstr "git checkout [Optionen] [<Branch>] -- <Datei>..."
 
-#: builtin/checkout.c:117 builtin/checkout.c:150
+#: 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:119 builtin/checkout.c:152
+#: 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:135
+#: 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:179
+#: 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:196
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "Pfad '%s': kann nicht zusammenführen"
 
-#: builtin/checkout.c:213
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr "Konnte Merge-Ergebnis von '%s' nicht hinzufügen."
 
-#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243
-#: builtin/checkout.c:246
+#: builtin/checkout.c:232 builtin/checkout.c:235 builtin/checkout.c:238
+#: builtin/checkout.c:241
 #, c-format
 msgid "'%s' cannot be used with updating paths"
 msgstr "'%s' kann nicht mit Pfaden verwendet werden"
 
-#: builtin/checkout.c:249 builtin/checkout.c:252
+#: builtin/checkout.c:244 builtin/checkout.c:247
 #, c-format
 msgid "'%s' cannot be used with %s"
 msgstr "'%s' kann nicht mit '%s' verwendet werden"
 
-#: builtin/checkout.c:255
+#: builtin/checkout.c:250
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
 msgstr ""
 "Kann nicht gleichzeitig Pfade aktualisieren und zu Branch '%s' wechseln"
 
-#: builtin/checkout.c:266 builtin/checkout.c:458
+#: builtin/checkout.c:261 builtin/checkout.c:451
 msgid "corrupt index file"
 msgstr "beschädigte Staging-Area-Datei"
 
-#: builtin/checkout.c:329 builtin/checkout.c:336
+#: builtin/checkout.c:322 builtin/checkout.c:329
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "Pfad '%s' ist nicht zusammengeführt."
 
-#: builtin/checkout.c:480
+#: builtin/checkout.c:473
 msgid "you need to resolve your current index first"
 msgstr "Sie müssen zuerst Ihre aktuelle Staging-Area auflösen."
 
-#: builtin/checkout.c:601
+#: builtin/checkout.c:594
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "Konnte \"reflog\" für '%s' nicht durchführen\n"
 
-#: builtin/checkout.c:639
+#: builtin/checkout.c:632
 msgid "HEAD is now at"
 msgstr "HEAD ist jetzt bei"
 
-#: builtin/checkout.c:646
+#: builtin/checkout.c:639
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Setze Branch '%s' neu\n"
 
-#: builtin/checkout.c:649
+#: builtin/checkout.c:642
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Bereits auf '%s'\n"
 
-#: builtin/checkout.c:653
+#: builtin/checkout.c:646
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Gewechselt zu umgesetzten Branch '%s'\n"
 
-#: builtin/checkout.c:655 builtin/checkout.c:997
+#: builtin/checkout.c:648 builtin/checkout.c:1033
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Gewechselt zu einem neuem Branch '%s'\n"
 
-#: builtin/checkout.c:657
+#: builtin/checkout.c:650
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Gewechselt zu Branch '%s'\n"
 
-#: builtin/checkout.c:713
+#: builtin/checkout.c:706
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... und %d weitere.\n"
 
 #. The singular version
-#: builtin/checkout.c:719
+#: builtin/checkout.c:712
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -3329,7 +3505,7 @@
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:737
+#: builtin/checkout.c:730
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -3344,136 +3520,140 @@
 " git branch neuer_branch_name %s\n"
 "\n"
 
-#: builtin/checkout.c:767
+#: builtin/checkout.c:760
 msgid "internal error in revision walk"
 msgstr "interner Fehler im Revisionsgang"
 
-#: builtin/checkout.c:771
+#: builtin/checkout.c:764
 msgid "Previous HEAD position was"
 msgstr "Vorherige Position von HEAD war"
 
-#: builtin/checkout.c:798 builtin/checkout.c:992
+#: builtin/checkout.c:791 builtin/checkout.c:1028
 msgid "You are on a branch yet to be born"
 msgstr "Sie sind auf einem Branch, der noch geboren wird"
 
-#. case (1)
-#: builtin/checkout.c:928
+#: builtin/checkout.c:935
+#, c-format
+msgid "only one reference expected, %d given."
+msgstr "nur eine Referenz erwartet, %d gegeben."
+
+#: builtin/checkout.c:974
 #, c-format
 msgid "invalid reference: %s"
 msgstr "Ungültige Referenz: %s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:967
+#: builtin/checkout.c:1003
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "Referenz ist kein \"Tree\"-Objekt: %s"
 
-#: builtin/checkout.c:1006
+#: builtin/checkout.c:1042
 msgid "paths cannot be used with switching branches"
 msgstr "Pfade können nicht beim Wechseln von Branches verwendet werden"
 
-#: builtin/checkout.c:1009 builtin/checkout.c:1013
+#: builtin/checkout.c:1045 builtin/checkout.c:1049
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "'%s' kann nicht beim Wechseln von Branches verwendet werden"
 
-#: builtin/checkout.c:1017 builtin/checkout.c:1020 builtin/checkout.c:1025
-#: builtin/checkout.c:1028
+#: builtin/checkout.c:1053 builtin/checkout.c:1056 builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "'%s' kann nicht mit '%s' verwendet werden"
 
-#: builtin/checkout.c:1033
+#: builtin/checkout.c:1069
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "Kann Branch nicht zu Nicht-Commit '%s' wechseln"
 
-#: builtin/checkout.c:1055 builtin/checkout.c:1057 builtin/clone.c:89
+#: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88
 #: builtin/remote.c:169 builtin/remote.c:171
 msgid "branch"
 msgstr "Branch"
 
-#: builtin/checkout.c:1056
+#: builtin/checkout.c:1092
 msgid "create and checkout a new branch"
 msgstr "erzeugt und checkt einen neuen Branch aus"
 
-#: builtin/checkout.c:1058
+#: builtin/checkout.c:1094
 msgid "create/reset and checkout a branch"
 msgstr "erzeugt/setzt um und checkt einen Branch aus"
 
-#: builtin/checkout.c:1059
+#: builtin/checkout.c:1095
 msgid "create reflog for new branch"
 msgstr "erzeugt das Reflog für den neuen Branch"
 
-#: builtin/checkout.c:1060
+#: builtin/checkout.c:1096
 msgid "detach the HEAD at named commit"
 msgstr "setzt HEAD zu benanntem Commit"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1097
 msgid "set upstream info for new branch"
 msgstr "setzt Informationen zum Upstream-Branch für den neuen Branch"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new branch"
 msgstr "neuer Branch"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new unparented branch"
 msgstr "neuer Branch ohne Eltern-Commit"
 
-#: builtin/checkout.c:1064
+#: builtin/checkout.c:1100
 msgid "checkout our version for unmerged files"
 msgstr "checkt unsere Variante für nicht zusammengeführte Dateien aus"
 
-#: builtin/checkout.c:1066
+#: builtin/checkout.c:1102
 msgid "checkout their version for unmerged files"
 msgstr "checkt ihre Variante für nicht zusammengeführte Dateien aus"
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1104
 msgid "force checkout (throw away local modifications)"
 msgstr "erzwingt Auschecken (verwirft lokale Änderungen)"
 
-#: builtin/checkout.c:1069
+#: builtin/checkout.c:1105
 msgid "perform a 3-way merge with the new branch"
 msgstr "führt einen 3-Wege-Merge mit dem neuen Branch aus"
 
-#: builtin/checkout.c:1070 builtin/merge.c:232
+#: builtin/checkout.c:1106 builtin/merge.c:232
 msgid "update ignored files (default)"
 msgstr "aktualisiert ignorierte Dateien (Standard)"
 
-#: builtin/checkout.c:1071 builtin/log.c:1208 parse-options.h:249
+#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:251
 msgid "style"
 msgstr "Stil"
 
-#: builtin/checkout.c:1072
+#: builtin/checkout.c:1108
 msgid "conflict style (merge or diff3)"
 msgstr "Konfliktstil (merge oder diff3)"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1111
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "Pfadspezifikationen ignorieren Einstellungen zum partiellen Auschecken"
 
-#: builtin/checkout.c:1077
+#: builtin/checkout.c:1113
 msgid "second guess 'git checkout no-such-branch'"
 msgstr "second guess 'git checkout no-such-branch'"
 
-#: builtin/checkout.c:1101
+#: builtin/checkout.c:1136
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "Die Optionen -b, -B und --orphan schließen sich gegenseitig aus."
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1153
 msgid "--track needs a branch name"
 msgstr "Bei der Option --track muss ein Branchname angegeben werden."
 
-#: builtin/checkout.c:1125
+#: builtin/checkout.c:1160
 msgid "Missing branch name; try -b"
 msgstr "Vermisse Branchnamen; versuchen Sie -b"
 
-#: builtin/checkout.c:1160
+#: builtin/checkout.c:1197
 msgid "invalid path specification"
 msgstr "ungültige Pfadspezifikation"
 
-#: builtin/checkout.c:1167
+#: builtin/checkout.c:1204
 #, c-format
 msgid ""
 "Cannot update paths and switch to branch '%s' at the same time.\n"
@@ -3483,12 +3663,12 @@
 "Haben Sie beabsichtigt '%s' auszuchecken, welcher nicht als Commit aufgelöst "
 "werden kann?"
 
-#: builtin/checkout.c:1172
+#: builtin/checkout.c:1209
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach nimmt kein Pfad-Argument '%s'"
 
-#: builtin/checkout.c:1176
+#: builtin/checkout.c:1213
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -3496,38 +3676,38 @@
 "git checkout: --ours/--theirs, --force und --merge sind inkompatibel wenn\n"
 "Sie aus der Staging-Area auschecken."
 
-#: builtin/clean.c:25
+#: builtin/clean.c:26
 msgid ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
 msgstr ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <Muster>] [-x | -X] [--] <Pfade>..."
 
-#: builtin/clean.c:29
+#: builtin/clean.c:30
 #, c-format
 msgid "Removing %s\n"
 msgstr "Lösche %s\n"
 
-#: builtin/clean.c:30
+#: builtin/clean.c:31
 #, c-format
 msgid "Would remove %s\n"
 msgstr "Würde %s löschen\n"
 
-#: builtin/clean.c:31
+#: builtin/clean.c:32
 #, c-format
 msgid "Skipping repository %s\n"
 msgstr "Überspringe Repository %s\n"
 
-#: builtin/clean.c:32
+#: builtin/clean.c:33
 #, c-format
 msgid "Would skip repository %s\n"
 msgstr "Würde Repository %s überspringen\n"
 
-#: builtin/clean.c:33
+#: builtin/clean.c:34
 #, c-format
 msgid "failed to remove %s"
 msgstr "Fehler beim Löschen von %s"
 
-#: builtin/clean.c:293
+#: builtin/clean.c:294
 msgid ""
 "Prompt help:\n"
 "1          - select a numbered item\n"
@@ -3536,10 +3716,10 @@
 msgstr ""
 "Eingabehilfe:\n"
 "1          - nummeriertes Element auswählen\n"
-"foo        - Element anhand eines eindeutigen Prefix auswählen\n"
+"foo        - Element anhand eines eindeutigen Präfix auswählen\n"
 "           - (leer) nichts auswählen"
 
-#: builtin/clean.c:297
+#: builtin/clean.c:298
 msgid ""
 "Prompt help:\n"
 "1          - select a single item\n"
@@ -3554,40 +3734,40 @@
 "1          - einzelnes Element auswählen\n"
 "3-5        - Bereich von Elementen auswählen\n"
 "2-3,6-9    - mehrere Bereiche auswählen\n"
-"foo        - Element anhand eines eindeutigen Prefix auswählen\n"
+"foo        - Element anhand eines eindeutigen Präfix auswählen\n"
 "-...       - angegebenes Element abwählen\n"
 "*          - alle Elemente auswählen\n"
 "           - (leer) Auswahl beenden"
 
-#: builtin/clean.c:515
+#: builtin/clean.c:516
 #, c-format
 msgid "Huh (%s)?"
 msgstr "Wie bitte (%s)?"
 
-#: builtin/clean.c:658
+#: builtin/clean.c:659
 #, c-format
 msgid "Input ignore patterns>> "
 msgstr "Ignorier-Muster eingeben>> "
 
-#: builtin/clean.c:695
+#: builtin/clean.c:696
 #, c-format
 msgid "WARNING: Cannot find items matched by: %s"
 msgstr "WARNUNG: Kann keine Einträge finden die Muster entsprechen: %s"
 
-#: builtin/clean.c:716
+#: builtin/clean.c:717
 msgid "Select items to delete"
 msgstr "Wählen Sie Einträge zum Löschen"
 
-#: builtin/clean.c:756
+#: builtin/clean.c:757
 #, c-format
 msgid "remove %s? "
 msgstr "'%s' löschen? "
 
-#: builtin/clean.c:781
+#: builtin/clean.c:782
 msgid "Bye."
 msgstr "Tschüss."
 
-#: builtin/clean.c:789
+#: builtin/clean.c:790
 msgid ""
 "clean               - start cleaning\n"
 "filter by pattern   - exclude items from deletion\n"
@@ -3605,21 +3785,21 @@
 "help                - diese Meldung anzeigen\n"
 "?                   - Hilfe zur Auswahl mittels Eingabe anzeigen"
 
-#: builtin/clean.c:816
+#: builtin/clean.c:817
 msgid "*** Commands ***"
 msgstr "*** Kommandos ***"
 
-#: builtin/clean.c:817
+#: builtin/clean.c:818
 msgid "What now"
 msgstr "Was nun"
 
-#: builtin/clean.c:825
+#: builtin/clean.c:826
 msgid "Would remove the following item:"
 msgid_plural "Would remove the following items:"
 msgstr[0] "Würde das folgende Element entfernen:"
 msgstr[1] "Würde die folgenden Elemente entfernen:"
 
-#: builtin/clean.c:842
+#: builtin/clean.c:843
 msgid "No more files to clean, exiting."
 msgstr "Keine Dateien mehr zum Löschen, beende."
 
@@ -3639,8 +3819,8 @@
 msgid "remove whole directories"
 msgstr "löscht ganze Verzeichnisse"
 
-#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:716
-#: builtin/ls-files.c:493 builtin/name-rev.c:315 builtin/show-ref.c:186
+#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718
+#: builtin/ls-files.c:483 builtin/name-rev.c:315 builtin/show-ref.c:185
 msgid "pattern"
 msgstr "Muster"
 
@@ -3680,8 +3860,8 @@
 msgid "git clone [options] [--] <repo> [<dir>]"
 msgstr "git clone [Optionen] [--] <Repository> [<Verzeichnis>]"
 
-#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:229
-#: builtin/push.c:462
+#: builtin/clone.c:64 builtin/fetch.c:96 builtin/merge.c:229
+#: builtin/push.c:474
 msgid "force progress reporting"
 msgstr "erzwingt Fortschrittsanzeige"
 
@@ -3693,123 +3873,123 @@
 msgid "create a bare repository"
 msgstr "erstellt ein Bare-Repository"
 
-#: builtin/clone.c:72
+#: builtin/clone.c:71
 msgid "create a mirror repository (implies bare)"
 msgstr "erstellt ein Spiegelarchiv (impliziert --bare)"
 
-#: builtin/clone.c:74
+#: builtin/clone.c:73
 msgid "to clone from a local repository"
 msgstr "um von einem lokalen Repository zu klonen"
 
-#: builtin/clone.c:76
+#: builtin/clone.c:75
 msgid "don't use local hardlinks, always copy"
 msgstr "verwendet lokal keine harten Verweise, immer Kopien"
 
-#: builtin/clone.c:78
+#: builtin/clone.c:77
 msgid "setup as shared repository"
 msgstr "Einrichtung als verteiltes Repository"
 
-#: builtin/clone.c:80 builtin/clone.c:82
+#: builtin/clone.c:79 builtin/clone.c:81
 msgid "initialize submodules in the clone"
 msgstr "initialisiert Submodule im Klon"
 
-#: builtin/clone.c:83 builtin/init-db.c:485
+#: builtin/clone.c:82 builtin/init-db.c:485
 msgid "template-directory"
 msgstr "Vorlagenverzeichnis"
 
-#: builtin/clone.c:84 builtin/init-db.c:486
+#: builtin/clone.c:83 builtin/init-db.c:486
 msgid "directory from which templates will be used"
 msgstr "Verzeichnis, von welchem die Vorlagen verwendet werden"
 
-#: builtin/clone.c:86
+#: builtin/clone.c:85
 msgid "reference repository"
 msgstr "referenziert Repository"
 
-#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44
+#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44
 msgid "name"
 msgstr "Name"
 
-#: builtin/clone.c:88
+#: builtin/clone.c:87
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "verwendet <Name> statt 'origin' für Upstream-Repository"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:89
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "checkt <Branch> aus, anstatt HEAD des Remote-Repositories"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:91
 msgid "path to git-upload-pack on the remote"
 msgstr "Pfad zu \"git-upload-pack\" auf der Gegenseite"
 
-#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:661
+#: builtin/clone.c:92 builtin/fetch.c:97 builtin/grep.c:663
 msgid "depth"
 msgstr "Tiefe"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:93
 msgid "create a shallow clone of that depth"
 msgstr "erstellt einen flachen Klon mit dieser Tiefe"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:95
 msgid "clone only one branch, HEAD or --branch"
 msgstr "klont nur einen Branch, HEAD oder --branch"
 
-#: builtin/clone.c:97 builtin/init-db.c:494
+#: builtin/clone.c:96 builtin/init-db.c:494
 msgid "gitdir"
 msgstr ".git-Verzeichnis"
 
-#: builtin/clone.c:98 builtin/init-db.c:495
+#: builtin/clone.c:97 builtin/init-db.c:495
 msgid "separate git dir from working tree"
 msgstr "separiert Git-Verzeichnis vom Arbeitsverzeichnis"
 
-#: builtin/clone.c:99
+#: builtin/clone.c:98
 msgid "key=value"
 msgstr "Schlüssel=Wert"
 
-#: builtin/clone.c:100
+#: builtin/clone.c:99
 msgid "set config inside the new repository"
 msgstr "setzt Konfiguration innerhalb des neuen Repositories"
 
-#: builtin/clone.c:253
+#: builtin/clone.c:252
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "Referenziertes Repository '%s' ist kein lokales Repository."
 
-#: builtin/clone.c:316
+#: builtin/clone.c:315
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "Fehler beim Erstellen von Verzeichnis '%s'"
 
-#: builtin/clone.c:318 builtin/diff.c:77
+#: builtin/clone.c:317 builtin/diff.c:77
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "Konnte '%s' nicht lesen"
 
-#: builtin/clone.c:320
+#: builtin/clone.c:319
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s existiert und ist kein Verzeichnis"
 
-#: builtin/clone.c:334
+#: builtin/clone.c:333
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "Konnte %s nicht lesen\n"
 
-#: builtin/clone.c:356
+#: builtin/clone.c:355
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "Konnte Verweis '%s' nicht erstellen"
 
-#: builtin/clone.c:360
+#: builtin/clone.c:359
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "Konnte Datei nicht nach '%s' kopieren"
 
-#: builtin/clone.c:383
+#: builtin/clone.c:382 builtin/clone.c:559
 #, c-format
 msgid "done.\n"
 msgstr "Fertig.\n"
 
-#: builtin/clone.c:396
+#: builtin/clone.c:395
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -3819,108 +3999,103 @@
 "Sie können mit 'git status' prüfen, was ausgecheckt worden ist\n"
 "und das Auschecken mit 'git checkout -f HEAD' erneut versuchen.\n"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:474
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Konnte zu klonenden Remote-Branch %s nicht finden."
 
-#: builtin/clone.c:555
+#: builtin/clone.c:554
 #, c-format
 msgid "Checking connectivity... "
 msgstr "Prüfe Konnektivität... "
 
-#: builtin/clone.c:558
+#: builtin/clone.c:557
 msgid "remote did not send all necessary objects"
 msgstr "Remote-Repository hat nicht alle erforderlichen Objekte gesendet."
 
-#: builtin/clone.c:560
-#, c-format
-msgid "done\n"
-msgstr "Fertig\n"
-
-#: builtin/clone.c:621
+#: builtin/clone.c:620
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 "Externer HEAD bezieht sich auf eine nicht existierende Referenz und kann "
 "nicht ausgecheckt werden.\n"
 
-#: builtin/clone.c:652
+#: builtin/clone.c:651
 msgid "unable to checkout working tree"
 msgstr "Arbeitsverzeichnis konnte nicht ausgecheckt werden"
 
-#: builtin/clone.c:760
+#: builtin/clone.c:759
 msgid "Too many arguments."
 msgstr "Zu viele Argumente."
 
-#: builtin/clone.c:764
+#: builtin/clone.c:763
 msgid "You must specify a repository to clone."
 msgstr "Sie müssen ein Repository zum Klonen angeben."
 
-#: builtin/clone.c:775
+#: builtin/clone.c:774
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "Die Optionen --bare und --origin %s sind inkompatibel."
 
-#: builtin/clone.c:778
+#: builtin/clone.c:777
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "Die Optionen --bare und --separate-git-dir sind inkompatibel."
 
-#: builtin/clone.c:791
+#: builtin/clone.c:790
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "Repository '%s' existiert nicht."
 
-#: builtin/clone.c:796
+#: builtin/clone.c:795
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr ""
 "Die Option --depth wird in lokalen Klonen ignoriert; benutzen Sie "
 "stattdessen file://"
 
-#: builtin/clone.c:798
+#: builtin/clone.c:797
 msgid "--local is ignored"
 msgstr "--local wird ignoriert"
 
-#: builtin/clone.c:808
+#: builtin/clone.c:807
 #, 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:818
+#: builtin/clone.c:817
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "Arbeitsverzeichnis '%s' existiert bereits."
 
-#: builtin/clone.c:831 builtin/clone.c:843
+#: builtin/clone.c:830 builtin/clone.c:842
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "Konnte führende Verzeichnisse von '%s' nicht erstellen."
 
-#: builtin/clone.c:834
+#: builtin/clone.c:833
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "Konnte Arbeitsverzeichnis '%s' nicht erstellen."
 
-#: builtin/clone.c:853
+#: builtin/clone.c:852
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Klone in Bare-Repository '%s'...\n"
 
-#: builtin/clone.c:855
+#: builtin/clone.c:854
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Klone nach '%s'...\n"
 
-#: builtin/clone.c:890
+#: builtin/clone.c:888
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "Weiß nicht wie %s zu klonen ist."
 
-#: builtin/clone.c:942
+#: builtin/clone.c:939 builtin/clone.c:947
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "Remote-Branch %s nicht im Upstream-Repository %s gefunden"
 
-#: builtin/clone.c:949
+#: builtin/clone.c:950
 msgid "You appear to have cloned an empty repository."
 msgstr "Sie scheinen ein leeres Repository geklont zu haben."
 
@@ -3956,15 +4131,15 @@
 msgid "--command must be the first argument"
 msgstr "Die Option --command muss an erster Stelle stehen."
 
-#: builtin/commit.c:35
+#: builtin/commit.c:36
 msgid "git commit [options] [--] <pathspec>..."
 msgstr "git commit [Optionen] [--] <Pfadspezifikation>..."
 
-#: builtin/commit.c:40
+#: builtin/commit.c:41
 msgid "git status [options] [--] <pathspec>..."
 msgstr "git status [Optionen] [--] <Pfadspezifikation>..."
 
-#: builtin/commit.c:45
+#: builtin/commit.c:46
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3990,7 +4165,7 @@
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: builtin/commit.c:57
+#: builtin/commit.c:58
 msgid ""
 "You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
@@ -4000,7 +4175,7 @@
 "machen. Sie können Ihr Kommando mit --allow-empty wiederholen, oder diesen\n"
 "Commit mit \"git reset HEAD^\" vollständig entfernen.\n"
 
-#: builtin/commit.c:62
+#: builtin/commit.c:63
 msgid ""
 "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 "If you wish to commit it anyway, use:\n"
@@ -4015,11 +4190,11 @@
 "    git commit --allow-empty\n"
 "\n"
 
-#: builtin/commit.c:69
+#: builtin/commit.c:70
 msgid "Otherwise, please use 'git reset'\n"
 msgstr "Andernfalls benutzen Sie bitte 'git reset'\n"
 
-#: builtin/commit.c:72
+#: builtin/commit.c:73
 msgid ""
 "If you wish to skip this commit, use:\n"
 "\n"
@@ -4035,94 +4210,94 @@
 "Benutzen Sie anschließend \"git cherry-pick --continue\", um die\n"
 "Cherry-Pick-Operation mit den verbleibenden Commits fortzusetzen.\n"
 
-#: builtin/commit.c:279
+#: builtin/commit.c:287
 msgid "failed to unpack HEAD tree object"
 msgstr "Fehler beim Entpacken des \"Tree\"-Objektes von HEAD."
 
-#: builtin/commit.c:321
+#: builtin/commit.c:329
 msgid "unable to create temporary index"
 msgstr "Konnte temporäre Staging-Area nicht erstellen."
 
-#: builtin/commit.c:327
+#: builtin/commit.c:335
 msgid "interactive add failed"
 msgstr "interaktives Hinzufügen fehlgeschlagen"
 
-#: builtin/commit.c:360 builtin/commit.c:381 builtin/commit.c:431
+#: builtin/commit.c:368 builtin/commit.c:389 builtin/commit.c:439
 msgid "unable to write new_index file"
 msgstr "Konnte new_index Datei nicht schreiben"
 
-#: builtin/commit.c:412
+#: builtin/commit.c:420
 msgid "cannot do a partial commit during a merge."
 msgstr "Kann keinen Teil-Commit durchführen, während ein Merge im Gange ist."
 
-#: builtin/commit.c:414
+#: builtin/commit.c:422
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr ""
 "Kann keinen Teil-Commit durchführen, während \"cherry-pick\" im Gange ist."
 
-#: builtin/commit.c:424
+#: builtin/commit.c:432
 msgid "cannot read the index"
 msgstr "Kann Staging-Area nicht lesen"
 
-#: builtin/commit.c:444
+#: builtin/commit.c:452
 msgid "unable to write temporary index file"
 msgstr "Konnte temporäre Staging-Area-Datei nicht schreiben."
 
-#: builtin/commit.c:535 builtin/commit.c:541
+#: builtin/commit.c:543 builtin/commit.c:549
 #, c-format
 msgid "invalid commit: %s"
 msgstr "Ungültiger Commit: %s"
 
-#: builtin/commit.c:563
+#: builtin/commit.c:571
 msgid "malformed --author parameter"
 msgstr "Fehlerhafter --author Parameter"
 
-#: builtin/commit.c:583
+#: builtin/commit.c:591
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "Fehlerhafter Ident-String: '%s'"
 
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:982
+#: builtin/commit.c:630 builtin/commit.c:663 builtin/commit.c:1007
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "Konnte Commit %s nicht nachschlagen"
 
-#: builtin/commit.c:633 builtin/shortlog.c:271
+#: builtin/commit.c:642 builtin/shortlog.c:273
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(lese Log-Nachricht von Standard-Eingabe)\n"
 
-#: builtin/commit.c:635
+#: builtin/commit.c:644
 msgid "could not read log from standard input"
 msgstr "Konnte Log nicht von Standard-Eingabe lesen."
 
-#: builtin/commit.c:639
+#: builtin/commit.c:648
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "Konnte Log-Datei '%s' nicht lesen"
 
-#: builtin/commit.c:645
+#: builtin/commit.c:654
 msgid "commit has empty message"
 msgstr "Commit hat eine leere Beschreibung"
 
-#: builtin/commit.c:661
+#: builtin/commit.c:670
 msgid "could not read MERGE_MSG"
 msgstr "Konnte MERGE_MSG nicht lesen"
 
-#: builtin/commit.c:665
+#: builtin/commit.c:674
 msgid "could not read SQUASH_MSG"
 msgstr "Konnte SQUASH_MSG nicht lesen"
 
-#: builtin/commit.c:669
+#: builtin/commit.c:678
 #, c-format
 msgid "could not read '%s'"
 msgstr "Konnte '%s' nicht lesen"
 
-#: builtin/commit.c:730
+#: builtin/commit.c:749
 msgid "could not write commit template"
 msgstr "Konnte Commit-Vorlage nicht schreiben"
 
-#: builtin/commit.c:741
+#: builtin/commit.c:760
 #, c-format
 msgid ""
 "\n"
@@ -4137,7 +4312,7 @@
 "\t%s\n"
 "und versuchen Sie es erneut.\n"
 
-#: builtin/commit.c:746
+#: builtin/commit.c:765
 #, c-format
 msgid ""
 "\n"
@@ -4152,7 +4327,7 @@
 "\t%s\n"
 "und versuchen Sie es erneut.\n"
 
-#: builtin/commit.c:758
+#: builtin/commit.c:777
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4162,7 +4337,7 @@
 "die mit '%c' beginnen, werden ignoriert, und eine leere Beschreibung\n"
 "bricht den Commit ab.\n"
 
-#: builtin/commit.c:763
+#: builtin/commit.c:782
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4175,152 +4350,152 @@
 "entfernen.\n"
 "Eine leere Beschreibung bricht den Commit ab.\n"
 
-#: builtin/commit.c:776
+#: builtin/commit.c:795
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%sAutor:    %s"
 
-#: builtin/commit.c:783
+#: builtin/commit.c:802
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%sCommit-Ersteller: %s"
 
-#: builtin/commit.c:803
+#: builtin/commit.c:822
 msgid "Cannot read index"
 msgstr "Kann Staging-Area nicht lesen"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:865
 msgid "Error building trees"
 msgstr "Fehler beim Erzeugen der \"Tree\"-Objekte"
 
-#: builtin/commit.c:860 builtin/tag.c:359
+#: builtin/commit.c:880 builtin/tag.c:359
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr ""
 "Bitte liefern Sie eine Beschreibung entweder mit der Option -m oder -F.\n"
 
-#: builtin/commit.c:957
+#: builtin/commit.c:982
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "Kein existierender Autor mit '%s' gefunden."
 
-#: builtin/commit.c:972 builtin/commit.c:1208
+#: builtin/commit.c:997 builtin/commit.c:1237
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Ungültiger Modus '%s' für unbeobachtete Dateien"
 
-#: builtin/commit.c:1009
+#: builtin/commit.c:1034
 msgid "--long and -z are incompatible"
 msgstr "Die Optionen --long und -z sind inkompatibel."
 
-#: builtin/commit.c:1039
+#: builtin/commit.c:1064
 msgid "Using both --reset-author and --author does not make sense"
 msgstr ""
 "Die Optionen --reset-author und --author können nicht gemeinsam verwendet "
 "werden."
 
-#: builtin/commit.c:1050
+#: builtin/commit.c:1075
 msgid "You have nothing to amend."
 msgstr "Sie haben nichts für \"--amend\"."
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1078
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Ein Merge ist im Gange -- kann \"--amend\" nicht ausführen."
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1080
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "\"cherry-pick\" ist im Gange -- kann \"--amend\" nicht ausführen."
 
-#: builtin/commit.c:1058
+#: builtin/commit.c:1083
 msgid "Options --squash and --fixup cannot be used together"
 msgstr ""
 "Die Optionen --squash und --fixup können nicht gemeinsam verwendet werden."
 
-#: builtin/commit.c:1068
+#: builtin/commit.c:1093
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Es kann nur eine Option von -c/-C/-F/--fixup verwendet werden."
 
-#: builtin/commit.c:1070
+#: builtin/commit.c:1095
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr "Die Option -m kann nicht mit -c/-C/-F/--fixup kombiniert werden."
 
-#: builtin/commit.c:1078
+#: builtin/commit.c:1103
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
 "Die Option --reset--author kann nur mit -C, -c oder --amend verwendet werden."
 
-#: builtin/commit.c:1095
+#: builtin/commit.c:1120
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "Es kann nur eine Option von --include/--only/--all/--interactive/--patch "
 "verwendet werden."
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1122
 msgid "No paths with --include/--only does not make sense."
 msgstr ""
 "Die Optionen --include und --only können nur mit der Angabe von Pfaden "
 "verwendet werden."
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1124
 msgid "Clever... amending the last one with dirty index."
 msgstr ""
 "Klug... den letzten Commit mit einer geänderten Staging-Area nachbessern."
 
-#: builtin/commit.c:1101
+#: builtin/commit.c:1126
 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:1111 builtin/tag.c:575
+#: builtin/commit.c:1136 builtin/tag.c:572
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Ungültiger \"cleanup\" Modus %s"
 
-#: builtin/commit.c:1116
+#: builtin/commit.c:1141
 msgid "Paths with -a does not make sense."
 msgstr "Die Option -a kann nur mit der Angabe von Pfaden verwendet werden."
 
-#: builtin/commit.c:1222 builtin/commit.c:1455
+#: builtin/commit.c:1251 builtin/commit.c:1482
 msgid "show status concisely"
 msgstr "zeigt Status im Kurzformat"
 
-#: builtin/commit.c:1224 builtin/commit.c:1457
+#: builtin/commit.c:1253 builtin/commit.c:1484
 msgid "show branch information"
 msgstr "zeigt Branchinformationen"
 
-#: builtin/commit.c:1226 builtin/commit.c:1459 builtin/push.c:452
+#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:460
 msgid "machine-readable output"
 msgstr "maschinenlesbare Ausgabe"
 
-#: builtin/commit.c:1229 builtin/commit.c:1461
+#: builtin/commit.c:1258 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "zeigt Status im Langformat (Standard)"
 
-#: builtin/commit.c:1232 builtin/commit.c:1464
+#: builtin/commit.c:1261 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "schließt Einträge mit NUL-Zeichen ab"
 
-#: builtin/commit.c:1234 builtin/commit.c:1467 builtin/fast-export.c:667
-#: builtin/fast-export.c:670 builtin/tag.c:459
+#: builtin/commit.c:1263 builtin/commit.c:1494 builtin/fast-export.c:674
+#: builtin/fast-export.c:677 builtin/tag.c:459
 msgid "mode"
 msgstr "Modus"
 
-#: builtin/commit.c:1235 builtin/commit.c:1467
+#: builtin/commit.c:1264 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 "zeigt nicht beobachtete Dateien, optionale Modi: all, normal, no. (Standard: "
 "all)"
 
-#: builtin/commit.c:1238
+#: builtin/commit.c:1267
 msgid "show ignored files"
 msgstr "zeigt ignorierte Dateien"
 
-#: builtin/commit.c:1239 parse-options.h:154
+#: builtin/commit.c:1268 parse-options.h:156
 msgid "when"
 msgstr "wann"
 
-#: builtin/commit.c:1240
+#: builtin/commit.c:1269
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -4328,219 +4503,219 @@
 "ignoriert Änderungen in Submodulen, optional wenn: all, dirty, untracked. "
 "(Standard: all)"
 
-#: builtin/commit.c:1242
+#: builtin/commit.c:1271
 msgid "list untracked files in columns"
 msgstr "listet unbeobachtete Dateien in Spalten auf"
 
-#: builtin/commit.c:1313
+#: builtin/commit.c:1340
 msgid "couldn't look up newly created commit"
 msgstr "Konnte neu erstellten Commit nicht nachschlagen."
 
-#: builtin/commit.c:1315
+#: builtin/commit.c:1342
 msgid "could not parse newly created commit"
 msgstr "Konnte neulich erstellten Commit nicht analysieren."
 
-#: builtin/commit.c:1356
+#: builtin/commit.c:1383
 msgid "detached HEAD"
 msgstr "losgelöster HEAD"
 
-#: builtin/commit.c:1358
+#: builtin/commit.c:1385
 msgid " (root-commit)"
 msgstr " (Basis-Commit)"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1452
 msgid "suppress summary after successful commit"
 msgstr "unterdrückt Zusammenfassung nach erfolgreichem Commit"
 
-#: builtin/commit.c:1426
+#: builtin/commit.c:1453
 msgid "show diff in commit message template"
 msgstr "zeigt Unterschiede in Commit-Beschreibungsvorlage an"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1455
 msgid "Commit message options"
 msgstr "Optionen für Commit-Beschreibung"
 
-#: builtin/commit.c:1429 builtin/tag.c:457
+#: builtin/commit.c:1456 builtin/tag.c:457
 msgid "read message from file"
 msgstr "liest Beschreibung von Datei"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "author"
 msgstr "Autor"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "override author for commit"
 msgstr "überschreibt Autor eines Commits"
 
-#: builtin/commit.c:1431 builtin/gc.c:178
+#: builtin/commit.c:1458 builtin/gc.c:260
 msgid "date"
 msgstr "Datum"
 
-#: builtin/commit.c:1431
+#: builtin/commit.c:1458
 msgid "override date for commit"
 msgstr "überschreibt Datum eines Commits"
 
-#: builtin/commit.c:1432 builtin/merge.c:223 builtin/notes.c:405
+#: builtin/commit.c:1459 builtin/merge.c:223 builtin/notes.c:405
 #: builtin/notes.c:562 builtin/tag.c:455
 msgid "message"
 msgstr "Beschreibung"
 
-#: builtin/commit.c:1432
+#: builtin/commit.c:1459
 msgid "commit message"
 msgstr "Commit-Beschreibung"
 
-#: builtin/commit.c:1433
+#: builtin/commit.c:1460
 msgid "reuse and edit message from specified commit"
 msgstr "verwendet wieder und editiert Beschreibung des angegebenen Commits"
 
-#: builtin/commit.c:1434
+#: builtin/commit.c:1461
 msgid "reuse message from specified commit"
 msgstr "verwendet Beschreibung des angegebenen Commits wieder"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1462
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 "verwendet eine automatisch zusammengesetzte Beschreibung zum Nachbessern des "
 "angegebenen Commits"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1463
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 "verwendet eine automatisch zusammengesetzte Beschreibung beim \"squash\" des "
 "angegebenen Commits"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1464
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "Setzt Sie als Autor des Commits (verwendet mit -C/-c/--amend)"
 
-#: builtin/commit.c:1438 builtin/log.c:1160 builtin/revert.c:111
+#: builtin/commit.c:1465 builtin/log.c:1180 builtin/revert.c:86
 msgid "add Signed-off-by:"
 msgstr "fügt 'Signed-off-by:'-Zeile hinzu"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1466
 msgid "use specified template file"
 msgstr "verwendet angegebene Vorlagendatei"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1467
 msgid "force edit of commit"
 msgstr "erzwingt Bearbeitung des Commits"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1468
 msgid "default"
 msgstr "Standard"
 
-#: builtin/commit.c:1441 builtin/tag.c:460
+#: builtin/commit.c:1468 builtin/tag.c:460
 msgid "how to strip spaces and #comments from message"
 msgstr ""
 "wie Leerzeichen und #Kommentare von der Beschreibung getrennt werden sollen"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1469
 msgid "include status in commit message template"
 msgstr "fügt Status in die Commit-Beschreibungsvorlage ein"
 
-#: builtin/commit.c:1443 builtin/merge.c:230 builtin/tag.c:461
+#: builtin/commit.c:1470 builtin/merge.c:230 builtin/tag.c:461
 msgid "key id"
 msgstr "Schlüssel-ID"
 
-#: builtin/commit.c:1444 builtin/merge.c:231
+#: builtin/commit.c:1471 builtin/merge.c:231
 msgid "GPG sign commit"
 msgstr "signiert Commit mit GPG"
 
 #. end commit message options
-#: builtin/commit.c:1447
+#: builtin/commit.c:1474
 msgid "Commit contents options"
 msgstr "Optionen für Commit-Inhalt"
 
-#: builtin/commit.c:1448
+#: builtin/commit.c:1475
 msgid "commit all changed files"
 msgstr "committet alle geänderten Dateien"
 
-#: builtin/commit.c:1449
+#: builtin/commit.c:1476
 msgid "add specified files to index for commit"
 msgstr "merkt die angegebenen Dateien zusätzlich zum Commit vor"
 
-#: builtin/commit.c:1450
+#: builtin/commit.c:1477
 msgid "interactively add files"
 msgstr "interaktives Hinzufügen von Dateien"
 
-#: builtin/commit.c:1451
+#: builtin/commit.c:1478
 msgid "interactively add changes"
 msgstr "interaktives Hinzufügen von Änderungen"
 
-#: builtin/commit.c:1452
+#: builtin/commit.c:1479
 msgid "commit only specified files"
 msgstr "committet nur die angegebenen Dateien"
 
-#: builtin/commit.c:1453
+#: builtin/commit.c:1480
 msgid "bypass pre-commit hook"
 msgstr "umgeht \"pre-commit hook\""
 
-#: builtin/commit.c:1454
+#: builtin/commit.c:1481
 msgid "show what would be committed"
 msgstr "zeigt an, was committet werden würde"
 
-#: builtin/commit.c:1465
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "ändert vorherigen Commit"
 
-#: builtin/commit.c:1466
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "umgeht \"post-rewrite hook\""
 
-#: builtin/commit.c:1471
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "erlaubt Aufzeichnung einer leeren Änderung"
 
-#: builtin/commit.c:1474
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "erlaubt Aufzeichnung einer Änderung mit einer leeren Beschreibung"
 
-#: builtin/commit.c:1507
+#: builtin/commit.c:1529
 msgid "could not parse HEAD commit"
 msgstr "Konnte Commit von HEAD nicht analysieren."
 
-#: builtin/commit.c:1545 builtin/merge.c:525
+#: builtin/commit.c:1567 builtin/merge.c:525
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "Konnte '%s' nicht zum Lesen öffnen."
 
-#: builtin/commit.c:1552
+#: builtin/commit.c:1574
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Beschädigte MERGE_HEAD-Datei (%s)"
 
-#: builtin/commit.c:1559
+#: builtin/commit.c:1581
 msgid "could not read MERGE_MODE"
 msgstr "Konnte MERGE_MODE nicht lesen"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1600
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "Konnte Commit-Beschreibung nicht lesen: %s"
 
-#: builtin/commit.c:1592
+#: builtin/commit.c:1614
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Commit abgebrochen; Sie haben die Beschreibung nicht editiert.\n"
 
-#: builtin/commit.c:1597
+#: builtin/commit.c:1619
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Commit aufgrund leerer Beschreibung abgebrochen.\n"
 
-#: builtin/commit.c:1612 builtin/merge.c:861 builtin/merge.c:886
+#: builtin/commit.c:1634 builtin/merge.c:861 builtin/merge.c:886
 msgid "failed to write commit object"
 msgstr "Fehler beim Schreiben des Commit-Objektes."
 
-#: builtin/commit.c:1633
+#: builtin/commit.c:1655
 msgid "cannot lock HEAD ref"
 msgstr "Kann Referenz von HEAD nicht sperren."
 
-#: builtin/commit.c:1637
+#: builtin/commit.c:1659
 msgid "cannot update HEAD ref"
 msgstr "Kann Referenz von HEAD nicht aktualisieren."
 
-#: builtin/commit.c:1648
+#: builtin/commit.c:1670
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -4551,127 +4726,131 @@
 "voll und Ihr Kontingent nicht aufgebraucht ist und führen Sie\n"
 "anschließend \"git reset HEAD\" zu Wiederherstellung aus."
 
-#: builtin/config.c:7
+#: builtin/config.c:8
 msgid "git config [options]"
 msgstr "git config [Optionen]"
 
-#: builtin/config.c:52
+#: builtin/config.c:54
 msgid "Config file location"
 msgstr "Ort der Konfigurationsdatei"
 
-#: builtin/config.c:53
+#: builtin/config.c:55
 msgid "use global config file"
 msgstr "verwendet globale Konfigurationsdatei"
 
-#: builtin/config.c:54
+#: builtin/config.c:56
 msgid "use system config file"
 msgstr "verwendet systemweite Konfigurationsdatei"
 
-#: builtin/config.c:55
+#: builtin/config.c:57
 msgid "use repository config file"
 msgstr "verwendet Konfigurationsdatei des Repositories"
 
-#: builtin/config.c:56
+#: builtin/config.c:58
 msgid "use given config file"
 msgstr "verwendet die angegebene Konfigurationsdatei"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "blob-id"
 msgstr "Blob-Id"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "read config from given blob object"
 msgstr "liest Konfiguration von angegebenem Blob-Objekt"
 
-#: builtin/config.c:58
+#: builtin/config.c:60
 msgid "Action"
 msgstr "Aktion"
 
-#: builtin/config.c:59
+#: builtin/config.c:61
 msgid "get value: name [value-regex]"
 msgstr "gibt Wert zurück: Name [Wert-regex]"
 
-#: builtin/config.c:60
+#: builtin/config.c:62
 msgid "get all values: key [value-regex]"
 msgstr "gibt alle Werte zurück: Schlüssel [Wert-regex]"
 
-#: builtin/config.c:61
+#: builtin/config.c:63
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "gibt Werte für den regulären Ausdruck zurück: Name-regex [Wert-regex]"
 
-#: builtin/config.c:62
+#: builtin/config.c:64
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "gibt Wert spezifisch für eine URL zurück: section[.var] URL"
+
+#: builtin/config.c:65
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "ersetzt alle passenden Variablen: Name Wert [Wert-regex] "
 
-#: builtin/config.c:63
+#: builtin/config.c:66
 msgid "add a new variable: name value"
 msgstr "fügt neue Variable hinzu: Name Wert"
 
-#: builtin/config.c:64
+#: builtin/config.c:67
 msgid "remove a variable: name [value-regex]"
 msgstr "entfernt eine Variable: Name [Wert-regex]"
 
-#: builtin/config.c:65
+#: builtin/config.c:68
 msgid "remove all matches: name [value-regex]"
 msgstr "entfernt alle Übereinstimmungen: Name [Wert-regex]"
 
-#: builtin/config.c:66
+#: builtin/config.c:69
 msgid "rename section: old-name new-name"
 msgstr "benennt eine Sektion um: alter-Name neuer-Name"
 
-#: builtin/config.c:67
+#: builtin/config.c:70
 msgid "remove a section: name"
 msgstr "entfernt eine Sektion: Name"
 
-#: builtin/config.c:68
+#: builtin/config.c:71
 msgid "list all"
 msgstr "listet alles auf"
 
-#: builtin/config.c:69
+#: builtin/config.c:72
 msgid "open an editor"
 msgstr "öffnet einen Editor"
 
-#: builtin/config.c:70 builtin/config.c:71
+#: builtin/config.c:73 builtin/config.c:74
 msgid "slot"
 msgstr "Slot"
 
-#: builtin/config.c:70
+#: builtin/config.c:73
 msgid "find the color configured: [default]"
 msgstr "findet die konfigurierte Farbe: [Standard]"
 
-#: builtin/config.c:71
+#: builtin/config.c:74
 msgid "find the color setting: [stdout-is-tty]"
 msgstr "findet die Farbeinstellung: [Standard-Ausgabe-ist-Terminal]"
 
-#: builtin/config.c:72
+#: builtin/config.c:75
 msgid "Type"
 msgstr "Typ"
 
-#: builtin/config.c:73
+#: builtin/config.c:76
 msgid "value is \"true\" or \"false\""
 msgstr "Wert ist \"true\" oder \"false\""
 
-#: builtin/config.c:74
+#: builtin/config.c:77
 msgid "value is decimal number"
 msgstr "Wert ist eine Dezimalzahl"
 
-#: builtin/config.c:75
+#: builtin/config.c:78
 msgid "value is --bool or --int"
 msgstr "Wert ist --bool oder --int"
 
-#: builtin/config.c:76
+#: builtin/config.c:79
 msgid "value is a path (file or directory name)"
 msgstr "Wert ist ein Pfad (Datei oder Verzeichnisname)"
 
-#: builtin/config.c:77
+#: builtin/config.c:80
 msgid "Other"
 msgstr "Sonstiges"
 
-#: builtin/config.c:78
+#: builtin/config.c:81
 msgid "terminate values with NUL byte"
 msgstr "schließt Werte mit NUL-Byte ab"
 
-#: builtin/config.c:79
+#: builtin/config.c:82
 msgid "respect include directives on lookup"
 msgstr "beachtet \"include\"-Direktiven beim Nachschlagen"
 
@@ -4684,8 +4863,8 @@
 msgstr "gibt Größenangaben in menschenlesbaren Format aus"
 
 #: builtin/describe.c:16
-msgid "git describe [options] <committish>*"
-msgstr "git describe [Optionen] <committish>*"
+msgid "git describe [options] <commit-ish>*"
+msgstr "git describe [Optionen] <commit-ish>*"
 
 #: builtin/describe.c:17
 msgid "git describe [options] --dirty"
@@ -4822,7 +5001,7 @@
 msgstr "Keine Namen gefunden, kann nichts beschreiben."
 
 #: builtin/describe.c:489
-msgid "--dirty is incompatible with committishes"
+msgid "--dirty is incompatible with commit-ishes"
 msgstr "Die Option --dirty kann nicht mit Commits verwendet werden."
 
 #: builtin/diff.c:79
@@ -4858,39 +5037,39 @@
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-opts]"
 
-#: builtin/fast-export.c:666
+#: builtin/fast-export.c:673
 msgid "show progress after <n> objects"
 msgstr "zeigt Fortschritt nach <n> Objekten an"
 
-#: builtin/fast-export.c:668
+#: builtin/fast-export.c:675
 msgid "select handling of signed tags"
 msgstr "wählt Behandlung von signierten Tags"
 
-#: builtin/fast-export.c:671
+#: builtin/fast-export.c:678
 msgid "select handling of tags that tag filtered objects"
 msgstr "wählt Behandlung von Tags, die gefilterte Objekte markieren"
 
-#: builtin/fast-export.c:674
+#: builtin/fast-export.c:681
 msgid "Dump marks to this file"
 msgstr "Schreibt Kennzeichen in diese Datei"
 
-#: builtin/fast-export.c:676
+#: builtin/fast-export.c:683
 msgid "Import marks from this file"
 msgstr "Importiert Kennzeichen von dieser Datei"
 
-#: builtin/fast-export.c:678
+#: builtin/fast-export.c:685
 msgid "Fake a tagger when tags lack one"
 msgstr "erzeugt künstlich einen Tag-Ersteller, wenn das Tag keinen hat"
 
-#: builtin/fast-export.c:680
+#: builtin/fast-export.c:687
 msgid "Output full tree for each commit"
 msgstr "gibt für jeden Commit das gesamte Verzeichnis aus"
 
-#: builtin/fast-export.c:682
+#: builtin/fast-export.c:689
 msgid "Use the done feature to terminate the stream"
 msgstr "Benutzt die \"done\"-Funktion um den Strom abzuschließen"
 
-#: builtin/fast-export.c:683
+#: builtin/fast-export.c:690
 msgid "Skip output of blob data"
 msgstr "Überspringt Ausgabe von Blob-Daten"
 
@@ -4910,147 +5089,147 @@
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<Optionen>]"
 
-#: builtin/fetch.c:60
+#: builtin/fetch.c:74
 msgid "fetch from all remotes"
 msgstr "fordert von allen Remote-Repositories an"
 
-#: builtin/fetch.c:62
+#: builtin/fetch.c:76
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "hängt an .git/FETCH_HEAD an, anstatt zu überschreiben"
 
-#: builtin/fetch.c:64
+#: builtin/fetch.c:78
 msgid "path to upload pack on remote end"
 msgstr "Pfad des Programms zum Hochladen von Paketen auf der Gegenseite"
 
-#: builtin/fetch.c:65
+#: builtin/fetch.c:79
 msgid "force overwrite of local branch"
 msgstr "erzwingt das Überschreiben von lokalen Branches"
 
-#: builtin/fetch.c:67
+#: builtin/fetch.c:81
 msgid "fetch from multiple remotes"
 msgstr "fordert von mehreren Remote-Repositories an"
 
-#: builtin/fetch.c:69
+#: builtin/fetch.c:83
 msgid "fetch all tags and associated objects"
 msgstr "fordert alle Tags und verbundene Objekte an"
 
-#: builtin/fetch.c:71
+#: builtin/fetch.c:85
 msgid "do not fetch all tags (--no-tags)"
 msgstr "fordert nicht alle Tags an (--no-tags)"
 
-#: builtin/fetch.c:73
+#: builtin/fetch.c:87
 msgid "prune remote-tracking branches no longer on remote"
 msgstr ""
 "entfernt Remote-Tracking-Branches, die sich nicht mehr im Remote-Repository "
 "befinden"
 
-#: builtin/fetch.c:74
+#: builtin/fetch.c:88
 msgid "on-demand"
 msgstr "bei-Bedarf"
 
-#: builtin/fetch.c:75
+#: builtin/fetch.c:89
 msgid "control recursive fetching of submodules"
 msgstr "kontrolliert rekursive Anforderungen von Submodulen"
 
-#: builtin/fetch.c:79
+#: builtin/fetch.c:93
 msgid "keep downloaded pack"
 msgstr "behält heruntergeladenes Paket"
 
-#: builtin/fetch.c:81
+#: builtin/fetch.c:95
 msgid "allow updating of HEAD ref"
 msgstr "erlaubt Aktualisierung der \"HEAD\"-Referenz"
 
-#: builtin/fetch.c:84
+#: builtin/fetch.c:98
 msgid "deepen history of shallow clone"
 msgstr "vertieft die Historie eines flachen Klons"
 
-#: builtin/fetch.c:86
+#: builtin/fetch.c:100
 msgid "convert to a complete repository"
 msgstr "konvertiert zu einem vollständigen Repository"
 
-#: builtin/fetch.c:88 builtin/log.c:1177
+#: builtin/fetch.c:102 builtin/log.c:1197
 msgid "dir"
 msgstr "Verzeichnis"
 
-#: builtin/fetch.c:89
+#: builtin/fetch.c:103
 msgid "prepend this to submodule path output"
 msgstr "stellt dies an die Ausgabe der Submodul-Pfade voran"
 
-#: builtin/fetch.c:92
+#: builtin/fetch.c:106
 msgid "default mode for recursion"
 msgstr "Standard-Modus für Rekursion"
 
-#: builtin/fetch.c:220
+#: builtin/fetch.c:236
 msgid "Couldn't find remote ref HEAD"
 msgstr "Konnte Remote-Referenz von HEAD nicht finden."
 
-#: builtin/fetch.c:273
+#: builtin/fetch.c:290
 #, c-format
 msgid "object %s not found"
 msgstr "Objekt %s nicht gefunden"
 
-#: builtin/fetch.c:278
+#: builtin/fetch.c:295
 msgid "[up to date]"
 msgstr "[aktuell]"
 
-#: builtin/fetch.c:292
+#: builtin/fetch.c:309
 #, c-format
 msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
 msgstr ""
 "! %-*s %-*s -> %s  (kann \"fetch\" im aktuellen Branch nicht ausführen)"
 
-#: builtin/fetch.c:293 builtin/fetch.c:379
+#: builtin/fetch.c:310 builtin/fetch.c:396
 msgid "[rejected]"
 msgstr "[zurückgewiesen]"
 
-#: builtin/fetch.c:304
+#: builtin/fetch.c:321
 msgid "[tag update]"
 msgstr "[Tag Aktualisierung]"
 
-#: builtin/fetch.c:306 builtin/fetch.c:341 builtin/fetch.c:359
+#: builtin/fetch.c:323 builtin/fetch.c:358 builtin/fetch.c:376
 msgid "  (unable to update local ref)"
 msgstr "  (kann lokale Referenz nicht aktualisieren)"
 
-#: builtin/fetch.c:324
+#: builtin/fetch.c:341
 msgid "[new tag]"
 msgstr "[neues Tag]"
 
-#: builtin/fetch.c:327
+#: builtin/fetch.c:344
 msgid "[new branch]"
 msgstr "[neuer Branch]"
 
-#: builtin/fetch.c:330
+#: builtin/fetch.c:347
 msgid "[new ref]"
 msgstr "[neue Referenz]"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "unable to update local ref"
 msgstr "kann lokale Referenz nicht aktualisieren"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "forced update"
 msgstr "Aktualisierung erzwungen"
 
-#: builtin/fetch.c:381
+#: builtin/fetch.c:398
 msgid "(non-fast-forward)"
 msgstr "(kein Vorspulen)"
 
-#: builtin/fetch.c:412 builtin/fetch.c:718
+#: builtin/fetch.c:429 builtin/fetch.c:735
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr "kann %s nicht öffnen: %s\n"
 
-#: builtin/fetch.c:421
+#: builtin/fetch.c:438
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s hat nicht alle erforderlichen Objekte gesendet\n"
 
-#: builtin/fetch.c:520
+#: builtin/fetch.c:537
 #, c-format
 msgid "From %.*s\n"
 msgstr "Von %.*s\n"
 
-#: builtin/fetch.c:531
+#: builtin/fetch.c:548
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -5059,57 +5238,57 @@
 "Einige lokale Referenzen konnten nicht aktualisiert werden; versuchen Sie\n"
 "'git remote prune %s' um jeden älteren, widersprüchlichen Branch zu löschen."
 
-#: builtin/fetch.c:581
+#: builtin/fetch.c:598
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s wird unreferenziert)"
 
-#: builtin/fetch.c:582
+#: builtin/fetch.c:599
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s wurde unreferenziert)"
 
-#: builtin/fetch.c:589
+#: builtin/fetch.c:606
 msgid "[deleted]"
 msgstr "[gelöscht]"
 
-#: builtin/fetch.c:590 builtin/remote.c:1055
+#: builtin/fetch.c:607 builtin/remote.c:1055
 msgid "(none)"
 msgstr "(nichts)"
 
-#: builtin/fetch.c:708
+#: builtin/fetch.c:725
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr ""
 "Der \"fetch\" in den aktuellen Branch %s von einem nicht-Bare-Repository "
 "wurde verweigert."
 
-#: builtin/fetch.c:742
-#, c-format
-msgid "Don't know how to fetch from %s"
-msgstr "Weiß nicht wie von %s angefordert wird."
-
-#: builtin/fetch.c:823
+#: builtin/fetch.c:744
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "Option \"%s\" Wert \"%s\" ist nicht gültig für %s"
 
-#: builtin/fetch.c:826
+#: builtin/fetch.c:747
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "Option \"%s\" wird ignoriert für %s\n"
 
-#: builtin/fetch.c:928
+#: builtin/fetch.c:801
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr "Weiß nicht wie von %s angefordert wird."
+
+#: builtin/fetch.c:976
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Fordere an von %s\n"
 
-#: builtin/fetch.c:930 builtin/remote.c:100
+#: builtin/fetch.c:978 builtin/remote.c:100
 #, c-format
 msgid "Could not fetch %s"
 msgstr "Konnte nicht von %s anfordern"
 
-#: builtin/fetch.c:949
+#: builtin/fetch.c:997
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -5118,35 +5297,35 @@
 "oder den Namen des Remote-Repositories an, von welchem neue\n"
 "Commits angefordert werden sollen."
 
-#: builtin/fetch.c:969
+#: builtin/fetch.c:1020
 msgid "You need to specify a tag name."
 msgstr "Sie müssen den Namen des Tags angeben."
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1068
 msgid "--depth and --unshallow cannot be used together"
 msgstr ""
 "Die Optionen --depth und --unshallow können nicht gemeinsam verwendet werden."
 
-#: builtin/fetch.c:1017
+#: builtin/fetch.c:1070
 msgid "--unshallow on a complete repository does not make sense"
 msgstr ""
 "Die Option --unshallow kann nicht in einem vollständigen Repository "
 "verwendet werden."
 
-#: builtin/fetch.c:1036
+#: builtin/fetch.c:1089
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all akzeptiert kein Repository als Argument"
 
-#: builtin/fetch.c:1038
+#: builtin/fetch.c:1091
 msgid "fetch --all does not make sense with refspecs"
 msgstr "fetch --all kann nicht mit Refspecs verwendet werden."
 
-#: builtin/fetch.c:1049
+#: builtin/fetch.c:1102
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "Kein Remote-Repository (einzeln oder Gruppe): %s"
 
-#: builtin/fetch.c:1057
+#: builtin/fetch.c:1110
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr ""
 "Das Abholen einer Gruppe von Remote-Repositories kann nicht mit der Angabe\n"
@@ -5157,9 +5336,9 @@
 msgstr ""
 "git fmt-merge-msg [-m <Beschreibung>] [--log[=<n>]|--no-log] [--file <Datei>]"
 
-#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:700
-#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:179
-#: builtin/tag.c:446 parse-options.h:133 parse-options.h:243
+#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:702
+#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:178
+#: builtin/tag.c:446 parse-options.h:135 parse-options.h:245
 msgid "n"
 msgstr "Anzahl"
 
@@ -5183,117 +5362,122 @@
 msgid "file to read from"
 msgstr "Datei zum Einlesen"
 
-#: builtin/for-each-ref.c:979
+#: builtin/for-each-ref.c:995
 msgid "git for-each-ref [options] [<pattern>]"
 msgstr "git for-each-ref [Optionen] [<Muster>]"
 
-#: builtin/for-each-ref.c:994
+#: builtin/for-each-ref.c:1010
 msgid "quote placeholders suitably for shells"
 msgstr "formatiert Platzhalter als Shell-String"
 
-#: builtin/for-each-ref.c:996
+#: builtin/for-each-ref.c:1012
 msgid "quote placeholders suitably for perl"
 msgstr "formatiert Platzhalter als Perl-String"
 
-#: builtin/for-each-ref.c:998
+#: builtin/for-each-ref.c:1014
 msgid "quote placeholders suitably for python"
 msgstr "formatiert Platzhalter als Python-String"
 
-#: builtin/for-each-ref.c:1000
+#: builtin/for-each-ref.c:1016
 msgid "quote placeholders suitably for tcl"
 msgstr "formatiert Platzhalter als TCL-String"
 
-#: builtin/for-each-ref.c:1003
+#: builtin/for-each-ref.c:1019
 msgid "show only <n> matched refs"
 msgstr "zeigt nur <n> passende Referenzen"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format"
 msgstr "Format"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format to use for the output"
 msgstr "für die Ausgabe zu verwendendes Format"
 
-#: builtin/for-each-ref.c:1005
+#: builtin/for-each-ref.c:1021
 msgid "key"
 msgstr "Schüssel"
 
-#: builtin/for-each-ref.c:1006
+#: builtin/for-each-ref.c:1022
 msgid "field name to sort on"
 msgstr "sortiere nach diesem Feld"
 
-#: builtin/fsck.c:608
+#: builtin/fsck.c:607
 msgid "git fsck [options] [<object>...]"
 msgstr "git fsck [Optionen] [<Objekt>...]"
 
-#: builtin/fsck.c:614
+#: builtin/fsck.c:613
 msgid "show unreachable objects"
 msgstr "zeigt unerreichbare Objekte"
 
-#: builtin/fsck.c:615
+#: builtin/fsck.c:614
 msgid "show dangling objects"
 msgstr "zeigt unreferenzierte Objekte"
 
-#: builtin/fsck.c:616
+#: builtin/fsck.c:615
 msgid "report tags"
 msgstr "meldet Tags"
 
-#: builtin/fsck.c:617
+#: builtin/fsck.c:616
 msgid "report root nodes"
 msgstr "meldet Hauptwurzeln"
 
-#: builtin/fsck.c:618
+#: builtin/fsck.c:617
 msgid "make index objects head nodes"
 msgstr "prüft Objekte in der Staging-Area"
 
-#: builtin/fsck.c:619
+#: builtin/fsck.c:618
 msgid "make reflogs head nodes (default)"
 msgstr "prüft die Reflogs (Standard)"
 
-#: builtin/fsck.c:620
+#: builtin/fsck.c:619
 msgid "also consider packs and alternate objects"
 msgstr ""
 
-#: builtin/fsck.c:621
+#: builtin/fsck.c:620
 msgid "enable more strict checking"
 msgstr "aktiviert genauere Prüfung"
 
-#: builtin/fsck.c:623
+#: builtin/fsck.c:622
 msgid "write dangling objects in .git/lost-found"
 msgstr "schreibt unreferenzierte Objekte nach .git/lost-found"
 
-#: builtin/fsck.c:624 builtin/prune.c:134
+#: builtin/fsck.c:623 builtin/prune.c:134
 msgid "show progress"
 msgstr "zeigt Fortschrittsanzeige"
 
-#: builtin/gc.c:22
+#: builtin/gc.c:23
 msgid "git gc [options]"
 msgstr "git gc [Optionen]"
 
-#: builtin/gc.c:63
+#: builtin/gc.c:79
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "Ungültiger %s: '%s'"
 
-#: builtin/gc.c:90
+#: builtin/gc.c:106
 #, c-format
 msgid "insanely long object directory %.*s"
 msgstr "zu langes Objekt-Verzeichnis %.*s"
 
-#: builtin/gc.c:179
+#: builtin/gc.c:261
 msgid "prune unreferenced objects"
 msgstr "entfernt unreferenzierte Objekte"
 
-#: builtin/gc.c:181
+#: builtin/gc.c:263
 msgid "be more thorough (increased runtime)"
 msgstr "mehr Gründlichkeit (erhöht Laufzeit)"
 
-#: builtin/gc.c:182
+#: builtin/gc.c:264
 msgid "enable auto-gc mode"
 msgstr "aktiviert \"auto-gc\" Modus"
 
-#: builtin/gc.c:222
+#: builtin/gc.c:265
+msgid "force running gc even if there may be another gc running"
+msgstr "erzwingt Ausführung von \"git gc\" selbst wenn ein anderes\n"
+"\"git gc\" bereits ausgeführt wird"
+
+#: builtin/gc.c:305
 #, c-format
 msgid ""
 "Auto packing the repository for optimum performance. You may also\n"
@@ -5303,43 +5487,52 @@
 "komprimiert. Sie können auch \"git gc\" manuell ausführen.\n"
 "Siehe \"git help gc\" für weitere Informationen.\n"
 
-#: builtin/gc.c:249
+#. be quiet on --auto
+#: builtin/gc.c:315
+#, c-format
+msgid ""
+"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
+msgstr ""
+"\"git gc\" wird bereits auf Maschine '%s' pid %<PRIuMAX> ausgeführt\n"
+"(benutzen Sie --force falls nicht)"
+
+#: builtin/gc.c:340
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "Es gibt zu viele unerreichbare lose Objekte; führen Sie 'git prune' aus, um "
 "diese zu löschen."
 
-#: builtin/grep.c:22
+#: builtin/grep.c:23
 msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [Optionen] [-e] <Muster> [<Commit>...] [[--] <Pfad>...]"
 
-#: builtin/grep.c:217
+#: builtin/grep.c:218
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: Fehler beim Erzeugen eines Thread: %s"
 
-#: builtin/grep.c:364
+#: builtin/grep.c:365
 #, c-format
 msgid "Failed to chdir: %s"
 msgstr "Fehler beim Verzeichniswechsel: %s"
 
-#: builtin/grep.c:442 builtin/grep.c:477
+#: builtin/grep.c:443 builtin/grep.c:478
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "konnte \"Tree\"-Objekt (%s) nicht lesen"
 
-#: builtin/grep.c:492
+#: builtin/grep.c:493
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "kann \"grep\" nicht mit Objekten des Typs %s durchführen"
 
-#: builtin/grep.c:550
+#: builtin/grep.c:551
 #, c-format
 msgid "switch `%c' expects a numerical value"
 msgstr "Schalter '%c' erwartet einen numerischen Wert"
 
-#: builtin/grep.c:567
+#: builtin/grep.c:568
 #, c-format
 msgid "cannot open '%s'"
 msgstr "kann '%s' nicht öffnen"
@@ -5381,169 +5574,173 @@
 msgstr "findet keine Muster in Binärdateien"
 
 #: builtin/grep.c:662
+msgid "process binary files with textconv filters"
+msgstr "verarbeitet binäre Dateien mit \"textconv\"-Filtern"
+
+#: builtin/grep.c:664
 msgid "descend at most <depth> levels"
 msgstr "durchläuft höchstens <Tiefe> Ebenen"
 
-#: builtin/grep.c:666
+#: builtin/grep.c:668
 msgid "use extended POSIX regular expressions"
 msgstr "verwendet erweiterte reguläre Ausdrücke aus POSIX"
 
-#: builtin/grep.c:669
+#: builtin/grep.c:671
 msgid "use basic POSIX regular expressions (default)"
 msgstr "verwendet grundlegende reguläre Ausdrücke aus POSIX (Standard)"
 
-#: builtin/grep.c:672
+#: builtin/grep.c:674
 msgid "interpret patterns as fixed strings"
 msgstr "interpretiert Muster als feste Zeichenketten"
 
-#: builtin/grep.c:675
+#: builtin/grep.c:677
 msgid "use Perl-compatible regular expressions"
 msgstr "verwendet Perl-kompatible reguläre Ausdrücke"
 
-#: builtin/grep.c:678
+#: builtin/grep.c:680
 msgid "show line numbers"
 msgstr "zeigt Zeilennummern"
 
-#: builtin/grep.c:679
+#: builtin/grep.c:681
 msgid "don't show filenames"
 msgstr "zeigt keine Dateinamen"
 
-#: builtin/grep.c:680
+#: builtin/grep.c:682
 msgid "show filenames"
 msgstr "zeigt Dateinamen"
 
-#: builtin/grep.c:682
+#: builtin/grep.c:684
 msgid "show filenames relative to top directory"
 msgstr "zeigt Dateinamen relativ zum Projektverzeichnis"
 
-#: builtin/grep.c:684
+#: builtin/grep.c:686
 msgid "show only filenames instead of matching lines"
 msgstr "zeigt nur Dateinamen anstatt übereinstimmende Zeilen"
 
-#: builtin/grep.c:686
+#: builtin/grep.c:688
 msgid "synonym for --files-with-matches"
 msgstr "Synonym für --files-with-matches"
 
-#: builtin/grep.c:689
+#: builtin/grep.c:691
 msgid "show only the names of files without match"
 msgstr "zeigt nur die Dateinamen ohne Übereinstimmungen"
 
-#: builtin/grep.c:691
+#: builtin/grep.c:693
 msgid "print NUL after filenames"
 msgstr "gibt NUL-Zeichen nach Dateinamen aus"
 
-#: builtin/grep.c:693
+#: builtin/grep.c:695
 msgid "show the number of matches instead of matching lines"
 msgstr "zeigt, anstatt der Zeilen, die Anzahl der übereinstimmenden Zeilen"
 
-#: builtin/grep.c:694
+#: builtin/grep.c:696
 msgid "highlight matches"
 msgstr "hebt Übereinstimmungen hervor"
 
-#: builtin/grep.c:696
+#: builtin/grep.c:698
 msgid "print empty line between matches from different files"
 msgstr ""
 "gibt eine Leerzeile zwischen Übereinstimmungen in verschiedenen Dateien aus"
 
-#: builtin/grep.c:698
+#: builtin/grep.c:700
 msgid "show filename only once above matches from same file"
 msgstr ""
 "zeigt den Dateinamen nur einmal oberhalb der Übereinstimmungen aus dieser "
 "Datei an"
 
-#: builtin/grep.c:701
+#: builtin/grep.c:703
 msgid "show <n> context lines before and after matches"
 msgstr "zeigt <n> Zeilen vor und nach den Übereinstimmungen an"
 
-#: builtin/grep.c:704
+#: builtin/grep.c:706
 msgid "show <n> context lines before matches"
 msgstr "zeigt <n> Zeilen vor den Übereinstimmungen an"
 
-#: builtin/grep.c:706
+#: builtin/grep.c:708
 msgid "show <n> context lines after matches"
 msgstr "zeigt <n> Zeilen nach den Übereinstimmungen an"
 
-#: builtin/grep.c:707
+#: builtin/grep.c:709
 msgid "shortcut for -C NUM"
 msgstr "Kurzform für -C NUM"
 
-#: builtin/grep.c:710
+#: builtin/grep.c:712
 msgid "show a line with the function name before matches"
 msgstr "zeigt eine Zeile mit dem Funktionsnamen vor Übereinstimmungen an"
 
-#: builtin/grep.c:712
+#: builtin/grep.c:714
 msgid "show the surrounding function"
 msgstr "zeigt die umgebende Funktion an"
 
-#: builtin/grep.c:715
+#: builtin/grep.c:717
 msgid "read patterns from file"
 msgstr "liest Muster von einer Datei"
 
-#: builtin/grep.c:717
+#: builtin/grep.c:719
 msgid "match <pattern>"
 msgstr "findet <Muster>"
 
-#: builtin/grep.c:719
+#: builtin/grep.c:721
 msgid "combine patterns specified with -e"
 msgstr "kombiniert Muster, die mit -e angegeben wurden"
 
-#: builtin/grep.c:731
+#: builtin/grep.c:733
 msgid "indicate hit with exit status without output"
 msgstr "zeigt Übereinstimmungen nur durch Beendigungsstatus an"
 
-#: builtin/grep.c:733
+#: builtin/grep.c:735
 msgid "show only matches from files that match all patterns"
 msgstr "zeigt nur Übereinstimmungen von Dateien, die allen Mustern entsprechen"
 
-#: builtin/grep.c:735
+#: builtin/grep.c:737
 msgid "show parse tree for grep expression"
 msgstr "zeigt geparstes Verzeichnis für \"grep\"-Ausdruck"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "pager"
 msgstr "Anzeigeprogramm"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "show matching files in the pager"
 msgstr "zeigt Dateien mit Übereinstimmungen im Anzeigeprogramm"
 
-#: builtin/grep.c:742
+#: builtin/grep.c:744
 msgid "allow calling of grep(1) (ignored by this build)"
 msgstr "erlaubt den Aufruf von grep(1) (von dieser Programmversion ignoriert)"
 
-#: builtin/grep.c:743 builtin/show-ref.c:188
+#: builtin/grep.c:745 builtin/show-ref.c:187
 msgid "show usage"
 msgstr "zeigt Verwendung"
 
-#: builtin/grep.c:810
+#: builtin/grep.c:812
 msgid "no pattern given."
 msgstr "keine Muster angegeben"
 
-#: builtin/grep.c:865
+#: builtin/grep.c:870
 msgid "--open-files-in-pager only works on the worktree"
 msgstr ""
 "Die Option --open-files-in-pager kann nur innerhalb des "
 "Arbeitsverzeichnisses verwendet werden."
 
-#: builtin/grep.c:888
+#: builtin/grep.c:893
 msgid "--cached or --untracked cannot be used with --no-index."
 msgstr ""
 "Die Optionen --cached und --untracked können nicht mit --no-index verwendet "
 "werden."
 
-#: builtin/grep.c:893
+#: builtin/grep.c:898
 msgid "--no-index or --untracked cannot be used with revs."
 msgstr ""
 "Die Optionen --no-index und --untracked können nicht mit Commits verwendet "
 "werden."
 
-#: builtin/grep.c:896
+#: builtin/grep.c:901
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
 msgstr ""
 "Die Option --[no-]exclude-standard kann nicht mit beobachteten Inhalten "
 "verwendet werden."
 
-#: builtin/grep.c:904
+#: builtin/grep.c:909
 msgid "both --cached and trees are given."
 msgstr "Die Option --cached kann nicht mit \"Tree\"-Objekten verwendet werden."
 
@@ -5799,8 +5996,8 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SHA1 KOLLISION MIT %s GEFUNDEN !"
 
-#: builtin/index-pack.c:669 builtin/pack-objects.c:170
-#: builtin/pack-objects.c:262
+#: builtin/index-pack.c:669 builtin/pack-objects.c:171
+#: builtin/pack-objects.c:263
 #, c-format
 msgid "unable to read %s"
 msgstr "kann %s nicht lesen"
@@ -5829,155 +6026,155 @@
 msgid "Not all child objects of %s are reachable"
 msgstr "Nicht alle Kind-Objekte von %s sind erreichbar"
 
-#: builtin/index-pack.c:838 builtin/index-pack.c:868
+#: builtin/index-pack.c:839 builtin/index-pack.c:869
 msgid "failed to apply delta"
 msgstr "Konnte Dateiunterschied nicht anwenden"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Receiving objects"
 msgstr "Empfange Objekte"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Indexing objects"
 msgstr "Indiziere Objekte"
 
-#: builtin/index-pack.c:1035
+#: builtin/index-pack.c:1036
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "Paket ist beschädigt (SHA1 unterschiedlich)"
 
-#: builtin/index-pack.c:1040
+#: builtin/index-pack.c:1041
 msgid "cannot fstat packfile"
 msgstr "kann Paketdatei nicht lesen"
 
-#: builtin/index-pack.c:1043
+#: builtin/index-pack.c:1044
 msgid "pack has junk at the end"
 msgstr "Paketende enthält nicht verwendbaren Inhalt"
 
-#: builtin/index-pack.c:1054
+#: builtin/index-pack.c:1055
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "Fehler beim Ausführen von \"parse_pack_objects()\""
 
-#: builtin/index-pack.c:1077
+#: builtin/index-pack.c:1078
 msgid "Resolving deltas"
 msgstr "Löse Unterschiede auf"
 
-#: builtin/index-pack.c:1087
+#: builtin/index-pack.c:1088
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "kann Thread nicht erzeugen: %s"
 
-#: builtin/index-pack.c:1129
+#: builtin/index-pack.c:1130
 msgid "confusion beyond insanity"
 msgstr "Fehler beim Auflösen der Unterschiede"
 
-#: builtin/index-pack.c:1137
+#: builtin/index-pack.c:1138
 #, c-format
 msgid "completed with %d local objects"
 msgstr "vervollständigt mit %d lokalen Objekten"
 
-#: builtin/index-pack.c:1147
+#: builtin/index-pack.c:1148
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "Unerwartete Prüfsumme für %s (Festplattenfehler?)"
 
-#: builtin/index-pack.c:1151
+#: builtin/index-pack.c:1152
 #, 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:1176
+#: builtin/index-pack.c:1177
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "Konnte angehängtes Objekt (%d) nicht komprimieren"
 
-#: builtin/index-pack.c:1255
+#: builtin/index-pack.c:1256
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "lokales Objekt %s ist beschädigt"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1280
 msgid "error while closing pack file"
 msgstr "Fehler beim Schließen der Paketdatei"
 
-#: builtin/index-pack.c:1292
+#: builtin/index-pack.c:1293
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "Kann Paketbeschreibungsdatei '%s' nicht schreiben"
 
-#: builtin/index-pack.c:1300
+#: builtin/index-pack.c:1301
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr "Kann eben erstellte Paketbeschreibungsdatei '%s' nicht schließen"
 
-#: builtin/index-pack.c:1313
+#: builtin/index-pack.c:1314
 msgid "cannot store pack file"
 msgstr "Kann Paketdatei nicht speichern"
 
-#: builtin/index-pack.c:1324
+#: builtin/index-pack.c:1325
 msgid "cannot store index file"
 msgstr "Kann Indexdatei nicht speichern"
 
-#: builtin/index-pack.c:1357
+#: builtin/index-pack.c:1358
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "\"pack.indexversion=%<PRIu32>\" ist ungültig"
 
-#: builtin/index-pack.c:1363
+#: builtin/index-pack.c:1364
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "ungültige Anzahl von Threads angegeben (%d)"
 
-#: builtin/index-pack.c:1367 builtin/index-pack.c:1545
+#: builtin/index-pack.c:1368 builtin/index-pack.c:1546
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "keine Unterstützung von Threads, '%s' wird ignoriert"
 
-#: builtin/index-pack.c:1425
+#: builtin/index-pack.c:1426
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Kann existierende Paketdatei '%s' nicht öffnen"
 
-#: builtin/index-pack.c:1427
+#: builtin/index-pack.c:1428
 #, 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:1474
+#: builtin/index-pack.c:1475
 #, 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:1481
+#: builtin/index-pack.c:1482
 #, 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:1509
+#: builtin/index-pack.c:1510
 msgid "Cannot come back to cwd"
 msgstr "Kann nicht zurück zu Arbeitsverzeichnis wechseln"
 
-#: builtin/index-pack.c:1557 builtin/index-pack.c:1560
-#: builtin/index-pack.c:1572 builtin/index-pack.c:1576
+#: builtin/index-pack.c:1558 builtin/index-pack.c:1561
+#: builtin/index-pack.c:1573 builtin/index-pack.c:1577
 #, c-format
 msgid "bad %s"
 msgstr "%s ist ungültig"
 
-#: builtin/index-pack.c:1590
+#: builtin/index-pack.c:1591
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "Die Option --fix-thin kann nicht ohne --stdin verwendet werden."
 
-#: builtin/index-pack.c:1594 builtin/index-pack.c:1604
+#: builtin/index-pack.c:1595 builtin/index-pack.c:1605
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "Name der Paketdatei '%s' endet nicht mit '.pack'"
 
-#: builtin/index-pack.c:1613
+#: builtin/index-pack.c:1614
 msgid "--verify with no packfile name given"
 msgstr "Die Option --verify wurde ohne Namen der Paketdatei angegeben."
 
@@ -6066,11 +6263,6 @@
 msgid "unable to move %s to %s"
 msgstr "Konnte %s nicht nach %s verschieben"
 
-#: builtin/init-db.c:363
-#, c-format
-msgid "Could not create git link %s"
-msgstr "Konnte git-Verweis %s nicht erstellen"
-
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
 #. * existing" or "Initialized empty", the second " shared" or
@@ -6113,7 +6305,7 @@
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "gibt an, dass das Git-Repository mit mehreren Benutzern geteilt wird"
 
-#: builtin/init-db.c:493 builtin/prune-packed.c:75
+#: builtin/init-db.c:493 builtin/prune-packed.c:75 builtin/repack.c:155
 msgid "be quiet"
 msgstr "weniger Ausgaben"
 
@@ -6153,249 +6345,249 @@
 msgid "   or: git show [options] <object>..."
 msgstr "   oder: git show [Optionen] <Objekt>..."
 
-#: builtin/log.c:124
+#: builtin/log.c:125
 msgid "suppress diff output"
 msgstr "unterdrückt Ausgabe der Unterschiede"
 
-#: builtin/log.c:125
+#: builtin/log.c:126
 msgid "show source"
 msgstr "zeigt Quelle"
 
-#: builtin/log.c:126
+#: builtin/log.c:127
 msgid "Use mail map file"
 msgstr "verwendet \"mailmap\"-Datei"
 
-#: builtin/log.c:127
+#: builtin/log.c:128
 msgid "decorate options"
 msgstr "decorate-Optionen"
 
-#: builtin/log.c:230
+#: builtin/log.c:231
 #, c-format
 msgid "Final output: %d %s\n"
 msgstr "letzte Ausgabe: %d %s\n"
 
-#: builtin/log.c:453 builtin/log.c:545
+#: builtin/log.c:473 builtin/log.c:565
 #, c-format
 msgid "Could not read object %s"
 msgstr "Kann Objekt %s nicht lesen."
 
-#: builtin/log.c:569
+#: builtin/log.c:589
 #, c-format
 msgid "Unknown type: %d"
 msgstr "Unbekannter Typ: %d"
 
-#: builtin/log.c:669
+#: builtin/log.c:689
 msgid "format.headers without value"
 msgstr "format.headers ohne Wert"
 
-#: builtin/log.c:751
+#: builtin/log.c:771
 msgid "name of output directory is too long"
 msgstr "Name des Ausgabeverzeichnisses ist zu lang."
 
-#: builtin/log.c:767
+#: builtin/log.c:787
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "Kann Patch-Datei %s nicht öffnen"
 
-#: builtin/log.c:781
+#: builtin/log.c:801
 msgid "Need exactly one range."
 msgstr "Brauche genau einen Commit-Bereich."
 
-#: builtin/log.c:789
+#: builtin/log.c:809
 msgid "Not a range."
 msgstr "Kein Commit-Bereich."
 
-#: builtin/log.c:891
+#: builtin/log.c:911
 msgid "Cover letter needs email format"
 msgstr "Anschreiben benötigt E-Mail-Format"
 
-#: builtin/log.c:967
+#: builtin/log.c:987
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "ungültiges in-reply-to: %s"
 
-#: builtin/log.c:995
+#: builtin/log.c:1015
 msgid "git format-patch [options] [<since> | <revision range>]"
 msgstr "git format-patch [Optionen] [<seit> | <Commitbereich>]"
 
-#: builtin/log.c:1040
+#: builtin/log.c:1060
 msgid "Two output directories?"
 msgstr "Zwei Ausgabeverzeichnisse?"
 
-#: builtin/log.c:1155
+#: builtin/log.c:1175
 msgid "use [PATCH n/m] even with a single patch"
 msgstr "verwendet [PATCH n/m] auch mit einzelnem Patch"
 
-#: builtin/log.c:1158
+#: builtin/log.c:1178
 msgid "use [PATCH] even with multiple patches"
 msgstr "verwendet [PATCH] auch mit mehreren Patches"
 
-#: builtin/log.c:1162
+#: builtin/log.c:1182
 msgid "print patches to standard out"
 msgstr "Ausgabe der Patches in Standard-Ausgabe"
 
-#: builtin/log.c:1164
+#: builtin/log.c:1184
 msgid "generate a cover letter"
 msgstr "erzeugt ein Deckblatt"
 
-#: builtin/log.c:1166
+#: builtin/log.c:1186
 msgid "use simple number sequence for output file names"
 msgstr "verwendet einfache Nummernfolge für die Namen der Ausgabedateien"
 
-#: builtin/log.c:1167
+#: builtin/log.c:1187
 msgid "sfx"
 msgstr "Dateiendung"
 
-#: builtin/log.c:1168
+#: builtin/log.c:1188
 msgid "use <sfx> instead of '.patch'"
 msgstr "verwendet <Dateiendung> anstatt '.patch'"
 
-#: builtin/log.c:1170
+#: builtin/log.c:1190
 msgid "start numbering patches at <n> instead of 1"
 msgstr "beginnt die Nummerierung der Patches bei <n> anstatt bei 1"
 
-#: builtin/log.c:1172
+#: builtin/log.c:1192
 msgid "mark the series as Nth re-roll"
 msgstr "kennzeichnet die Serie als n-te Fassung"
 
-#: builtin/log.c:1174
+#: builtin/log.c:1194
 msgid "Use [<prefix>] instead of [PATCH]"
-msgstr "verwendet [<Prefix>] anstatt [PATCH]"
+msgstr "verwendet [<Präfix>] anstatt [PATCH]"
 
-#: builtin/log.c:1177
+#: builtin/log.c:1197
 msgid "store resulting files in <dir>"
 msgstr "speichert erzeugte Dateien in <Verzeichnis>"
 
-#: builtin/log.c:1180
+#: builtin/log.c:1200
 msgid "don't strip/add [PATCH]"
 msgstr "[PATCH] wird nicht entfernt/hinzugefügt"
 
-#: builtin/log.c:1183
+#: builtin/log.c:1203
 msgid "don't output binary diffs"
 msgstr "gibt keine binären Unterschiede aus"
 
-#: builtin/log.c:1185
+#: builtin/log.c:1205
 msgid "don't include a patch matching a commit upstream"
 msgstr ""
 "schließt keine Patches ein, die einem Commit im Upstream-Branch entsprechen"
 
-#: builtin/log.c:1187
+#: builtin/log.c:1207
 msgid "show patch format instead of default (patch + stat)"
 msgstr "zeigt Patchformat anstatt des Standards (Patch + Zusammenfassung)"
 
-#: builtin/log.c:1189
+#: builtin/log.c:1209
 msgid "Messaging"
 msgstr "Email-Einstellungen"
 
-#: builtin/log.c:1190
+#: builtin/log.c:1210
 msgid "header"
 msgstr "Header"
 
-#: builtin/log.c:1191
+#: builtin/log.c:1211
 msgid "add email header"
 msgstr "fügt Email-Header hinzu"
 
-#: builtin/log.c:1192 builtin/log.c:1194
+#: builtin/log.c:1212 builtin/log.c:1214
 msgid "email"
 msgstr "Email"
 
-#: builtin/log.c:1192
+#: builtin/log.c:1212
 msgid "add To: header"
 msgstr "fügt  \"To:\"-Header hinzu"
 
-#: builtin/log.c:1194
+#: builtin/log.c:1214
 msgid "add Cc: header"
 msgstr "fügt \"Cc:\"-Header hinzu"
 
-#: builtin/log.c:1196
+#: builtin/log.c:1216
 msgid "ident"
 msgstr "Ident"
 
-#: builtin/log.c:1197
+#: builtin/log.c:1217
 msgid "set From address to <ident> (or committer ident if absent)"
 msgstr ""
 "setzt \"From\"-Adresse auf <Ident> (oder Ident des Commit-Erstellers,wenn "
 "fehlend)"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1219
 msgid "message-id"
 msgstr "message-id"
 
-#: builtin/log.c:1200
+#: builtin/log.c:1220
 msgid "make first mail a reply to <message-id>"
 msgstr "macht aus erster Email eine Antwort zu <message-id>"
 
-#: builtin/log.c:1201 builtin/log.c:1204
+#: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
 msgstr "Grenze"
 
-#: builtin/log.c:1202
+#: builtin/log.c:1222
 msgid "attach the patch"
 msgstr "hängt einen Patch an"
 
-#: builtin/log.c:1205
+#: builtin/log.c:1225
 msgid "inline the patch"
 msgstr "fügt den Patch direkt in die Nachricht ein"
 
-#: builtin/log.c:1209
+#: builtin/log.c:1229
 msgid "enable message threading, styles: shallow, deep"
 msgstr "aktiviert Nachrichtenverkettung, Stile: shallow, deep"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1231
 msgid "signature"
 msgstr "Signatur"
 
-#: builtin/log.c:1212
+#: builtin/log.c:1232
 msgid "add a signature"
 msgstr "fügt eine Signatur hinzu"
 
-#: builtin/log.c:1214
+#: builtin/log.c:1233
 msgid "don't print the patch filenames"
 msgstr "zeigt keine Dateinamen der Patches"
 
-#: builtin/log.c:1288
+#: builtin/log.c:1307
 #, c-format
 msgid "invalid ident line: %s"
 msgstr "Ungültige Identifikationszeile: %s"
 
-#: builtin/log.c:1303
+#: builtin/log.c:1322
 msgid "-n and -k are mutually exclusive."
 msgstr "Die Optionen -n und -k schließen sich gegenseitig aus."
 
-#: builtin/log.c:1305
+#: builtin/log.c:1324
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "Die Optionen --subject-prefix und -k schließen sich gegenseitig aus."
 
-#: builtin/log.c:1313
+#: builtin/log.c:1332
 msgid "--name-only does not make sense"
 msgstr "Die Option --name-only kann nicht verwendet werden."
 
-#: builtin/log.c:1315
+#: builtin/log.c:1334
 msgid "--name-status does not make sense"
 msgstr "Die Option --name-status kann nicht verwendet werden."
 
-#: builtin/log.c:1317
+#: builtin/log.c:1336
 msgid "--check does not make sense"
 msgstr "Die Option --check kann nicht verwendet werden."
 
-#: builtin/log.c:1340
+#: builtin/log.c:1359
 msgid "standard output, or directory, which one?"
 msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?"
 
-#: builtin/log.c:1342
+#: builtin/log.c:1361
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "Konnte Verzeichnis '%s' nicht erstellen."
 
-#: builtin/log.c:1490
+#: builtin/log.c:1509
 msgid "Failed to create output files"
 msgstr "Fehler beim Erstellen der Ausgabedateien."
 
-#: builtin/log.c:1539
+#: builtin/log.c:1558
 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
 msgstr "git cherry [-v] [<Upstream> [<Branch> [<Limit>]]]"
 
-#: builtin/log.c:1594
+#: builtin/log.c:1613
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
@@ -6403,143 +6595,143 @@
 "Konnte gefolgten Remote-Branch nicht finden, bitte geben Sie <Upstream> "
 "manuell an.\n"
 
-#: builtin/log.c:1607 builtin/log.c:1609 builtin/log.c:1621
+#: builtin/log.c:1626 builtin/log.c:1628 builtin/log.c:1640
 #, c-format
 msgid "Unknown commit %s"
 msgstr "Unbekannter Commit %s"
 
-#: builtin/ls-files.c:408
+#: builtin/ls-files.c:398
 msgid "git ls-files [options] [<file>...]"
 msgstr "git ls-files [Optionen] [<Datei>...]"
 
-#: builtin/ls-files.c:465
+#: builtin/ls-files.c:455
 msgid "identify the file status with tags"
 msgstr "zeigt den Dateistatus mit Tags"
 
-#: builtin/ls-files.c:467
+#: builtin/ls-files.c:457
 msgid "use lowercase letters for 'assume unchanged' files"
 msgstr ""
 "verwendet Kleinbuchstaben für Dateien mit 'assume unchanged' Markierung"
 
-#: builtin/ls-files.c:469
+#: builtin/ls-files.c:459
 msgid "show cached files in the output (default)"
 msgstr "zeigt zwischengespeicherten Dateien in der Ausgabe an (Standard)"
 
-#: builtin/ls-files.c:471
+#: builtin/ls-files.c:461
 msgid "show deleted files in the output"
 msgstr "zeigt entfernte Dateien in der Ausgabe an"
 
-#: builtin/ls-files.c:473
+#: builtin/ls-files.c:463
 msgid "show modified files in the output"
 msgstr "zeigt geänderte Dateien in der Ausgabe an"
 
-#: builtin/ls-files.c:475
+#: builtin/ls-files.c:465
 msgid "show other files in the output"
 msgstr "zeigt sonstige Dateien in der Ausgabe an"
 
-#: builtin/ls-files.c:477
+#: builtin/ls-files.c:467
 msgid "show ignored files in the output"
 msgstr "zeigt ignorierte Dateien in der Ausgabe an"
 
-#: builtin/ls-files.c:480
+#: builtin/ls-files.c:470
 msgid "show staged contents' object name in the output"
 msgstr ""
 "zeigt Objektnamen von Inhalten, die zum Commit vorgemerkt sind, in der "
 "Ausgabe an"
 
-#: builtin/ls-files.c:482
+#: builtin/ls-files.c:472
 msgid "show files on the filesystem that need to be removed"
 msgstr "zeigt Dateien im Dateisystem, die gelöscht werden müssen, an"
 
-#: builtin/ls-files.c:484
+#: builtin/ls-files.c:474
 msgid "show 'other' directories' name only"
 msgstr "zeigt nur Namen von 'sonstigen' Verzeichnissen an"
 
-#: builtin/ls-files.c:487
+#: builtin/ls-files.c:477
 msgid "don't show empty directories"
 msgstr "zeigt keine leeren Verzeichnisse an"
 
-#: builtin/ls-files.c:490
+#: builtin/ls-files.c:480
 msgid "show unmerged files in the output"
 msgstr "zeigt nicht zusammengeführte Dateien in der Ausgabe an"
 
-#: builtin/ls-files.c:492
+#: builtin/ls-files.c:482
 msgid "show resolve-undo information"
 msgstr "zeigt 'resolve-undo' Informationen an"
 
-#: builtin/ls-files.c:494
+#: builtin/ls-files.c:484
 msgid "skip files matching pattern"
 msgstr "lässt Dateien aus, die einem Muster entsprechen"
 
-#: builtin/ls-files.c:497
+#: builtin/ls-files.c:487
 msgid "exclude patterns are read from <file>"
 msgstr "schließt Muster, gelesen von <Datei>, aus"
 
-#: builtin/ls-files.c:500
+#: builtin/ls-files.c:490
 msgid "read additional per-directory exclude patterns in <file>"
 msgstr "liest zusätzliche pro-Verzeichnis Auschlussmuster aus <Datei>"
 
-#: builtin/ls-files.c:502
+#: builtin/ls-files.c:492
 msgid "add the standard git exclusions"
 msgstr "fügt die standardmäßigen Git-Ausschlüsse hinzu"
 
-#: builtin/ls-files.c:505
+#: builtin/ls-files.c:495
 msgid "make the output relative to the project top directory"
 msgstr "Ausgabe relativ zum Projektverzeichnis"
 
-#: builtin/ls-files.c:508
+#: builtin/ls-files.c:498
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr ""
 "behandle es als Fehler, wenn sich eine <Datei> nicht in der Staging-Area "
 "befindet"
 
-#: builtin/ls-files.c:509
+#: builtin/ls-files.c:499
 msgid "tree-ish"
 msgstr "Commit-Referenz"
 
-#: builtin/ls-files.c:510
+#: builtin/ls-files.c:500
 msgid "pretend that paths removed since <tree-ish> are still present"
 msgstr ""
 "gibt vor, dass Pfade, die seit <Commit-Referenz> gelöscht wurden, immer noch "
 "vorhanden sind"
 
-#: builtin/ls-files.c:512
+#: builtin/ls-files.c:502
 msgid "show debugging data"
 msgstr "zeigt Ausgaben zur Fehlersuche an"
 
-#: builtin/ls-tree.c:27
+#: builtin/ls-tree.c:28
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<Optionen>] <Commit-Referenz> [<Pfad>...]"
 
-#: builtin/ls-tree.c:125
+#: builtin/ls-tree.c:126
 msgid "only show trees"
 msgstr "zeigt nur Verzeichnisse an"
 
-#: builtin/ls-tree.c:127
+#: builtin/ls-tree.c:128
 msgid "recurse into subtrees"
 msgstr "führt Rekursion in Unterverzeichnissen durch"
 
-#: builtin/ls-tree.c:129
+#: builtin/ls-tree.c:130
 msgid "show trees when recursing"
 msgstr "zeigt Verzeichnisse bei Rekursion an"
 
-#: builtin/ls-tree.c:132
+#: builtin/ls-tree.c:133
 msgid "terminate entries with NUL byte"
 msgstr "schließt Einträge mit NUL-Byte ab"
 
-#: builtin/ls-tree.c:133
+#: builtin/ls-tree.c:134
 msgid "include object size"
 msgstr "schließt Objektgröße ein"
 
-#: builtin/ls-tree.c:135 builtin/ls-tree.c:137
+#: builtin/ls-tree.c:136 builtin/ls-tree.c:138
 msgid "list only filenames"
 msgstr "listet nur Dateinamen auf"
 
-#: builtin/ls-tree.c:140
+#: builtin/ls-tree.c:141
 msgid "use full path names"
 msgstr "verwendet vollständige Pfadnamen"
 
-#: builtin/ls-tree.c:142
+#: builtin/ls-tree.c:143
 msgid "list entire tree; not just current directory (implies --full-name)"
 msgstr ""
 "listet das gesamte Verzeichnis auf; nicht nur das aktuelle Verzeichnis "
@@ -6618,7 +6810,7 @@
 msgid "Verify that the named commit has a valid GPG signature"
 msgstr "überprüft den genannten Commit auf eine gültige GPG-Signatur"
 
-#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:114
+#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:89
 msgid "strategy"
 msgstr "Strategie"
 
@@ -6994,76 +7186,87 @@
 msgid "allow creation of more than one tree"
 msgstr "erlaubt die Erstellung von mehr als einem \"Tree\"-Objekt"
 
-#: builtin/mv.c:14
+#: builtin/mv.c:15
 msgid "git mv [options] <source>... <destination>"
 msgstr "git mv [Optionen] <Quelle>... <Ziel>"
 
-#: builtin/mv.c:64
+#: builtin/mv.c:67
 msgid "force move/rename even if target exists"
 msgstr "erzwingt Verschieben/Umbenennen, auch wenn das Ziel existiert"
 
-#: builtin/mv.c:65
+#: builtin/mv.c:68
 msgid "skip move/rename errors"
 msgstr "überspringt Fehler beim Verschieben oder Umbenennen"
 
-#: builtin/mv.c:108
+#: builtin/mv.c:113
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
 msgstr "Prüfe Umbenennung von '%s' nach '%s'\n"
 
-#: builtin/mv.c:112
+#: builtin/mv.c:117
 msgid "bad source"
 msgstr "ungültige Quelle"
 
-#: builtin/mv.c:115
+#: builtin/mv.c:120
 msgid "can not move directory into itself"
 msgstr "kann Verzeichnis nicht in sich selbst verschieben"
 
-#: builtin/mv.c:118
+#: builtin/mv.c:123
 msgid "cannot move directory over file"
 msgstr "kann Verzeichnis nicht über Datei verschieben"
 
-#: builtin/mv.c:128
+#: builtin/mv.c:129
+#, c-format
+msgid "Huh? Directory %s is in index and no submodule?"
+msgstr "Huh? Verzeichnis %s ist zum Commit vorgemerkt und kein Submodul?"
+
+#: builtin/mv.c:131 builtin/rm.c:318
+msgid "Please, stage your changes to .gitmodules or stash them to proceed"
+msgstr ""
+"Bitte merken Sie Ihre Änderungen in .gitmodules zum Commit vor oder benutzen\n"
+"Sie \"stash\" um fortzufahren."
+
+#: builtin/mv.c:147
 #, c-format
 msgid "Huh? %.*s is in index?"
 msgstr "Huh? %.*s ist zum Commit vorgemerkt?"
 
-#: builtin/mv.c:140
+#: builtin/mv.c:159
 msgid "source directory is empty"
 msgstr "Quellverzeichnis ist leer"
 
-#: builtin/mv.c:171
+#: builtin/mv.c:191
 msgid "not under version control"
 msgstr "nicht unter Versionskontrolle"
 
-#: builtin/mv.c:173
+#: builtin/mv.c:193
 msgid "destination exists"
 msgstr "Ziel existiert bereits"
 
-#: builtin/mv.c:181
+#: builtin/mv.c:201
 #, c-format
 msgid "overwriting '%s'"
 msgstr "überschreibe '%s'"
 
-#: builtin/mv.c:184
+#: builtin/mv.c:204
 msgid "Cannot overwrite"
 msgstr "Kann nicht überschreiben"
 
-#: builtin/mv.c:187
+#: builtin/mv.c:207
 msgid "multiple sources for the same target"
 msgstr "mehrere Quellen für das selbe Ziel"
 
-#: builtin/mv.c:202
+#: builtin/mv.c:222
 #, c-format
 msgid "%s, source=%s, destination=%s"
 msgstr "%s, Quelle=%s, Ziel=%s"
 
-#: builtin/mv.c:212
+#: builtin/mv.c:232
 #, c-format
 msgid "Renaming %s to %s\n"
 msgstr "Benenne %s nach %s um\n"
 
-#: builtin/mv.c:215 builtin/remote.c:731
+#: builtin/mv.c:235 builtin/remote.c:731 builtin/repack.c:330
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "Umbenennung von '%s' fehlgeschlagen"
@@ -7101,8 +7304,8 @@
 msgstr "liest von der Standard-Eingabe"
 
 #: builtin/name-rev.c:320
-msgid "allow to print `undefined` names"
-msgstr "erlaubt Ausgabe von `undefinierten` Namen"
+msgid "allow to print `undefined` names (default)"
+msgstr "erlaubt Ausgabe von `undefinierten` Namen (Standard)"
 
 #: builtin/name-rev.c:326
 msgid "dereference tags in the input (internal use)"
@@ -7258,12 +7461,12 @@
 msgid "The note contents has been left in %s"
 msgstr "Die Notiz-Inhalte wurden in %s belassen"
 
-#: builtin/notes.c:248 builtin/tag.c:540
+#: builtin/notes.c:248 builtin/tag.c:537
 #, c-format
 msgid "cannot read '%s'"
 msgstr "kann '%s' nicht lesen"
 
-#: builtin/notes.c:250 builtin/tag.c:543
+#: builtin/notes.c:250 builtin/tag.c:540
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "konnte '%s' nicht öffnen oder lesen"
@@ -7271,7 +7474,7 @@
 #: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318
 #: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515
 #: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637
-#: builtin/notes.c:839 builtin/tag.c:556
+#: builtin/notes.c:839 builtin/tag.c:553
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "Konnte '%s' nicht als gültige Referenz auflösen."
@@ -7448,153 +7651,153 @@
 msgstr ""
 "git pack-objects [Optionen...] Basis-Name [< Referenzliste | < Objektliste]"
 
-#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#: builtin/pack-objects.c:184 builtin/pack-objects.c:187
 #, c-format
 msgid "deflate error (%d)"
 msgstr "Fehler beim Komprimieren (%d)"
 
-#: builtin/pack-objects.c:2397
+#: builtin/pack-objects.c:2398
 #, c-format
 msgid "unsupported index version %s"
 msgstr "Nicht unterstützte Staging-Area-Version %s"
 
-#: builtin/pack-objects.c:2401
+#: builtin/pack-objects.c:2402
 #, c-format
 msgid "bad index version '%s'"
 msgstr "Ungültige Staging-Area-Version '%s'"
 
-#: builtin/pack-objects.c:2424
+#: builtin/pack-objects.c:2425
 #, c-format
 msgid "option %s does not accept negative form"
 msgstr "Option %s akzeptiert keine negative Form"
 
-#: builtin/pack-objects.c:2428
+#: builtin/pack-objects.c:2429
 #, c-format
 msgid "unable to parse value '%s' for option %s"
 msgstr "konnte Wert '%s' für Option %s nicht parsen"
 
-#: builtin/pack-objects.c:2447
+#: builtin/pack-objects.c:2448
 msgid "do not show progress meter"
 msgstr "zeigt keine Fortschrittsanzeige"
 
-#: builtin/pack-objects.c:2449
+#: builtin/pack-objects.c:2450
 msgid "show progress meter"
 msgstr "zeigt Fortschrittsanzeige"
 
-#: builtin/pack-objects.c:2451
+#: builtin/pack-objects.c:2452
 msgid "show progress meter during object writing phase"
 msgstr "zeigt Forschrittsanzeige während der Phase des Schreibens der Objekte"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:2455
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "ähnlich zu --all-progress wenn Fortschrittsanzeige darstellt wird"
 
-#: builtin/pack-objects.c:2455
+#: builtin/pack-objects.c:2456
 msgid "version[,offset]"
 msgstr "version[,offset]"
 
-#: builtin/pack-objects.c:2456
+#: builtin/pack-objects.c:2457
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
 "schreibt die Index-Datei des Paketes in der angegebenen Indexformat-Version"
 
-#: builtin/pack-objects.c:2459
+#: builtin/pack-objects.c:2460
 msgid "maximum size of each output pack file"
 msgstr "maximale Größe für jede ausgegebene Paketdatei"
 
-#: builtin/pack-objects.c:2461
+#: builtin/pack-objects.c:2462
 msgid "ignore borrowed objects from alternate object store"
 msgstr "ignoriert geliehene Objekte von alternativem Objektspeicher"
 
-#: builtin/pack-objects.c:2463
+#: builtin/pack-objects.c:2464
 msgid "ignore packed objects"
 msgstr "ignoriert gepackte Objekte"
 
-#: builtin/pack-objects.c:2465
+#: builtin/pack-objects.c:2466
 msgid "limit pack window by objects"
 msgstr "begrenzt Paketfenster durch Objekte"
 
-#: builtin/pack-objects.c:2467
+#: builtin/pack-objects.c:2468
 msgid "limit pack window by memory in addition to object limit"
 msgstr "begrenzt Paketfenster, zusätzlich zur Objektbegrenzung, durch Speicher"
 
-#: builtin/pack-objects.c:2469
+#: builtin/pack-objects.c:2470
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr ""
 "maximale Länge der erlaubten Differenzverkettung im resultierenden Paket"
 
-#: builtin/pack-objects.c:2471
+#: builtin/pack-objects.c:2472
 msgid "reuse existing deltas"
 msgstr "verwendet existierende Unterschiede wieder"
 
-#: builtin/pack-objects.c:2473
+#: builtin/pack-objects.c:2474
 msgid "reuse existing objects"
 msgstr "verwendet existierende Objekte wieder"
 
-#: builtin/pack-objects.c:2475
+#: builtin/pack-objects.c:2476
 msgid "use OFS_DELTA objects"
 msgstr "verwendet OFS_DELTA Objekte"
 
-#: builtin/pack-objects.c:2477
+#: builtin/pack-objects.c:2478
 msgid "use threads when searching for best delta matches"
 msgstr ""
 "verwendet Threads bei der Suche nach den besten Übereinstimmungen bei "
 "Unterschieden"
 
-#: builtin/pack-objects.c:2479
+#: builtin/pack-objects.c:2480
 msgid "do not create an empty pack output"
 msgstr "erzeugt keine leeren Pakete"
 
-#: builtin/pack-objects.c:2481
+#: builtin/pack-objects.c:2482
 msgid "read revision arguments from standard input"
 msgstr "liest Argumente bezüglich Commits von der Standard-Eingabe"
 
-#: builtin/pack-objects.c:2483
+#: builtin/pack-objects.c:2484
 msgid "limit the objects to those that are not yet packed"
 msgstr "begrenzt die Objekte zu solchen, die noch nicht gepackt wurden"
 
-#: builtin/pack-objects.c:2486
+#: builtin/pack-objects.c:2487
 msgid "include objects reachable from any reference"
 msgstr "schließt Objekte ein, die von jeder Referenz erreichbar sind"
 
-#: builtin/pack-objects.c:2489
+#: builtin/pack-objects.c:2490
 msgid "include objects referred by reflog entries"
 msgstr ""
 "schließt Objekte ein, die von Einträgen des Reflogs referenziert werden"
 
-#: builtin/pack-objects.c:2492
+#: builtin/pack-objects.c:2493
 msgid "output pack to stdout"
 msgstr "schreibt Paket in die Standard-Ausgabe"
 
-#: builtin/pack-objects.c:2494
+#: builtin/pack-objects.c:2495
 msgid "include tag objects that refer to objects to be packed"
 msgstr "schließt Tag-Objekte ein, die auf gepackte Objekte referenzieren"
 
-#: builtin/pack-objects.c:2496
+#: builtin/pack-objects.c:2497
 msgid "keep unreachable objects"
 msgstr "behält nicht erreichbare Objekte"
 
-#: builtin/pack-objects.c:2497 parse-options.h:141
+#: builtin/pack-objects.c:2498 parse-options.h:143
 msgid "time"
 msgstr "Zeit"
 
-#: builtin/pack-objects.c:2498
+#: builtin/pack-objects.c:2499
 msgid "unpack unreachable objects newer than <time>"
 msgstr "entpackt nicht erreichbare Objekte, die neuer als <Zeit> sind"
 
-#: builtin/pack-objects.c:2501
+#: builtin/pack-objects.c:2502
 msgid "create thin packs"
 msgstr "erzeugt dünnere Pakete"
 
-#: builtin/pack-objects.c:2503
+#: builtin/pack-objects.c:2504
 msgid "ignore packs that have companion .keep file"
 msgstr "ignoriert Pakete die .keep Dateien haben"
 
-#: builtin/pack-objects.c:2505
+#: builtin/pack-objects.c:2506
 msgid "pack compression level"
 msgstr "Komprimierungsgrad für Paketierung"
 
-#: builtin/pack-objects.c:2507
+#: builtin/pack-objects.c:2508
 msgid "do not hide commits by grafts"
 msgstr "verbirgt keine Commits mit künstlichen Vorgängern (\"grafts\")"
 
@@ -7634,15 +7837,15 @@
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<Optionen>] [<Repository> [<Refspec>...]]"
 
-#: builtin/push.c:45
+#: builtin/push.c:47
 msgid "tag shorthand without <tag>"
 msgstr "Kurzschrift für Tag ohne <Tag>"
 
-#: builtin/push.c:64
+#: builtin/push.c:66
 msgid "--delete only accepts plain target ref names"
 msgstr "Die Option --delete akzeptiert nur reine Referenznamen als Ziel."
 
-#: builtin/push.c:99
+#: builtin/push.c:101
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -7651,7 +7854,7 @@
 "Um eine Variante permanent zu verwenden, siehe push.default in 'git help "
 "config'."
 
-#: builtin/push.c:102
+#: builtin/push.c:104
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -7677,7 +7880,7 @@
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:117
+#: builtin/push.c:119
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -7692,7 +7895,7 @@
 "\n"
 "    git push %s HEAD:<Name-des-Remote-Branches>\n"
 
-#: builtin/push.c:131
+#: builtin/push.c:133
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -7706,13 +7909,13 @@
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:139
+#: builtin/push.c:141
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr ""
 "Der aktuelle Branch %s hat mehrere Upstream-Branches, \"push\" verweigert."
 
-#: builtin/push.c:142
+#: builtin/push.c:144
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -7720,10 +7923,10 @@
 "to update which remote branch."
 msgstr ""
 "Sie versenden nach '%s', welches kein Upstream-Repository Ihres aktuellen\n"
-"Branches '%s' ist, ohne mir mitzuteilen, was ich versenden soll, um welchen\n"
+"Branches '%s' ist, ohne anzugeben, was versendet werden soll, um welchen\n"
 "Remote-Branch zu aktualisieren."
 
-#: builtin/push.c:165
+#: builtin/push.c:167
 msgid ""
 "push.default is unset; its implicit value is changing in\n"
 "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -7758,14 +7961,14 @@
 "Modus 'current' anstatt 'simple', falls Sie gelegentlich ältere Versionen "
 "von Git benutzen.)"
 
-#: builtin/push.c:225
+#: builtin/push.c:227
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "Sie haben keine Refspec für \"push\" angegeben, und push.default ist "
 "\"nothing\"."
 
-#: builtin/push.c:232
+#: builtin/push.c:234
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -7779,7 +7982,7 @@
 "Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
 "für weitere Details."
 
-#: builtin/push.c:238
+#: builtin/push.c:240
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. If you did not intend to push that branch, you may want to\n"
@@ -7795,7 +7998,7 @@
 "'simple', 'current'\n"
 "oder 'upstream' setzen, um nur den aktuellen Branch zu versenden."
 
-#: builtin/push.c:244
+#: builtin/push.c:246
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. Check out this branch and integrate the remote changes\n"
@@ -7809,7 +8012,7 @@
 "Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
 "für weitere Details."
 
-#: builtin/push.c:250
+#: builtin/push.c:252
 msgid ""
 "Updates were rejected because the remote contains work that you do\n"
 "not have locally. This is usually caused by another repository pushing\n"
@@ -7828,13 +8031,13 @@
 "Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
 "für weitere Details."
 
-#: builtin/push.c:257
+#: builtin/push.c:259
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
 "Aktualisierungen wurden zurückgewiesen, weil das Tag bereits\n"
 "im Remote-Repository existiert."
 
-#: builtin/push.c:260
+#: builtin/push.c:262
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -7844,22 +8047,22 @@
 "das kein Commit ist, oder es auf ein solches Objekt zeigen lassen, ohne\n"
 "die Option '--force' zu verwenden.\n"
 
-#: builtin/push.c:320
+#: builtin/push.c:328
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Versende nach %s\n"
 
-#: builtin/push.c:324
+#: builtin/push.c:332
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "Fehler beim Versenden einiger Referenzen nach '%s'"
 
-#: builtin/push.c:357
+#: builtin/push.c:365
 #, c-format
 msgid "bad repository '%s'"
 msgstr "ungültiges Repository '%s'"
 
-#: builtin/push.c:358
+#: builtin/push.c:366
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -7881,87 +8084,95 @@
 "\n"
 "    git push <Name>\n"
 
-#: builtin/push.c:373
+#: builtin/push.c:381
 msgid "--all and --tags are incompatible"
 msgstr "Die Optionen --all und --tags sind inkompatibel."
 
-#: builtin/push.c:374
+#: builtin/push.c:382
 msgid "--all can't be combined with refspecs"
 msgstr "Die Option --all kann nicht mit Refspecs kombiniert werden."
 
-#: builtin/push.c:379
+#: builtin/push.c:387
 msgid "--mirror and --tags are incompatible"
 msgstr "Die Optionen --mirror und --tags sind inkompatibel."
 
-#: builtin/push.c:380
+#: builtin/push.c:388
 msgid "--mirror can't be combined with refspecs"
 msgstr "Die Option --mirror kann nicht mit Refspecs kombiniert werden."
 
-#: builtin/push.c:385
+#: builtin/push.c:393
 msgid "--all and --mirror are incompatible"
 msgstr "Die Optionen --all und --mirror sind inkompatibel."
 
-#: builtin/push.c:445
+#: builtin/push.c:453
 msgid "repository"
 msgstr "Repository"
 
-#: builtin/push.c:446
+#: builtin/push.c:454
 msgid "push all refs"
 msgstr "versendet alle Referenzen"
 
-#: builtin/push.c:447
+#: builtin/push.c:455
 msgid "mirror all refs"
 msgstr "spiegelt alle Referenzen"
 
-#: builtin/push.c:449
+#: builtin/push.c:457
 msgid "delete refs"
 msgstr "löscht Referenzen"
 
-#: builtin/push.c:450
+#: builtin/push.c:458
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "versendet Tags (kann nicht mit --all oder --mirror verwendet werden)"
 
-#: builtin/push.c:453
+#: builtin/push.c:461
 msgid "force updates"
 msgstr "erzwingt Aktualisierung"
 
-#: builtin/push.c:454
+#: builtin/push.c:463
+msgid "refname>:<expect"
+msgstr "Referenzname>:<Erwartungswert"
+
+#: builtin/push.c:464
+msgid "require old value of ref to be at this value"
+msgstr "Referenz muss sich auf dem angegebenen Wert befinden"
+
+#: builtin/push.c:466
 msgid "check"
 msgstr ""
 
-#: builtin/push.c:455
+#: builtin/push.c:467
 msgid "control recursive pushing of submodules"
 msgstr "steuert rekursiven \"push\" von Submodulen"
 
-#: builtin/push.c:457
+#: builtin/push.c:469
 msgid "use thin pack"
 msgstr "verwendet kleinere Pakete"
 
-#: builtin/push.c:458 builtin/push.c:459
+#: builtin/push.c:470 builtin/push.c:471
 msgid "receive pack program"
 msgstr "'receive pack' Programm"
 
-#: builtin/push.c:460
+#: builtin/push.c:472
 msgid "set upstream for git pull/status"
 msgstr "setzt Upstream für \"git pull/status\""
 
-#: builtin/push.c:463
+#: builtin/push.c:475
 msgid "prune locally removed refs"
 msgstr "entfernt lokal gelöschte Referenzen"
 
-#: builtin/push.c:465
+#: builtin/push.c:477
 msgid "bypass pre-push hook"
 msgstr "umgeht \"pre-push hook\""
 
-#: builtin/push.c:466
+#: builtin/push.c:478
 msgid "push missing but relevant tags"
 msgstr "versendet fehlende, aber relevante Tags"
 
-#: builtin/push.c:476
+#: builtin/push.c:488
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "Die Option --delete ist inkompatibel mit --all, --mirror und --tags."
 
-#: builtin/push.c:478
+#: builtin/push.c:490
 msgid "--delete doesn't make sense without any refs"
 msgstr "Die Option --delete kann nur mit Referenzen verwendet werden."
 
@@ -7971,7 +8182,7 @@
 "[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
 "index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
 msgstr ""
-"git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<Prefix>] "
+"git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<Präfix>] "
 "[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
 "index-output=<Datei>] (--empty | <Commit-Referenz1> [<Commit-Referenz2> "
 "[<Commit-Referenz3>]])"
@@ -8040,12 +8251,12 @@
 msgid "debug unpack-trees"
 msgstr "protokolliert Entpacken der Bäume"
 
-#: builtin/reflog.c:500
+#: builtin/reflog.c:499
 #, c-format
 msgid "%s' for '%s' is not a valid timestamp"
 msgstr "'%s' für '%s' ist kein gültiger Zeitstempel"
 
-#: builtin/reflog.c:616 builtin/reflog.c:621
+#: builtin/reflog.c:615 builtin/reflog.c:620
 #, c-format
 msgid "'%s' is not a valid timestamp"
 msgstr "'%s' ist kein gültiger Zeitstempel"
@@ -8070,9 +8281,9 @@
 msgid "git remote remove <name>"
 msgstr "git remote remove <Name>"
 
-#: builtin/remote.c:15 builtin/remote.c:42
-msgid "git remote set-head <name> (-a | -d | <branch>)"
-msgstr "git remote set-head <Name> (-a | -d | <Branch>)"
+#: builtin/remote.c:15
+msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"
+msgstr "git remote set-head <Name> (-a | --auto | -d | --delete | <Branch>)"
 
 #: builtin/remote.c:16
 msgid "git remote [-v | --verbose] show [-n] <name>"
@@ -8108,6 +8319,10 @@
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<Optionen>] <Name> <URL>"
 
+#: builtin/remote.c:42
+msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
+msgstr "git remote set-head <Name> (-a | --auto | -d | --delete | <Branch>)"
+
 #: builtin/remote.c:47
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <Name> <Branch>..."
@@ -8557,6 +8772,68 @@
 msgid "be verbose; must be placed before a subcommand"
 msgstr "erweiterte Ausgaben; muss vor einem Unterkommando angegeben werden"
 
+#: builtin/repack.c:15
+msgid "git repack [options]"
+msgstr "git repack [Optionen]"
+
+#: builtin/repack.c:143
+msgid "pack everything in a single pack"
+msgstr "packt alles in eine einzige Pack-Datei"
+
+#: builtin/repack.c:145
+msgid "same as -a, and turn unreachable objects loose"
+msgstr "genau wie -a, unerreichbare Objekte werden aber nicht gelöscht"
+
+#: builtin/repack.c:148
+msgid "remove redundant packs, and run git-prune-packed"
+msgstr "entfernt redundante Pakete und führt \"git-prune-packed\" aus"
+
+#: builtin/repack.c:150
+msgid "pass --no-reuse-delta to git-pack-objects"
+msgstr "übergibt --no-reuse-delta an git-pack-objects"
+
+#: builtin/repack.c:152
+msgid "pass --no-reuse-object to git-pack-objects"
+msgstr "übergibt --no-reuse-object an git-pack-objects"
+
+#: builtin/repack.c:154
+msgid "do not run git-update-server-info"
+msgstr "git-update-server-info nicht ausführen"
+
+#: builtin/repack.c:157
+msgid "pass --local to git-pack-objects"
+msgstr "übergibt --local an git-pack-objects"
+
+#: builtin/repack.c:158
+msgid "approxidate"
+msgstr "Datumsangabe"
+
+#: builtin/repack.c:159
+msgid "with -A, do not loosen objects older than this"
+msgstr "mit -A, löscht keine Objekte älter als dieses Datum"
+
+#: builtin/repack.c:161
+msgid "size of the window used for delta compression"
+msgstr "Größe des Fensters für die Delta-Kompression"
+
+#: builtin/repack.c:163
+msgid "same as the above, but limit memory size instead of entries count"
+msgstr "gleiches wie oben, limitiert aber die Speichergröße anstatt der\n"
+"Anzahl der Einträge"
+
+#: builtin/repack.c:165
+msgid "limits the maximum delta depth"
+msgstr "limitiert die maximale Delta-Tiefe"
+
+#: builtin/repack.c:167
+msgid "maximum size of each packfile"
+msgstr "maximale Größe für jede Paketdatei"
+
+#: builtin/repack.c:345
+#, c-format
+msgid "removing '%s' failed"
+msgstr "Löschen von '%s' fehlgeschlagen"
+
 #: builtin/replace.c:17
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <Objekt> <Ersetzung>"
@@ -8569,23 +8846,23 @@
 msgid "git replace -l [<pattern>]"
 msgstr "git replace -l [<Muster>]"
 
-#: builtin/replace.c:121
+#: builtin/replace.c:131
 msgid "list replace refs"
 msgstr "listet ersetzende Referenzen auf"
 
-#: builtin/replace.c:122
+#: builtin/replace.c:132
 msgid "delete replace refs"
 msgstr "löscht ersetzende Referenzen"
 
-#: builtin/replace.c:123
+#: builtin/replace.c:133
 msgid "replace the ref if it exists"
 msgstr "ersetzt die Referenz, wenn sie existiert"
 
-#: builtin/rerere.c:11
+#: builtin/rerere.c:12
 msgid "git rerere [clear | forget path... | status | remaining | diff | gc]"
 msgstr "git rerere [clean | forget path... | status | remaining | diff | gc]"
 
-#: builtin/rerere.c:56
+#: builtin/rerere.c:57
 msgid "register clean resolutions in index"
 msgstr "registriert saubere Auflösungen in der Staging-Area"
 
@@ -8646,71 +8923,71 @@
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr "Kann keinen '%s'-Reset durchführen, während ein Merge im Gange ist."
 
-#: builtin/reset.c:251
+#: builtin/reset.c:262
 msgid "be quiet, only report errors"
 msgstr "weniger Ausgaben, meldet nur Fehler"
 
-#: builtin/reset.c:253
+#: builtin/reset.c:264
 msgid "reset HEAD and index"
 msgstr "setzt HEAD und Staging-Area um"
 
-#: builtin/reset.c:254
+#: builtin/reset.c:265
 msgid "reset only HEAD"
 msgstr "setzt nur HEAD um"
 
-#: builtin/reset.c:256 builtin/reset.c:258
+#: builtin/reset.c:267 builtin/reset.c:269
 msgid "reset HEAD, index and working tree"
 msgstr "setzt HEAD, Staging-Area und Arbeitsverzeichnis um"
 
-#: builtin/reset.c:260
+#: builtin/reset.c:271
 msgid "reset HEAD but keep local changes"
 msgstr "setzt HEAD um, behält aber lokale Änderungen"
 
-#: builtin/reset.c:278
+#: builtin/reset.c:289
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
 msgstr "Konnte '%s' nicht als gültigen Commit auflösen."
 
-#: builtin/reset.c:281 builtin/reset.c:289
+#: builtin/reset.c:292 builtin/reset.c:300
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "Konnte Objekt '%s' nicht parsen."
 
-#: builtin/reset.c:286
+#: builtin/reset.c:297
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
 msgstr "Konnte '%s' nicht als gültiges \"Tree\"-Objekt auflösen."
 
-#: builtin/reset.c:295
+#: builtin/reset.c:306
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch ist inkompatibel mit --{hard,mixed,soft}"
 
-#: builtin/reset.c:304
+#: builtin/reset.c:315
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
 "--mixed mit Pfaden ist veraltet; benutzen Sie stattdessen 'git reset -- "
 "<Pfade>'."
 
-#: builtin/reset.c:306
+#: builtin/reset.c:317
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "Ein '%s'-Reset mit Pfaden ist nicht möglich."
 
-#: builtin/reset.c:316
+#: builtin/reset.c:327
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr "'%s'-Reset ist in einem Bare-Repository nicht erlaubt"
 
-#: builtin/reset.c:336
+#: builtin/reset.c:344
+msgid "Unstaged changes after reset:"
+msgstr "Nicht zum Commit vorgemerkte Änderungen nach Zurücksetzung:"
+
+#: builtin/reset.c:350
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "Konnte Staging-Area-Datei nicht zu Commit '%s' setzen."
 
-#: builtin/reset.c:342
-msgid "Unstaged changes after reset:"
-msgstr "Nicht zum Commit vorgemerkte Änderungen nach Zurücksetzung:"
-
-#: builtin/reset.c:347
+#: builtin/reset.c:355
 msgid "Could not write new index file."
 msgstr "Konnte neue Staging-Area-Datei nicht schreiben."
 
@@ -8757,84 +9034,84 @@
 msgid "git cherry-pick <subcommand>"
 msgstr "git cherry-pick <Unterkommando>"
 
-#: builtin/revert.c:71 builtin/revert.c:94
+#: builtin/revert.c:71
 #, c-format
 msgid "%s: %s cannot be used with %s"
 msgstr "%s: %s kann nicht mit %s verwendet werden"
 
-#: builtin/revert.c:105
+#: builtin/revert.c:80
 msgid "end revert or cherry-pick sequence"
 msgstr "beendet \"revert\" oder \"cherry-pick\" Ablauf"
 
-#: builtin/revert.c:106
+#: builtin/revert.c:81
 msgid "resume revert or cherry-pick sequence"
 msgstr "setzt \"revert\" oder \"cherry-pick\" Ablauf fort"
 
-#: builtin/revert.c:107
+#: builtin/revert.c:82
 msgid "cancel revert or cherry-pick sequence"
 msgstr "bricht \"revert\" oder \"cherry-pick\" Ablauf ab"
 
-#: builtin/revert.c:108
+#: builtin/revert.c:83
 msgid "don't automatically commit"
 msgstr "committet nicht automatisch"
 
-#: builtin/revert.c:109
+#: builtin/revert.c:84
 msgid "edit the commit message"
 msgstr "Bearbeitung der Commit-Beschreibung"
 
-#: builtin/revert.c:112
+#: builtin/revert.c:87
 msgid "parent number"
 msgstr "Nummer des Elternteils"
 
-#: builtin/revert.c:114
+#: builtin/revert.c:89
 msgid "merge strategy"
 msgstr "Merge-Strategie"
 
-#: builtin/revert.c:115
+#: builtin/revert.c:90
 msgid "option"
 msgstr "Option"
 
-#: builtin/revert.c:116
+#: builtin/revert.c:91
 msgid "option for merge strategy"
 msgstr "Option für Merge-Strategie"
 
-#: builtin/revert.c:127
+#: builtin/revert.c:102
 msgid "append commit name"
 msgstr "hängt Commit-Namen an"
 
-#: builtin/revert.c:128
+#: builtin/revert.c:103
 msgid "allow fast-forward"
 msgstr "erlaubt Vorspulen"
 
-#: builtin/revert.c:129
+#: builtin/revert.c:104
 msgid "preserve initially empty commits"
 msgstr "erhält ursprüngliche, leere Commits"
 
-#: builtin/revert.c:130
+#: builtin/revert.c:105
 msgid "allow commits with empty messages"
 msgstr "erlaubt Commits mit leerer Beschreibung"
 
-#: builtin/revert.c:131
+#: builtin/revert.c:106
 msgid "keep redundant, empty commits"
 msgstr "behält redundante, leere Commits"
 
-#: builtin/revert.c:135
+#: builtin/revert.c:110
 msgid "program error"
 msgstr "Programmfehler"
 
-#: builtin/revert.c:225
+#: builtin/revert.c:195
 msgid "revert failed"
 msgstr "\"revert\" fehlgeschlagen"
 
-#: builtin/revert.c:240
+#: builtin/revert.c:210
 msgid "cherry-pick failed"
 msgstr "\"cherry-pick\" fehlgeschlagen"
 
-#: builtin/rm.c:16
+#: builtin/rm.c:17
 msgid "git rm [options] [--] <file>..."
 msgstr "git rm [Optionen] [--] [<Datei>...]"
 
-#: builtin/rm.c:64
+#: builtin/rm.c:65
 msgid ""
 "the following submodule (or one of its nested submodules)\n"
 "uses a .git directory:"
@@ -8848,7 +9125,7 @@
 "die folgenden Submodule (oder ein geschachteltes Submodul hiervon)\n"
 "benutzen ein .git-Verzeichnis:"
 
-#: builtin/rm.c:70
+#: builtin/rm.c:71
 msgid ""
 "\n"
 "(use 'rm -rf' if you really want to remove it including all of its history)"
@@ -8857,7 +9134,7 @@
 "(benutzen Sie 'rm -rf' wenn Sie dieses Submodul wirklich mitsamt\n"
 "seiner Historie löschen möchten)"
 
-#: builtin/rm.c:230
+#: builtin/rm.c:231
 msgid ""
 "the following file has staged content different from both the\n"
 "file and the HEAD:"
@@ -8872,7 +9149,7 @@
 "unterschiedlich\n"
 "zu der Datei und HEAD:"
 
-#: builtin/rm.c:235
+#: builtin/rm.c:236
 msgid ""
 "\n"
 "(use -f to force removal)"
@@ -8880,13 +9157,13 @@
 "\n"
 "(benutzen Sie -f um die Löschung zu erzwingen)"
 
-#: builtin/rm.c:239
+#: builtin/rm.c:240
 msgid "the following file has changes staged in the index:"
 msgid_plural "the following files have changes staged in the index:"
 msgstr[0] "die folgende Datei hat zum Commit vorgemerkte Änderungen:"
 msgstr[1] "die folgenden Dateien haben zum Commit vorgemerkte Änderungen:"
 
-#: builtin/rm.c:243 builtin/rm.c:254
+#: builtin/rm.c:244 builtin/rm.c:255
 msgid ""
 "\n"
 "(use --cached to keep the file, or -f to force removal)"
@@ -8895,38 +9172,38 @@
 "(benutzen Sie --cached um die Datei zu behalten, oder -f um die Entfernung "
 "zu erzwingen)"
 
-#: builtin/rm.c:251
+#: builtin/rm.c:252
 msgid "the following file has local modifications:"
 msgid_plural "the following files have local modifications:"
 msgstr[0] "die folgende Datei hat lokale Änderungen:"
 msgstr[1] "die folgenden Dateien haben lokale Änderungen:"
 
-#: builtin/rm.c:269
+#: builtin/rm.c:270
 msgid "do not list removed files"
 msgstr "listet keine gelöschten Dateien auf"
 
-#: builtin/rm.c:270
+#: builtin/rm.c:271
 msgid "only remove from the index"
 msgstr "entfernt nur aus der Staging-Area"
 
-#: builtin/rm.c:271
+#: builtin/rm.c:272
 msgid "override the up-to-date check"
 msgstr "überschreibt die \"up-to-date\" Prüfung"
 
-#: builtin/rm.c:272
+#: builtin/rm.c:273
 msgid "allow recursive removal"
 msgstr "erlaubt rekursive Entfernung"
 
-#: builtin/rm.c:274
+#: builtin/rm.c:275
 msgid "exit with a zero status even if nothing matched"
 msgstr "beendet mit Rückgabewert 0, wenn keine Übereinstimmung gefunden wurde"
 
-#: builtin/rm.c:345
+#: builtin/rm.c:336
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "'%s' wird nicht ohne -r rekursiv entfernt"
 
-#: builtin/rm.c:384
+#: builtin/rm.c:375
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: konnte %s nicht löschen"
@@ -8940,23 +9217,23 @@
 msgid "Missing author: %s"
 msgstr "fehlender Autor: %s"
 
-#: builtin/shortlog.c:228
+#: builtin/shortlog.c:230
 msgid "sort output according to the number of commits per author"
 msgstr "sortiert die Ausgabe entsprechend der Anzahl von Commits pro Autor"
 
-#: builtin/shortlog.c:230
+#: builtin/shortlog.c:232
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "Unterdrückt Commit-Beschreibungen, liefert nur Anzahl der Commits"
 
-#: builtin/shortlog.c:232
+#: builtin/shortlog.c:234
 msgid "Show the email address of each author"
 msgstr "Zeigt die Email-Adresse von jedem Autor"
 
-#: builtin/shortlog.c:233
+#: builtin/shortlog.c:235
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:234
+#: builtin/shortlog.c:236
 msgid "Linewrap output"
 msgstr "Ausgabe mit Zeilenumbrüchen"
 
@@ -9064,24 +9341,24 @@
 msgid "stricter reference checking, requires exact ref path"
 msgstr "strengere Referenzprüfung, erfordert exakten Referenzpfad"
 
-#: builtin/show-ref.c:173 builtin/show-ref.c:176
+#: builtin/show-ref.c:173 builtin/show-ref.c:175
 msgid "show the HEAD reference, even if it would be filtered out"
 msgstr "zeigt die HEAD-Referenz, selbst wenn diese ausgefiltert werden würde"
 
-#: builtin/show-ref.c:178
+#: builtin/show-ref.c:177
 msgid "dereference tags into object IDs"
 msgstr "dereferenziert Tags in Objekt-Identifikationen"
 
-#: builtin/show-ref.c:180
+#: builtin/show-ref.c:179
 msgid "only show SHA1 hash using <n> digits"
 msgstr "zeigt nur SHA1 Hash mit <n> Ziffern"
 
-#: builtin/show-ref.c:184
+#: builtin/show-ref.c:183
 msgid "do not print results to stdout (useful with --verify)"
 msgstr ""
 "keine Ausgabe der Ergebnisse in die Standard-Ausgabe (nützlich mit --verify)"
 
-#: builtin/show-ref.c:186
+#: builtin/show-ref.c:185
 msgid "show refs from stdin that aren't in local repository"
 msgstr ""
 "zeigt Referenzen von der Standard-Eingabe, die sich nicht im lokalen "
@@ -9108,11 +9385,11 @@
 msgid "shorten ref output"
 msgstr "verkürzte Ausgabe der Referenzen"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason"
 msgstr "Grund"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason of the update"
 msgstr "Grund für die Aktualisierung"
 
@@ -9278,191 +9555,203 @@
 msgid "print only tags of the object"
 msgstr "gibt nur Tags von dem Objekt aus"
 
-#: builtin/tag.c:504
+#: builtin/tag.c:501
 msgid "--column and -n are incompatible"
 msgstr "--column und -n sind inkompatibel"
 
-#: builtin/tag.c:521
+#: builtin/tag.c:518
 msgid "-n option is only allowed with -l."
 msgstr "-n Option ist nur erlaubt mit -l."
 
-#: builtin/tag.c:523
+#: builtin/tag.c:520
 msgid "--contains option is only allowed with -l."
 msgstr "--contains Option ist nur erlaubt mit -l."
 
-#: builtin/tag.c:525
+#: builtin/tag.c:522
 msgid "--points-at option is only allowed with -l."
 msgstr "--points-at Option ist nur erlaubt mit -l."
 
-#: builtin/tag.c:533
+#: builtin/tag.c:530
 msgid "only one -F or -m option is allowed."
 msgstr "nur eine -F oder -m Option ist erlaubt."
 
-#: builtin/tag.c:553
+#: builtin/tag.c:550
 msgid "too many params"
 msgstr "zu viele Parameter"
 
-#: builtin/tag.c:559
+#: builtin/tag.c:556
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "'%s' ist kein gültiger Tagname."
 
-#: builtin/tag.c:564
+#: builtin/tag.c:561
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "Tag '%s' existiert bereits"
 
-#: builtin/tag.c:582
+#: builtin/tag.c:579
 #, c-format
 msgid "%s: cannot lock the ref"
 msgstr "%s: kann Referenz nicht sperren"
 
-#: builtin/tag.c:584
+#: builtin/tag.c:581
 #, c-format
 msgid "%s: cannot update the ref"
 msgstr "%s: kann Referenz nicht aktualisieren"
 
-#: builtin/tag.c:586
+#: builtin/tag.c:583
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Tag '%s' aktualisiert (war %s)\n"
 
-#: builtin/update-index.c:401
+#: builtin/update-index.c:402
 msgid "git update-index [options] [--] [<file>...]"
 msgstr "git update-index [Optionen] [--] [<Datei>...]"
 
-#: builtin/update-index.c:718
+#: builtin/update-index.c:720
 msgid "continue refresh even when index needs update"
 msgstr ""
 "Aktualisierung fortsetzen, auch wenn die Staging-Area aktualisiert werden "
 "muss"
 
-#: builtin/update-index.c:721
+#: builtin/update-index.c:723
 msgid "refresh: ignore submodules"
 msgstr "Aktualisierung: ignoriert Submodule"
 
-#: builtin/update-index.c:724
+#: builtin/update-index.c:726
 msgid "do not ignore new files"
 msgstr "ignoriert keine neuen Dateien"
 
-#: builtin/update-index.c:726
+#: builtin/update-index.c:728
 msgid "let files replace directories and vice-versa"
 msgstr "lässt Dateien Verzeichnisse ersetzen, und umgedreht"
 
-#: builtin/update-index.c:728
+#: builtin/update-index.c:730
 msgid "notice files missing from worktree"
 msgstr "beachtet fehlende Dateien im Arbeitsverzeichnis"
 
-#: builtin/update-index.c:730
+#: builtin/update-index.c:732
 msgid "refresh even if index contains unmerged entries"
 msgstr ""
 "aktualisiert, auch wenn die Staging-Area nicht zusammengeführte Einträge "
 "beinhaltet"
 
-#: builtin/update-index.c:733
+#: builtin/update-index.c:735
 msgid "refresh stat information"
 msgstr "aktualisiert Dateiinformationen"
 
-#: builtin/update-index.c:737
+#: builtin/update-index.c:739
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "wie --refresh, ignoriert aber \"assume-unchanged\" Einstellung"
 
-#: builtin/update-index.c:741
+#: builtin/update-index.c:743
 msgid "<mode> <object> <path>"
 msgstr "<Modus> <Objekt> <Pfad>"
 
-#: builtin/update-index.c:742
+#: builtin/update-index.c:744
 msgid "add the specified entry to the index"
 msgstr "merkt den angegebenen Eintrag zum Commit vor"
 
-#: builtin/update-index.c:746
+#: builtin/update-index.c:748
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/update-index.c:747
+#: builtin/update-index.c:749
 msgid "override the executable bit of the listed files"
 msgstr "überschreibt das \"ausführbar\"-Bit der aufgelisteten Dateien"
 
-#: builtin/update-index.c:751
+#: builtin/update-index.c:753
 msgid "mark files as \"not changing\""
 msgstr "betrachte diese Datei immer als unverändert"
 
-#: builtin/update-index.c:754
+#: builtin/update-index.c:756
 msgid "clear assumed-unchanged bit"
 msgstr "löscht \"assumed-unchanged\"-Bit"
 
-#: builtin/update-index.c:757
+#: builtin/update-index.c:759
 msgid "mark files as \"index-only\""
 msgstr "markiert Dateien als \"index-only\""
 
-#: builtin/update-index.c:760
+#: builtin/update-index.c:762
 msgid "clear skip-worktree bit"
 msgstr "löscht \"skip-worktree\"-Bit"
 
-#: builtin/update-index.c:763
+#: builtin/update-index.c:765
 msgid "add to index only; do not add content to object database"
 msgstr ""
 "merkt die Änderungen nur zum Commit vor; Inhalt wird nicht der Objekt-"
 "Datenbank hinzugefügt"
 
-#: builtin/update-index.c:765
+#: builtin/update-index.c:767
 msgid "remove named paths even if present in worktree"
 msgstr ""
 "löscht benannte Pfade, auch wenn sie sich im Arbeitsverzeichnis befinden"
 
-#: builtin/update-index.c:767
+#: builtin/update-index.c:769
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "mit --stdin: eingegebene Zeilen sind durch NUL-Bytes abgeschlossen"
 
-#: builtin/update-index.c:769
+#: builtin/update-index.c:771
 msgid "read list of paths to be updated from standard input"
 msgstr "liest Liste der zu aktualisierenden Pfade von der Standard-Eingabe"
 
-#: builtin/update-index.c:773
+#: builtin/update-index.c:775
 msgid "add entries from standard input to the index"
 msgstr "merkt Einträge von der Standard-Eingabe zum Commit vor"
 
-#: builtin/update-index.c:777
+#: builtin/update-index.c:779
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr ""
 "wiederholtes Einpflegen der Zustände #2 und #3 für die aufgelisteten Pfade"
 
-#: builtin/update-index.c:781
+#: builtin/update-index.c:783
 msgid "only update entries that differ from HEAD"
 msgstr "aktualisiert nur Einträge, die unterschiedlich zu HEAD sind"
 
-#: builtin/update-index.c:785
+#: builtin/update-index.c:787
 msgid "ignore files missing from worktree"
 msgstr "ignoriert fehlende Dateien im Arbeitsverzeichnis"
 
-#: builtin/update-index.c:788
+#: builtin/update-index.c:790
 msgid "report actions to standard output"
 msgstr "gibt die Aktionen in der Standard-Ausgabe aus"
 
-#: builtin/update-index.c:790
+#: builtin/update-index.c:792
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(für Fremdprogramme) keine gespeicherten, nicht aufgelöste Konflikte"
 
-#: builtin/update-index.c:794
+#: builtin/update-index.c:796
 msgid "write index in this format"
 msgstr "schreibt Staging-Area-Datei in diesem Format"
 
-#: builtin/update-ref.c:7
+#: builtin/update-ref.c:9
 msgid "git update-ref [options] -d <refname> [<oldval>]"
 msgstr "git update-ref [Optionen] -d <Referenzname> [<alterWert>]"
 
-#: builtin/update-ref.c:8
+#: builtin/update-ref.c:10
 msgid "git update-ref [options]    <refname> <newval> [<oldval>]"
 msgstr "git update-ref [Optionen]    <Referenzname> <neuerWert> [<alterWert>]"
 
-#: builtin/update-ref.c:19
+#: builtin/update-ref.c:11
+msgid "git update-ref [options] --stdin [-z]"
+msgstr "git update-ref [Optionen] --stdin [-z]"
+
+#: builtin/update-ref.c:255
 msgid "delete the reference"
 msgstr "löscht diese Referenz"
 
-#: builtin/update-ref.c:21
+#: builtin/update-ref.c:257
 msgid "update <refname> not the one it points to"
 msgstr "aktualisiert <Referenzname>, nicht den Verweis"
 
+#: builtin/update-ref.c:258
+msgid "stdin has NUL-terminated arguments"
+msgstr "Standard-Eingabe hat durch NUL-Zeichen abgeschlossene Argumente"
+
+#: builtin/update-ref.c:259
+msgid "read updates from stdin"
+msgstr "liest Aktualisierungen von der Standard-Eingabe"
+
 #: builtin/update-server-info.c:6
 msgid "git update-server-info [--force]"
 msgstr "git update-server-info [--force]"
@@ -9493,15 +9782,15 @@
 
 #: builtin/write-tree.c:13
 msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]"
-msgstr "git write-tree [--missing-ok] [--prefix=<Prefix>/]"
+msgstr "git write-tree [--missing-ok] [--prefix=<Präfix>/]"
 
 #: builtin/write-tree.c:26
 msgid "<prefix>/"
-msgstr "<Prefix>/"
+msgstr "<Präfix>/"
 
 #: builtin/write-tree.c:27
 msgid "write tree object for a subdirectory <prefix>"
-msgstr "schreibt das \"Tree\"-Objekt für ein Unterverzeichnis <Prefix>"
+msgstr "schreibt das \"Tree\"-Objekt für ein Unterverzeichnis <Präfix>"
 
 #: builtin/write-tree.c:30
 msgid "only useful for debugging"
@@ -9518,23 +9807,23 @@
 "oder 'git help <Konzept>' um mehr über ein spezifisches Kommando oder\n"
 "Konzept zu erfahren."
 
-#: parse-options.h:144
+#: parse-options.h:146
 msgid "expiry date"
 msgstr "Verfallsdatum"
 
-#: parse-options.h:159
+#: parse-options.h:161
 msgid "no-op (backward compatibility)"
 msgstr "Kein Effekt (Rückwärtskompatibilität)"
 
-#: parse-options.h:236
+#: parse-options.h:238
 msgid "be more verbose"
 msgstr "erweiterte Ausgaben"
 
-#: parse-options.h:238
+#: parse-options.h:240
 msgid "be more quiet"
 msgstr "weniger Ausgaben"
 
-#: parse-options.h:244
+#: parse-options.h:246
 msgid "use <n> digits to display SHA-1s"
 msgstr "benutze <n> Ziffern zur Anzeige von SHA-1s"
 
@@ -9993,7 +10282,7 @@
 msgstr ""
 "\"pull\" ist nicht möglich, weil Sie nicht zusammengeführte Dateien haben."
 
-#: git-pull.sh:203
+#: git-pull.sh:223
 msgid "updating an unborn branch with changes added to the index"
 msgstr ""
 "Aktualisiere einen ungeborenen Branch mit Änderungen, die zum Commit "
@@ -10003,7 +10292,7 @@
 #. The working tree and the index file is still based on the
 #. $orig_head commit, but we are merging into $curr_head.
 #. First update the working tree to match $curr_head.
-#: git-pull.sh:235
+#: git-pull.sh:255
 #, sh-format
 msgid ""
 "Warning: fetch updated the current branch head.\n"
@@ -10013,11 +10302,11 @@
 "Warnung: \"fetch\" aktualisierte die Spitze des aktuellen Branches.\n"
 "Warnung: Spule Ihr Arbeitsverzeichnis von Commit $orig_head vor."
 
-#: git-pull.sh:260
+#: git-pull.sh:280
 msgid "Cannot merge multiple branches into empty head"
 msgstr "Kann nicht mehrere Branches in einen ungeborenen Branch zusammenführen"
 
-#: git-pull.sh:264
+#: git-pull.sh:284
 msgid "Cannot rebase onto multiple branches"
 msgstr "kann Rebase nicht auf mehrere Branches ausführen"
 
@@ -10054,33 +10343,33 @@
 "Ihre Änderungen sind im Stash sicher.\n"
 "Sie können jederzeit \"git stash pop\" oder \"git stash drop\" ausführen.\n"
 
-#: git-rebase.sh:190
+#: git-rebase.sh:199
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Der \"pre-rebase hook\" hat den Rebase zurückgewiesen."
 
-#: git-rebase.sh:195
+#: git-rebase.sh:204
 msgid "It looks like git-am is in progress. Cannot rebase."
 msgstr "\"git-am\" scheint im Gange zu sein. Kann Rebase nicht durchführen."
 
-#: git-rebase.sh:329
+#: git-rebase.sh:338
 msgid "The --exec option must be used with the --interactive option"
 msgstr "Die Option --exec muss mit --interactive verwendet werden."
 
-#: git-rebase.sh:334
+#: git-rebase.sh:343
 msgid "No rebase in progress?"
 msgstr "Kein Rebase im Gange?"
 
-#: git-rebase.sh:345
+#: git-rebase.sh:354
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 "Die --edit-todo Aktion kann nur während eines interaktiven Rebase verwendet "
 "werden."
 
-#: git-rebase.sh:352
+#: git-rebase.sh:361
 msgid "Cannot read HEAD"
 msgstr "Kann HEAD nicht lesen"
 
-#: git-rebase.sh:355
+#: git-rebase.sh:364
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -10088,12 +10377,12 @@
 "Sie müssen alle Merge-Konflikte editieren und diese dann\n"
 "mittels \"git add\" als aufgelöst markieren"
 
-#: git-rebase.sh:373
+#: git-rebase.sh:382
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Konnte nicht zu $head_name zurückgehen"
 
-#: git-rebase.sh:392
+#: git-rebase.sh:401
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -10114,68 +10403,68 @@
 "und führen Sie dieses Kommando nochmal aus. Es wird angehalten, falls noch\n"
 "etwas Schützenswertes vorhanden ist."
 
-#: git-rebase.sh:437
+#: git-rebase.sh:446
 #, sh-format
 msgid "invalid upstream $upstream_name"
 msgstr "ungültiger Upstream-Branch $upstream_name"
 
-#: git-rebase.sh:461
+#: git-rebase.sh:470
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: es gibt mehr als eine Merge-Basis"
 
-#: git-rebase.sh:464 git-rebase.sh:468
+#: git-rebase.sh:473 git-rebase.sh:477
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: es gibt keine Merge-Basis"
 
-#: git-rebase.sh:473
+#: git-rebase.sh:482
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "$onto_name zeigt auf keinen gültigen Commit"
 
-#: git-rebase.sh:496
+#: git-rebase.sh:505
 #, sh-format
 msgid "fatal: no such branch: $branch_name"
 msgstr "fatal: Branch $branch_name nicht gefunden"
 
-#: git-rebase.sh:519
+#: git-rebase.sh:528
 msgid "Cannot autostash"
 msgstr "Kann \"autostash\" nicht ausführen."
 
-#: git-rebase.sh:524
+#: git-rebase.sh:533
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "\"autostash\" erzeugt: $stash_abbrev"
 
-#: git-rebase.sh:528
+#: git-rebase.sh:537
 msgid "Please commit or stash them."
 msgstr "Bitte committen Sie die Änderungen oder benutzen Sie \"stash\"."
 
-#: git-rebase.sh:548
+#: git-rebase.sh:557
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "Aktueller Branch $branch_name ist auf dem neusten Stand."
 
-#: git-rebase.sh:552
+#: git-rebase.sh:561
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr ""
 "Aktueller Branch $branch_name ist auf dem neusten Stand, Rebase erzwungen."
 
-#: git-rebase.sh:563
+#: git-rebase.sh:572
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Änderungen von $mb zu $onto:"
 
 #. Detach HEAD and reset the tree
-#: git-rebase.sh:572
+#: git-rebase.sh:581
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
 "Zunächst wird der Branch zurückgespult, um Ihre Änderungen\n"
 "darauf neu anzuwenden..."
 
-#: git-rebase.sh:582
+#: git-rebase.sh:591
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "$branch_name zu $onto_name vorgespult."
@@ -10223,7 +10512,7 @@
 #. $ git stash save --blah-blah 2>&1 | head -n 2
 #. error: unknown option for 'stash save': --blah-blah
 #. To provide a message, use git stash save -- '--blah-blah'
-#: git-stash.sh:241
+#: git-stash.sh:237
 #, sh-format
 msgid ""
 "error: unknown option for 'stash save': $option\n"
@@ -10233,100 +10522,85 @@
 "        Um eine Beschreibung anzugeben, benutzen Sie \"git stash save -- "
 "'$option'\""
 
-#: git-stash.sh:262
+#: git-stash.sh:258
 msgid "No local changes to save"
 msgstr "Keine lokalen Änderungen zum Speichern"
 
-#: git-stash.sh:268
-msgid ""
-"The following untracked files would NOT be saved but need to be removed by "
-"stash save:"
-msgstr ""
-"Die folgenden unbeobachteten Dateien würden NICHT gespeichert werden,\n"
-"müssen aber durch \"stash save\" entfernt werden:"
-
-#: git-stash.sh:270
-msgid ""
-"Aborting. Consider using either the --force or --include-untracked option."
-msgstr ""
-"Abgebrochen. Benutzen Sie entweder die Option --force oder --include-"
-"untracked."
-
-#: git-stash.sh:274
+#: git-stash.sh:262
 msgid "Cannot initialize stash"
 msgstr "Kann \"stash\" nicht initialisieren"
 
-#: git-stash.sh:278
+#: git-stash.sh:266
 msgid "Cannot save the current status"
 msgstr "Kann den aktuellen Status nicht speichern"
 
-#: git-stash.sh:296
+#: git-stash.sh:284
 msgid "Cannot remove worktree changes"
 msgstr "Kann Änderungen im Arbeitsverzeichnis nicht löschen"
 
-#: git-stash.sh:395
+#: git-stash.sh:383
 msgid "No stash found."
 msgstr "Kein \"stash\" gefunden."
 
-#: git-stash.sh:402
+#: git-stash.sh:390
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "Zu viele Commits angegeben: $REV"
 
-#: git-stash.sh:408
+#: git-stash.sh:396
 #, sh-format
 msgid "$reference is not valid reference"
 msgstr "$reference ist keine gültige Referenz"
 
-#: git-stash.sh:436
+#: git-stash.sh:424
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "'$args' ist kein \"stash\"-artiger Commit"
 
-#: git-stash.sh:447
+#: git-stash.sh:435
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "'$args' ist keine \"stash\"-Referenz"
 
-#: git-stash.sh:455
+#: git-stash.sh:443
 msgid "unable to refresh index"
 msgstr "unfähig die Staging-Area zu aktualisieren"
 
-#: git-stash.sh:459
+#: git-stash.sh:447
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "Kann \"stash\" nicht anwenden, solang ein Merge im Gange ist"
 
-#: git-stash.sh:467
+#: git-stash.sh:455
 msgid "Conflicts in index. Try without --index."
 msgstr "Konflikte in der Staging-Area. Versuchen Sie es ohne --index."
 
-#: git-stash.sh:469
+#: git-stash.sh:457
 msgid "Could not save index tree"
 msgstr "Konnte Staging-Area-Verzeichnis nicht speichern"
 
-#: git-stash.sh:503
+#: git-stash.sh:491
 msgid "Cannot unstage modified files"
 msgstr "Kann geänderte Dateien nicht aus der Staging-Area entfernen"
 
-#: git-stash.sh:518
+#: git-stash.sh:506
 msgid "Index was not unstashed."
 msgstr "Staging-Area wurde nicht aus dem Stash zurückgeladen."
 
-#: git-stash.sh:535
+#: git-stash.sh:523
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "Gelöscht ${REV} ($s)"
 
-#: git-stash.sh:536
+#: git-stash.sh:524
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: Konnte \"stash\"-Eintrag nicht löschen"
 
-#: git-stash.sh:543
+#: git-stash.sh:531
 msgid "No branch name specified"
 msgstr "Kein Branchname spezifiziert"
 
-#: git-stash.sh:615
+#: git-stash.sh:603
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(Zur Wiederherstellung geben Sie \"git stash apply\" ein)"
 
@@ -10608,49 +10882,60 @@
 "Die Optionen --cached und --files können nicht gemeinsam verwendet werden."
 
 #. unexpected type
-#: git-submodule.sh:1066
+#: git-submodule.sh:1073
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "unerwarteter Modus $mod_dst"
 
-#: git-submodule.sh:1086
+#: git-submodule.sh:1093
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  Warnung: $display_name beinhaltet nicht Commit $sha1_src"
 
-#: git-submodule.sh:1089
+#: git-submodule.sh:1096
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  Warnung: $display_name beinhaltet nicht Commit $sha1_dst"
 
-#: git-submodule.sh:1092
+#: git-submodule.sh:1099
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
 "  Warnung: $display_name beinhaltet nicht die Commits $sha1_src und $sha1_dst"
 
-#: git-submodule.sh:1117
+#: git-submodule.sh:1124
 msgid "blob"
 msgstr "Blob"
 
-#: git-submodule.sh:1155
-msgid "Submodules changed but not updated:"
-msgstr "Submodule geändert, aber nicht aktualisiert:"
-
-#: git-submodule.sh:1157
-msgid "Submodule changes to be committed:"
-msgstr "Änderungen in Submodul zum Committen:"
-
-#: git-submodule.sh:1242
+#: git-submodule.sh:1238
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "Fehler bei Rekursion in Submodul-Pfad '$sm_path'"
 
-#: git-submodule.sh:1306
+#: git-submodule.sh:1302
 #, sh-format
 msgid "Synchronizing submodule url for '$displaypath'"
 msgstr "Synchronisiere Submodul-URL für '$displaypath'"
 
+#~ msgid "input paths are terminated by a null character"
+#~ msgstr "Eingabepfade sind durch ein NUL Zeichen abgeschlossen"
+
+#~ msgid "done\n"
+#~ msgstr "Fertig\n"
+
+#~ msgid ""
+#~ "The following untracked files would NOT be saved but need to be removed "
+#~ "by stash save:"
+#~ msgstr ""
+#~ "Die folgenden unbeobachteten Dateien würden NICHT gespeichert werden,\n"
+#~ "müssen aber durch \"stash save\" entfernt werden:"
+
+#~ msgid ""
+#~ "Aborting. Consider using either the --force or --include-untracked option."
+#~ msgstr ""
+#~ "Abgebrochen. Benutzen Sie entweder die Option --force oder --include-"
+#~ "untracked."
+
 #~ msgid "  (fix conflicts and then run \"git am --resolved\")"
 #~ msgstr ""
 #~ "  (beheben Sie die Konflikte und führen Sie dann \"git am --resolved\" "
@@ -10783,9 +11068,6 @@
 #~ msgid "-B cannot be used with -b"
 #~ msgstr "-B kann nicht mit -b benutzt werden"
 
-#~ msgid "--patch is incompatible with all other options"
-#~ msgstr "--patch ist inkompatibel mit allen anderen Optionen"
-
 #~ msgid "--detach cannot be used with -b/-B/--orphan"
 #~ msgstr "--detach kann nicht mit -b/-B/--orphan benutzt werden"
 
diff --git a/po/fr.po b/po/fr.po
index 2cdb6f9..44995ba 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -8,6 +8,7 @@
 #
 #   English          |  French
 #   -----------------+---------------------------------
+#   3-way merge      |  fusion à 3 points
 #   #NN              |  n°NN
 #   a commit         |  un commit
 #   backward         |
@@ -17,35 +18,53 @@
 #   blob             |  blob
 #   bug              |  bogue
 #   bundle           |  colis
+#   bypass           |  éviter d'utiliser
+#   to checkout      |  extraire
 #   cherry-pick      |  picorer
+#   to commit        |  valider
+#   commit-ish       |  commit ou apparenté
+#   config file      |  fichier de configuration
 #   dangling         |  en suspens
+#   to debug         |  déboguer
 #   debugging        |  débogage
+#   to deflate       |  compresser
+#   email            |  e-mail
+#   entry            |  élément
 #   fast-forward     |  avance rapide
 #   fast-forwarded   |  mis à jour en avance rapide
+#   to fetch         |  rapatrier
+#   fix conflicts    |  réglez les conflits
+#   to format        |  formater
 #   glob             |  glob
 #   hash             |  hachage
 #   HEAD             |  HEAD (genre féminin)
-#   hook             |  hook
+#   hook             |  crochet
 #   hunk             |  section
+#   to inflate       |  décompresser
+#   to list          |  afficher
+#   mapping          |  mise en correspondance
 #   merge            |  fusion
+#   pack             |  paquet
+#   patches          |  patchs
 #   pattern          |  motif
+#   to prune         |  éliminer
+#   to push          |  pousser
+#   to rebase        |  rebaser
 #   repository       |  dépôt
 #   remote           |  distante (ou serveur distant)
 #   revision         |  révision
+#   shell            |  interpréteur de commandes
 #   stash            |  remisage
+#   to stash         |  remiser
 #   tag              |  étiquette
 #   template         |  modèle
-#   to checkout      |  extraire
-#   to commit        |  valider
-#   to fetch         |  rapatrier
-#   to prune         |  élaguer
-#   to push          |  pousser
-#   to rebase        |  rebaser
-#   to stash         |  remiser
+#   thread           |  fil
 #   to track         |  suivre
+#   tree             |  arbre
+#   tree-ish         |  arbre ou apparenté
 #   to unstage       |  désindexer
-#   tree-ish         |  arbre
 #   upstream         |  amont
+#   viewer           |  visualiseur
 #   worktree /       |
 #   work(ing) tree   |  copie de travail
 #
@@ -53,8 +72,8 @@
 msgstr ""
 "Project-Id-Version: git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2013-04-30 08:25+0800\n"
-"PO-Revision-Date: 2013-08-27 19:43+0200\n"
+"POT-Creation-Date: 2013-11-02 08:06+0800\n"
+"PO-Revision-Date: 2013-11-07 21:41+0100\n"
 "Last-Translator: Sébastien Helleu <flashcode@flashtux.org>\n"
 "Language-Team: Jean-Noël Avila <jn.avila@free.fr>\n"
 "Language: fr\n"
@@ -64,7 +83,7 @@
 "Plural-Forms: nplurals=2; plural=n<=1 ?0 : 1;\n"
 "X-Generator: Poedit 1.5.4\n"
 
-#: advice.c:53
+#: advice.c:57
 #, c-format
 msgid "hint: %.*s\n"
 msgstr "astuce: %.*s\n"
@@ -73,7 +92,7 @@
 #. * Message used both when 'git commit' fails and when
 #. * other commands doing a merge do.
 #.
-#: advice.c:83
+#: advice.c:87
 msgid ""
 "Fix them up in the work tree,\n"
 "and then use 'git add/rm <file>' as\n"
@@ -87,7 +106,7 @@
 
 #: archive.c:10
 msgid "git archive [options] <tree-ish> [<path>...]"
-msgstr "git archive [options] <arbre> [<chemin>...]"
+msgstr "git archive [options] <arbre ou apparenté> [<chemin>...]"
 
 #: archive.c:11
 msgid "git archive --list"
@@ -96,77 +115,84 @@
 #: archive.c:12
 msgid ""
 "git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]"
-msgstr "git archive --remote <dépôt> [--exec <commande>] [options] <arbre> [<chemin>...]"
+msgstr ""
+"git archive --remote <dépôt> [--exec <commande>] [options] <arbre ou "
+"apparenté> [<chemin>...]"
 
 #: archive.c:13
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <dépôt> [--exec <commande>] --list"
 
-#: archive.c:323
+#: archive.c:242 builtin/add.c:240 builtin/add.c:556 builtin/rm.c:328
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr "le chemin '%s' ne correspond à aucun fichier"
+
+#: archive.c:327
 msgid "fmt"
 msgstr "fmt"
 
-#: archive.c:323
+#: archive.c:327
 msgid "archive format"
 msgstr "format d'archive"
 
-#: archive.c:324 builtin/log.c:1126
+#: archive.c:328 builtin/log.c:1193
 msgid "prefix"
 msgstr "préfixe"
 
-#: archive.c:325
+#: archive.c:329
 msgid "prepend prefix to each pathname in the archive"
 msgstr "préfixer chaque chemin de fichier dans l'archive"
 
-#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2371
-#: builtin/blame.c:2372 builtin/config.c:55 builtin/fast-export.c:665
-#: builtin/fast-export.c:667 builtin/grep.c:715 builtin/hash-object.c:77
-#: builtin/ls-files.c:490 builtin/ls-files.c:493 builtin/notes.c:536
-#: builtin/notes.c:693 builtin/read-tree.c:107 parse-options.h:149
+#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2264
+#: builtin/blame.c:2265 builtin/config.c:58 builtin/fast-export.c:680
+#: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77
+#: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408
+#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154
 msgid "file"
 msgstr "fichier"
 
-#: archive.c:327 builtin/archive.c:89
+#: archive.c:331 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "écrire l'archive dans ce fichier"
 
-#: archive.c:329
+#: archive.c:333
 msgid "read .gitattributes in working directory"
 msgstr "lire .gitattributes dans le répertoire de travail"
 
-#: archive.c:330
+#: archive.c:334
 msgid "report archived files on stderr"
 msgstr "afficher les fichiers archivés sur stderr"
 
-#: archive.c:331
+#: archive.c:335
 msgid "store only"
 msgstr "stockage seulement"
 
-#: archive.c:332
+#: archive.c:336
 msgid "compress faster"
 msgstr "compression rapide"
 
-#: archive.c:340
+#: archive.c:344
 msgid "compress better"
 msgstr "compression efficace"
 
-#: archive.c:343
+#: archive.c:347
 msgid "list supported archive formats"
-msgstr "lister les formats d'archive supportés"
+msgstr "afficher les formats d'archive supportés"
 
-#: archive.c:345 builtin/archive.c:90 builtin/clone.c:86
+#: archive.c:349 builtin/archive.c:90 builtin/clone.c:84
 msgid "repo"
 msgstr "dépôt"
 
-#: archive.c:346 builtin/archive.c:91
+#: archive.c:350 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "récupérer l'archive depuis le dépôt distant <dépôt>"
 
-#: archive.c:347 builtin/archive.c:92 builtin/notes.c:615
+#: archive.c:351 builtin/archive.c:92 builtin/notes.c:487
 msgid "command"
 msgstr "commande"
 
-#: archive.c:348 builtin/archive.c:93
+#: archive.c:352 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "chemin vers la commande distante git-upload-archive"
 
@@ -186,17 +212,21 @@
 #: branch.c:82
 #, c-format
 msgid "Branch %s set up to track remote branch %s from %s by rebasing."
-msgstr "La branche %s est paramétrée pour suivre la branche distante %s de %s en rebasant."
+msgstr ""
+"La branche %s est paramétrée pour suivre la branche distante %s de %s en "
+"rebasant."
 
 #: branch.c:83
 #, c-format
 msgid "Branch %s set up to track remote branch %s from %s."
-msgstr "La branche %s est paramétrée pour suivre la branche distante %s depuis %s."
+msgstr ""
+"La branche %s est paramétrée pour suivre la branche distante %s depuis %s."
 
 #: branch.c:87
 #, c-format
 msgid "Branch %s set up to track local branch %s by rebasing."
-msgstr "La branche %s est paramétrée pour suivre la branche locale %s en rebasant."
+msgstr ""
+"La branche %s est paramétrée pour suivre la branche locale %s en rebasant."
 
 #: branch.c:88
 #, c-format
@@ -206,7 +236,9 @@
 #: branch.c:92
 #, c-format
 msgid "Branch %s set up to track remote ref %s by rebasing."
-msgstr "La branche %s est paramétrée pour suivre la référence distante %s en rebasant."
+msgstr ""
+"La branche %s est paramétrée pour suivre la référence distante %s en "
+"rebasant."
 
 #: branch.c:93
 #, c-format
@@ -216,7 +248,8 @@
 #: branch.c:97
 #, c-format
 msgid "Branch %s set up to track local ref %s by rebasing."
-msgstr "La branche %s est paramétrée pour suivre la référence locale %s en rebasant."
+msgstr ""
+"La branche %s est paramétrée pour suivre la référence locale %s en rebasant."
 
 #: branch.c:98
 #, c-format
@@ -247,17 +280,19 @@
 msgid "Cannot force update the current branch."
 msgstr "Impossible de forcer la mise à jour de la branche courante."
 
-#: branch.c:201
+#: branch.c:215
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
-msgstr "Impossible de paramétrer le suivi de branche ; le point de départ '%s' n'est pas une branche."
+msgstr ""
+"Impossible de paramétrer le suivi de branche ; le point de départ '%s' n'est "
+"pas une branche."
 
-#: branch.c:203
+#: branch.c:217
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "la branche amont demandée '%s' n'existe pas"
 
-#: branch.c:205
+#: branch.c:219
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -277,26 +312,26 @@
 "sa jumelle distante, vous souhaiterez utiliser \"git push -u\"\n"
 "pour paramétrer le suivi distant en même temps que vous poussez."
 
-#: branch.c:250
+#: branch.c:264
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Nom d'objet invalide : '%s'."
 
-#: branch.c:270
+#: branch.c:284
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Nom d'objet ambigu : '%s'."
 
-#: branch.c:275
+#: branch.c:289
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Point d'embranchement invalide : '%s'."
 
-#: branch.c:281
+#: branch.c:295
 msgid "Failed to lock ref for update"
 msgstr "Échec du verrouillage de la référence pour mise à jour"
 
-#: branch.c:299
+#: branch.c:313
 msgid "Failed to write ref"
 msgstr "Échec de l'écriture de la référence"
 
@@ -310,7 +345,7 @@
 msgid "unrecognized header: %s%s (%d)"
 msgstr "en-tête non reconnu : %s%s (%d)"
 
-#: bundle.c:89 builtin/commit.c:676
+#: bundle.c:89 builtin/commit.c:706
 #, c-format
 msgid "could not open '%s'"
 msgstr "impossible d'ouvrir '%s'"
@@ -319,9 +354,9 @@
 msgid "Repository lacks these prerequisite commits:"
 msgstr "Le dépôt ne dispose pas des commits prérequis :"
 
-#: bundle.c:164 sequencer.c:651 sequencer.c:1101 builtin/log.c:300
-#: builtin/log.c:770 builtin/log.c:1344 builtin/log.c:1570 builtin/merge.c:349
-#: builtin/shortlog.c:155
+#: bundle.c:164 sequencer.c:662 sequencer.c:1112 builtin/log.c:332
+#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:364
+#: builtin/shortlog.c:158
 msgid "revision walk setup failed"
 msgstr "échec de la préparation du parcours des révisions"
 
@@ -347,7 +382,7 @@
 msgid "rev-list died"
 msgstr "rev-list a disparu"
 
-#: bundle.c:300 builtin/log.c:1255 builtin/shortlog.c:258
+#: bundle.c:300 builtin/log.c:1329 builtin/shortlog.c:261
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "argument non reconnu : %s"
@@ -378,12 +413,12 @@
 msgid "index-pack died"
 msgstr "l'index de groupe a disparu"
 
-#: commit.c:50
+#: commit.c:53
 #, c-format
 msgid "could not parse %s"
 msgstr "impossible d'analyser %s"
 
-#: commit.c:52
+#: commit.c:55
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s n'est pas un commit !"
@@ -392,19 +427,19 @@
 msgid "memory exhausted"
 msgstr "plus de mémoire"
 
-#: connected.c:39
+#: connected.c:60
 msgid "Could not run 'git rev-list'"
 msgstr "Impossible de lancer 'git rev-list'"
 
-#: connected.c:48
+#: connected.c:80
 #, c-format
 msgid "failed write to rev-list: %s"
 msgstr "impossible d'écrire dans la rev-list : %s"
 
-#: connected.c:56
+#: connected.c:88
 #, c-format
 msgid "failed to close rev-list's stdin: %s"
-msgstr "impossible de fermer le stdin du rev-list : %s"
+msgstr "impossible de fermer l'entrée standard du rev-list : %s"
 
 #: date.c:95
 msgid "in the future"
@@ -476,7 +511,8 @@
 #: diff.c:112
 #, c-format
 msgid "  Failed to parse dirstat cut-off percentage '%s'\n"
-msgstr "  Impossible d'analyser le pourcentage de modification de dirstat '%s'\n"
+msgstr ""
+"  Impossible d'analyser le pourcentage de modification de dirstat '%s'\n"
 
 #: diff.c:117
 #, c-format
@@ -486,25 +522,28 @@
 #: diff.c:210
 #, c-format
 msgid "Unknown value for 'diff.submodule' config variable: '%s'"
-msgstr "Valeur inconnue pour la variable de configuration 'diff.submodule' : '%s'"
+msgstr ""
+"Valeur inconnue pour la variable de configuration 'diff.submodule' : '%s'"
 
 #: diff.c:260
 #, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
-msgstr "Erreurs dans la variable de configuration 'diff.dirstat' :\n"
+msgstr ""
+"Erreurs dans la variable de configuration 'diff.dirstat' :\n"
 "%s"
 
-#: diff.c:3481
+#: diff.c:3490
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
 "%s"
-msgstr "Impossible d'analyser le paramètre de l'option --dirstat/-X :\n"
+msgstr ""
+"Impossible d'analyser le paramètre de l'option --dirstat/-X :\n"
 "%s"
 
-#: diff.c:3495
+#: diff.c:3504
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Impossible d'analyser le paramètre de l'option --submodule : '%s'"
@@ -531,35 +570,35 @@
 msgid "failed writing detached signature to '%s': %s"
 msgstr "impossible d'écrire la signature détachée dans '%s' : %s"
 
-#: grep.c:1623
+#: grep.c:1695
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "'%s' : lecture de %s impossible"
 
-#: grep.c:1640
+#: grep.c:1712
 #, c-format
 msgid "'%s': %s"
 msgstr "'%s' : %s"
 
-#: grep.c:1651
+#: grep.c:1723
 #, c-format
 msgid "'%s': short read %s"
 msgstr "'%s' : lecture tronquée %s"
 
-#: help.c:212
+#: help.c:210
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "commandes git disponibles dans '%s'"
 
-#: help.c:219
+#: help.c:217
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "commandes git disponibles depuis un autre endroit de votre $PATH"
 
-#: help.c:235
+#: help.c:233
 msgid "The most commonly used git commands are:"
 msgstr "Les commandes git les plus utilisées sont :"
 
-#: help.c:292
+#: help.c:290
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -568,45 +607,55 @@
 "'%s' semble être une commande git, mais elle n'a pas pu\n"
 "être exécutée. Peut-être git-%s est-elle cassée ?"
 
-#: help.c:349
+#: help.c:347
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Ahem. Votre système n'indique aucune commande Git."
 
-#: help.c:371
+#: help.c:369
 #, 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 "ATTENTION : vous avez invoqué une commande Git nommée '%s' qui n'existe pas.\n"
+msgstr ""
+"ATTENTION : vous avez invoqué une commande Git nommée '%s' qui n'existe "
+"pas.\n"
 "Poursuite en supposant que vous avez voulu dire '%s'"
 
-#: help.c:376
+#: help.c:374
 #, c-format
 msgid "in %0.1f seconds automatically..."
 msgstr "dans %0.1f secondes automatiquement..."
 
-#: help.c:383
+#: help.c:381
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git : '%s' n'est pas une commande git. Voir 'git --help'."
 
-#: help.c:387
+#: help.c:385 help.c:444
 msgid ""
 "\n"
 "Did you mean this?"
 msgid_plural ""
 "\n"
 "Did you mean one of these?"
-msgstr[0] "\n"
+msgstr[0] ""
+"\n"
 "Vouliez-vous dire cela ?"
-msgstr[1] "\nVouliez-vous dire un de ceux-là ?"
+msgstr[1] ""
+"\n"
+"Vouliez-vous dire un de ceux-là ?"
+
+#: help.c:440
+#, c-format
+msgid "%s: %s - %s"
+msgstr "%s: %s - %s"
 
 #: merge.c:56
 msgid "failed to read the cache"
 msgstr "impossible de lire le cache"
 
-#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566
-#: builtin/clone.c:645
+#: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559
+#: builtin/clone.c:655
 msgid "unable to write new index file"
 msgstr "impossible d'écrire le nouveau fichier d'index"
 
@@ -620,306 +669,404 @@
 msgid "addinfo_cache failed for path '%s'"
 msgstr "échec de addinfo_cache pour le chemin '%s'"
 
-#: merge-recursive.c:268
+#: merge-recursive.c:269
 msgid "error building trees"
 msgstr "erreur de construction des arbres"
 
-#: merge-recursive.c:672
+#: merge-recursive.c:673
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "impossible de créer le chemin '%s' %s"
 
-#: merge-recursive.c:683
+#: merge-recursive.c:684
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "Suppression de %s pour faire de la place pour le sous-répertoire\n"
 
 #. something else exists
 #. .. but not some other error (who really cares what?)
-#: merge-recursive.c:697 merge-recursive.c:718
+#: merge-recursive.c:698 merge-recursive.c:719
 msgid ": perhaps a D/F conflict?"
 msgstr ": peut-être un conflit D/F ?"
 
-#: merge-recursive.c:708
+#: merge-recursive.c:709
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr "refus de perdre le fichier non suivi '%s'"
 
-#: merge-recursive.c:748
+#: merge-recursive.c:749
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "impossible de lire l'objet %s '%s'"
 
-#: merge-recursive.c:750
+#: merge-recursive.c:751
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "blob attendu pour %s '%s'"
 
-#: merge-recursive.c:773 builtin/clone.c:313
+#: merge-recursive.c:774 builtin/clone.c:311
 #, c-format
 msgid "failed to open '%s'"
 msgstr "échec à l'ouverture de '%s'"
 
-#: merge-recursive.c:781
+#: merge-recursive.c:782
 #, c-format
 msgid "failed to symlink '%s'"
 msgstr "échec à la création du lien symbolique '%s'"
 
-#: merge-recursive.c:784
+#: merge-recursive.c:785
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr "ne sait pas traiter %06o %s '%s'"
 
-#: merge-recursive.c:922
+#: merge-recursive.c:923
 msgid "Failed to execute internal merge"
 msgstr "Échec à l'exécution de la fusion interne"
 
-#: merge-recursive.c:926
+#: merge-recursive.c:927
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "Impossible d'ajouter %s à la base de données"
 
-#: merge-recursive.c:942
+#: merge-recursive.c:943
 msgid "unsupported object type in the tree"
 msgstr "type d'objet non supporté dans l'arbre"
 
-#: merge-recursive.c:1021 merge-recursive.c:1035
+#: merge-recursive.c:1022 merge-recursive.c:1036
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree."
-msgstr "CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s de %s laissée dans l'arbre."
+msgstr ""
+"CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s de "
+"%s laissée dans l'arbre."
 
-#: merge-recursive.c:1027 merge-recursive.c:1040
+#: merge-recursive.c:1028 merge-recursive.c:1041
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree at %s."
-msgstr "CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s de %s laissée dans l'arbre dans le fichier %s."
+msgstr ""
+"CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s de "
+"%s laissée dans l'arbre dans le fichier %s."
 
-#: merge-recursive.c:1081
+#: merge-recursive.c:1082
 msgid "rename"
 msgstr "renommage"
 
-#: merge-recursive.c:1081
+#: merge-recursive.c:1082
 msgid "renamed"
 msgstr "renommé"
 
-#: merge-recursive.c:1137
+#: merge-recursive.c:1138
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "%s est un répertoire dans %s ajouté plutôt comme %s"
 
-#: merge-recursive.c:1159
+#: merge-recursive.c:1160
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
 "\"->\"%s\" in \"%s\"%s"
-msgstr "CONFLIT (renommage/renommage) : Renommage de \"%s\"->\"%s\" dans la branche \"%s\" et renommage \"%s\"->\"%s\" dans \"%s\"%s"
+msgstr ""
+"CONFLIT (renommage/renommage) : Renommage de \"%s\"->\"%s\" dans la branche "
+"\"%s\" et renommage \"%s\"->\"%s\" dans \"%s\"%s"
 
-#: merge-recursive.c:1164
+#: merge-recursive.c:1165
 msgid " (left unresolved)"
 msgstr " (laissé non résolu)"
 
-#: merge-recursive.c:1218
+#: merge-recursive.c:1219
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
-msgstr "CONFLIT (renommage/renommage) : renommage '%s'->'%s' dans %s. Renommage '%s'->'%s' dans %s"
+msgstr ""
+"CONFLIT (renommage/renommage) : renommage '%s'->'%s' dans %s. Renommage '%s'-"
+">'%s' dans %s"
 
-#: merge-recursive.c:1248
+#: merge-recursive.c:1249
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "Renommage de %s en %s et de %s en %s à la place"
 
-#: merge-recursive.c:1447
+#: merge-recursive.c:1448
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
-msgstr "CONFLIT (renommage/ajout) : Renommage de %s->%s dans %s. %s ajouté dans %s"
+msgstr ""
+"CONFLIT (renommage/ajout) : Renommage de %s->%s dans %s. %s ajouté dans %s"
 
-#: merge-recursive.c:1457
+#: merge-recursive.c:1458
 #, c-format
 msgid "Adding merged %s"
 msgstr "Ajout de %s fusionné"
 
-#: merge-recursive.c:1462 merge-recursive.c:1660
+#: merge-recursive.c:1463 merge-recursive.c:1661
 #, c-format
 msgid "Adding as %s instead"
 msgstr "Ajout plutôt comme %s"
 
-#: merge-recursive.c:1513
+#: merge-recursive.c:1514
 #, c-format
 msgid "cannot read object %s"
 msgstr "impossible de lire l'objet %s"
 
-#: merge-recursive.c:1516
+#: merge-recursive.c:1517
 #, c-format
 msgid "object %s is not a blob"
 msgstr "l'objet %s n'est pas un blob"
 
-#: merge-recursive.c:1564
+#: merge-recursive.c:1565
 msgid "modify"
 msgstr "modification"
 
-#: merge-recursive.c:1564
+#: merge-recursive.c:1565
 msgid "modified"
 msgstr "modifié"
 
-#: merge-recursive.c:1574
+#: merge-recursive.c:1575
 msgid "content"
 msgstr "contenu"
 
-#: merge-recursive.c:1581
+#: merge-recursive.c:1582
 msgid "add/add"
 msgstr "ajout/ajout"
 
-#: merge-recursive.c:1615
+#: merge-recursive.c:1616
 #, c-format
 msgid "Skipped %s (merged same as existing)"
-msgstr "%s ignoré (fusion identique à l'existant)"
+msgstr "%s sauté (fusion identique à l'existant)"
 
-#: merge-recursive.c:1629
+#: merge-recursive.c:1630
 #, c-format
 msgid "Auto-merging %s"
 msgstr "Fusion automatique de %s"
 
-#: merge-recursive.c:1633 git-submodule.sh:1029
+#: merge-recursive.c:1634 git-submodule.sh:1125
 msgid "submodule"
 msgstr "sous-module"
 
-#: merge-recursive.c:1634
+#: merge-recursive.c:1635
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "CONFLIT (%s) : Conflit de fusion dans %s"
 
-#: merge-recursive.c:1724
+#: merge-recursive.c:1725
 #, c-format
 msgid "Removing %s"
 msgstr "Suppression de %s"
 
-#: merge-recursive.c:1749
+#: merge-recursive.c:1750
 msgid "file/directory"
 msgstr "fichier/répertoire"
 
-#: merge-recursive.c:1755
+#: merge-recursive.c:1756
 msgid "directory/file"
 msgstr "répertoire/fichier"
 
-#: merge-recursive.c:1760
+#: merge-recursive.c:1761
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
-msgstr "CONFLIT (%s) : Il y a un répertoire nommé %s dans %s. Ajout de %s comme %s"
+msgstr ""
+"CONFLIT (%s) : Il y a un répertoire nommé %s dans %s. Ajout de %s comme %s"
 
-#: merge-recursive.c:1770
+#: merge-recursive.c:1771
 #, c-format
 msgid "Adding %s"
 msgstr "Ajout de %s"
 
-#: merge-recursive.c:1787
+#: merge-recursive.c:1788
 msgid "Fatal merge failure, shouldn't happen."
 msgstr "Échec fatal de fusion, qui ne devrait jamais arriver."
 
-#: merge-recursive.c:1806
+#: merge-recursive.c:1807
 msgid "Already up-to-date!"
 msgstr "Déjà à jour !"
 
-#: merge-recursive.c:1815
+#: merge-recursive.c:1816
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "échec de fusion des arbres %s et %s"
 
-#: merge-recursive.c:1845
+#: merge-recursive.c:1846
 #, c-format
 msgid "Unprocessed path??? %s"
 msgstr "Chemin non traité ??? %s"
 
-#: merge-recursive.c:1890
+#: merge-recursive.c:1891
 msgid "Merging:"
 msgstr "Fusion :"
 
-#: merge-recursive.c:1903
+#: merge-recursive.c:1904
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "%u ancêtre commun trouvé :"
 msgstr[1] "%u ancêtres communs trouvés :"
 
-#: merge-recursive.c:1940
+#: merge-recursive.c:1941
 msgid "merge returned no commit"
 msgstr "la fusion n'a pas retourné de commit"
 
-#: merge-recursive.c:1997
+#: merge-recursive.c:1998
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "Impossible d'analyser l'objet '%s'"
 
-#: merge-recursive.c:2009 builtin/merge.c:658
+#: merge-recursive.c:2010 builtin/merge.c:672
 msgid "Unable to write index."
 msgstr "Impossible d'écrire l'index."
 
-#: object.c:195
+#: notes-utils.c:40
+msgid "Cannot commit uninitialized/unreferenced notes tree"
+msgstr "Impossible de valider un arbre de notes non initialisé/référencé"
+
+#: notes-utils.c:81
+#, c-format
+msgid "Bad notes.rewriteMode value: '%s'"
+msgstr "Mauvaise valeur de notes.rewriteMode : '%s'"
+
+#: notes-utils.c:91
+#, c-format
+msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
+msgstr "Refus de réécrire des notes dans %s (hors de refs/notes/)"
+
+#. TRANSLATORS: The first %s is the name of the
+#. environment variable, the second %s is its value
+#: notes-utils.c:118
+#, c-format
+msgid "Bad %s value: '%s'"
+msgstr "Mauvaise valeur de %s : '%s'"
+
+#: object.c:202
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "impossible d'analyser l'objet : %s"
 
-#: parse-options.c:489
+#: parse-options.c:537
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:507
+#: parse-options.c:555
 #, c-format
 msgid "usage: %s"
 msgstr "usage : %s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:511
+#: parse-options.c:559
 #, c-format
 msgid "   or: %s"
 msgstr "   ou : %s"
 
-#: parse-options.c:514
+#: parse-options.c:562
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:548
+#: parse-options.c:596
 msgid "-NUM"
 msgstr "-NUM"
 
-#: pathspec.c:83
+#: pathspec.c:118
+msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
+msgstr "les réglages de spécificateurs de chemin généraux 'glob' et 'noglob' sont incompatibles"
+
+#: pathspec.c:128
+msgid ""
+"global 'literal' pathspec setting is incompatible with all other global "
+"pathspec settings"
+msgstr "le réglage global de spécificateur de chemin 'literal' est incompatible avec tous les autres réglages globaux de spécificateur de chemin"
+
+#: pathspec.c:158
+msgid "invalid parameter for pathspec magic 'prefix'"
+msgstr "paramètre invalide pour le spécificateur magique de chemin 'prefix'"
+
+#: pathspec.c:164
 #, c-format
-msgid "Path '%s' is in submodule '%.*s'"
+msgid "Invalid pathspec magic '%.*s' in '%s'"
+msgstr "La spécification magique de chemin '%.*s' est invalide dans '%s'"
+
+#: pathspec.c:168
+#, c-format
+msgid "Missing ')' at the end of pathspec magic in '%s'"
+msgstr "')' manquante à la fin du spécificateur magique de chemin dans '%s'"
+
+#: pathspec.c:186
+#, c-format
+msgid "Unimplemented pathspec magic '%c' in '%s'"
+msgstr "Spécificateur magique '%c' non implémenté dans '%s'"
+
+#: pathspec.c:211
+#, c-format
+msgid "%s: 'literal' and 'glob' are incompatible"
+msgstr "%s : 'literal' et 'glob' sont incompatibles"
+
+#: pathspec.c:222
+#, c-format
+msgid "%s: '%s' is outside repository"
+msgstr "%s : '%s' est hors du dépôt"
+
+#: pathspec.c:278
+#, c-format
+msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "Le chemin '%s' est dans le sous-module '%.*s'"
 
-#: pathspec.c:99
+#.
+#. * We may want to substitute "this command" with a command
+#. * name. E.g. when add--interactive dies when running
+#. * "checkout -p"
+#.
+#: pathspec.c:340
 #, c-format
-msgid "'%s' is beyond a symbolic link"
-msgstr "'%s' est au delà d'un lien symbolique"
+msgid "%s: pathspec magic not supported by this command: %s"
+msgstr "%s : le spécificateur magique de chemin n'est pas supporté par cette commande : %s"
 
-#: remote.c:1781
+#: pathspec.c:415
+#, c-format
+msgid "pathspec '%s' is beyond a symbolic link"
+msgstr "le chemin '%s' est au-delà d'un lien symbolique"
+
+#: remote.c:1833
+#, c-format
+msgid "Your branch is based on '%s', but the upstream is gone.\n"
+msgstr "Votre branche est basée sur '%s', mais la branche amont a disparu.\n"
+
+#: remote.c:1837
+msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
+msgstr "  (utilisez \"git branch -unset-upstream\" pour corriger)\n"
+
+#: remote.c:1840
+#, c-format
+msgid "Your branch is up-to-date with '%s'.\n"
+msgstr "Votre branche est à jour avec '%s'.\n"
+
+#: remote.c:1844
 #, 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] "Votre branche est en avance sur '%s' de %d commit.\n"
 msgstr[1] "Votre branche est en avance sur '%s' de %d commits.\n"
 
-#: remote.c:1787
+#: remote.c:1850
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (utilisez \"git push\" pour publier vos commits locaux)\n"
 
-#: remote.c:1790
+#: remote.c:1853
 #, 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] "Votre branche est en retard sur '%s' de %d commit, et peut être mise à jour en avance rapide.\n"
-msgstr[1] "Votre branche est en retard sur '%s' de %d commits, et peut être mise à jour en avance rapide.\n"
+msgstr[0] ""
+"Votre branche est en retard sur '%s' de %d commit, et peut être mise à jour "
+"en avance rapide.\n"
+msgstr[1] ""
+"Votre branche est en retard sur '%s' de %d commits, et peut être mise à jour "
+"en avance rapide.\n"
 
-#: remote.c:1798
+#: remote.c:1861
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (utilisez \"git pull\" pour mettre à jour votre branche locale)\n"
 
-#: remote.c:1801
+#: remote.c:1864
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -927,23 +1074,35 @@
 msgid_plural ""
 "Your branch and '%s' have diverged,\n"
 "and have %d and %d different commits each, respectively.\n"
-msgstr[0] "Votre branche et '%s' ont divergé,\n"
+msgstr[0] ""
+"Votre branche et '%s' ont divergé,\n"
 "et ont %d et %d commit différent chacune respectivement.\n"
-msgstr[1] "Votre branche et '%s' ont divergé,\n"
+msgstr[1] ""
+"Votre branche et '%s' ont divergé,\n"
 "et ont %d et %d commits différents chacune respectivement.\n"
 
-#: remote.c:1811
+#: remote.c:1874
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
-msgstr "  (utilisez \"git pull\" pour fusionner la branche distante dans la vôtre)\n"
+msgstr ""
+"  (utilisez \"git pull\" pour fusionner la branche distante dans la vôtre)\n"
 
-#: sequencer.c:206 builtin/merge.c:776 builtin/merge.c:889 builtin/merge.c:999
-#: builtin/merge.c:1009
+#: run-command.c:80
+msgid "open /dev/null failed"
+msgstr "échec de l'ouverture de /dev/null"
+
+#: run-command.c:82
+#, c-format
+msgid "dup2(%d,%d) failed"
+msgstr "échec de dup2(%d,%d)"
+
+#: sequencer.c:206 builtin/merge.c:790 builtin/merge.c:903
+#: builtin/merge.c:1013 builtin/merge.c:1023
 #, c-format
 msgid "Could not open '%s' for writing"
 msgstr "Impossible d'ouvrir '%s' en écriture"
 
-#: sequencer.c:208 builtin/merge.c:335 builtin/merge.c:779
-#: builtin/merge.c:1001 builtin/merge.c:1014
+#: sequencer.c:208 builtin/merge.c:350 builtin/merge.c:793
+#: builtin/merge.c:1015 builtin/merge.c:1028
 #, c-format
 msgid "Could not write to '%s'"
 msgstr "Impossible d'écrire dans '%s'"
@@ -952,7 +1111,8 @@
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
-msgstr "après résolution des conflits, marquez les chemins corrigés\n"
+msgstr ""
+"après résolution des conflits, marquez les chemins corrigés\n"
 "avec 'git add <chemins>' ou 'git rm <chemins>'"
 
 #: sequencer.c:232
@@ -965,7 +1125,7 @@
 "avec 'git add <chemins>' ou 'git rm <chemins>'\n"
 "puis validez le résultat avec 'git commit'"
 
-#: sequencer.c:245 sequencer.c:859 sequencer.c:942
+#: sequencer.c:245 sequencer.c:870 sequencer.c:953
 #, c-format
 msgid "Could not write to %s"
 msgstr "Impossible d'écrire dans %s"
@@ -985,633 +1145,802 @@
 
 #: sequencer.c:268
 msgid "Commit your changes or stash them to proceed."
-msgstr "Validez vos modifications ou remisez-les pour continuer."
+msgstr "Validez vos modifications ou les remiser pour continuer."
 
 #. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:319
+#: sequencer.c:325
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: Impossible d'écrire le nouveau fichier index"
 
-#: sequencer.c:350
+#: sequencer.c:356
 msgid "Could not resolve HEAD commit\n"
 msgstr "Impossible de résoudre le commit HEAD\n"
 
-#: sequencer.c:371
+#: sequencer.c:378
 msgid "Unable to update cache tree\n"
 msgstr "Impossible de mettre à jour l'arbre de cache\n"
 
-#: sequencer.c:416
+#: sequencer.c:423
 #, c-format
 msgid "Could not parse commit %s\n"
 msgstr "Impossible d'analyser le commit %s\n"
 
-#: sequencer.c:421
+#: sequencer.c:428
 #, c-format
 msgid "Could not parse parent commit %s\n"
 msgstr "Impossible d'analyser le commit parent %s\n"
 
-#: sequencer.c:487
+#: sequencer.c:494
 msgid "Your index file is unmerged."
 msgstr "Votre fichier d'index n'est pas fusionné."
 
-#: sequencer.c:506
+#: sequencer.c:513
 #, c-format
 msgid "Commit %s is a merge but no -m option was given."
 msgstr "Le commit %s est une fusion mais l'option -m n'a pas été spécifiée."
 
-#: sequencer.c:514
+#: sequencer.c:521
 #, c-format
 msgid "Commit %s does not have parent %d"
 msgstr "Le commit %s n'a pas le parent %d"
 
-#: sequencer.c:518
+#: sequencer.c:525
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
-msgstr "Une branche principale a été spécifiée mais le commit %s n'est pas une fusion."
+msgstr ""
+"Une branche principale a été spécifiée mais le commit %s n'est pas une "
+"fusion."
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
-#: sequencer.c:531
+#: sequencer.c:538
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s : impossible d'analyser le commit parent %s"
 
-#: sequencer.c:535
+#: sequencer.c:542
 #, c-format
 msgid "Cannot get commit message for %s"
 msgstr "Impossible d'obtenir un message de validation pour %s"
 
-#: sequencer.c:621
+#: sequencer.c:628
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "impossible d'annuler %s... %s"
 
-#: sequencer.c:622
+#: sequencer.c:629
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "impossible d'appliquer %s... %s"
 
-#: sequencer.c:654
+#: sequencer.c:665
 msgid "empty commit set passed"
-msgstr "l'ensemble de commits spéficifié est vide"
+msgstr "l'ensemble de commits spécifié est vide"
 
-#: sequencer.c:662
+#: sequencer.c:673
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s : échec à la lecture de l'index"
 
-#: sequencer.c:667
+#: sequencer.c:678
 #, c-format
 msgid "git %s: failed to refresh the index"
-msgstr "git %s : échec du raffraîchissement de l'index"
+msgstr "git %s : échec du rafraîchissement de l'index"
 
-#: sequencer.c:725
+#: sequencer.c:736
 #, c-format
 msgid "Cannot %s during a %s"
 msgstr "Impossible de %s pendant un %s"
 
-#: sequencer.c:747
+#: sequencer.c:758
 #, c-format
 msgid "Could not parse line %d."
 msgstr "Impossible d'analyser la ligne %d."
 
-#: sequencer.c:752
+#: sequencer.c:763
 msgid "No commits parsed."
 msgstr "Aucun commit analysé."
 
-#: sequencer.c:765
+#: sequencer.c:776
 #, c-format
 msgid "Could not open %s"
 msgstr "Impossible d'ouvrir %s"
 
-#: sequencer.c:769
+#: sequencer.c:780
 #, c-format
 msgid "Could not read %s."
 msgstr "Impossible de lire %s."
 
-#: sequencer.c:776
+#: sequencer.c:787
 #, c-format
 msgid "Unusable instruction sheet: %s"
 msgstr "Feuille d'instruction inutilisable : %s"
 
-#: sequencer.c:804
+#: sequencer.c:815
 #, c-format
 msgid "Invalid key: %s"
 msgstr "Clé invalide: %s"
 
-#: sequencer.c:807
+#: sequencer.c:818
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Valeur invalide pour %s : %s"
 
-#: sequencer.c:819
+#: sequencer.c:830
 #, c-format
 msgid "Malformed options sheet: %s"
 msgstr "Feuille d'options malformée : %s"
 
-#: sequencer.c:840
+#: sequencer.c:851
 msgid "a cherry-pick or revert is already in progress"
 msgstr "un picorage ou un retour est déjà en cours"
 
-#: sequencer.c:841
+#: sequencer.c:852
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "essayez \"git cherry-pick (--continue|--quit|-- abort)\""
 
-#: sequencer.c:845
+#: sequencer.c:856
 #, c-format
 msgid "Could not create sequencer directory %s"
 msgstr "Impossible de créer le répertoire de séquenceur %s"
 
-#: sequencer.c:861 sequencer.c:946
+#: sequencer.c:872 sequencer.c:957
 #, c-format
 msgid "Error wrapping up %s."
 msgstr "Erreur lors de l'emballage de %s."
 
-#: sequencer.c:880 sequencer.c:1014
+#: sequencer.c:891 sequencer.c:1025
 msgid "no cherry-pick or revert in progress"
 msgstr "aucun picorage ou retour en cours"
 
-#: sequencer.c:882
+#: sequencer.c:893
 msgid "cannot resolve HEAD"
 msgstr "impossible de résoudre HEAD"
 
-#: sequencer.c:884
+#: sequencer.c:895
 msgid "cannot abort from a branch yet to be born"
 msgstr "impossible d'abandonner depuis une branche non encore créée"
 
-#: sequencer.c:906 builtin/apply.c:4060
+#: sequencer.c:917 builtin/apply.c:4061
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "impossible d'ouvrir %s : %s"
 
-#: sequencer.c:909
+#: sequencer.c:920
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "impossible de lire %s : %s"
 
-#: sequencer.c:910
+#: sequencer.c:921
 msgid "unexpected end of file"
 msgstr "fin de fichier inattendue"
 
-#: sequencer.c:916
+#: sequencer.c:927
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "le fichier HEAD de préparation de picorage '%s' est corrompu"
 
-#: sequencer.c:939
+#: sequencer.c:950
 #, c-format
 msgid "Could not format %s."
 msgstr "Impossible de formater %s."
 
-#: sequencer.c:1083
+#: sequencer.c:1093
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s : impossible de picorer un %s"
 
-#: sequencer.c:1085
+#: sequencer.c:1096
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s : mauvaise révision"
 
-#: sequencer.c:1119
+#: sequencer.c:1130
 msgid "Can't revert as initial commit"
 msgstr "Impossible d'annuler en tant que commit initial"
 
-#: sequencer.c:1120
+#: sequencer.c:1131
 msgid "Can't cherry-pick into empty head"
 msgstr "Impossible de picorer vers une HEAD vide"
 
-#: sha1_name.c:1036
+#: sha1_name.c:440
+msgid ""
+"Git normally never creates a ref that ends with 40 hex characters\n"
+"because it will be ignored when you just specify 40-hex. These refs\n"
+"may be created by mistake. For example,\n"
+"\n"
+"  git checkout -b $br $(git rev-parse ...)\n"
+"\n"
+"where \"$br\" is somehow empty and a 40-hex ref is created. Please\n"
+"examine these refs and maybe delete them. Turn this message off by\n"
+"running \"git config advice.objectNameWarning false\""
+msgstr ""
+"Git ne créé normalement jamais de référence qui se termine par 40 caractères "
+"hexa\n"
+"car elle serait ignorée si vous spécifiiez 40-hexa. Ces références\n"
+"peuvent être créées par erreur. Par exemple,\n"
+"\n"
+"  git checkout -b $br $(git rev-parse ...)\n"
+"\n"
+"où \"$br\" est d'une manière ou d'une autre vide et une référence 40-hexa "
+"est créée.\n"
+"Veuillez examiner ces références et peut-être les supprimer. Désactivez ce "
+"message\n"
+"en lançant \"git config advice.objectNameWarning false\""
+
+#: sha1_name.c:1112
 msgid "HEAD does not point to a branch"
 msgstr "HEAD ne pointe pas sur une branche"
 
-#: sha1_name.c:1039
+#: sha1_name.c:1115
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "Branche inconnue : '%s'"
 
-#: sha1_name.c:1041
+#: sha1_name.c:1117
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "Aucune branche amont configurée pour la branche '%s'"
 
-#: sha1_name.c:1044
+#: sha1_name.c:1121
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "La branche amont '%s' n'est pas stockée comme branche de suivi"
 
-#: wrapper.c:408
+#: submodule.c:64 submodule.c:98
+msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
+msgstr "Modification impossible de .gitmodules non fusionné, résolvez les conflits d'abord"
+
+#: submodule.c:68 submodule.c:102
+#, c-format
+msgid "Could not find section in .gitmodules where path=%s"
+msgstr "Impossible de trouver une section où path=%s dans .gitmodules"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:76
+#, c-format
+msgid "Could not update .gitmodules entry %s"
+msgstr "Impossible de mettre à jour l'élément %s de .gitmodules"
+
+# ici %s est un chemin
+#. Maybe the user already did that, don't error out here
+#: submodule.c:109
+#, c-format
+msgid "Could not remove .gitmodules entry for %s"
+msgstr "Impossible de supprimer l'élément de .gitmodules pour %s"
+
+#: submodule.c:127
+msgid "could not find .gitmodules in index"
+msgstr "impossible de trouver .gitmodules dans l'index"
+
+#: submodule.c:133
+msgid "reading updated .gitmodules failed"
+msgstr "échec de la lecture du .gitmodules mis à jour"
+
+#: submodule.c:135
+msgid "unable to stat updated .gitmodules"
+msgstr "échec de stat du .gitmodules mis à jour"
+
+#: submodule.c:139
+msgid "unable to remove .gitmodules from index"
+msgstr "suppression du .gitmodules dans l'index impossible"
+
+#: submodule.c:141
+msgid "adding updated .gitmodules failed"
+msgstr "échec de l'ajout du .gitmodules mis à jour"
+
+#: submodule.c:143
+msgid "staging updated .gitmodules failed"
+msgstr "échec de la mise en index du .gitmodules mis à jour"
+
+#: submodule.c:1144 builtin/init-db.c:363
+#, c-format
+msgid "Could not create git link %s"
+msgstr "Impossible de créer le lien git %s"
+
+#: submodule.c:1155
+#, c-format
+msgid "Could not set core.worktree in %s"
+msgstr "Impossible de paramétrer core.worktree dans %s"
+
+#: urlmatch.c:120
+msgid "invalid URL scheme name or missing '://' suffix"
+msgstr "nom de schéma d'URL invalide ou suffixe '://' manquant"
+
+#: urlmatch.c:144 urlmatch.c:297 urlmatch.c:356
+#, c-format
+msgid "invalid %XX escape sequence"
+msgstr "séquence d'échappement %XX invalide"
+
+#: urlmatch.c:172
+msgid "missing host and scheme is not 'file:'"
+msgstr "hôte manquant et le schéma n'est pas 'file:'"
+
+#: urlmatch.c:189
+msgid "a 'file:' URL may not have a port number"
+msgstr "une URL 'file:' ne peut pas contenir de numéro de port"
+
+#: urlmatch.c:199
+msgid "invalid characters in host name"
+msgstr "caractères invalides dans le nom d'hôte"
+
+#: urlmatch.c:244 urlmatch.c:255
+msgid "invalid port number"
+msgstr "numéro de port invalide"
+
+#: urlmatch.c:322
+msgid "invalid '..' path segment"
+msgstr "segment de chemin '..' invalide"
+
+#: wrapper.c:422
 #, c-format
 msgid "unable to access '%s': %s"
 msgstr "impossible d'accéder à '%s' : %s"
 
-#: wrapper.c:423
+#: wrapper.c:443
 #, c-format
 msgid "unable to access '%s'"
 msgstr "impossible d'accéder à '%s'"
 
-#: wrapper.c:434
+#: wrapper.c:454
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
-msgstr "impossible de rechercher l'utilisateur actuel dans le fichier de mots de passe : %s"
+msgstr ""
+"impossible de rechercher l'utilisateur actuel dans le fichier de mots de "
+"passe : %s"
 
-#: wrapper.c:435
+#: wrapper.c:455
 msgid "no such user"
 msgstr "utilisateur inconnu"
 
-#: wt-status.c:140
+#: wt-status.c:146
 msgid "Unmerged paths:"
 msgstr "Chemins non fusionnés :"
 
-#: wt-status.c:167 wt-status.c:194
+#: wt-status.c:173 wt-status.c:200
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (utilisez \"git reset %s <fichier>...\" pour désindexer)"
 
-#: wt-status.c:169 wt-status.c:196
+#: wt-status.c:175 wt-status.c:202
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (utilisez \"git rm --cached <fichier>...\" pour désindexer)"
 
-#: wt-status.c:173
+#: wt-status.c:179
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (utilisez \"git add <fichier>...\" pour marquer comme résolu)"
 
-#: wt-status.c:175 wt-status.c:179
+#: wt-status.c:181 wt-status.c:185
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
-msgstr "  (utilisez \"git add/rm <fichier>...\" si nécessaire pour marquer comme résolu)"
+msgstr ""
+"  (utilisez \"git add/rm <fichier>...\" si nécessaire pour marquer comme "
+"résolu)"
 
-#: wt-status.c:177
+#: wt-status.c:183
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (utilisez \"git rm <fichier>...\" pour marquer comme résolu)"
 
-#: wt-status.c:188
+#: wt-status.c:194
 msgid "Changes to be committed:"
 msgstr "Modifications qui seront validées :"
 
-#: wt-status.c:206
+#: wt-status.c:212
 msgid "Changes not staged for commit:"
 msgstr "Modifications qui ne seront pas validées :"
 
-#: wt-status.c:210
+#: wt-status.c:216
 msgid "  (use \"git add <file>...\" to update what will be committed)"
-msgstr "  (utilisez \"git add <fichier>...\" pour mettre à jour ce qui sera validé)"
+msgstr ""
+"  (utilisez \"git add <fichier>...\" pour mettre à jour ce qui sera validé)"
 
-#: wt-status.c:212
+#: wt-status.c:218
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
-msgstr "  (utilisez \"git add/rm <fichier>...\" pour mettre à jour ce qui sera validé)"
+msgstr ""
+"  (utilisez \"git add/rm <fichier>...\" pour mettre à jour ce qui sera "
+"validé)"
 
-#: wt-status.c:213
+#: wt-status.c:219
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
-msgstr "  (utilisez \"git checkout -- <fichier>...\" pour annuler les modifications dans la copie de travail)"
+msgstr ""
+"  (utilisez \"git checkout -- <fichier>...\" pour annuler les modifications "
+"dans la copie de travail)"
 
-#: wt-status.c:215
+#: wt-status.c:221
 msgid "  (commit or discard the untracked or modified content in submodules)"
-msgstr "  (valider ou annuler le contenu non suivi ou modifié dans les sous-modules)"
+msgstr ""
+"  (valider ou annuler le contenu non suivi ou modifié dans les sous-modules)"
 
-#: wt-status.c:227
+#: wt-status.c:233
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
-msgstr "  (utilisez \"git %s <fichier>...\" pour inclure dans ce qui sera validé)"
+msgstr ""
+"  (utilisez \"git %s <fichier>...\" pour inclure dans ce qui sera validé)"
 
-#: wt-status.c:244
+#: wt-status.c:250
 msgid "bug"
 msgstr "bogue"
 
-#: wt-status.c:249
+#: wt-status.c:255
 msgid "both deleted:"
 msgstr "supprimé des deux côtés :"
 
-#: wt-status.c:250
+#: wt-status.c:256
 msgid "added by us:"
 msgstr "ajouté par nous :"
 
-#: wt-status.c:251
+#: wt-status.c:257
 msgid "deleted by them:"
 msgstr "supprimé par eux :"
 
-#: wt-status.c:252
+#: wt-status.c:258
 msgid "added by them:"
 msgstr "ajouté par eux :"
 
-#: wt-status.c:253
+#: wt-status.c:259
 msgid "deleted by us:"
 msgstr "supprimé par nous :"
 
-#: wt-status.c:254
+#: wt-status.c:260
 msgid "both added:"
 msgstr "ajouté de deux côtés :"
 
-#: wt-status.c:255
+#: wt-status.c:261
 msgid "both modified:"
 msgstr "modifié des deux côtés :"
 
-#: wt-status.c:285
+#: wt-status.c:291
 msgid "new commits, "
 msgstr "nouveaux commits, "
 
-#: wt-status.c:287
+#: wt-status.c:293
 msgid "modified content, "
 msgstr "contenu modifié, "
 
-#: wt-status.c:289
+#: wt-status.c:295
 msgid "untracked content, "
 msgstr "contenu non suivi, "
 
-#: wt-status.c:306
+#: wt-status.c:312
 #, c-format
 msgid "new file:   %s"
 msgstr "nouveau :   %s"
 
-#: wt-status.c:309
+#: wt-status.c:315
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "copié :     %s -> %s"
 
-#: wt-status.c:312
+#: wt-status.c:318
 #, c-format
 msgid "deleted:    %s"
 msgstr "supprimé :  %s"
 
-#: wt-status.c:315
+#: wt-status.c:321
 #, c-format
 msgid "modified:   %s"
 msgstr "modifié :   %s"
 
-#: wt-status.c:318
+#: wt-status.c:324
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "renommé :   %s -> %s"
 
-#: wt-status.c:321
+#: wt-status.c:327
 #, c-format
 msgid "typechange: %s"
 msgstr "nv type :   %s"
 
-#: wt-status.c:324
+#: wt-status.c:330
 #, c-format
 msgid "unknown:    %s"
 msgstr "inconnu :   %s"
 
-#: wt-status.c:327
+#: wt-status.c:333
 #, c-format
 msgid "unmerged:   %s"
 msgstr "non fus. :  %s"
 
-#: wt-status.c:330
+#: wt-status.c:336
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "bogue : état de diff non géré %c"
 
-#: wt-status.c:803
+#: wt-status.c:703
+msgid "Submodules changed but not updated:"
+msgstr "Sous-modules modifiés mais non mis à jour :"
+
+#: wt-status.c:705
+msgid "Submodule changes to be committed:"
+msgstr "Changements du sous-module à valider :"
+
+#: wt-status.c:848
 msgid "You have unmerged paths."
 msgstr "Vous avez des chemins non fusionnés."
 
-#: wt-status.c:806 wt-status.c:958
+#: wt-status.c:851
 msgid "  (fix conflicts and run \"git commit\")"
-msgstr "  (réglez les conflits et lancez \"git commit\")"
+msgstr "  (réglez les conflits puis lancez \"git commit\")"
 
-#: wt-status.c:809
+#: wt-status.c:854
 msgid "All conflicts fixed but you are still merging."
 msgstr "Tous les conflits sont réglés mais la fusion n'est pas terminée."
 
-#: wt-status.c:812
+#: wt-status.c:857
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (utilisez \"git commit\" pour terminer la fusion)"
 
-#: wt-status.c:822
+#: wt-status.c:867
 msgid "You are in the middle of an am session."
 msgstr "Vous êtes au milieu d'une session am."
 
-#: wt-status.c:825
+#: wt-status.c:870
 msgid "The current patch is empty."
 msgstr "Le patch actuel est vide."
 
-#: wt-status.c:829
-msgid "  (fix conflicts and then run \"git am --resolved\")"
-msgstr "  (réglez les conflits puis lancez \"git am --resolved\")"
+#: wt-status.c:874
+msgid "  (fix conflicts and then run \"git am --continue\")"
+msgstr "  (réglez les conflits puis lancez \"git am --continue\")"
 
-#: wt-status.c:831
+#: wt-status.c:876
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (utilisez \"git am --skip\" pour sauter ce patch)"
 
-#: wt-status.c:833
+#: wt-status.c:878
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (utilisez \"git am --abort\" pour restaurer la branche d'origine)"
 
-#: wt-status.c:893 wt-status.c:910
+#: wt-status.c:938 wt-status.c:955
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "Vous êtes en train de rebaser la branche '%s' sur '%s'."
 
-#: wt-status.c:898 wt-status.c:915
+#: wt-status.c:943 wt-status.c:960
 msgid "You are currently rebasing."
 msgstr "Vous êtes en train de rebaser."
 
-#: wt-status.c:901
+#: wt-status.c:946
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
-msgstr "  (résolvez les conflits puis lancez \"git rebase --continue\")"
+msgstr "  (réglez les conflits puis lancez \"git rebase --continue\")"
 
-#: wt-status.c:903
+#: wt-status.c:948
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (utilisez \"git rebase --skip\" pour sauter ce patch)"
 
-#: wt-status.c:905
+#: wt-status.c:950
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (utilisez \"git rebase --abort\" pour extraire la branche d'origine)"
 
-#: wt-status.c:918
+#: wt-status.c:963
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
-msgstr "  (tous les conflits sont résolus : lancez \"git rebase --continue\")"
+msgstr "  (tous les conflits sont réglés : lancez \"git rebase --continue\")"
 
-#: wt-status.c:922
+#: wt-status.c:967
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
-msgstr "Vous êtes actuellement en train de fractionner un commit pendant un rebasage de la branche '%s' sur '%s'."
+msgstr ""
+"Vous êtes actuellement en train de fractionner un commit pendant un rebasage "
+"de la branche '%s' sur '%s'."
 
-#: wt-status.c:927
+#: wt-status.c:972
 msgid "You are currently splitting a commit during a rebase."
-msgstr "Vous êtes actuellement en train de fractionner un commit pendant un rebasage."
+msgstr ""
+"Vous êtes actuellement en train de fractionner un commit pendant un rebasage."
 
-#: wt-status.c:930
+#: wt-status.c:975
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
-msgstr "  (Une fois la copie de travail nettoyée, lancez \"git rebase --continue\")"
+msgstr ""
+"  (Une fois la copie de travail nettoyée, lancez \"git rebase --continue\")"
 
-#: wt-status.c:934
+#: wt-status.c:979
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
-msgstr "Vous êtes actuellement en train d'éditer un commit pendant un rebasage de la branche '%s' sur '%s'."
+msgstr ""
+"Vous êtes actuellement en train d'éditer un commit pendant un rebasage de la "
+"branche '%s' sur '%s'."
 
-#: wt-status.c:939
+#: wt-status.c:984
 msgid "You are currently editing a commit during a rebase."
-msgstr "Vous êtes actuellement en train d'éditer un commit pendant un rebasage."
+msgstr ""
+"Vous êtes actuellement en train d'éditer un commit pendant un rebasage."
 
-#: wt-status.c:942
+#: wt-status.c:987
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (utilisez \"git commit --amend\" pour corriger le commit actuel)"
 
-#: wt-status.c:944
+#: wt-status.c:989
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
-msgstr "  (utilisez \"git rebase --continue\" quand vous êtes satisfait de vos modifications)"
+msgstr ""
+"  (utilisez \"git rebase --continue\" quand vous êtes satisfait de vos "
+"modifications)"
 
-#: wt-status.c:954
-msgid "You are currently cherry-picking."
-msgstr "Vous êtes actuellement en train de picorer."
+#: wt-status.c:999
+#, c-format
+msgid "You are currently cherry-picking commit %s."
+msgstr "Vous êtes actuellement en train de picorer le commit %s."
 
-#: wt-status.c:961
-msgid "  (all conflicts fixed: run \"git commit\")"
-msgstr "  (tous les conflits sont résolus : lancez \"git commit\")"
+#: wt-status.c:1004
+msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
+msgstr "  (réglez les conflits puis lancez \"git cherry-pick --continue\")"
 
-#: wt-status.c:970
+#: wt-status.c:1007
+msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
+msgstr ""
+"  (tous les conflits sont réglés : lancez \"git cherry-pick --continue\")"
+
+#: wt-status.c:1009
+msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
+msgstr "  (utilisez \"git cherry-pick --abort\" pour annuler le picorage)"
+
+#: wt-status.c:1018
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "Vous êtes actuellement en train de rétablir le commit %s."
 
-#: wt-status.c:975
+#: wt-status.c:1023
 msgid "  (fix conflicts and run \"git revert --continue\")"
-msgstr "  (résolvez les conflits et lancez \"git revert --continue\")"
+msgstr "  (réglez les conflits puis lancez \"git revert --continue\")"
 
-#: wt-status.c:978
+#: wt-status.c:1026
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
-msgstr "  (tous les conflits sont résolus : lancez \"git revert --continue\")"
+msgstr "  (tous les conflits sont réglés : lancez \"git revert --continue\")"
 
-#: wt-status.c:980
+#: wt-status.c:1028
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (utilisez \"git revert --abort\" pour annuler le rétablissement)"
 
-#: wt-status.c:991
+#: wt-status.c:1039
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "Vous êtes en cours de bissection, depuis la branche '%s'."
 
-#: wt-status.c:995
+#: wt-status.c:1043
 msgid "You are currently bisecting."
 msgstr "Vous êtes en cours de bissection."
 
-#: wt-status.c:998
+#: wt-status.c:1046
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (utilisez \"git bisect reset\" pour revenir à la branche d'origine)"
 
-#: wt-status.c:1173
+#: wt-status.c:1221
 msgid "On branch "
 msgstr "Sur la branche "
 
-#: wt-status.c:1184
+#: wt-status.c:1228
+msgid "rebase in progress; onto "
+msgstr "rebasage en cours ; sur "
+
+#: wt-status.c:1235
 msgid "HEAD detached at "
 msgstr "HEAD détachée sur "
 
-#: wt-status.c:1186
+#: wt-status.c:1237
 msgid "HEAD detached from "
 msgstr "HEAD détachée depuis "
 
-#: wt-status.c:1189
+#: wt-status.c:1240
 msgid "Not currently on any branch."
 msgstr "Actuellement sur aucun branche."
 
-#: wt-status.c:1206
+#: wt-status.c:1257
 msgid "Initial commit"
 msgstr "Validation initiale"
 
-#: wt-status.c:1220
+#: wt-status.c:1271
 msgid "Untracked files"
 msgstr "Fichiers non suivis"
 
-#: wt-status.c:1222
+#: wt-status.c:1273
 msgid "Ignored files"
 msgstr "Fichiers ignorés"
 
-#: wt-status.c:1226
+#: wt-status.c:1277
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
 "may speed it up, but you have to be careful not to forget to add\n"
 "new files yourself (see 'git help status')."
-msgstr "L'énumération des fichiers non suivis a duré %.2f secondes. 'status -uno'\n"
-"peut l'accélerer, mais vous devez alors faire attention à ne pas\n"
-"oublier d'ajouter les nouveaux fichiers par vous-même (voir 'git help status')."
+msgstr ""
+"L'énumération des fichiers non suivis a duré %.2f secondes. 'status -uno'\n"
+"peut l'accélérer, mais vous devez alors faire attention à ne pas\n"
+"oublier d'ajouter les nouveaux fichiers par vous-même (voir 'git help "
+"status')."
 
-#: wt-status.c:1232
+#: wt-status.c:1283
 #, c-format
 msgid "Untracked files not listed%s"
-msgstr "Fichiers non suivis non listés%s"
+msgstr "Fichiers non suivis non affichés%s"
 
-#: wt-status.c:1234
+#: wt-status.c:1285
 msgid " (use -u option to show untracked files)"
 msgstr " (utilisez -u pour afficher les fichiers non suivis)"
 
-#: wt-status.c:1240
+#: wt-status.c:1291
 msgid "No changes"
 msgstr "Aucune modification"
 
-#: wt-status.c:1245
+#: wt-status.c:1296
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
-msgstr "aucune modification n'a été ajoutée à la validation (utilisez \"git add\" ou \"git commit -a\")\n"
+msgstr ""
+"aucune modification n'a été ajoutée à la validation (utilisez \"git add\" ou "
+"\"git commit -a\")\n"
 
-#: wt-status.c:1248
+#: wt-status.c:1299
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "aucune modification ajoutée à la validation\n"
 
-#: wt-status.c:1251
+#: wt-status.c:1302
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
 "track)\n"
-msgstr "aucune modification ajoutée à la validation mais des fichiers non suivis sont présents (utilisez \"git add\" pour les suivre)\n"
+msgstr ""
+"aucune modification ajoutée à la validation mais des fichiers non suivis "
+"sont présents (utilisez \"git add\" pour les suivre)\n"
 
-#: wt-status.c:1254
+#: wt-status.c:1305
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
-msgstr "aucune modification ajoutée à la validation mais des fichiers non suivis sont présents\n"
+msgstr ""
+"aucune modification ajoutée à la validation mais des fichiers non suivis "
+"sont présents\n"
 
-#: wt-status.c:1257
+#: wt-status.c:1308
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
-msgstr "rien à valider (créez/copiez des fichiers et utilisez \"git add\" pour les suivre)\n"
+msgstr ""
+"rien à valider (créez/copiez des fichiers et utilisez \"git add\" pour les "
+"suivre)\n"
 
-#: wt-status.c:1260 wt-status.c:1265
+#: wt-status.c:1311 wt-status.c:1316
 #, c-format
 msgid "nothing to commit\n"
 msgstr "rien à valider\n"
 
-#: wt-status.c:1263
+#: wt-status.c:1314
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr "rien à valider (utilisez -u pour afficher les fichiers non suivis)\n"
 
-#: wt-status.c:1267
+#: wt-status.c:1318
 #, c-format
 msgid "nothing to commit, working directory clean\n"
 msgstr "rien à valider, la copie de travail est propre\n"
 
-#: wt-status.c:1375
+#: wt-status.c:1427
 msgid "HEAD (no branch)"
 msgstr "HEAD (aucune branche)"
 
-#: wt-status.c:1381
+#: wt-status.c:1433
 msgid "Initial commit on "
 msgstr "Validation initiale sur "
 
-#: wt-status.c:1396
+# à priori on parle d'une branche ici
+#: wt-status.c:1463
+msgid "gone"
+msgstr "disparue"
+
+#: wt-status.c:1465
 msgid "behind "
 msgstr "derrière "
 
-#: wt-status.c:1399 wt-status.c:1402
+#: wt-status.c:1468 wt-status.c:1471
 msgid "ahead "
 msgstr "devant "
 
-#: wt-status.c:1404
+#: wt-status.c:1473
 msgid ", behind "
 msgstr ", derrière "
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:352
+#: compat/precompose_utf8.c:55 builtin/clone.c:350
 #, c-format
 msgid "failed to unlink '%s'"
-msgstr "echec lors de l'unlink de '%s'"
+msgstr "échec lors de l'unlink de '%s'"
 
 #: builtin/add.c:20
 msgid "git add [options] [--] <pathspec>..."
@@ -1647,7 +1976,8 @@
 "directory.\n"
 msgstr ""
 "Le comportement de 'git add %s (ou %s)' sans argument de chemin depuis un\n"
-"sous-répertoire du projet va changer dans Git 2.0 et ne doit plus être utilisé.\n"
+"sous-répertoire du projet va changer dans Git 2.0 et ne doit plus être "
+"utilisé.\n"
 "Pour ajouter le contenu de toute l'arborescence, lancez :\n"
 "\n"
 "  git add %s :/\n"
@@ -1658,7 +1988,8 @@
 "  git add %s .\n"
 "  (ou git add %s .)\n"
 "\n"
-"Avec la version actuelle de Git, la commande est restreinte au répertoire courant.\n"
+"Avec la version actuelle de Git, la commande est restreinte au répertoire "
+"courant.\n"
 
 #: builtin/add.c:100
 #, c-format
@@ -1676,23 +2007,26 @@
 "Run 'git status' to check the paths you removed from your working tree.\n"
 msgstr ""
 "Vous avez lancé 'git add' sans '-A (--all)' ni '--ignore-removal',\n"
-"dont le comportement va changer dans Git 2.0 avec le respect des chemins que vous supprimez.\n"
+"dont le comportement va changer dans Git 2.0 avec le respect des chemins que "
+"vous supprimez.\n"
 "Les chemins tels que '%s' qui ont été\n"
 "retirés de votre copie de travail sont ignorés avec cette version de Git.\n"
 "\n"
-"* 'git add --ignore-removal <chemin>', qui est l'option par défaut actuelle,\n"
+"* 'git add --ignore-removal <chemin>', qui est l'option par défaut "
+"actuelle,\n"
 "  ignore les chemins que vous avez supprimés de votre copie de travail.\n"
 "\n"
 "* 'git add --all <chemin>' permet d'enregistrer aussi les suppressions.\n"
 "\n"
-"Lancez 'git status' pour vérifier les chemins que vous avez supprimés de votre copie de travail.\n"
+"Lancez 'git status' pour vérifier les chemins que vous avez supprimés de "
+"votre copie de travail.\n"
 
 #: builtin/add.c:144
 #, c-format
 msgid "unexpected diff status %c"
 msgstr "status de diff inattendu %c"
 
-#: builtin/add.c:149 builtin/commit.c:233
+#: builtin/add.c:149 builtin/commit.c:260
 msgid "updating files failed"
 msgstr "échec de la mise à jour des fichiers"
 
@@ -1701,140 +2035,140 @@
 msgid "remove '%s'\n"
 msgstr "suppression de '%s'\n"
 
-#: builtin/add.c:253
+#: builtin/add.c:237
 msgid "Unstaged changes after refreshing the index:"
 msgstr "Modifications non indexées après rafraîchissement de l'index :"
 
-#: builtin/add.c:256 builtin/add.c:572 builtin/rm.c:275
-#, c-format
-msgid "pathspec '%s' did not match any files"
-msgstr "le chemin '%s' ne correspond à aucun fichier"
-
-#: builtin/add.c:339
+#: builtin/add.c:299
 msgid "Could not read the index"
 msgstr "Impossible de lire l'index"
 
-#: builtin/add.c:349
+#: builtin/add.c:310
 #, c-format
 msgid "Could not open '%s' for writing."
 msgstr "Impossible d'ouvrir '%s' en écriture."
 
-#: builtin/add.c:353
+#: builtin/add.c:314
 msgid "Could not write patch"
 msgstr "Impossible d'écrire le patch"
 
-#: builtin/add.c:358
+#: builtin/add.c:319
 #, c-format
 msgid "Could not stat '%s'"
 msgstr "Stat de '%s' impossible"
 
-#: builtin/add.c:360
+#: builtin/add.c:321
 msgid "Empty patch. Aborted."
 msgstr "Patch vide. Abandon."
 
-#: builtin/add.c:366
+#: builtin/add.c:327
 #, c-format
 msgid "Could not apply '%s'"
 msgstr "Impossible d'appliquer '%s'"
 
-#: builtin/add.c:376
+#: builtin/add.c:337
 msgid "The following paths are ignored by one of your .gitignore files:\n"
-msgstr "Les chemins suivants sont ignorés par un de vos fichiers .gitignore :\n"
+msgstr ""
+"Les chemins suivants sont ignorés par un de vos fichiers .gitignore :\n"
 
-#: builtin/add.c:393 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63
-#: builtin/prune-packed.c:76 builtin/push.c:425 builtin/remote.c:1253
-#: builtin/rm.c:206
+#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:92 builtin/mv.c:66
+#: builtin/prune-packed.c:73 builtin/push.c:459 builtin/remote.c:1253
+#: builtin/rm.c:269
 msgid "dry run"
-msgstr "à vide"
+msgstr "simuler l'action"
 
-#: builtin/add.c:394 builtin/apply.c:4409 builtin/check-ignore.c:19
-#: builtin/commit.c:1152 builtin/count-objects.c:95 builtin/fsck.c:613
-#: builtin/log.c:1518 builtin/mv.c:62 builtin/read-tree.c:112
+#: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19
+#: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612
+#: builtin/log.c:1592 builtin/mv.c:65 builtin/read-tree.c:113
 msgid "be verbose"
 msgstr "mode verbeux"
 
-#: builtin/add.c:396
+#: builtin/add.c:357
 msgid "interactive picking"
 msgstr "sélection interactive"
 
-#: builtin/add.c:397 builtin/checkout.c:1063 builtin/reset.c:258
+#: builtin/add.c:358 builtin/checkout.c:1109 builtin/reset.c:272
 msgid "select hunks interactively"
 msgstr "sélection interactive des sections"
 
-#: builtin/add.c:398
+#: builtin/add.c:359
 msgid "edit current diff and apply"
 msgstr "édition du diff actuel et application"
 
-#: builtin/add.c:399
+#: builtin/add.c:360
 msgid "allow adding otherwise ignored files"
 msgstr "permettre l'ajout de fichiers ignorés"
 
-#: builtin/add.c:400
+#: builtin/add.c:361
 msgid "update tracked files"
 msgstr "mettre à jour les fichiers suivis"
 
-#: builtin/add.c:401
+#: builtin/add.c:362
 msgid "record only the fact that the path will be added later"
 msgstr "enregistrer seulement le fait que le chemin sera ajouté plus tard"
 
-#: builtin/add.c:402
+#: builtin/add.c:363
 msgid "add changes from all tracked and untracked files"
 msgstr "ajouter les modifications de tous les fichiers suivis et non suivis"
 
 #. takes no arguments
-#: builtin/add.c:405
+#: builtin/add.c:366
 msgid "ignore paths removed in the working tree (same as --no-all)"
-msgstr "ignorer les chemins effacés dans la copie de travail (identique à --no-all)"
+msgstr ""
+"ignorer les chemins effacés dans la copie de travail (identique à --no-all)"
 
-#: builtin/add.c:407
+#: builtin/add.c:368
 msgid "don't add, only refresh the index"
 msgstr "ne pas ajouter, juste rafraîchir l'index"
 
-#: builtin/add.c:408
+#: builtin/add.c:369
 msgid "just skip files which cannot be added because of errors"
-msgstr "sauter seulement les fichiers qui ne peuvent pas être ajoutés du fait d'erreurs"
+msgstr ""
+"sauter seulement les fichiers qui ne peuvent pas être ajoutés du fait "
+"d'erreurs"
 
-#: builtin/add.c:409
+#: builtin/add.c:370
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "vérifier si des fichiers - même manquants - sont ignorés, à vide"
 
-#: builtin/add.c:431
+#: builtin/add.c:392
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Utilisez -f si vous voulez réellement les ajouter.\n"
 
-#: builtin/add.c:432
+#: builtin/add.c:393
 msgid "no files added"
 msgstr "aucun fichier ajouté"
 
-#: builtin/add.c:438
+#: builtin/add.c:399
 msgid "adding files failed"
 msgstr "échec de l'ajout de fichiers"
 
-#: builtin/add.c:477
+#: builtin/add.c:438
 msgid "-A and -u are mutually incompatible"
 msgstr "-A et -u sont mutuellement incompatibles"
 
-#: builtin/add.c:495
+#: builtin/add.c:456
 msgid "Option --ignore-missing can only be used together with --dry-run"
-msgstr "L'option --ignore-missing ne peut être utilisée qu'en complément de --dry-run"
+msgstr ""
+"L'option --ignore-missing ne peut être utilisée qu'en complément de --dry-run"
 
-#: builtin/add.c:525
+#: builtin/add.c:486
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Rien de spécifié, rien n'a été ajouté.\n"
 
-#: builtin/add.c:526
+#: builtin/add.c:487
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Vous vouliez sûrement dire 'git add .' ?\n"
 
-#: builtin/add.c:532 builtin/check-ignore.c:66 builtin/clean.c:204
-#: builtin/commit.c:293 builtin/mv.c:82 builtin/rm.c:235
+#: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919
+#: builtin/commit.c:320 builtin/mv.c:86 builtin/reset.c:224 builtin/rm.c:299
 msgid "index file corrupt"
 msgstr "fichier d'index corrompu"
 
-#: builtin/add.c:604 builtin/apply.c:4505 builtin/mv.c:229 builtin/rm.c:370
+#: builtin/add.c:589 builtin/apply.c:4506 builtin/mv.c:259 builtin/rm.c:432
 msgid "Unable to write new index file"
 msgstr "Impossible d'écrire le nouveau fichier d'index"
 
@@ -1850,7 +2184,7 @@
 #: builtin/apply.c:125
 #, c-format
 msgid "unrecognized whitespace ignore option '%s'"
-msgstr "option d'ignorance d'espce non reconnue '%s'"
+msgstr "option d'ignorance d'espace non reconnue '%s'"
 
 #: builtin/apply.c:823
 #, c-format
@@ -1870,27 +2204,34 @@
 #: builtin/apply.c:945
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
-msgstr "git apply : mauvais format de git-diff - /dev/null attendu, %s trouvé à la ligne %d"
+msgstr ""
+"git apply : mauvais format de git-diff - /dev/null attendu, %s trouvé à la "
+"ligne %d"
 
 #: builtin/apply.c:949
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
-msgstr "git apply : mauvais format de git-diff - nouveau nom de fichier inconsistant à la ligne %d"
+msgstr ""
+"git apply : mauvais format de git-diff - nouveau nom de fichier inconsistant "
+"à la ligne %d"
 
 #: builtin/apply.c:950
 #, c-format
 msgid "git apply: bad git-diff - inconsistent old filename on line %d"
-msgstr "git apply : mauvais format de git-diff - ancien nom de fichier inconsistant à la ligne %d"
+msgstr ""
+"git apply : mauvais format de git-diff - ancien nom de fichier inconsistant "
+"à la ligne %d"
 
 #: builtin/apply.c:957
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
-msgstr "git apply : mauvais format de git-diff - /dev/null attendu à la ligne %d"
+msgstr ""
+"git apply : mauvais format de git-diff - /dev/null attendu à la ligne %d"
 
 #: builtin/apply.c:1422
 #, c-format
 msgid "recount: unexpected line: %.*s"
-msgstr "recount : ligne inattendue : %.*s"
+msgstr "recomptage : ligne inattendue : %.*s"
 
 #: builtin/apply.c:1479
 #, c-format
@@ -1905,8 +2246,12 @@
 msgid_plural ""
 "git diff header lacks filename information when removing %d leading pathname "
 "components (line %d)"
-msgstr[0] "information de nom de fichier manquante dans l'en-tête de git diff lors de la suppression de %d composant de préfixe de chemin (ligne %d)"
-msgstr[1] "information de nom de fichier manquante dans l'en-tête de git diff lors de la suppression de %d composants de préfixe de chemin (ligne %d)"
+msgstr[0] ""
+"information de nom de fichier manquante dans l'en-tête de git diff lors de "
+"la suppression de %d composant de préfixe de chemin (ligne %d)"
+msgstr[1] ""
+"information de nom de fichier manquante dans l'en-tête de git diff lors de "
+"la suppression de %d composants de préfixe de chemin (ligne %d)"
 
 #: builtin/apply.c:1656
 msgid "new file depends on old contents"
@@ -1984,7 +2329,8 @@
 msgid ""
 "while searching for:\n"
 "%.*s"
-msgstr "pendant la recherche de :\n"
+msgstr ""
+"pendant la recherche de :\n"
 "%.*s"
 
 #: builtin/apply.c:2843
@@ -2000,7 +2346,9 @@
 #: builtin/apply.c:2952
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
-msgstr "le patch binaire sur '%s' crée un résultat incorrect (%s attendu, mais %s trouvé)"
+msgstr ""
+"le patch binaire sur '%s' crée un résultat incorrect (%s attendu, mais %s "
+"trouvé)"
 
 #: builtin/apply.c:2973
 #, c-format
@@ -2012,293 +2360,302 @@
 msgid "cannot checkout %s"
 msgstr "extraction de %s impossible"
 
-#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3193
+#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3194
 #, c-format
 msgid "read of %s failed"
-msgstr "echec de la lecture de %s"
+msgstr "échec de la lecture de %s"
 
-#: builtin/apply.c:3173 builtin/apply.c:3395
+#: builtin/apply.c:3174 builtin/apply.c:3396
 #, c-format
 msgid "path %s has been renamed/deleted"
 msgstr "le chemin %s a été renommé/supprimé"
 
-#: builtin/apply.c:3254 builtin/apply.c:3409
+#: builtin/apply.c:3255 builtin/apply.c:3410
 #, c-format
 msgid "%s: does not exist in index"
 msgstr "%s : n'existe pas dans l'index"
 
-#: builtin/apply.c:3258 builtin/apply.c:3401 builtin/apply.c:3423
+#: builtin/apply.c:3259 builtin/apply.c:3402 builtin/apply.c:3424
 #, c-format
 msgid "%s: %s"
 msgstr "%s : %s"
 
-#: builtin/apply.c:3263 builtin/apply.c:3417
+#: builtin/apply.c:3264 builtin/apply.c:3418
 #, c-format
 msgid "%s: does not match index"
 msgstr "%s : ne correspond pas à l'index"
 
-#: builtin/apply.c:3365
+#: builtin/apply.c:3366
 msgid "removal patch leaves file contents"
 msgstr "le patch de suppression laisse un contenu dans le fichier"
 
-#: builtin/apply.c:3434
+#: builtin/apply.c:3435
 #, c-format
 msgid "%s: wrong type"
 msgstr "%s : type erroné"
 
-#: builtin/apply.c:3436
+#: builtin/apply.c:3437
 #, c-format
 msgid "%s has type %o, expected %o"
 msgstr "%s est de type %o, mais %o attendu"
 
-#: builtin/apply.c:3537
+#: builtin/apply.c:3538
 #, c-format
 msgid "%s: already exists in index"
 msgstr "%s : existe déjà dans l'index"
 
-#: builtin/apply.c:3540
+#: builtin/apply.c:3541
 #, c-format
 msgid "%s: already exists in working directory"
 msgstr "%s : existe déjà dans la copie de travail"
 
-#: builtin/apply.c:3560
+#: builtin/apply.c:3561
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
 msgstr "le nouveau mode (%o) de %s ne correspond pas à l'ancien mode (%o)"
 
-#: builtin/apply.c:3565
+#: builtin/apply.c:3566
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
-msgstr "le nouveau mode (%o) de %s ne correspond pas à l'ancien mode (%o) de %s"
+msgstr ""
+"le nouveau mode (%o) de %s ne correspond pas à l'ancien mode (%o) de %s"
 
-#: builtin/apply.c:3573
+#: builtin/apply.c:3574
 #, c-format
 msgid "%s: patch does not apply"
 msgstr "%s : le patch ne s'applique pas"
 
-#: builtin/apply.c:3586
+#: builtin/apply.c:3587
 #, c-format
 msgid "Checking patch %s..."
 msgstr "Vérification du patch %s..."
 
-#: builtin/apply.c:3679 builtin/checkout.c:216 builtin/reset.c:124
+#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:127
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
-msgstr "echec de make_cache_entry pour le chemin '%s'"
+msgstr "échec de make_cache_entry pour le chemin '%s'"
 
-#: builtin/apply.c:3822
+#: builtin/apply.c:3823
 #, c-format
 msgid "unable to remove %s from index"
 msgstr "suppression de %s dans l'index impossible"
 
-#: builtin/apply.c:3850
+#: builtin/apply.c:3851
 #, c-format
-msgid "corrupt patch for subproject %s"
-msgstr "patch corrompu pour le sous-projet %s"
+msgid "corrupt patch for submodule %s"
+msgstr "patch corrompu pour le sous-module %s"
 
-#: builtin/apply.c:3854
+#: builtin/apply.c:3855
 #, c-format
 msgid "unable to stat newly created file '%s'"
 msgstr "stat du fichier nouvellement créé '%s' impossible"
 
-#: builtin/apply.c:3859
+#: builtin/apply.c:3860
 #, c-format
 msgid "unable to create backing store for newly created file %s"
-msgstr "création du magasin de stockage pour le fichier nouvellement créé %s impossible"
+msgstr ""
+"création du magasin de stockage pour le fichier nouvellement créé %s "
+"impossible"
 
-#: builtin/apply.c:3862 builtin/apply.c:3970
+#: builtin/apply.c:3863 builtin/apply.c:3971
 #, c-format
 msgid "unable to add cache entry for %s"
-msgstr "ajout de l'entrée de cache %s impossible"
+msgstr "ajout de l'élément de cache %s impossible"
 
-#: builtin/apply.c:3895
+#: builtin/apply.c:3896
 #, c-format
 msgid "closing file '%s'"
 msgstr "fermeture du fichier '%s'"
 
-#: builtin/apply.c:3944
+#: builtin/apply.c:3945
 #, c-format
 msgid "unable to write file '%s' mode %o"
 msgstr "écriture du fichier '%s' mode %o impossible"
 
-#: builtin/apply.c:4031
+#: builtin/apply.c:4032
 #, c-format
 msgid "Applied patch %s cleanly."
 msgstr "Patch %s appliqué proprement."
 
-#: builtin/apply.c:4039
+#: builtin/apply.c:4040
 msgid "internal error"
 msgstr "erreur interne"
 
 #. Say this even without --verbose
-#: builtin/apply.c:4042
+#: builtin/apply.c:4043
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
 msgstr[0] "Application du patch %%s avec %d rejet..."
 msgstr[1] "Application du patch %%s avec %d rejets..."
 
-#: builtin/apply.c:4052
+#: builtin/apply.c:4053
 #, c-format
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "troncature du nom de fichier .rej en %.*s.rej"
 
-#: builtin/apply.c:4073
+#: builtin/apply.c:4074
 #, c-format
 msgid "Hunk #%d applied cleanly."
 msgstr "Section n°%d appliquée proprement."
 
-#: builtin/apply.c:4076
+#: builtin/apply.c:4077
 #, c-format
 msgid "Rejected hunk #%d."
 msgstr "Section n°%d rejetée."
 
-#: builtin/apply.c:4226
+#: builtin/apply.c:4227
 msgid "unrecognized input"
 msgstr "entrée non reconnue"
 
-#: builtin/apply.c:4237
+#: builtin/apply.c:4238
 msgid "unable to read index file"
 msgstr "lecture du fichier d'index impossible"
 
-#: builtin/apply.c:4356 builtin/apply.c:4359 builtin/clone.c:92
-#: builtin/fetch.c:63
+#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90
+#: builtin/fetch.c:77
 msgid "path"
 msgstr "chemin"
 
-#: builtin/apply.c:4357
+#: builtin/apply.c:4358
 msgid "don't apply changes matching the given path"
 msgstr "ne pas appliquer les modifications qui correspondent au chemin donné"
 
-#: builtin/apply.c:4360
+#: builtin/apply.c:4361
 msgid "apply changes matching the given path"
 msgstr "appliquer les modifications qui correspondent au chemin donné"
 
-#: builtin/apply.c:4362
+#: builtin/apply.c:4363
 msgid "num"
 msgstr "num"
 
-#: builtin/apply.c:4363
+#: builtin/apply.c:4364
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr "supprimer <num> barres obliques des chemins traditionnels de diff"
 
-#: builtin/apply.c:4366
+#: builtin/apply.c:4367
 msgid "ignore additions made by the patch"
 msgstr "ignorer les additions réalisées par le patch"
 
-#: builtin/apply.c:4368
+#: builtin/apply.c:4369
 msgid "instead of applying the patch, output diffstat for the input"
 msgstr "au lieu d'appliquer le patch, afficher le diffstat de l'entrée"
 
-#: builtin/apply.c:4372
+#: builtin/apply.c:4373
 msgid "show number of added and deleted lines in decimal notation"
-msgstr "afficher le nombre de lignes ajoutées et supprimées en notation décimale"
+msgstr ""
+"afficher le nombre de lignes ajoutées et supprimées en notation décimale"
 
-#: builtin/apply.c:4374
+#: builtin/apply.c:4375
 msgid "instead of applying the patch, output a summary for the input"
 msgstr "au lieu d'appliquer le patch, afficher un résumer de l'entrée"
 
-#: builtin/apply.c:4376
+#: builtin/apply.c:4377
 msgid "instead of applying the patch, see if the patch is applicable"
 msgstr "au lieu d'appliquer le patch, voir si le patch est applicable"
 
-#: builtin/apply.c:4378
+#: builtin/apply.c:4379
 msgid "make sure the patch is applicable to the current index"
 msgstr "s'assurer que le patch est applicable sur l'index actuel"
 
-#: builtin/apply.c:4380
+#: builtin/apply.c:4381
 msgid "apply a patch without touching the working tree"
 msgstr "appliquer les patch sans toucher à la copie de travail"
 
-#: builtin/apply.c:4382
+#: builtin/apply.c:4383
 msgid "also apply the patch (use with --stat/--summary/--check)"
 msgstr "appliquer aussi le patch (à utiliser avec ---stat/--summary/--check)"
 
-#: builtin/apply.c:4384
+#: builtin/apply.c:4385
 msgid "attempt three-way merge if a patch does not apply"
 msgstr "tenter une fusion à 3 points si le patch ne s'applique pas proprement"
 
-#: builtin/apply.c:4386
+#: builtin/apply.c:4387
 msgid "build a temporary index based on embedded index information"
-msgstr "construire un index temporaire fondé sur l'information de l'index embarqué"
+msgstr ""
+"construire un index temporaire fondé sur l'information de l'index embarqué"
 
-#: builtin/apply.c:4388 builtin/checkout-index.c:197 builtin/ls-files.c:456
+#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:452
 msgid "paths are separated with NUL character"
 msgstr "les chemins sont séparés par un caractère NUL"
 
-#: builtin/apply.c:4391
+#: builtin/apply.c:4392
 msgid "ensure at least <n> lines of context match"
 msgstr "s'assurer d'au moins <n> lignes de correspondance de contexte"
 
-#: builtin/apply.c:4392
+#: builtin/apply.c:4393
 msgid "action"
 msgstr "action"
 
-#: builtin/apply.c:4393
+#: builtin/apply.c:4394
 msgid "detect new or modified lines that have whitespace errors"
-msgstr "détecter des lignes nouvelles ou modifiées qui contiennent des erreurs d'espace"
+msgstr ""
+"détecter des lignes nouvelles ou modifiées qui contiennent des erreurs "
+"d'espace"
 
-#: builtin/apply.c:4396 builtin/apply.c:4399
+#: builtin/apply.c:4397 builtin/apply.c:4400
 msgid "ignore changes in whitespace when finding context"
 msgstr "ignorer des modifications d'espace lors de la recherche de contexte"
 
-#: builtin/apply.c:4402
+#: builtin/apply.c:4403
 msgid "apply the patch in reverse"
 msgstr "appliquer le patch en sens inverse"
 
-#: builtin/apply.c:4404
+#: builtin/apply.c:4405
 msgid "don't expect at least one line of context"
 msgstr "ne pas s'attendre à au moins une ligne de contexte"
 
-#: builtin/apply.c:4406
+#: builtin/apply.c:4407
 msgid "leave the rejected hunks in corresponding *.rej files"
 msgstr "laisser les sections rejetées dans les fichiers *.rej correspondants"
 
-#: builtin/apply.c:4408
+#: builtin/apply.c:4409
 msgid "allow overlapping hunks"
 msgstr "accepter les recouvrements de sections"
 
-#: builtin/apply.c:4411
+#: builtin/apply.c:4412
 msgid "tolerate incorrectly detected missing new-line at the end of file"
-msgstr "tolérer des erreurs de détection de retours chariot manquants en fin de fichier"
+msgstr ""
+"tolérer des erreurs de détection de retours chariot manquants en fin de "
+"fichier"
 
-#: builtin/apply.c:4414
+#: builtin/apply.c:4415
 msgid "do not trust the line counts in the hunk headers"
 msgstr "ne pas se fier au compte de lignes dans les en-têtes de section"
 
-#: builtin/apply.c:4416
+#: builtin/apply.c:4417
 msgid "root"
 msgstr "racine"
 
-#: builtin/apply.c:4417
+#: builtin/apply.c:4418
 msgid "prepend <root> to all filenames"
 msgstr "préfixer tous les noms de fichier avec <root>"
 
-#: builtin/apply.c:4439
+#: builtin/apply.c:4440
 msgid "--3way outside a repository"
 msgstr "--3way hors d'un dépôt"
 
-#: builtin/apply.c:4447
+#: builtin/apply.c:4448
 msgid "--index outside a repository"
 msgstr "--index hors d'un dépôt"
 
-#: builtin/apply.c:4450
+#: builtin/apply.c:4451
 msgid "--cached outside a repository"
 msgstr "--cached hors d'un dépôt"
 
-#: builtin/apply.c:4466
+#: builtin/apply.c:4467
 #, c-format
 msgid "can't open patch '%s'"
 msgstr "ouverture impossible du patch '%s'"
 
-#: builtin/apply.c:4480
+#: builtin/apply.c:4481
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
 msgstr[0] "%d erreur d'espace ignorée"
 msgstr[1] "%d erreurs d'espace ignorées"
 
-#: builtin/apply.c:4486 builtin/apply.c:4496
+#: builtin/apply.c:4487 builtin/apply.c:4497
 #, c-format
 msgid "%d line adds whitespace errors."
 msgid_plural "%d lines add whitespace errors."
@@ -2352,105 +2709,111 @@
 msgid "update BISECT_HEAD instead of checking out the current commit"
 msgstr "mettre à jour BISECT_HEAD au lieu d'extraire le commit actuel"
 
-#: builtin/blame.c:25
+#: builtin/blame.c:27
 msgid "git blame [options] [rev-opts] [rev] [--] file"
 msgstr "git blame [options] [options-de-révision] [rev] [--] fichier"
 
-#: builtin/blame.c:30
+#: builtin/blame.c:32
 msgid "[rev-opts] are documented in git-rev-list(1)"
 msgstr "[options-de-révision] sont documentés dans git-rev-list(1)"
 
-#: builtin/blame.c:2355
+#: builtin/blame.c:2248
 msgid "Show blame entries as we find them, incrementally"
-msgstr "Montrer les entrée de blâme au fur et à mesure de leur découverte, de manière incrémentale"
+msgstr ""
+"Montrer les éléments de blâme au fur et à mesure de leur découverte, de "
+"manière incrémentale"
 
-#: builtin/blame.c:2356
+#: builtin/blame.c:2249
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "Montrer un SHA-1 blanc pour les commits de limite (Défaut : désactivé)"
 
-#: builtin/blame.c:2357
+#: builtin/blame.c:2250
 msgid "Do not treat root commits as boundaries (Default: off)"
-msgstr "Ne pas traiter les commits racine comme des limites (Défaut : désactivé)"
+msgstr ""
+"Ne pas traiter les commits racine comme des limites (Défaut : désactivé)"
 
-#: builtin/blame.c:2358
+#: builtin/blame.c:2251
 msgid "Show work cost statistics"
 msgstr "Montrer les statistiques de coût d'activité"
 
-#: builtin/blame.c:2359
+#: builtin/blame.c:2252
 msgid "Show output score for blame entries"
-msgstr "Montrer le score de sortie pour les entrées de blâme"
+msgstr "Montrer le score de sortie pour les éléments de blâme"
 
-#: builtin/blame.c:2360
+#: builtin/blame.c:2253
 msgid "Show original filename (Default: auto)"
 msgstr "Montrer les noms de fichier originaux (Défaut : auto)"
 
-#: builtin/blame.c:2361
+#: builtin/blame.c:2254
 msgid "Show original linenumber (Default: off)"
 msgstr "Montrer les numéros de lignes originaux (Défaut : désactivé)"
 
-#: builtin/blame.c:2362
+#: builtin/blame.c:2255
 msgid "Show in a format designed for machine consumption"
 msgstr "Afficher dans un format propice à la consommation par machine"
 
-#: builtin/blame.c:2363
+#: builtin/blame.c:2256
 msgid "Show porcelain format with per-line commit information"
 msgstr "Afficher en format porcelaine avec l'information de commit par ligne"
 
-#: builtin/blame.c:2364
+#: builtin/blame.c:2257
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "Utiliser le même mode de sortie que git-annotate (Défaut : désactivé)"
 
-#: builtin/blame.c:2365
+#: builtin/blame.c:2258
 msgid "Show raw timestamp (Default: off)"
-msgstr "Afficher les horodatages bruts (Défaut: désactivé)"
+msgstr "Afficher les horodatages bruts (Défaut : désactivé)"
 
-#: builtin/blame.c:2366
+#: builtin/blame.c:2259
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Afficher les longs SHA1 de commits (Défaut : désactivé)"
 
-#: builtin/blame.c:2367
+#: builtin/blame.c:2260
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Supprimer le nom de l'auteur et l'horodatage (Défaut : désactivé)"
 
-#: builtin/blame.c:2368
+#: builtin/blame.c:2261
 msgid "Show author email instead of name (Default: off)"
 msgstr "Afficher l'e-mail de l'auteur au lieu du nom (Défaut : désactivé)"
 
-#: builtin/blame.c:2369
+#: builtin/blame.c:2262
 msgid "Ignore whitespace differences"
 msgstr "Ignorer les différences d'espace"
 
-#: builtin/blame.c:2370
+#: builtin/blame.c:2263
 msgid "Spend extra cycles to find better match"
-msgstr "Dépenser des cycles supplémentaires pour trouver une meilleure correspondance"
+msgstr ""
+"Dépenser des cycles supplémentaires pour trouver une meilleure correspondance"
 
-#: builtin/blame.c:2371
+#: builtin/blame.c:2264
 msgid "Use revisions from <file> instead of calling git-rev-list"
-msgstr "Utiliser les révisions du fichier <fichier> au lieu d'appeler git-rev-list"
+msgstr ""
+"Utiliser les révisions du fichier <fichier> au lieu d'appeler git-rev-list"
 
-#: builtin/blame.c:2372
+#: builtin/blame.c:2265
 msgid "Use <file>'s contents as the final image"
 msgstr "Utiliser le contenu de <fichier> comme image finale"
 
-#: builtin/blame.c:2373 builtin/blame.c:2374
+#: builtin/blame.c:2266 builtin/blame.c:2267
 msgid "score"
 msgstr "score"
 
-#: builtin/blame.c:2373
+#: builtin/blame.c:2266
 msgid "Find line copies within and across files"
 msgstr "Trouver les copies de ligne dans et entre les fichiers"
 
-#: builtin/blame.c:2374
+#: builtin/blame.c:2267
 msgid "Find line movements within and across files"
 msgstr "Trouver les mouvements de ligne dans et entre les fichiers"
 
-#: builtin/blame.c:2375
+#: builtin/blame.c:2268
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:2375
+#: builtin/blame.c:2268
 msgid "Process only line range n,m, counting from 1"
-msgstr "Traiter seulement l'intervalle de ligne n,m en commençant le compte à 1"
+msgstr ""
+"Traiter seulement l'intervalle de ligne n,m en commençant le compte à 1"
 
 #: builtin/branch.c:24
 msgid "git branch [options] [-r | -a] [--merged | --no-merged]"
@@ -2458,7 +2821,7 @@
 
 #: builtin/branch.c:25
 msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]"
-msgstr "git branch [options] [-l] [-f] <nomdebranch> [<point-de-départ>]"
+msgstr "git branch [options] [-l] [-f] <nomdebranche> [<point-de-départ>]"
 
 #: builtin/branch.c:26
 msgid "git branch [options] [-r] (-d | -D) <branchname>..."
@@ -2502,7 +2865,7 @@
 
 #: builtin/branch.c:185
 msgid "Update of config-file failed"
-msgstr "Échec de la mise à jour du fichier de config"
+msgstr "Échec de la mise à jour du fichier de configuration"
 
 #: builtin/branch.c:213
 msgid "cannot use -a with -d"
@@ -2552,297 +2915,318 @@
 msgid "branch '%s' does not point at a commit"
 msgstr "la branche '%s' ne pointe pas sur un commit"
 
+# féminin pour une branche
 #: builtin/branch.c:453
 #, c-format
+msgid "[%s: gone]"
+msgstr "[%s: disparue]"
+
+#: builtin/branch.c:456
+#, c-format
+msgid "[%s]"
+msgstr "[%s]"
+
+#: builtin/branch.c:459
+#, c-format
 msgid "[%s: behind %d]"
 msgstr "[%s: en retard de %d]"
 
-#: builtin/branch.c:455
+#: builtin/branch.c:461
 #, c-format
 msgid "[behind %d]"
 msgstr "[en retard de %d]"
 
-#: builtin/branch.c:459
+#: builtin/branch.c:465
 #, c-format
 msgid "[%s: ahead %d]"
 msgstr "[%s : en avance de %d]"
 
-#: builtin/branch.c:461
+#: builtin/branch.c:467
 #, c-format
 msgid "[ahead %d]"
 msgstr "[en avance de %d]"
 
-#: builtin/branch.c:464
+#: builtin/branch.c:470
 #, c-format
 msgid "[%s: ahead %d, behind %d]"
 msgstr "[%s : en avance de %d, en retard de %d]"
 
-#: builtin/branch.c:467
+#: builtin/branch.c:473
 #, c-format
 msgid "[ahead %d, behind %d]"
 msgstr "[en avance de %d, en retard de %d]"
 
-#: builtin/branch.c:490
+#: builtin/branch.c:496
 msgid " **** invalid ref ****"
 msgstr " **** référence invalide ****"
 
-#: builtin/branch.c:582
+#: builtin/branch.c:588
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(aucune branche, rebasage de %s)"
 
-#: builtin/branch.c:585
+#: builtin/branch.c:591
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(aucune branche, bisect a démarré sur %s)"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:594
 #, c-format
 msgid "(detached from %s)"
 msgstr "(détaché de %s)"
 
-#: builtin/branch.c:591
+#: builtin/branch.c:597
 msgid "(no branch)"
 msgstr "(aucune branche)"
 
-#: builtin/branch.c:637
+#: builtin/branch.c:643
 #, c-format
 msgid "object '%s' does not point to a commit"
 msgstr "l'objet '%s' ne pointe pas sur un commit"
 
-#: builtin/branch.c:669
+#: builtin/branch.c:675
 msgid "some refs could not be read"
 msgstr "des références n'ont pas pu être lues"
 
-#: builtin/branch.c:682
+#: builtin/branch.c:688
 msgid "cannot rename the current branch while not on any."
 msgstr "impossible de renommer la branche actuelle, il n'y en a pas."
 
-#: builtin/branch.c:692
+#: builtin/branch.c:698
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Nom de branche invalide : '%s'"
 
-#: builtin/branch.c:707
+#: builtin/branch.c:713
 msgid "Branch rename failed"
-msgstr "Echec de renommage de la branche"
+msgstr "Échec de renommage de la branche"
 
-#: builtin/branch.c:711
+#: builtin/branch.c:717
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Renommage d'un branche mal nommée '%s'"
 
-#: builtin/branch.c:715
+#: builtin/branch.c:721
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "La branche a été renommée en %s, mais HEAD n'est pas mise à jour !"
 
-#: builtin/branch.c:722
+#: builtin/branch.c:728
 msgid "Branch is renamed, but update of config-file failed"
-msgstr "La branche est renommée, mais la mise à jour du fichier de config a échoué"
+msgstr ""
+"La branche est renommée, mais la mise à jour du fichier de configuration a "
+"échoué"
 
-#: builtin/branch.c:737
+#: builtin/branch.c:743
 #, c-format
 msgid "malformed object name %s"
 msgstr "nom d'objet malformé %s"
 
-#: builtin/branch.c:761
+#: builtin/branch.c:767
 #, c-format
 msgid "could not write branch description template: %s"
 msgstr "impossible d'écrire le modèle de description de branche : %s"
 
-#: builtin/branch.c:791
+#: builtin/branch.c:797
 msgid "Generic options"
 msgstr "Options génériques"
 
-#: builtin/branch.c:793
+#: builtin/branch.c:799
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "afficher le hachage et le sujet, doublé pour la branche amont"
 
-#: builtin/branch.c:794
+#: builtin/branch.c:800
 msgid "suppress informational messages"
 msgstr "supprimer les messages d'information"
 
-#: builtin/branch.c:795
+#: builtin/branch.c:801
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "régler le mode de suivi (voir git-pull(1))"
 
-#: builtin/branch.c:797
+#: builtin/branch.c:803
 msgid "change upstream info"
 msgstr "modifier l'information amont"
 
-#: builtin/branch.c:801
+#: builtin/branch.c:807
 msgid "use colored output"
 msgstr "utiliser la coloration dans la sortie"
 
-#: builtin/branch.c:802
+#: builtin/branch.c:808
 msgid "act on remote-tracking branches"
 msgstr "agir sur les branches de suivi distantes"
 
-#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832
-#: builtin/branch.c:838 builtin/commit.c:1368 builtin/commit.c:1369
-#: builtin/commit.c:1370 builtin/commit.c:1371 builtin/tag.c:468
+#: builtin/branch.c:811 builtin/branch.c:817 builtin/branch.c:838
+#: builtin/branch.c:844 builtin/commit.c:1460 builtin/commit.c:1461
+#: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468
 msgid "commit"
-msgstr "valider"
+msgstr "commit"
 
-#: builtin/branch.c:806 builtin/branch.c:812
+#: builtin/branch.c:812 builtin/branch.c:818
 msgid "print only branches that contain the commit"
 msgstr "afficher seulement les branches qui contiennent le commit"
 
-#: builtin/branch.c:818
+#: builtin/branch.c:824
 msgid "Specific git-branch actions:"
 msgstr "Actions spécifiques à git-branch :"
 
-#: builtin/branch.c:819
+#: builtin/branch.c:825
 msgid "list both remote-tracking and local branches"
 msgstr "afficher à la fois les branches de suivi et les branches locales"
 
-#: builtin/branch.c:821
+#: builtin/branch.c:827
 msgid "delete fully merged branch"
 msgstr "supprimer une branche totalement fusionnée"
 
-#: builtin/branch.c:822
+#: builtin/branch.c:828
 msgid "delete branch (even if not merged)"
 msgstr "supprimer une branche (même non fusionnée)"
 
-#: builtin/branch.c:823
+#: builtin/branch.c:829
 msgid "move/rename a branch and its reflog"
 msgstr "déplacer/renommer une branche et son reflog"
 
-#: builtin/branch.c:824
+#: builtin/branch.c:830
 msgid "move/rename a branch, even if target exists"
 msgstr "déplacer/renommer une branche, même si la cible existe"
 
-#: builtin/branch.c:825
+#: builtin/branch.c:831
 msgid "list branch names"
 msgstr "afficher les noms des branches"
 
-#: builtin/branch.c:826
+#: builtin/branch.c:832
 msgid "create the branch's reflog"
 msgstr "créer le reflog de la branche"
 
-#: builtin/branch.c:828
+#: builtin/branch.c:834
 msgid "edit the description for the branch"
 msgstr "éditer la description de la branche"
 
-#: builtin/branch.c:829
+#: builtin/branch.c:835
 msgid "force creation (when already exists)"
 msgstr "forcer la création (même si la cible existe)"
 
-#: builtin/branch.c:832
+#: builtin/branch.c:838
 msgid "print only not merged branches"
 msgstr "afficher seulement les branches non fusionnées"
 
-#: builtin/branch.c:838
+#: builtin/branch.c:844
 msgid "print only merged branches"
 msgstr "afficher seulement les branches fusionnées"
 
-#: builtin/branch.c:842
+#: builtin/branch.c:848
 msgid "list branches in columns"
 msgstr "afficher les branches en colonnes"
 
-#: builtin/branch.c:855
+#: builtin/branch.c:861
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Échec de résolution de HEAD comme référence valide."
 
-#: builtin/branch.c:860 builtin/clone.c:619
+#: builtin/branch.c:866 builtin/clone.c:629
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD non trouvée sous refs/heads !"
 
-#: builtin/branch.c:883
+#: builtin/branch.c:890
 msgid "--column and --verbose are incompatible"
 msgstr "--column et --verbose sont incompatibles"
 
-#: builtin/branch.c:889 builtin/branch.c:928
+#: builtin/branch.c:896 builtin/branch.c:935
 msgid "branch name required"
 msgstr "le nom de branche est requis"
 
-#: builtin/branch.c:904
+#: builtin/branch.c:911
 msgid "Cannot give description to detached HEAD"
 msgstr "Impossible de décrire une HEAD détachée"
 
-#: builtin/branch.c:909
+#: builtin/branch.c:916
 msgid "cannot edit description of more than one branch"
 msgstr "impossible d'éditer la description de plus d'une branche"
 
-#: builtin/branch.c:916
+#: builtin/branch.c:923
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Aucun commit sur la branche '%s'."
 
-#: builtin/branch.c:919
+#: builtin/branch.c:926
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Aucune branche nommée '%s'."
 
-#: builtin/branch.c:934
+#: builtin/branch.c:941
 msgid "too many branches for a rename operation"
 msgstr "trop de branches pour une opération de renommage"
 
-#: builtin/branch.c:939
+#: builtin/branch.c:946
 msgid "too many branches to set new upstream"
 msgstr "trop de branches pour spécifier une branche amont"
 
-#: builtin/branch.c:943
+#: builtin/branch.c:950
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
-msgstr "impossible de spécifier une branche amont de HEAD par %s qui ne pointe sur aucune branche."
+msgstr ""
+"impossible de spécifier une branche amont de HEAD par %s qui ne pointe sur "
+"aucune branche."
 
-#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990
+#: builtin/branch.c:953 builtin/branch.c:975 builtin/branch.c:997
 #, c-format
 msgid "no such branch '%s'"
 msgstr "pas de branche '%s'"
 
-#: builtin/branch.c:950
+#: builtin/branch.c:957
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "la branche '%s' n'existe pas"
 
-#: builtin/branch.c:962
+#: builtin/branch.c:969
 msgid "too many branches to unset upstream"
 msgstr "trop de branches pour désactiver un amont"
 
-#: builtin/branch.c:966
+#: builtin/branch.c:973
 msgid "could not unset upstream of HEAD when it does not point to any branch."
-msgstr "impossible de désactiver une branche amont de HEAD quand elle ne pointe sur aucune branche."
+msgstr ""
+"impossible de désactiver une branche amont de HEAD quand elle ne pointe sur "
+"aucune branche."
 
-#: builtin/branch.c:972
+#: builtin/branch.c:979
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "La branche '%s' n'a aucune information de branche amont"
 
-#: builtin/branch.c:987
+#: builtin/branch.c:994
 msgid "it does not make sense to create 'HEAD' manually"
-msgstr "créer manuellement 'HEAD' n'a aucun sens"
+msgstr "créer manuellement 'HEAD' n'a pas de sens"
 
-#: builtin/branch.c:993
+#: builtin/branch.c:1000
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
-msgstr "les options -a et -r de 'git branch' n'ont pas de sens avec un nom de branche"
+msgstr ""
+"les options -a et -r de 'git branch' n'ont pas de sens avec un nom de branche"
 
-#: builtin/branch.c:996
+#: builtin/branch.c:1003
 #, c-format
 msgid ""
 "The --set-upstream flag is deprecated and will be removed. Consider using --"
 "track or --set-upstream-to\n"
-msgstr "l'option --set-upstream est obsolète et va disparaître. Utilisez plutôt --track ou --set-upstream-to\n"
+msgstr ""
+"l'option --set-upstream est obsolète et va disparaître. Utilisez plutôt --"
+"track ou --set-upstream-to\n"
 
-#: builtin/branch.c:1013
+#: builtin/branch.c:1020
 #, c-format
 msgid ""
 "\n"
 "If you wanted to make '%s' track '%s', do this:\n"
 "\n"
-msgstr "\n"
+msgstr ""
+"\n"
 "Si vous vouliez que '%s' suive '%s', faîtes ceci :\n"
 "\n"
 
-#: builtin/branch.c:1014
+#: builtin/branch.c:1021
 #, c-format
 msgid "    git branch -d %s\n"
 msgstr "    git branch -d %s\n"
 
-#: builtin/branch.c:1015
+#: builtin/branch.c:1022
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
 msgstr "    git branch -set-upstream-to %s\n"
@@ -2860,43 +3244,44 @@
 msgid "Need a repository to unbundle."
 msgstr "Le dépaquetage d'un colis requiert un dépôt."
 
-#: builtin/cat-file.c:176
+#: builtin/cat-file.c:312
 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"
 msgstr "git cat-file (-t|-s|-e|-p|<type>|--textconv) <objet>"
 
-#: builtin/cat-file.c:177
+#: builtin/cat-file.c:313
 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>"
 msgstr "git cat-file (--batch|--batch-check) < <liste_d_objets>"
 
-#: builtin/cat-file.c:195
+#: builtin/cat-file.c:350
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<type> peut être : blob, tree, commit ou tag"
 
-#: builtin/cat-file.c:196
+#: builtin/cat-file.c:351
 msgid "show object type"
 msgstr "afficher le type de l'objet"
 
-#: builtin/cat-file.c:197
+#: builtin/cat-file.c:352
 msgid "show object size"
 msgstr "afficher la taille de l'objet"
 
-#: builtin/cat-file.c:199
+#: builtin/cat-file.c:354
 msgid "exit with zero when there's no error"
 msgstr "sortir avec un code d'erreur nul quand il n'y a aucune erreur"
 
-#: builtin/cat-file.c:200
+#: builtin/cat-file.c:355
 msgid "pretty-print object's content"
 msgstr "afficher avec mise en forme le contenu de l'objet"
 
-#: builtin/cat-file.c:202
+#: builtin/cat-file.c:357
 msgid "for blob objects, run textconv on object's content"
 msgstr "pour les objets blob, lancer textconv sur le contenu de l'objet"
 
-#: builtin/cat-file.c:204
+#: builtin/cat-file.c:359
 msgid "show info and content of objects fed from the standard input"
-msgstr "afficher l'information et le contenu des objets passés en entrée standard"
+msgstr ""
+"afficher l'information et le contenu des objets passés en entrée standard"
 
-#: builtin/cat-file.c:207
+#: builtin/cat-file.c:362
 msgid "show info about objects fed from the standard input"
 msgstr "afficher l'information des objets passés en entrée standard"
 
@@ -2906,7 +3291,8 @@
 
 #: builtin/check-attr.c:12
 msgid "git check-attr --stdin [-z] [-a | --all | attr...] < <list-of-paths>"
-msgstr "git check-attr --stdin [-z] [-a | --all | attr...] < <liste-de-chemins>"
+msgstr ""
+"git check-attr --stdin [-z] [-a | --all | attr...] < <liste-de-chemins>"
 
 #: builtin/check-attr.c:19
 msgid "report all attributes set on file"
@@ -2918,36 +3304,65 @@
 
 #: builtin/check-attr.c:21 builtin/check-ignore.c:22 builtin/hash-object.c:75
 msgid "read file names from stdin"
-msgstr "lire les noms de fichier depuis stdin"
+msgstr "lire les noms de fichier depuis l'entrée standard"
 
 #: builtin/check-attr.c:23 builtin/check-ignore.c:24
-msgid "input paths are terminated by a null character"
-msgstr "les chemins en entrée sont terminés par le caractère nul"
+msgid "terminate input and output records by a NUL character"
+msgstr "terminer les enregistrements en entrée et en sortie par un caractère NUL"
 
-#: builtin/check-ignore.c:18 builtin/checkout.c:1044 builtin/gc.c:177
+#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:259
 msgid "suppress progress reporting"
 msgstr "supprimer l'état d'avancement"
 
-#: builtin/check-ignore.c:146
+#: builtin/check-ignore.c:26
+msgid "show non-matching input paths"
+msgstr "afficher les chemins en entrée qui ne correspondent pas"
+
+#: builtin/check-ignore.c:28
+msgid "ignore index when checking"
+msgstr "ignorer l'index pendant la vérification"
+
+#: builtin/check-ignore.c:154
 msgid "cannot specify pathnames with --stdin"
 msgstr "impossible de spécifier les chemins avec --stdin"
 
-#: builtin/check-ignore.c:149
+#: builtin/check-ignore.c:157
 msgid "-z only makes sense with --stdin"
 msgstr "-z n'a de sens qu'avec l'option --stdin"
 
-#: builtin/check-ignore.c:151
+#: builtin/check-ignore.c:159
 msgid "no path specified"
 msgstr "aucun chemin spécifié"
 
-#: builtin/check-ignore.c:155
+#: builtin/check-ignore.c:163
 msgid "--quiet is only valid with a single pathname"
 msgstr "--quiet n'est valide qu'avec un seul chemin"
 
-#: builtin/check-ignore.c:157
+#: builtin/check-ignore.c:165
 msgid "cannot have both --quiet and --verbose"
 msgstr "impossible d'avoir --quiet et --verbose"
 
+#: builtin/check-ignore.c:168
+msgid "--non-matching is only valid with --verbose"
+msgstr "--non-matching n'est valide qu'avec --verbose"
+
+#: builtin/check-mailmap.c:8
+msgid "git check-mailmap [options] <contact>..."
+msgstr "git check-mailmap [options] <contact>..."
+
+#: builtin/check-mailmap.c:13
+msgid "also read contacts from stdin"
+msgstr "lire aussi les contacts depuis l'entrée standard"
+
+#: builtin/check-mailmap.c:24
+#, c-format
+msgid "unable to parse contact: %s"
+msgstr "impossible d'analyser le contact : %s"
+
+#: builtin/check-mailmap.c:47
+msgid "no contacts specified"
+msgstr "aucun contact spécifié"
+
 #: builtin/checkout-index.c:126
 msgid "git checkout-index [options] [--] [<file>...]"
 msgstr "git checkout-index [options] [--] [<fichier>...]"
@@ -2962,7 +3377,9 @@
 
 #: builtin/checkout-index.c:190
 msgid "no warning for existing files and files not in index"
-msgstr "pas d'avertissement pour les fichiers existants et les fichiers absents de l'index"
+msgstr ""
+"pas d'avertissement pour les fichiers existants et les fichiers absents de "
+"l'index"
 
 #: builtin/checkout-index.c:192
 msgid "don't checkout new files"
@@ -3000,106 +3417,108 @@
 msgid "git checkout [options] [<branch>] -- <file>..."
 msgstr "git checkout [options] [<branche>] -- <fichier>..."
 
-#: builtin/checkout.c:117 builtin/checkout.c:150
+#: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr "le chemin '%s' n'a pas notre version"
 
-#: builtin/checkout.c:119 builtin/checkout.c:152
+#: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr "le chemin '%s' n'a pas leur version"
 
-#: builtin/checkout.c:135
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr "le chemin '%s' n'a aucune des versions nécessaires"
 
-#: builtin/checkout.c:179
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr "le chemin '%s' n'a pas les versions nécessaires"
 
-#: builtin/checkout.c:196
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "chemin '%s' : impossible de fusionner"
 
-#: builtin/checkout.c:213
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr "Impossible d'ajouter le résultat de fusion pour '%s'"
 
-#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243
-#: builtin/checkout.c:246
+#: builtin/checkout.c:232 builtin/checkout.c:235 builtin/checkout.c:238
+#: builtin/checkout.c:241
 #, c-format
 msgid "'%s' cannot be used with updating paths"
 msgstr "'%s' ne peut pas être utilisé avec des mises à jour de chemins"
 
-#: builtin/checkout.c:249 builtin/checkout.c:252
+#: builtin/checkout.c:244 builtin/checkout.c:247
 #, c-format
 msgid "'%s' cannot be used with %s"
 msgstr "'%s' ne peut pas être utilisé avec %s"
 
-#: builtin/checkout.c:255
+#: builtin/checkout.c:250
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
-msgstr "Impossible de mettre à jour les chemins et basculer sur la branche '%s' en même temps."
+msgstr ""
+"Impossible de mettre à jour les chemins et basculer sur la branche '%s' en "
+"même temps."
 
-#: builtin/checkout.c:266 builtin/checkout.c:458
+#: builtin/checkout.c:261 builtin/checkout.c:451
 msgid "corrupt index file"
 msgstr "fichier d'index corrompu"
 
-#: builtin/checkout.c:329 builtin/checkout.c:336
+#: builtin/checkout.c:322 builtin/checkout.c:329
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "le chemin '%s' n'est pas fusionné"
 
-#: builtin/checkout.c:480
+#: builtin/checkout.c:473
 msgid "you need to resolve your current index first"
 msgstr "vous devez d'abord résoudre votre index courant"
 
-#: builtin/checkout.c:601
+#: builtin/checkout.c:594
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "Impossible de faire un reflog pour '%s'\n"
 
-#: builtin/checkout.c:634
+#: builtin/checkout.c:632
 msgid "HEAD is now at"
 msgstr "HEAD est maintenant sur"
 
-#: builtin/checkout.c:641
+#: builtin/checkout.c:639
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Remise à zéro de la branche '%s'\n"
 
-#: builtin/checkout.c:644
+#: builtin/checkout.c:642
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Déjà sur '%s'\n"
 
-#: builtin/checkout.c:648
+#: builtin/checkout.c:646
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Basculement et remise à zéro de la branche '%s'\n"
 
-#: builtin/checkout.c:650 builtin/checkout.c:987
+#: builtin/checkout.c:648 builtin/checkout.c:1033
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Basculement sur la nouvelle branche '%s'\n"
 
-#: builtin/checkout.c:652
+#: builtin/checkout.c:650
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Basculement sur la branche '%s'\n"
 
-#: builtin/checkout.c:708
+#: builtin/checkout.c:706
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... et %d en plus.\n"
 
 #. The singular version
-#: builtin/checkout.c:714
+#: builtin/checkout.c:712
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -3122,7 +3541,7 @@
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:732
+#: builtin/checkout.c:730
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -3131,156 +3550,162 @@
 " git branch new_branch_name %s\n"
 "\n"
 msgstr ""
-"Si vous souhaitez les garder en créant une nouvelle branche, c'est le bon moment\n"
+"Si vous souhaitez les garder en créant une nouvelle branche, c'est le bon "
+"moment\n"
 "de le faire avec :\n"
 "\n"
 "git branche nouvelle_branche %s\n"
 "\n"
 
-#: builtin/checkout.c:762
+#: builtin/checkout.c:760
 msgid "internal error in revision walk"
 msgstr "erreur interne lors du parcours des révisions"
 
-#: builtin/checkout.c:766
+#: builtin/checkout.c:764
 msgid "Previous HEAD position was"
 msgstr "La position précédente de HEAD était"
 
-#: builtin/checkout.c:793 builtin/checkout.c:982
+#: builtin/checkout.c:791 builtin/checkout.c:1028
 msgid "You are on a branch yet to be born"
 msgstr "Vous êtes sur une branche qui doit encore naître"
 
-#. case (1)
-#: builtin/checkout.c:918
+#: builtin/checkout.c:935
+#, c-format
+msgid "only one reference expected, %d given."
+msgstr "une seule référence attendue, %d fournies."
+
+#: builtin/checkout.c:974
 #, c-format
 msgid "invalid reference: %s"
 msgstr "référence invalide : %s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:957
+#: builtin/checkout.c:1003
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "la référence n'est pas un arbre : %s"
 
-#: builtin/checkout.c:996
+#: builtin/checkout.c:1042
 msgid "paths cannot be used with switching branches"
 msgstr "impossible d'utiliser des chemins avec un basculement de branches"
 
-#: builtin/checkout.c:999 builtin/checkout.c:1003
+#: builtin/checkout.c:1045 builtin/checkout.c:1049
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "'%s' ne peut pas être utilisé avec un basculement de branches"
 
-#: builtin/checkout.c:1007 builtin/checkout.c:1010 builtin/checkout.c:1015
-#: builtin/checkout.c:1018
+#: builtin/checkout.c:1053 builtin/checkout.c:1056 builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "'%s' ne peut pas être utilisé avec '%s'"
 
-#: builtin/checkout.c:1023
+#: builtin/checkout.c:1069
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "Impossible de basculer de branche vers '%s' qui n'est pas un commit"
 
-#: builtin/checkout.c:1045 builtin/checkout.c:1047 builtin/clone.c:90
+#: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88
 #: builtin/remote.c:169 builtin/remote.c:171
 msgid "branch"
 msgstr "branche"
 
-#: builtin/checkout.c:1046
+#: builtin/checkout.c:1092
 msgid "create and checkout a new branch"
 msgstr "créer et extraire une nouvelle branche"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1094
 msgid "create/reset and checkout a branch"
 msgstr "créer/réinitialiser et extraire une branche"
 
-#: builtin/checkout.c:1049
+#: builtin/checkout.c:1095
 msgid "create reflog for new branch"
-msgstr "créer un refog pour une nouvelle branche"
+msgstr "créer un reflog pour une nouvelle branche"
 
-#: builtin/checkout.c:1050
+#: builtin/checkout.c:1096
 msgid "detach the HEAD at named commit"
 msgstr "détacher la HEAD à la validation nommée"
 
-#: builtin/checkout.c:1051
+#: builtin/checkout.c:1097
 msgid "set upstream info for new branch"
 msgstr "paramétrer l'information de branche amont pour une nouvelle branche"
 
-#: builtin/checkout.c:1053
+#: builtin/checkout.c:1099
 msgid "new branch"
 msgstr "nouvelle branche"
 
-#: builtin/checkout.c:1053
+#: builtin/checkout.c:1099
 msgid "new unparented branch"
 msgstr "nouvelle branche sans parent"
 
-#: builtin/checkout.c:1054
+#: builtin/checkout.c:1100
 msgid "checkout our version for unmerged files"
 msgstr "extraire notre version pour les fichiers non fusionnés"
 
-#: builtin/checkout.c:1056
+#: builtin/checkout.c:1102
 msgid "checkout their version for unmerged files"
 msgstr "extraire leur version pour les fichiers non fusionnés"
 
-#: builtin/checkout.c:1058
+#: builtin/checkout.c:1104
 msgid "force checkout (throw away local modifications)"
 msgstr "forcer l'extraction (laisser tomber les modifications locales)"
 
-#: builtin/checkout.c:1059
+#: builtin/checkout.c:1105
 msgid "perform a 3-way merge with the new branch"
-msgstr "réaliser une fusion à 3 points avec la nouvelle branche"
+msgstr "effectuer une fusion à 3 points avec la nouvelle branche"
 
-#: builtin/checkout.c:1060 builtin/merge.c:217
+#: builtin/checkout.c:1106 builtin/merge.c:232
 msgid "update ignored files (default)"
 msgstr "mettre à jour les fichiers ignorés (par défaut)"
 
-#: builtin/checkout.c:1061 builtin/log.c:1158 parse-options.h:245
+#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:251
 msgid "style"
 msgstr "style"
 
-#: builtin/checkout.c:1062
+#: builtin/checkout.c:1108
 msgid "conflict style (merge or diff3)"
 msgstr "style de conflit (fusion ou diff3)"
 
-#: builtin/checkout.c:1065
+#: builtin/checkout.c:1111
 msgid "do not limit pathspecs to sparse entries only"
-msgstr "ne pas limiter les spécificateurs de chemins aux seules entrées creuses"
+msgstr "ne pas limiter les spécificateurs de chemins aux seuls éléments creux"
 
-#: builtin/checkout.c:1067
+#: builtin/checkout.c:1113
 msgid "second guess 'git checkout no-such-branch'"
 msgstr "deuxième chance 'git checkout branche-inexistante'"
 
-#: builtin/checkout.c:1091
+#: builtin/checkout.c:1136
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b, -B et --orphan sont mutuellement exclusifs"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1153
 msgid "--track needs a branch name"
 msgstr "--track requiert un nom de branche"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1160
 msgid "Missing branch name; try -b"
 msgstr "Nom de branche manquant ; essayez -b"
 
-#: builtin/checkout.c:1150
+#: builtin/checkout.c:1197
 msgid "invalid path specification"
 msgstr "spécification de chemin invalide"
 
-#: builtin/checkout.c:1157
+#: builtin/checkout.c:1204
 #, c-format
 msgid ""
 "Cannot update paths and switch to branch '%s' at the same time.\n"
 "Did you intend to checkout '%s' which can not be resolved as commit?"
 msgstr ""
-"Impossible de mettre à jour les chemins et de basculer sur la branche '%s' en même temps.\n"
+"Impossible de mettre à jour les chemins et de basculer sur la branche '%s' "
+"en même temps.\n"
 "Souhaitiez-vous extraire '%s' qui ne peut être résolu comme commit ?"
 
-#: builtin/checkout.c:1162
+#: builtin/checkout.c:1209
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach n'accepte pas un argument de chemin '%s'"
 
-#: builtin/checkout.c:1166
+#: builtin/checkout.c:1213
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -3288,305 +3713,426 @@
 "git checkout: --ours/--theirs, --force et --merge sont incompatibles lors\n"
 "de l'extraction de l'index."
 
-#: builtin/clean.c:20
-msgid "git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
-msgstr "git clean [-d] [-f] [-n] [-q] [-e <motif>] [-x | -X] [--] <chemins>..."
+#: builtin/clean.c:26
+msgid ""
+"git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
+msgstr ""
+"git clean [-d] [-f] [-i] [-n] [-q] [-e <motif>] [-x | -X] [--] <chemins>..."
 
-#: builtin/clean.c:24
+#: builtin/clean.c:30
 #, c-format
 msgid "Removing %s\n"
 msgstr "Suppression de %s\n"
 
-#: builtin/clean.c:25
+#: builtin/clean.c:31
 #, c-format
 msgid "Would remove %s\n"
 msgstr "Supprimerait %s\n"
 
-#: builtin/clean.c:26
+#: builtin/clean.c:32
 #, c-format
 msgid "Skipping repository %s\n"
 msgstr "Ignore le dépôt %s\n"
 
-#: builtin/clean.c:27
+#: builtin/clean.c:33
 #, c-format
 msgid "Would skip repository %s\n"
 msgstr "Ignorerait le dépôt %s\n"
 
-#: builtin/clean.c:28
+#: builtin/clean.c:34
 #, c-format
 msgid "failed to remove %s"
 msgstr "échec de la suppression de %s"
 
-#: builtin/clean.c:160
+#: builtin/clean.c:294
+msgid ""
+"Prompt help:\n"
+"1          - select a numbered item\n"
+"foo        - select item based on unique prefix\n"
+"           - (empty) select nothing"
+msgstr ""
+"Aide en ligne :\n"
+"1           - sélectionner un élément numéroté\n"
+"foo         - sélectionner un élément par un préfixe unique\n"
+"            - (vide) ne rien sélectionner"
+
+#: builtin/clean.c:298
+msgid ""
+"Prompt help:\n"
+"1          - select a single item\n"
+"3-5        - select a range of items\n"
+"2-3,6-9    - select multiple ranges\n"
+"foo        - select item based on unique prefix\n"
+"-...       - unselect specified items\n"
+"*          - choose all items\n"
+"           - (empty) finish selecting"
+msgstr ""
+"Aide en ligne :\n"
+"1          - sélectionner un seul élément\n"
+"3-5        - sélectionner une plage d'éléments\n"
+"2-3,6-9    - sélectionner plusieurs plages\n"
+"foo        - sélectionner un élément par un préfixe unique\n"
+"-...       - désélectionner les éléments spécifiés\n"
+"*          - choisir tous les éléments\n"
+"           - (vide) terminer la sélection"
+
+#: builtin/clean.c:516
+#, c-format
+msgid "Huh (%s)?"
+msgstr "Hein (%s) ?"
+
+#: builtin/clean.c:659
+#, c-format
+msgid "Input ignore patterns>> "
+msgstr "Entrez les motifs à ignorer>> "
+
+#: builtin/clean.c:696
+#, c-format
+msgid "WARNING: Cannot find items matched by: %s"
+msgstr "ATTENTION : Impossible de trouver les éléments correspondant à : %s"
+
+#: builtin/clean.c:717
+msgid "Select items to delete"
+msgstr "Sélectionner les éléments à supprimer"
+
+#: builtin/clean.c:757
+#, c-format
+msgid "remove %s? "
+msgstr "supprimer %s ? "
+
+#: builtin/clean.c:782
+msgid "Bye."
+msgstr "Au revoir."
+
+#: builtin/clean.c:790
+msgid ""
+"clean               - start cleaning\n"
+"filter by pattern   - exclude items from deletion\n"
+"select by numbers   - select items to be deleted by numbers\n"
+"ask each            - confirm each deletion (like \"rm -i\")\n"
+"quit                - stop cleaning\n"
+"help                - this screen\n"
+"?                   - help for prompt selection"
+msgstr ""
+"clean               - démarrer le nettoyage\n"
+"filter by pattern   - exclure des éléments par motif\n"
+"select by numbers   - sélectionner les éléments à supprimer par numéros\n"
+"ask each            - confirmer chaque suppression (comme \"rm -i\")\n"
+"quit                - arrêter le nettoyage\n"
+"help                - cet écran\n"
+"?                   - aide pour la sélection en ligne"
+
+#: builtin/clean.c:817
+msgid "*** Commands ***"
+msgstr "*** Commandes ***"
+
+#: builtin/clean.c:818
+msgid "What now"
+msgstr "Et maintenant ?"
+
+#: builtin/clean.c:826
+msgid "Would remove the following item:"
+msgid_plural "Would remove the following items:"
+msgstr[0] "Supprimerait l'élément suivant :"
+msgstr[1] "Supprimerait les éléments suivants :"
+
+#: builtin/clean.c:843
+msgid "No more files to clean, exiting."
+msgstr "Plus de fichier à nettoyer, sortie."
+
+#: builtin/clean.c:874
 msgid "do not print names of files removed"
 msgstr "ne pas afficher les noms des fichiers supprimés"
 
-#: builtin/clean.c:162
+#: builtin/clean.c:876
 msgid "force"
 msgstr "forcer"
 
-#: builtin/clean.c:164
+#: builtin/clean.c:877
+msgid "interactive cleaning"
+msgstr "nettoyage interactif"
+
+#: builtin/clean.c:879
 msgid "remove whole directories"
 msgstr "supprimer les répertoires entiers"
 
-#: builtin/clean.c:165 builtin/describe.c:412 builtin/grep.c:717
-#: builtin/ls-files.c:487 builtin/name-rev.c:231 builtin/show-ref.c:182
+#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718
+#: builtin/ls-files.c:483 builtin/name-rev.c:315 builtin/show-ref.c:185
 msgid "pattern"
 msgstr "motif"
 
-#: builtin/clean.c:166
+#: builtin/clean.c:881
 msgid "add <pattern> to ignore rules"
 msgstr "ajouter <motif> aux règles ignore"
 
-#: builtin/clean.c:167
+#: builtin/clean.c:882
 msgid "remove ignored files, too"
 msgstr "supprimer les fichiers ignorés, aussi"
 
-#: builtin/clean.c:169
+#: builtin/clean.c:884
 msgid "remove only ignored files"
 msgstr "supprimer seulement les fichiers ignorés"
 
-#: builtin/clean.c:187
+#: builtin/clean.c:902
 msgid "-x and -X cannot be used together"
 msgstr "-x et -X ne peuvent pas être utilisés ensemble"
 
-#: builtin/clean.c:191
+#: builtin/clean.c:906
 msgid ""
-"clean.requireForce set to true and neither -n nor -f given; refusing to clean"
-msgstr "clean.requireForce positionné à true et ni -n ni -f fourni ; refus de nettoyer"
-
-#: builtin/clean.c:194
-msgid ""
-"clean.requireForce defaults to true and neither -n nor -f given; refusing to "
+"clean.requireForce set to true and neither -i, -n nor -f given; refusing to "
 "clean"
-msgstr "clean.requireForce à true par défaut et ni -n ni -f fourni ; refus de nettoyer"
+msgstr ""
+"clean.requireForce positionné à true et ni -i, -n ou -f fourni ; refus de "
+"nettoyer"
 
-#: builtin/clone.c:37
+#: builtin/clean.c:909
+msgid ""
+"clean.requireForce defaults to true and neither -i, -n nor -f given; "
+"refusing to clean"
+msgstr ""
+"clean.requireForce à true par défaut et ni -i, -n ou -f fourni ; refus de "
+"nettoyer"
+
+#: builtin/clone.c:36
 msgid "git clone [options] [--] <repo> [<dir>]"
 msgstr "git clone [options] [--] <dépôt> [<répertoire>]"
 
-#: builtin/clone.c:65 builtin/fetch.c:82 builtin/merge.c:214
-#: builtin/push.c:436
+#: builtin/clone.c:64 builtin/fetch.c:96 builtin/merge.c:229
+#: builtin/push.c:474
 msgid "force progress reporting"
 msgstr "forcer l'état d'avancement"
 
-#: builtin/clone.c:67
+#: builtin/clone.c:66
 msgid "don't create a checkout"
 msgstr "ne pas créer d'extraction"
 
-#: builtin/clone.c:68 builtin/clone.c:70 builtin/init-db.c:488
+#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488
 msgid "create a bare repository"
 msgstr "créer un dépôt nu"
 
-#: builtin/clone.c:73
+#: builtin/clone.c:71
 msgid "create a mirror repository (implies bare)"
 msgstr "créer un dépôt miroir (implique dépôt nu)"
 
-#: builtin/clone.c:75
+#: builtin/clone.c:73
 msgid "to clone from a local repository"
 msgstr "pour cloner depuis un dépôt local"
 
-#: builtin/clone.c:77
+#: builtin/clone.c:75
 msgid "don't use local hardlinks, always copy"
 msgstr "ne pas utiliser de liens durs locaux, toujours copier"
 
-#: builtin/clone.c:79
+#: builtin/clone.c:77
 msgid "setup as shared repository"
 msgstr "régler comme dépôt partagé"
 
-#: builtin/clone.c:81 builtin/clone.c:83
+#: builtin/clone.c:79 builtin/clone.c:81
 msgid "initialize submodules in the clone"
 msgstr "initialiser les sous-modules dans le clone"
 
-#: builtin/clone.c:84 builtin/init-db.c:485
+#: builtin/clone.c:82 builtin/init-db.c:485
 msgid "template-directory"
 msgstr "répertoire-modèle"
 
-#: builtin/clone.c:85 builtin/init-db.c:486
+#: builtin/clone.c:83 builtin/init-db.c:486
 msgid "directory from which templates will be used"
 msgstr "répertoire depuis lequel les modèles vont être utilisés"
 
-#: builtin/clone.c:87
+#: builtin/clone.c:85
 msgid "reference repository"
 msgstr "dépôt de référence"
 
-#: builtin/clone.c:88 builtin/column.c:26 builtin/merge-file.c:44
+#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44
 msgid "name"
 msgstr "nom"
 
-#: builtin/clone.c:89
+#: builtin/clone.c:87
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "utiliser <nom> au lieu de 'origin' pour suivre la branche amont"
 
-#: builtin/clone.c:91
+#: builtin/clone.c:89
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "extraire <branche> au lieu de la HEAD du répertoire distant"
 
-#: builtin/clone.c:93
+#: builtin/clone.c:91
 msgid "path to git-upload-pack on the remote"
 msgstr "chemin vers git-upload-pack sur le serveur distant"
 
-#: builtin/clone.c:94 builtin/fetch.c:83 builtin/grep.c:662
+#: builtin/clone.c:92 builtin/fetch.c:97 builtin/grep.c:663
 msgid "depth"
 msgstr "profondeur"
 
-#: builtin/clone.c:95
+#: builtin/clone.c:93
 msgid "create a shallow clone of that depth"
 msgstr "créer un clone superficiel de cette profondeur"
 
-#: builtin/clone.c:97
+#: builtin/clone.c:95
 msgid "clone only one branch, HEAD or --branch"
 msgstr "cloner seulement une branche, HEAD ou --branch"
 
-#: builtin/clone.c:98 builtin/init-db.c:494
+#: builtin/clone.c:96 builtin/init-db.c:494
 msgid "gitdir"
 msgstr "gitdir"
 
-#: builtin/clone.c:99 builtin/init-db.c:495
+#: builtin/clone.c:97 builtin/init-db.c:495
 msgid "separate git dir from working tree"
 msgstr "séparer le répertoire git de la copie de travail"
 
-#: builtin/clone.c:100
+#: builtin/clone.c:98
 msgid "key=value"
 msgstr "clé=valeur"
 
-#: builtin/clone.c:101
+#: builtin/clone.c:99
 msgid "set config inside the new repository"
 msgstr "régler la configuration dans le nouveau dépôt"
 
-#: builtin/clone.c:254
+#: builtin/clone.c:252
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "le dépôt de référence '%s' n'est pas un dépôt local."
 
-#: builtin/clone.c:317
+#: builtin/clone.c:315
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "échec de la création du répertoire '%s'"
 
-#: builtin/clone.c:319 builtin/diff.c:77
+#: builtin/clone.c:317 builtin/diff.c:77
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "échec du stat de '%s'"
 
-#: builtin/clone.c:321
+#: builtin/clone.c:319
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s existe et n'est pas un répertoire"
 
-#: builtin/clone.c:335
+#: builtin/clone.c:333
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "échec du stat de %s\n"
 
-#: builtin/clone.c:357
+#: builtin/clone.c:355
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "échec de la création du lien '%s'"
 
-#: builtin/clone.c:361
+#: builtin/clone.c:359
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "échec de la copie vers '%s'"
 
-#: builtin/clone.c:384
+#: builtin/clone.c:382 builtin/clone.c:559
 #, c-format
 msgid "done.\n"
 msgstr "fait.\n"
 
-#: builtin/clone.c:397
+#: builtin/clone.c:395
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
 "and retry the checkout with 'git checkout -f HEAD'\n"
-msgstr "Le clone a réussi, mais l'extraction a échoué.\n"
+msgstr ""
+"Le clone a réussi, mais l'extraction a échoué.\n"
 "Vous pouvez inspecter ce qui a été extrait avec 'git status'\n"
 "et réessayer l'extraction avec 'git checkout -f HEAD'\n"
 
-#: builtin/clone.c:476
+#: builtin/clone.c:474
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Impossible de trouver la branche distante '%s' à cloner."
 
-#: builtin/clone.c:550
+#: builtin/clone.c:554
+#, c-format
+msgid "Checking connectivity... "
+msgstr "Vérification de la connectivité... "
+
+#: builtin/clone.c:557
 msgid "remote did not send all necessary objects"
 msgstr "le serveur distant n'a pas envoyé tous les objets nécessaires"
 
-#: builtin/clone.c:610
+#: builtin/clone.c:620
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr "la HEAD distante réfère à une référence non existante, impossible de l'extraire.\n"
+msgstr ""
+"la HEAD distante réfère à une référence non existante, impossible de "
+"l'extraire.\n"
 
-#: builtin/clone.c:641
+#: builtin/clone.c:651
 msgid "unable to checkout working tree"
-msgstr "inpossible d'extraire la copie de travail"
+msgstr "impossible d'extraire la copie de travail"
 
-#: builtin/clone.c:749
+#: builtin/clone.c:759
 msgid "Too many arguments."
 msgstr "Trop d'arguments."
 
-#: builtin/clone.c:753
+#: builtin/clone.c:763
 msgid "You must specify a repository to clone."
 msgstr "Vous devez spécifier un dépôt à cloner."
 
-#: builtin/clone.c:764
+#: builtin/clone.c:774
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "les options --bare et --origin %s sont incompatibles."
 
-#: builtin/clone.c:767
+#: builtin/clone.c:777
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "--bare et --separate-git-dir sont incompatibles."
 
-#: builtin/clone.c:780
+#: builtin/clone.c:790
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "le dépôt '%s' n'existe pas"
 
-#: builtin/clone.c:785
-msgid "--depth is ignored in local clones; use file:// instead."
-msgstr "--depth est ignoré dans les clones locaux : utilisez plutôt \"file://\"."
-
 #: builtin/clone.c:795
+msgid "--depth is ignored in local clones; use file:// instead."
+msgstr ""
+"--depth est ignoré dans les clones locaux : utilisez plutôt \"file://\"."
+
+#: builtin/clone.c:797
+msgid "--local is ignored"
+msgstr "--local est ignoré"
+
+#: builtin/clone.c:807
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
-msgstr "le chemin de destination '%s' existe déjà et n'est pas un répertoire vide."
+msgstr ""
+"le chemin de destination '%s' existe déjà et n'est pas un répertoire vide."
 
-#: builtin/clone.c:805
+#: builtin/clone.c:817
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "la copie de travail '%s' existe déjà."
 
-#: builtin/clone.c:818 builtin/clone.c:830
+#: builtin/clone.c:830 builtin/clone.c:842
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "impossible de créer les répertoires de premier niveau dans '%s'"
 
-#: builtin/clone.c:821
+#: builtin/clone.c:833
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "impossible de créer le répertoire de la copie de travail '%s'."
 
-#: builtin/clone.c:840
+#: builtin/clone.c:852
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Clonage dans le dépôt nu '%s'\n"
 
-#: builtin/clone.c:842
+#: builtin/clone.c:854
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Clonage dans '%s'...\n"
 
-#: builtin/clone.c:877
+#: builtin/clone.c:888
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "Je ne sais pas cloner %s"
 
-#: builtin/clone.c:926
+#: builtin/clone.c:939 builtin/clone.c:947
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "La branche distante %s n'a pas été trouvée dans le dépôt amont %s"
 
-#: builtin/clone.c:933
+#: builtin/clone.c:950
 msgid "You appear to have cloned an empty repository."
 msgstr "Vous semblez avoir cloné un dépôt vide."
 
@@ -3622,15 +4168,15 @@
 msgid "--command must be the first argument"
 msgstr "--command doit être le premier argument"
 
-#: builtin/commit.c:34
+#: builtin/commit.c:36
 msgid "git commit [options] [--] <pathspec>..."
 msgstr "git commit [options] [--] <spécification-de-chemin>..."
 
-#: builtin/commit.c:39
+#: builtin/commit.c:41
 msgid "git status [options] [--] <pathspec>..."
 msgstr "git status [options] [--] <spécification-de-chemin>..."
 
-#: builtin/commit.c:44
+#: builtin/commit.c:46
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3643,8 +4189,10 @@
 "\n"
 "    git commit --amend --reset-author\n"
 msgstr ""
-"Votre nom et votre adresse e-mail ont été configurés automatiquement en se fondant\n"
-"sur votre nom d'utilisateur et votre nom d'ordinateur. Veuillez vérifier qu'ils sont corrects.\n"
+"Votre nom et votre adresse e-mail ont été configurés automatiquement en se "
+"fondant\n"
+"sur votre nom d'utilisateur et votre nom d'ordinateur. Veuillez vérifier "
+"qu'ils sont corrects.\n"
 "Vous pouvez supprimer ce message en les paramétrant explicitement :\n"
 "\n"
 "    git config --global user.name \"Votre Nom\"\n"
@@ -3654,118 +4202,139 @@
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: builtin/commit.c:56
+#: builtin/commit.c:58
 msgid ""
 "You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
 "remove the commit entirely with \"git reset HEAD^\".\n"
-msgstr "Vous avez demandé de corriger le commit le plus récent, mais le faire le rendrait\n"
+msgstr ""
+"Vous avez demandé de corriger le commit le plus récent, mais le faire le "
+"rendrait\n"
 "vide. Vous pouvez répéter votre commande avec --allow-empty, ou vous pouvez\n"
 "supprimer complètement le commit avec \"git reset HEAD^\".\n"
 
-#: builtin/commit.c:61
+#: builtin/commit.c:63
 msgid ""
 "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 "If you wish to commit it anyway, use:\n"
 "\n"
 "    git commit --allow-empty\n"
 "\n"
-"Otherwise, please use 'git reset'\n"
 msgstr ""
-"Le picorage précédent est à présent vide, vraisemblablement dû à une résolution de conflit.\n"
+"Le picorage précédent est à présent vide, vraisemblablement dû à une "
+"résolution de conflit.\n"
 "Si vous souhaitez tout de même le valider, utilisez :\n"
 "\n"
 "    git commit --allow-empty\n"
 "\n"
-"Sinon, utilisez 'git reset'\n"
 
-#: builtin/commit.c:260
+#: builtin/commit.c:70
+msgid "Otherwise, please use 'git reset'\n"
+msgstr "Sinon, veuillez utiliser 'git reset'\n"
+
+#: builtin/commit.c:73
+msgid ""
+"If you wish to skip this commit, use:\n"
+"\n"
+"    git reset\n"
+"\n"
+"Then \"git cherry-pick --continue\" will resume cherry-picking\n"
+"the remaining commits.\n"
+msgstr ""
+"Si vous souhaitez sauter ce commit, utilisez :\n"
+"\n"
+"    git reset\n"
+"\n"
+"Puis \"git cherry-pick --continue\" continuera le picorage \n"
+"des commits restants.\n"
+
+#: builtin/commit.c:287
 msgid "failed to unpack HEAD tree object"
 msgstr "échec du dépaquetage de l'objet arbre HEAD"
 
-#: builtin/commit.c:302
+#: builtin/commit.c:329
 msgid "unable to create temporary index"
 msgstr "impossible de créer l'index temporaire"
 
-#: builtin/commit.c:308
+#: builtin/commit.c:335
 msgid "interactive add failed"
 msgstr "échec de l'ajout interactif"
 
-#: builtin/commit.c:341 builtin/commit.c:362 builtin/commit.c:412
+#: builtin/commit.c:368 builtin/commit.c:389 builtin/commit.c:439
 msgid "unable to write new_index file"
 msgstr "impossible d'écrire le fichier new_index"
 
-#: builtin/commit.c:393
+#: builtin/commit.c:420
 msgid "cannot do a partial commit during a merge."
 msgstr "impossible de faire une validation partielle pendant une fusion."
 
-#: builtin/commit.c:395
+#: builtin/commit.c:422
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "impossible de faire une validation partielle pendant un picorage."
 
-#: builtin/commit.c:405
+#: builtin/commit.c:432
 msgid "cannot read the index"
 msgstr "impossible de lire l'index"
 
-#: builtin/commit.c:425
+#: builtin/commit.c:452
 msgid "unable to write temporary index file"
 msgstr "impossible d'écrire le fichier d'index temporaire"
 
-#: builtin/commit.c:513 builtin/commit.c:519
+#: builtin/commit.c:543 builtin/commit.c:549
 #, c-format
 msgid "invalid commit: %s"
 msgstr "commit invalide : %s"
 
-#: builtin/commit.c:542
+#: builtin/commit.c:571
 msgid "malformed --author parameter"
 msgstr "paramètre --author mal formé"
 
-#: builtin/commit.c:562
+#: builtin/commit.c:591
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "Chaîne ident mal formée : '%s'"
 
-#: builtin/commit.c:600 builtin/commit.c:633 builtin/commit.c:956
+#: builtin/commit.c:630 builtin/commit.c:663 builtin/commit.c:1007
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "impossible de rechercher le commit %s"
 
-#: builtin/commit.c:612 builtin/shortlog.c:270
+#: builtin/commit.c:642 builtin/shortlog.c:273
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(lecture du message de journal depuis l'entrée standard)\n"
 
-#: builtin/commit.c:614
+#: builtin/commit.c:644
 msgid "could not read log from standard input"
 msgstr "impossible de lire le journal depuis l'entrée standard"
 
-#: builtin/commit.c:618
+#: builtin/commit.c:648
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "impossible de lire le fichier de journal '%s'"
 
-#: builtin/commit.c:624
+#: builtin/commit.c:654
 msgid "commit has empty message"
 msgstr "le commit a un message vide"
 
-#: builtin/commit.c:640
+#: builtin/commit.c:670
 msgid "could not read MERGE_MSG"
 msgstr "impossible de lire MERGE_MSG"
 
-#: builtin/commit.c:644
+#: builtin/commit.c:674
 msgid "could not read SQUASH_MSG"
 msgstr "impossible de lire SQUASH_MSG"
 
-#: builtin/commit.c:648
+#: builtin/commit.c:678
 #, c-format
 msgid "could not read '%s'"
 msgstr "impossible de lire '%s'"
 
-#: builtin/commit.c:709
+#: builtin/commit.c:749
 msgid "could not write commit template"
 msgstr "impossible d'écrire le modèle de commit"
 
-#: builtin/commit.c:720
+#: builtin/commit.c:760
 #, c-format
 msgid ""
 "\n"
@@ -3780,7 +4349,7 @@
 "\t%s\n"
 "et essayez à nouveau.\n"
 
-#: builtin/commit.c:725
+#: builtin/commit.c:765
 #, c-format
 msgid ""
 "\n"
@@ -3795,16 +4364,17 @@
 "\t%s\n"
 "et essayez à nouveau.\n"
 
-#: builtin/commit.c:737
+#: builtin/commit.c:777
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '%c' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Veuillez saisir le message de validation pour vos modifications. Les lignes\n"
-"commençant par '%c' seront ignorées, et un message vide abandonne la validation.\n"
+"commençant par '%c' seront ignorées, et un message vide abandonne la "
+"validation.\n"
 
-#: builtin/commit.c:742
+#: builtin/commit.c:782
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -3815,1802 +4385,1884 @@
 "commençant par '%c' seront conservées ; vous pouvez les supprimer vous-même\n"
 "si vous le souhaitez. Un message vide abandonne la validation.\n"
 
-#: builtin/commit.c:755
+#: builtin/commit.c:795
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%sAuteur :     %s"
 
-#: builtin/commit.c:762
+#: builtin/commit.c:802
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%sValidateur : %s"
 
-#: builtin/commit.c:782
+#: builtin/commit.c:822
 msgid "Cannot read index"
 msgstr "Impossible de lire l'index"
 
-#: builtin/commit.c:819
+#: builtin/commit.c:865
 msgid "Error building trees"
 msgstr "Erreur lors de la construction des arbres"
 
-#: builtin/commit.c:834 builtin/tag.c:359
+#: builtin/commit.c:880 builtin/tag.c:359
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Veuillez fournir le message en utilisant l'option -m ou -F.\n"
 
-#: builtin/commit.c:931
+#: builtin/commit.c:982
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "Aucun auteur existant trouvé avec '%s'"
 
-#: builtin/commit.c:946 builtin/commit.c:1140
+#: builtin/commit.c:997 builtin/commit.c:1237
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Mode de fichier non suivi invalide '%s'"
 
-#: builtin/commit.c:976
+#: builtin/commit.c:1034
+msgid "--long and -z are incompatible"
+msgstr "--long et -z sont incompatibles"
+
+#: builtin/commit.c:1064
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "L'utilisation simultanée de --reset-author et --author n'a pas de sens"
 
-#: builtin/commit.c:987
+#: builtin/commit.c:1075
 msgid "You have nothing to amend."
 msgstr "Il n'y a rien à corriger."
 
-#: builtin/commit.c:990
+#: builtin/commit.c:1078
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Vous êtes en pleine fusion -- impossible de corriger (amend)."
 
-#: builtin/commit.c:992
+#: builtin/commit.c:1080
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "Vous êtes en plein picorage -- impossible de corriger (amend)."
 
-#: builtin/commit.c:995
+#: builtin/commit.c:1083
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Les options --squash et --fixup ne peuvent pas être utilisées ensemble"
 
-#: builtin/commit.c:1005
+#: builtin/commit.c:1093
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Une seule option parmi -c/-C/-F/--fixup peut être utilisée."
 
-#: builtin/commit.c:1007
+#: builtin/commit.c:1095
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr "L'option -m ne peut pas être combinée avec -c/-C/-F/--fixup."
 
-#: builtin/commit.c:1015
+#: builtin/commit.c:1103
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author ne peut être utilisé qu'avec -C, -c ou --amend."
 
-#: builtin/commit.c:1032
+#: builtin/commit.c:1120
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
-msgstr "Une seule option parmi --include/--only/--all/--interactive/--patch peut être utilisée."
+msgstr ""
+"Une seule option parmi --include/--only/--all/--interactive/--patch peut "
+"être utilisée."
 
-#: builtin/commit.c:1034
+#: builtin/commit.c:1122
 msgid "No paths with --include/--only does not make sense."
 msgstr "Aucun chemin avec les options --include/--only n'a pas de sens."
 
-#: builtin/commit.c:1036
+#: builtin/commit.c:1124
 msgid "Clever... amending the last one with dirty index."
 msgstr "Malin... correction du dernier avec un index sale."
 
-#: builtin/commit.c:1038
+#: builtin/commit.c:1126
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
-msgstr ""
+msgstr "Chemins explicites spécifiés sans -i ni -o ; --only supposé..."
 
-#: builtin/commit.c:1048 builtin/tag.c:575
+#: builtin/commit.c:1136 builtin/tag.c:572
 #, c-format
 msgid "Invalid cleanup mode %s"
-msgstr ""
+msgstr "Mode de nettoyage invalide %s"
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1141
 msgid "Paths with -a does not make sense."
-msgstr ""
+msgstr "Spécifier des chemins avec l'option -a n'a pas de sens."
 
-#: builtin/commit.c:1059 builtin/commit.c:1194
-msgid "--long and -z are incompatible"
-msgstr ""
-
-#: builtin/commit.c:1154 builtin/commit.c:1390
+#: builtin/commit.c:1251 builtin/commit.c:1482
 msgid "show status concisely"
-msgstr ""
+msgstr "afficher le statut avec concision"
 
-#: builtin/commit.c:1156 builtin/commit.c:1392
+#: builtin/commit.c:1253 builtin/commit.c:1484
 msgid "show branch information"
-msgstr ""
+msgstr "afficher l'information de branche"
 
-#: builtin/commit.c:1158 builtin/commit.c:1394 builtin/push.c:426
+#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:460
 msgid "machine-readable output"
-msgstr ""
+msgstr "sortie pour traitement automatique"
 
-#: builtin/commit.c:1161 builtin/commit.c:1396
+#: builtin/commit.c:1258 builtin/commit.c:1488
 msgid "show status in long format (default)"
-msgstr ""
+msgstr "afficher le statut en format long (par défaut)"
 
-#: builtin/commit.c:1164 builtin/commit.c:1399
+#: builtin/commit.c:1261 builtin/commit.c:1491
 msgid "terminate entries with NUL"
-msgstr ""
+msgstr "terminer les éléments par NUL"
 
-#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/fast-export.c:659
-#: builtin/fast-export.c:662 builtin/tag.c:459
+#: builtin/commit.c:1263 builtin/commit.c:1494 builtin/fast-export.c:674
+#: builtin/fast-export.c:677 builtin/tag.c:459
 msgid "mode"
-msgstr ""
+msgstr "mode"
 
-#: builtin/commit.c:1167 builtin/commit.c:1402
+#: builtin/commit.c:1264 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
+"afficher les fichiers non suivis, \"mode\" facultatif : all (tous), normal, "
+"no. (Défaut : all)"
 
-#: builtin/commit.c:1170
+#: builtin/commit.c:1267
 msgid "show ignored files"
-msgstr ""
+msgstr "afficher les fichiers ignorés"
 
-#: builtin/commit.c:1171 parse-options.h:151
+#: builtin/commit.c:1268 parse-options.h:156
 msgid "when"
-msgstr ""
+msgstr "quand"
 
-#: builtin/commit.c:1172
+#: builtin/commit.c:1269
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
 msgstr ""
+"ignorer les modifications dans les sous-modules, \"quand\" facultatif : all "
+"(tous), dirty (sale), untracked (non suivi). (Défaut : all)"
 
-#: builtin/commit.c:1174
+#: builtin/commit.c:1271
 msgid "list untracked files in columns"
-msgstr ""
+msgstr "afficher les fichiers non suivis en colonnes"
 
-#: builtin/commit.c:1248
+#: builtin/commit.c:1340
 msgid "couldn't look up newly created commit"
-msgstr ""
+msgstr "impossible de retrouver le commit nouvellement créé"
 
-#: builtin/commit.c:1250
+#: builtin/commit.c:1342
 msgid "could not parse newly created commit"
-msgstr ""
-
-#: builtin/commit.c:1291
-msgid "detached HEAD"
-msgstr ""
-
-#: builtin/commit.c:1293
-msgid " (root-commit)"
-msgstr ""
-
-#: builtin/commit.c:1360
-msgid "suppress summary after successful commit"
-msgstr ""
-
-#: builtin/commit.c:1361
-msgid "show diff in commit message template"
-msgstr ""
-
-#: builtin/commit.c:1363
-msgid "Commit message options"
-msgstr ""
-
-#: builtin/commit.c:1364 builtin/tag.c:457
-msgid "read message from file"
-msgstr ""
-
-#: builtin/commit.c:1365
-msgid "author"
-msgstr ""
-
-#: builtin/commit.c:1365
-msgid "override author for commit"
-msgstr ""
-
-#: builtin/commit.c:1366 builtin/gc.c:178
-msgid "date"
-msgstr ""
-
-#: builtin/commit.c:1366
-msgid "override date for commit"
-msgstr ""
-
-#: builtin/commit.c:1367 builtin/merge.c:208 builtin/notes.c:533
-#: builtin/notes.c:690 builtin/tag.c:455
-msgid "message"
-msgstr ""
-
-#: builtin/commit.c:1367
-msgid "commit message"
-msgstr ""
-
-#: builtin/commit.c:1368
-msgid "reuse and edit message from specified commit"
-msgstr ""
-
-#: builtin/commit.c:1369
-msgid "reuse message from specified commit"
-msgstr ""
-
-#: builtin/commit.c:1370
-msgid "use autosquash formatted message to fixup specified commit"
-msgstr ""
-
-#: builtin/commit.c:1371
-msgid "use autosquash formatted message to squash specified commit"
-msgstr ""
-
-#: builtin/commit.c:1372
-msgid "the commit is authored by me now (used with -C/-c/--amend)"
-msgstr ""
-
-#: builtin/commit.c:1373 builtin/log.c:1113 builtin/revert.c:109
-msgid "add Signed-off-by:"
-msgstr ""
-
-#: builtin/commit.c:1374
-msgid "use specified template file"
-msgstr ""
-
-#: builtin/commit.c:1375
-msgid "force edit of commit"
-msgstr ""
-
-#: builtin/commit.c:1376
-msgid "default"
-msgstr ""
-
-#: builtin/commit.c:1376 builtin/tag.c:460
-msgid "how to strip spaces and #comments from message"
-msgstr ""
-
-#: builtin/commit.c:1377
-msgid "include status in commit message template"
-msgstr ""
-
-#: builtin/commit.c:1378 builtin/merge.c:215 builtin/tag.c:461
-msgid "key id"
-msgstr ""
-
-#: builtin/commit.c:1379 builtin/merge.c:216
-msgid "GPG sign commit"
-msgstr ""
-
-#. end commit message options
-#: builtin/commit.c:1382
-msgid "Commit contents options"
-msgstr ""
+msgstr "impossible d'analyser le commit nouvellement créé"
 
 #: builtin/commit.c:1383
-msgid "commit all changed files"
-msgstr ""
-
-#: builtin/commit.c:1384
-msgid "add specified files to index for commit"
-msgstr ""
+msgid "detached HEAD"
+msgstr "HEAD détachée"
 
 #: builtin/commit.c:1385
+msgid " (root-commit)"
+msgstr " (commit racine)"
+
+#: builtin/commit.c:1452
+msgid "suppress summary after successful commit"
+msgstr "supprimer le résumé après une validation réussie"
+
+#: builtin/commit.c:1453
+msgid "show diff in commit message template"
+msgstr "afficher les diff dans le modèle de message de validation"
+
+#: builtin/commit.c:1455
+msgid "Commit message options"
+msgstr "Options du message de validation"
+
+#: builtin/commit.c:1456 builtin/tag.c:457
+msgid "read message from file"
+msgstr "lire le message depuis un fichier"
+
+#: builtin/commit.c:1457
+msgid "author"
+msgstr "auteur"
+
+#: builtin/commit.c:1457
+msgid "override author for commit"
+msgstr "remplacer l'auteur pour la validation"
+
+#: builtin/commit.c:1458 builtin/gc.c:260
+msgid "date"
+msgstr "date"
+
+#: builtin/commit.c:1458
+msgid "override date for commit"
+msgstr "remplacer la date pour la validation"
+
+#: builtin/commit.c:1459 builtin/merge.c:223 builtin/notes.c:405
+#: builtin/notes.c:562 builtin/tag.c:455
+msgid "message"
+msgstr "message"
+
+#: builtin/commit.c:1459
+msgid "commit message"
+msgstr "message de validation"
+
+#: builtin/commit.c:1460
+msgid "reuse and edit message from specified commit"
+msgstr "réutiliser et éditer le message du commit spécifié"
+
+#: builtin/commit.c:1461
+msgid "reuse message from specified commit"
+msgstr "réutiliser le message du commit spécifié"
+
+#: builtin/commit.c:1462
+msgid "use autosquash formatted message to fixup specified commit"
+msgstr ""
+"utiliser un message formaté par autosquash pour corriger le commit spécifié"
+
+#: builtin/commit.c:1463
+msgid "use autosquash formatted message to squash specified commit"
+msgstr ""
+"utiliser un message formaté par autosquash pour compresser le commit spécifié"
+
+#: builtin/commit.c:1464
+msgid "the commit is authored by me now (used with -C/-c/--amend)"
+msgstr ""
+"à présent je suis l'auteur de la validation (utilisé avec -C/-c/--amend)"
+
+#: builtin/commit.c:1465 builtin/log.c:1180 builtin/revert.c:86
+msgid "add Signed-off-by:"
+msgstr "ajouter une entrée Signed-off-by :"
+
+#: builtin/commit.c:1466
+msgid "use specified template file"
+msgstr "utiliser le fichier de modèle spécifié"
+
+#: builtin/commit.c:1467
+msgid "force edit of commit"
+msgstr "forcer l'édition du commit"
+
+#: builtin/commit.c:1468
+msgid "default"
+msgstr "défaut"
+
+#: builtin/commit.c:1468 builtin/tag.c:460
+msgid "how to strip spaces and #comments from message"
+msgstr "comment éliminer les espaces et les commentaires # du message"
+
+#: builtin/commit.c:1469
+msgid "include status in commit message template"
+msgstr "inclure le statut dans le modèle de message de validation"
+
+#: builtin/commit.c:1470 builtin/merge.c:230 builtin/tag.c:461
+msgid "key id"
+msgstr "identifiant de clé"
+
+#: builtin/commit.c:1471 builtin/merge.c:231
+msgid "GPG sign commit"
+msgstr "signer la validation avec GPG"
+
+#. end commit message options
+#: builtin/commit.c:1474
+msgid "Commit contents options"
+msgstr "Valider les options des contenus"
+
+#: builtin/commit.c:1475
+msgid "commit all changed files"
+msgstr "valider tous les fichiers modifiés"
+
+#: builtin/commit.c:1476
+msgid "add specified files to index for commit"
+msgstr "ajouter les fichiers spécifiés à l'index pour la validation"
+
+#: builtin/commit.c:1477
 msgid "interactively add files"
-msgstr ""
+msgstr "ajouter des fichiers en mode interactif"
 
-#: builtin/commit.c:1386
+#: builtin/commit.c:1478
 msgid "interactively add changes"
-msgstr ""
+msgstr "ajouter les modifications en mode interactif"
 
-#: builtin/commit.c:1387
+#: builtin/commit.c:1479
 msgid "commit only specified files"
-msgstr ""
+msgstr "valider seulement les fichiers spécifiés"
 
-#: builtin/commit.c:1388
+#: builtin/commit.c:1480
 msgid "bypass pre-commit hook"
-msgstr ""
+msgstr "éviter d'utiliser le crochet pre-commit"
 
-#: builtin/commit.c:1389
+#: builtin/commit.c:1481
 msgid "show what would be committed"
-msgstr ""
+msgstr "afficher ce qui serait validé"
 
-#: builtin/commit.c:1400
+#: builtin/commit.c:1492
 msgid "amend previous commit"
-msgstr ""
-
-#: builtin/commit.c:1401
-msgid "bypass post-rewrite hook"
-msgstr ""
-
-#: builtin/commit.c:1406
-msgid "ok to record an empty change"
-msgstr ""
-
-#: builtin/commit.c:1409
-msgid "ok to record a change with an empty message"
-msgstr ""
-
-#: builtin/commit.c:1441
-msgid "could not parse HEAD commit"
-msgstr ""
-
-#: builtin/commit.c:1479 builtin/merge.c:510
-#, c-format
-msgid "could not open '%s' for reading"
-msgstr ""
-
-#: builtin/commit.c:1486
-#, c-format
-msgid "Corrupt MERGE_HEAD file (%s)"
-msgstr ""
+msgstr "corriger la validation précédente"
 
 #: builtin/commit.c:1493
-msgid "could not read MERGE_MODE"
-msgstr ""
+msgid "bypass post-rewrite hook"
+msgstr "éviter d'utiliser le crochet post-rewrite"
 
-#: builtin/commit.c:1512
+#: builtin/commit.c:1498
+msgid "ok to record an empty change"
+msgstr "accepter d'enregistrer une modification vide"
+
+#: builtin/commit.c:1500
+msgid "ok to record a change with an empty message"
+msgstr "accepter d'enregistrer une modification avec un message vide"
+
+#: builtin/commit.c:1529
+msgid "could not parse HEAD commit"
+msgstr "impossible d'analyser le commit HEAD"
+
+#: builtin/commit.c:1567 builtin/merge.c:525
+#, c-format
+msgid "could not open '%s' for reading"
+msgstr "impossible d'ouvrir '%s' en lecture"
+
+#: builtin/commit.c:1574
+#, c-format
+msgid "Corrupt MERGE_HEAD file (%s)"
+msgstr "Fichier MERGE_HEAD corrompu (%s)"
+
+#: builtin/commit.c:1581
+msgid "could not read MERGE_MODE"
+msgstr "impossible de lire MERGE_MODE"
+
+#: builtin/commit.c:1600
 #, c-format
 msgid "could not read commit message: %s"
-msgstr ""
+msgstr "impossible de lire le message de validation : %s"
 
-#: builtin/commit.c:1526
+#: builtin/commit.c:1614
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
-msgstr ""
+msgstr "Abandon de la validation ; vous n'avez pas édité le message\n"
 
-#: builtin/commit.c:1531
+#: builtin/commit.c:1619
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
-msgstr ""
+msgstr "Abandon de la validation du à un message de validation vide\n"
 
-#: builtin/commit.c:1546 builtin/merge.c:847 builtin/merge.c:872
+#: builtin/commit.c:1634 builtin/merge.c:861 builtin/merge.c:886
 msgid "failed to write commit object"
-msgstr ""
+msgstr "échec de l'écriture de l'objet commit"
 
-#: builtin/commit.c:1567
+#: builtin/commit.c:1655
 msgid "cannot lock HEAD ref"
-msgstr ""
+msgstr "impossible de verrouiller la référence HEAD"
 
-#: builtin/commit.c:1571
+#: builtin/commit.c:1659
 msgid "cannot update HEAD ref"
-msgstr ""
+msgstr "impossible de mettre à jour la référence HEAD"
 
-#: builtin/commit.c:1582
+#: builtin/commit.c:1670
 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 ""
+"Le dépôt a été mis à jour, mais impossible d'écrire le fichier\n"
+"new_index. Vérifiez que le disque n'est pas plein ou que le quota\n"
+"n'a pas été dépassé, puis lancez \"git reset HEAD\" pour réparer."
 
-#: builtin/config.c:7
+#: builtin/config.c:8
 msgid "git config [options]"
-msgstr ""
-
-#: builtin/config.c:51
-msgid "Config file location"
-msgstr ""
-
-#: builtin/config.c:52
-msgid "use global config file"
-msgstr ""
-
-#: builtin/config.c:53
-msgid "use system config file"
-msgstr ""
+msgstr "git config [options]"
 
 #: builtin/config.c:54
-msgid "use repository config file"
-msgstr ""
+msgid "Config file location"
+msgstr "Emplacement du fichier de configuration"
 
 #: builtin/config.c:55
-msgid "use given config file"
-msgstr ""
+msgid "use global config file"
+msgstr "utiliser les fichier de configuration global"
 
 #: builtin/config.c:56
-msgid "Action"
-msgstr ""
+msgid "use system config file"
+msgstr "utiliser le fichier de configuration du système"
 
 #: builtin/config.c:57
-msgid "get value: name [value-regex]"
-msgstr ""
+msgid "use repository config file"
+msgstr "utiliser le fichier de configuration du dépôt"
 
 #: builtin/config.c:58
-msgid "get all values: key [value-regex]"
-msgstr ""
+msgid "use given config file"
+msgstr "utiliser le fichier de configuration spécifié"
 
 #: builtin/config.c:59
-msgid "get values for regexp: name-regex [value-regex]"
-msgstr ""
+msgid "blob-id"
+msgstr "blob-id"
+
+#: builtin/config.c:59
+msgid "read config from given blob object"
+msgstr "lire la configuration depuis l'objet blob fourni"
 
 #: builtin/config.c:60
-msgid "replace all matching variables: name value [value_regex]"
-msgstr ""
+msgid "Action"
+msgstr "Action"
 
 #: builtin/config.c:61
-msgid "add a new variable: name value"
-msgstr ""
+msgid "get value: name [value-regex]"
+msgstr "obtenir la valeur : nom [regex-de-valeur]"
 
 #: builtin/config.c:62
-msgid "remove a variable: name [value-regex]"
-msgstr ""
+msgid "get all values: key [value-regex]"
+msgstr "obtenir toutes le valeurs : clé [regex-de-valeur]"
 
 #: builtin/config.c:63
-msgid "remove all matches: name [value-regex]"
-msgstr ""
+msgid "get values for regexp: name-regex [value-regex]"
+msgstr "obtenir les valeur pour la regexp : regex-de-nom [regex-de-valeur]"
 
 #: builtin/config.c:64
-msgid "rename section: old-name new-name"
-msgstr ""
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "obtenir la valeur spécifique pour l'URL : section[.var] URL"
 
 #: builtin/config.c:65
-msgid "remove a section: name"
+msgid "replace all matching variables: name value [value_regex]"
 msgstr ""
+"remplacer toutes les variables correspondant : nom valeur [regex-de-valeur]"
 
 #: builtin/config.c:66
-msgid "list all"
-msgstr ""
+msgid "add a new variable: name value"
+msgstr "ajouter une nouvelle variable : nom valeur"
 
 #: builtin/config.c:67
-msgid "open an editor"
-msgstr ""
-
-#: builtin/config.c:68 builtin/config.c:69
-msgid "slot"
-msgstr ""
+msgid "remove a variable: name [value-regex]"
+msgstr "supprimer une variable : nom [regex-de-valeur]"
 
 #: builtin/config.c:68
-msgid "find the color configured: [default]"
-msgstr ""
+msgid "remove all matches: name [value-regex]"
+msgstr "supprimer toutes les correspondances nom [regex-de-valeur]"
 
 #: builtin/config.c:69
-msgid "find the color setting: [stdout-is-tty]"
-msgstr ""
+msgid "rename section: old-name new-name"
+msgstr "renommer une section : ancien-nom nouveau-nom"
 
 #: builtin/config.c:70
-msgid "Type"
-msgstr ""
+msgid "remove a section: name"
+msgstr "supprimer une section : nom"
 
 #: builtin/config.c:71
-msgid "value is \"true\" or \"false\""
-msgstr ""
+msgid "list all"
+msgstr "afficher tout"
 
 #: builtin/config.c:72
-msgid "value is decimal number"
-msgstr ""
+msgid "open an editor"
+msgstr "ouvrir un éditeur"
+
+#: builtin/config.c:73 builtin/config.c:74
+msgid "slot"
+msgstr "emplacement"
 
 #: builtin/config.c:73
-msgid "value is --bool or --int"
-msgstr ""
+msgid "find the color configured: [default]"
+msgstr "trouver la couleur configurée : [par défaut]"
 
 #: builtin/config.c:74
-msgid "value is a path (file or directory name)"
-msgstr ""
+msgid "find the color setting: [stdout-is-tty]"
+msgstr "trouver le réglage de la couleur : [stdout-est-tty]"
 
 #: builtin/config.c:75
-msgid "Other"
-msgstr ""
+msgid "Type"
+msgstr "Type"
 
 #: builtin/config.c:76
-msgid "terminate values with NUL byte"
-msgstr ""
+msgid "value is \"true\" or \"false\""
+msgstr "la valeur est \"true\" (vrai) our \"false\" (faux)"
 
 #: builtin/config.c:77
+msgid "value is decimal number"
+msgstr "la valeur est un nombre décimal"
+
+#: builtin/config.c:78
+msgid "value is --bool or --int"
+msgstr "la valeur est --bool ou --int"
+
+#: builtin/config.c:79
+msgid "value is a path (file or directory name)"
+msgstr "la valeur est un chemin (vers un fichier ou un répertoire)"
+
+#: builtin/config.c:80
+msgid "Other"
+msgstr "Autre"
+
+#: builtin/config.c:81
+msgid "terminate values with NUL byte"
+msgstr "terminer les valeurs avec un caractère NUL"
+
+#: builtin/config.c:82
 msgid "respect include directives on lookup"
-msgstr ""
+msgstr "respecter les directives d'inclusion lors de la recherche"
 
 #: builtin/count-objects.c:82
 msgid "git count-objects [-v] [-H | --human-readable]"
-msgstr ""
+msgstr "git count-objects [-v] [-H | --human-readable]"
 
 #: builtin/count-objects.c:97
 msgid "print sizes in human readable format"
-msgstr ""
-
-#: builtin/describe.c:15
-msgid "git describe [options] <committish>*"
-msgstr ""
+msgstr "affiche les tailles dans un format humainement lisible"
 
 #: builtin/describe.c:16
-msgid "git describe [options] --dirty"
-msgstr ""
+msgid "git describe [options] <commit-ish>*"
+msgstr "git describe [options] <commit ou apparenté>*"
 
-#: builtin/describe.c:233
-#, c-format
-msgid "annotated tag %s not available"
-msgstr ""
+#: builtin/describe.c:17
+msgid "git describe [options] --dirty"
+msgstr "git describe [options] --dirty"
 
 #: builtin/describe.c:237
 #, c-format
-msgid "annotated tag %s has no embedded name"
-msgstr ""
+msgid "annotated tag %s not available"
+msgstr "l'étiquette annotée %s n'est pas disponible"
 
-#: builtin/describe.c:239
+#: builtin/describe.c:241
+#, c-format
+msgid "annotated tag %s has no embedded name"
+msgstr "l'étiquette annotée %s n'a pas de nom embarqué"
+
+#: builtin/describe.c:243
 #, c-format
 msgid "tag '%s' is really '%s' here"
-msgstr ""
+msgstr "l'étiquette '%s' est en fait '%s'"
 
-#: builtin/describe.c:266
+#: builtin/describe.c:270
 #, c-format
 msgid "Not a valid object name %s"
-msgstr ""
+msgstr "%s n'est pas un nom d'objet valide"
 
-#: builtin/describe.c:269
+#: builtin/describe.c:273
 #, c-format
 msgid "%s is not a valid '%s' object"
 msgstr "%s n'est pas un objet '%s' valide"
 
-#: builtin/describe.c:286
+#: builtin/describe.c:290
 #, c-format
 msgid "no tag exactly matches '%s'"
-msgstr ""
+msgstr "aucune étiquette ne correspond parfaitement à '%s'"
 
-#: builtin/describe.c:288
+#: builtin/describe.c:292
 #, c-format
 msgid "searching to describe %s\n"
-msgstr ""
+msgstr "recherche de la description de %s\n"
 
-#: builtin/describe.c:328
+#: builtin/describe.c:332
 #, c-format
 msgid "finished search at %s\n"
-msgstr ""
+msgstr "recherche terminée à %s\n"
 
-#: builtin/describe.c:352
+#: builtin/describe.c:359
 #, c-format
 msgid ""
 "No annotated tags can describe '%s'.\n"
 "However, there were unannotated tags: try --tags."
 msgstr ""
+"Aucune étiquette annotée ne peut décrire '%s'.\n"
+"Cependant, il existe des étiquettes non-annotées : essayez avec --tags."
 
-#: builtin/describe.c:356
+#: builtin/describe.c:363
 #, c-format
 msgid ""
 "No tags can describe '%s'.\n"
 "Try --always, or create some tags."
 msgstr ""
+"Aucune étiquette ne peut décrire '%s'.\n"
+"Essayez --always, ou créez des étiquettes."
 
-#: builtin/describe.c:377
+#: builtin/describe.c:384
 #, c-format
 msgid "traversed %lu commits\n"
-msgstr ""
+msgstr "%lu commits parcourus\n"
 
-#: builtin/describe.c:380
+#: builtin/describe.c:387
 #, c-format
 msgid ""
 "more than %i tags found; listed %i most recent\n"
 "gave up search at %s\n"
 msgstr ""
-
-#: builtin/describe.c:402
-msgid "find the tag that comes after the commit"
-msgstr ""
-
-#: builtin/describe.c:403
-msgid "debug search strategy on stderr"
-msgstr ""
-
-#: builtin/describe.c:404
-msgid "use any ref"
-msgstr ""
-
-#: builtin/describe.c:405
-msgid "use any tag, even unannotated"
-msgstr ""
-
-#: builtin/describe.c:406
-msgid "always use long format"
-msgstr ""
+"plus de %i étiquettes ont été trouvées; seules les %i plus récentes sont "
+"affichées\n"
+"abandon de la recherche à %s\n"
 
 #: builtin/describe.c:409
-msgid "only output exact matches"
-msgstr ""
+msgid "find the tag that comes after the commit"
+msgstr "rechercher l'étiquette qui suit le commit"
+
+#: builtin/describe.c:410
+msgid "debug search strategy on stderr"
+msgstr "déboguer la stratégie de recherche sur stderr"
 
 #: builtin/describe.c:411
-msgid "consider <n> most recent tags (default: 10)"
-msgstr ""
+msgid "use any ref"
+msgstr "utiliser n'importe quelle référence"
+
+#: builtin/describe.c:412
+msgid "use any tag, even unannotated"
+msgstr "utiliser n'importe quelle étiquette, même non-annotée"
 
 #: builtin/describe.c:413
-msgid "only consider tags matching <pattern>"
-msgstr ""
+msgid "always use long format"
+msgstr "toujours utiliser le format long"
 
-#: builtin/describe.c:415 builtin/name-rev.c:238
-msgid "show abbreviated commit object as fallback"
-msgstr ""
-
-#: builtin/describe.c:416
-msgid "mark"
-msgstr ""
+#: builtin/describe.c:414
+msgid "only follow first parent"
+msgstr "ne suivre que le premier parent"
 
 #: builtin/describe.c:417
+msgid "only output exact matches"
+msgstr "n'afficher que les correspondances exactes"
+
+#: builtin/describe.c:419
+msgid "consider <n> most recent tags (default: 10)"
+msgstr ""
+"considérer uniquement les <n> étiquettes le plus récentes (défaut : 10)"
+
+#: builtin/describe.c:421
+msgid "only consider tags matching <pattern>"
+msgstr "ne considérer que les étiquettes correspondant à <motif>"
+
+#: builtin/describe.c:423 builtin/name-rev.c:322
+msgid "show abbreviated commit object as fallback"
+msgstr "afficher les objets commits abrégés en dernier recours"
+
+#: builtin/describe.c:424
+msgid "mark"
+msgstr "marque"
+
+#: builtin/describe.c:425
 msgid "append <mark> on dirty working tree (default: \"-dirty\")"
-msgstr ""
+msgstr "ajouter <marque> si la copie de travail est sale (défaut : \"-dirty\")"
 
-#: builtin/describe.c:435
+#: builtin/describe.c:443
 msgid "--long is incompatible with --abbrev=0"
-msgstr ""
+msgstr "--long et --abbrev=0 sont incompatibles"
 
-#: builtin/describe.c:461
+#: builtin/describe.c:469
 msgid "No names found, cannot describe anything."
-msgstr ""
+msgstr "aucun nom trouvé, impossible de décrire quoi que ce soit."
 
-#: builtin/describe.c:481
-msgid "--dirty is incompatible with committishes"
-msgstr ""
+#: builtin/describe.c:489
+msgid "--dirty is incompatible with commit-ishes"
+msgstr "--dirty est incompatible avec la spécification de commits ou assimilés"
 
 #: builtin/diff.c:79
 #, c-format
 msgid "'%s': not a regular file or symlink"
-msgstr ""
+msgstr "'%s' : n'est pas un fichier régulier ni un lien symbolique"
 
-#: builtin/diff.c:228
+#: builtin/diff.c:230
 #, c-format
 msgid "invalid option: %s"
-msgstr ""
+msgstr "option invalide : %s"
 
-#: builtin/diff.c:305
+#: builtin/diff.c:307
 msgid "Not a git repository"
-msgstr ""
+msgstr "Ce n'est pas un dépôt git !"
 
-#: builtin/diff.c:348
+#: builtin/diff.c:350
 #, c-format
 msgid "invalid object '%s' given."
-msgstr ""
+msgstr "objet spécifié '%s' invalide."
 
-#: builtin/diff.c:353
-#, c-format
-msgid "more than %d trees given: '%s'"
-msgstr ""
-
-#: builtin/diff.c:363
+#: builtin/diff.c:359
 #, c-format
 msgid "more than two blobs given: '%s'"
-msgstr ""
+msgstr "plus de deux blobs spécifiés : '%s'"
 
-#: builtin/diff.c:371
+#: builtin/diff.c:366
 #, c-format
 msgid "unhandled object '%s' given."
-msgstr ""
+msgstr "objet non géré '%s' spécifié."
 
 #: builtin/fast-export.c:22
 msgid "git fast-export [rev-list-opts]"
-msgstr ""
+msgstr "git fast-export [options-de-liste-de-révisions]"
 
-#: builtin/fast-export.c:658
+#: builtin/fast-export.c:673
 msgid "show progress after <n> objects"
-msgstr ""
-
-#: builtin/fast-export.c:660
-msgid "select handling of signed tags"
-msgstr ""
-
-#: builtin/fast-export.c:663
-msgid "select handling of tags that tag filtered objects"
-msgstr ""
-
-#: builtin/fast-export.c:666
-msgid "Dump marks to this file"
-msgstr ""
-
-#: builtin/fast-export.c:668
-msgid "Import marks from this file"
-msgstr ""
-
-#: builtin/fast-export.c:670
-msgid "Fake a tagger when tags lack one"
-msgstr ""
-
-#: builtin/fast-export.c:672
-msgid "Output full tree for each commit"
-msgstr ""
-
-#: builtin/fast-export.c:674
-msgid "Use the done feature to terminate the stream"
-msgstr ""
+msgstr "afficher la progression après <n> objets"
 
 #: builtin/fast-export.c:675
-msgid "Skip output of blob data"
+msgid "select handling of signed tags"
+msgstr "sélectionner la gestion des étiquettes signées"
+
+#: builtin/fast-export.c:678
+msgid "select handling of tags that tag filtered objects"
 msgstr ""
+"sélectionner la gestion des étiquettes qui pointent sur des objets filtrés"
+
+#: builtin/fast-export.c:681
+msgid "Dump marks to this file"
+msgstr "Enregistrer les marques dans ce fichier"
+
+#: builtin/fast-export.c:683
+msgid "Import marks from this file"
+msgstr "importer les marques depuis ce fichier"
+
+#: builtin/fast-export.c:685
+msgid "Fake a tagger when tags lack one"
+msgstr "falsifier un auteur d'étiquette si l'étiquette n'en présente pas"
+
+#: builtin/fast-export.c:687
+msgid "Output full tree for each commit"
+msgstr "Afficher l'arbre complet pour chaque commit"
+
+#: builtin/fast-export.c:689
+msgid "Use the done feature to terminate the stream"
+msgstr "Utiliser la fonction \"done\" pour terminer le flux"
+
+#: builtin/fast-export.c:690
+msgid "Skip output of blob data"
+msgstr "Sauter l'affichage de données de blob"
 
 #: builtin/fetch.c:20
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
-msgstr ""
+msgstr "git fetch [<options>] [<dépôt> [<spécification-de-référence>...]]"
 
 #: builtin/fetch.c:21
 msgid "git fetch [<options>] <group>"
-msgstr ""
+msgstr "git fetch [<options>] <groupe>"
 
 #: builtin/fetch.c:22
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
-msgstr ""
+msgstr "git fetch --multiple [<options>] [(<dépôt> | <groupe>)...]"
 
 #: builtin/fetch.c:23
 msgid "git fetch --all [<options>]"
-msgstr ""
-
-#: builtin/fetch.c:60
-msgid "fetch from all remotes"
-msgstr ""
-
-#: builtin/fetch.c:62
-msgid "append to .git/FETCH_HEAD instead of overwriting"
-msgstr ""
-
-#: builtin/fetch.c:64
-msgid "path to upload pack on remote end"
-msgstr ""
-
-#: builtin/fetch.c:65
-msgid "force overwrite of local branch"
-msgstr ""
-
-#: builtin/fetch.c:67
-msgid "fetch from multiple remotes"
-msgstr ""
-
-#: builtin/fetch.c:69
-msgid "fetch all tags and associated objects"
-msgstr ""
-
-#: builtin/fetch.c:71
-msgid "do not fetch all tags (--no-tags)"
-msgstr ""
-
-#: builtin/fetch.c:73
-msgid "prune remote-tracking branches no longer on remote"
-msgstr ""
+msgstr "git fetch --all [<options>]"
 
 #: builtin/fetch.c:74
-msgid "on-demand"
-msgstr ""
+msgid "fetch from all remotes"
+msgstr "récupérer depuis tous le dépôts distants"
 
-#: builtin/fetch.c:75
-msgid "control recursive fetching of submodules"
-msgstr ""
+#: builtin/fetch.c:76
+msgid "append to .git/FETCH_HEAD instead of overwriting"
+msgstr "ajouter à .git/FETCH_HEAD au lieu de l'écraser"
+
+#: builtin/fetch.c:78
+msgid "path to upload pack on remote end"
+msgstr "chemin vers lequel télécharger le paquet sur le poste distant"
 
 #: builtin/fetch.c:79
-msgid "keep downloaded pack"
-msgstr ""
+msgid "force overwrite of local branch"
+msgstr "forcer l'écrasement de la branche locale"
 
 #: builtin/fetch.c:81
-msgid "allow updating of HEAD ref"
-msgstr ""
+msgid "fetch from multiple remotes"
+msgstr "récupérer depuis plusieurs dépôts distants"
 
-#: builtin/fetch.c:84
-msgid "deepen history of shallow clone"
-msgstr ""
+#: builtin/fetch.c:83
+msgid "fetch all tags and associated objects"
+msgstr "récupérer toutes les étiquettes et leurs objets associés"
 
-#: builtin/fetch.c:86
-msgid "convert to a complete repository"
-msgstr ""
+#: builtin/fetch.c:85
+msgid "do not fetch all tags (--no-tags)"
+msgstr "ne pas récupérer toutes les étiquettes (--no-tags)"
 
-#: builtin/fetch.c:88 builtin/log.c:1130
-msgid "dir"
+#: builtin/fetch.c:87
+msgid "prune remote-tracking branches no longer on remote"
 msgstr ""
+"éliminer les branches de suivi distant si la branche n'existe plus dans le "
+"dépôt distant"
+
+#: builtin/fetch.c:88
+msgid "on-demand"
+msgstr "à la demande"
 
 #: builtin/fetch.c:89
+msgid "control recursive fetching of submodules"
+msgstr "contrôler la récupération récursive dans les sous-modules"
+
+#: builtin/fetch.c:93
+msgid "keep downloaded pack"
+msgstr "conserver le paquet téléchargé"
+
+#: builtin/fetch.c:95
+msgid "allow updating of HEAD ref"
+msgstr "permettre la mise à jour de la référence HEAD"
+
+#: builtin/fetch.c:98
+msgid "deepen history of shallow clone"
+msgstr "approfondir l'historique d'un clone superficiel"
+
+#: builtin/fetch.c:100
+msgid "convert to a complete repository"
+msgstr "convertir en un dépôt complet"
+
+#: builtin/fetch.c:102 builtin/log.c:1197
+msgid "dir"
+msgstr "dir"
+
+#: builtin/fetch.c:103
 msgid "prepend this to submodule path output"
-msgstr ""
+msgstr "préfixer ceci à la sortie du chemin du sous-module"
 
-#: builtin/fetch.c:92
+#: builtin/fetch.c:106
 msgid "default mode for recursion"
-msgstr ""
+msgstr "mode par défaut pour la récursion"
 
-#: builtin/fetch.c:204
+#: builtin/fetch.c:236
 msgid "Couldn't find remote ref HEAD"
-msgstr ""
+msgstr "impossible de trouver la référence HEAD distante"
 
-#: builtin/fetch.c:257
+#: builtin/fetch.c:290
 #, c-format
 msgid "object %s not found"
-msgstr ""
+msgstr "objet %s non trouvé"
 
-#: builtin/fetch.c:262
+#: builtin/fetch.c:295
 msgid "[up to date]"
-msgstr ""
+msgstr "[à jour]"
 
-#: builtin/fetch.c:276
+#: builtin/fetch.c:309
 #, c-format
 msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
-msgstr ""
+msgstr "! %-*s %-*s -> %s  (impossible de récupérer la branche actuelle)"
 
-#: builtin/fetch.c:277 builtin/fetch.c:363
+#: builtin/fetch.c:310 builtin/fetch.c:396
 msgid "[rejected]"
-msgstr ""
+msgstr "[rejeté]"
 
-#: builtin/fetch.c:288
+#: builtin/fetch.c:321
 msgid "[tag update]"
-msgstr ""
+msgstr "[mise à jour de l'étiquette]"
 
-#: builtin/fetch.c:290 builtin/fetch.c:325 builtin/fetch.c:343
+#: builtin/fetch.c:323 builtin/fetch.c:358 builtin/fetch.c:376
 msgid "  (unable to update local ref)"
-msgstr ""
+msgstr "  (impossible de mettre à jour la référence locale)"
 
-#: builtin/fetch.c:308
+#: builtin/fetch.c:341
 msgid "[new tag]"
-msgstr ""
+msgstr "[nouvelle étiquette]"
 
-#: builtin/fetch.c:311
+#: builtin/fetch.c:344
 msgid "[new branch]"
-msgstr ""
+msgstr "[nouvelle branche]"
 
-#: builtin/fetch.c:314
+#: builtin/fetch.c:347
 msgid "[new ref]"
-msgstr ""
+msgstr "[nouvelle référence]"
 
-#: builtin/fetch.c:359
+#: builtin/fetch.c:392
 msgid "unable to update local ref"
-msgstr ""
+msgstr "impossible de mettre à jour la référence locale"
 
-#: builtin/fetch.c:359
+#: builtin/fetch.c:392
 msgid "forced update"
-msgstr ""
+msgstr "mise à jour forcée"
 
-#: builtin/fetch.c:365
+#: builtin/fetch.c:398
 msgid "(non-fast-forward)"
-msgstr ""
+msgstr "(pas d'avance rapide)"
 
-#: builtin/fetch.c:396 builtin/fetch.c:688
+#: builtin/fetch.c:429 builtin/fetch.c:735
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr "impossible d'ouvrir %s : %s\n"
 
-#: builtin/fetch.c:405
+#: builtin/fetch.c:438
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s n'a pas envoyé tous les objets nécessaires\n"
 
-#: builtin/fetch.c:491
+#: builtin/fetch.c:537
 #, c-format
 msgid "From %.*s\n"
-msgstr ""
+msgstr "Depuis %.*s\n"
 
-#: builtin/fetch.c:502
+#: builtin/fetch.c:548
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
 " 'git remote prune %s' to remove any old, conflicting branches"
 msgstr ""
+"des références locales n'ont pas pu être mises à jour ; essayez de lancer\n"
+" 'git remote prune %s' pour supprimer des branches anciennes en conflit"
 
-#: builtin/fetch.c:552
+#: builtin/fetch.c:598
 #, c-format
 msgid "   (%s will become dangling)"
-msgstr ""
+msgstr "   (%s sera en suspens)"
 
-#: builtin/fetch.c:553
+#: builtin/fetch.c:599
 #, c-format
 msgid "   (%s has become dangling)"
-msgstr ""
+msgstr "   (%s est devenu en suspens)"
 
-#: builtin/fetch.c:560
+#: builtin/fetch.c:606
 msgid "[deleted]"
-msgstr ""
+msgstr "[supprimé]"
 
-#: builtin/fetch.c:561 builtin/remote.c:1055
+#: builtin/fetch.c:607 builtin/remote.c:1055
 msgid "(none)"
-msgstr ""
+msgstr "(aucun(e))"
 
-#: builtin/fetch.c:678
+#: builtin/fetch.c:725
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
-msgstr ""
+msgstr "Refus de récupérer dans la branche courant %s d'un dépôt non nu"
 
-#: builtin/fetch.c:712
-#, c-format
-msgid "Don't know how to fetch from %s"
-msgstr ""
-
-#: builtin/fetch.c:789
+#: builtin/fetch.c:744
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
-msgstr ""
+msgstr "La valeur \"%2$s\" de l'option \"%1$s\" est invalide pour %3$s"
 
-#: builtin/fetch.c:792
+#: builtin/fetch.c:747
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
-msgstr ""
+msgstr "L'option \"%s\" est ignorée pour %s\n"
 
-#: builtin/fetch.c:894
+#: builtin/fetch.c:801
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr "Je ne sais pas récupérer depuis %s"
+
+#: builtin/fetch.c:976
 #, c-format
 msgid "Fetching %s\n"
-msgstr ""
+msgstr "Récupération de %s\n"
 
-#: builtin/fetch.c:896 builtin/remote.c:100
+#: builtin/fetch.c:978 builtin/remote.c:100
 #, c-format
 msgid "Could not fetch %s"
-msgstr ""
+msgstr "Impossible de récupérer %s"
 
-#: builtin/fetch.c:915
+#: builtin/fetch.c:997
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
 msgstr ""
+"Aucun dépôt distant spécifié. Veuillez spécifier une URL ou un nom\n"
+"distant depuis lesquels les nouvelles révisions devraient être récupérées."
 
-#: builtin/fetch.c:935
+#: builtin/fetch.c:1020
 msgid "You need to specify a tag name."
-msgstr ""
+msgstr "Vous devez spécifier un nom d'étiquette."
 
-#: builtin/fetch.c:981
+#: builtin/fetch.c:1068
 msgid "--depth and --unshallow cannot be used together"
-msgstr ""
+msgstr "--depth et --unshallow ne peuvent pas être utilisés ensemble"
 
-#: builtin/fetch.c:983
+#: builtin/fetch.c:1070
 msgid "--unshallow on a complete repository does not make sense"
-msgstr ""
+msgstr "--unshallow sur un dépôt complet n'a pas de sens"
 
-#: builtin/fetch.c:1002
+#: builtin/fetch.c:1089
 msgid "fetch --all does not take a repository argument"
-msgstr ""
+msgstr "fetch --all n'accepte pas d'argument de dépôt"
 
-#: builtin/fetch.c:1004
+#: builtin/fetch.c:1091
 msgid "fetch --all does not make sense with refspecs"
-msgstr ""
+msgstr "fetch --all n'a pas de sens avec des spécifications de référence"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1102
 #, c-format
 msgid "No such remote or remote group: %s"
-msgstr ""
+msgstr "distant ou groupe distant inexistant : %s"
 
-#: builtin/fetch.c:1023
+#: builtin/fetch.c:1110
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr ""
+"La récupération d'un groupe et les spécifications de référence n'ont pas de "
+"sens"
 
 #: builtin/fmt-merge-msg.c:13
 msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]"
 msgstr ""
+"git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <fichier>]"
 
-#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:701
-#: builtin/merge.c:188 builtin/show-branch.c:655 builtin/show-ref.c:175
-#: builtin/tag.c:446 parse-options.h:133 parse-options.h:239
+#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:702
+#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:178
+#: builtin/tag.c:446 parse-options.h:135 parse-options.h:245
 msgid "n"
-msgstr ""
+msgstr "n"
 
 #: builtin/fmt-merge-msg.c:664
 msgid "populate log with at most <n> entries from shortlog"
-msgstr ""
+msgstr "peupler le journal avec au plus <n> éléments depuis le journal court"
 
 #: builtin/fmt-merge-msg.c:667
 msgid "alias for --log (deprecated)"
-msgstr ""
+msgstr "alias pour --log (obsolète)"
 
 #: builtin/fmt-merge-msg.c:670
 msgid "text"
-msgstr ""
+msgstr "texte"
 
 #: builtin/fmt-merge-msg.c:671
 msgid "use <text> as start of message"
-msgstr ""
+msgstr "utiliser <texte> comme début de message"
 
 #: builtin/fmt-merge-msg.c:672
 msgid "file to read from"
-msgstr ""
+msgstr "fichier d'où lire"
 
-#: builtin/for-each-ref.c:979
+#: builtin/for-each-ref.c:995
 msgid "git for-each-ref [options] [<pattern>]"
-msgstr ""
+msgstr "git for-each-ref [options] [<motif>]"
 
-#: builtin/for-each-ref.c:994
+#: builtin/for-each-ref.c:1010
 msgid "quote placeholders suitably for shells"
-msgstr ""
+msgstr "échapper les champs réservés pour les interpréteurs de commandes"
 
-#: builtin/for-each-ref.c:996
+#: builtin/for-each-ref.c:1012
 msgid "quote placeholders suitably for perl"
-msgstr ""
+msgstr "échapper les champs réservés pour perl"
 
-#: builtin/for-each-ref.c:998
+#: builtin/for-each-ref.c:1014
 msgid "quote placeholders suitably for python"
-msgstr ""
+msgstr "échapper les champs réservés pour python"
 
-#: builtin/for-each-ref.c:1000
+#: builtin/for-each-ref.c:1016
 msgid "quote placeholders suitably for tcl"
-msgstr ""
+msgstr "échapper les champs réservés pour tcl"
 
-#: builtin/for-each-ref.c:1003
+#: builtin/for-each-ref.c:1019
 msgid "show only <n> matched refs"
-msgstr ""
+msgstr "n'afficher que <n> références correspondant"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format"
-msgstr ""
+msgstr "format"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format to use for the output"
-msgstr ""
+msgstr "format à utiliser pour la sortie"
 
-#: builtin/for-each-ref.c:1005
+#: builtin/for-each-ref.c:1021
 msgid "key"
-msgstr ""
+msgstr "clé"
 
-#: builtin/for-each-ref.c:1006
+#: builtin/for-each-ref.c:1022
 msgid "field name to sort on"
-msgstr ""
+msgstr "nom du champ servant à trier"
 
-#: builtin/fsck.c:608
+#: builtin/fsck.c:607
 msgid "git fsck [options] [<object>...]"
-msgstr ""
+msgstr "git fsck [options] [<objet>...]"
+
+#: builtin/fsck.c:613
+msgid "show unreachable objects"
+msgstr "afficher les objets inaccessibles"
 
 #: builtin/fsck.c:614
-msgid "show unreachable objects"
-msgstr ""
+msgid "show dangling objects"
+msgstr "afficher les objets en suspens"
 
 #: builtin/fsck.c:615
-msgid "show dangling objects"
-msgstr ""
+msgid "report tags"
+msgstr "afficher les étiquettes"
 
 #: builtin/fsck.c:616
-msgid "report tags"
-msgstr ""
+msgid "report root nodes"
+msgstr "signaler les nœuds racines"
 
 #: builtin/fsck.c:617
-msgid "report root nodes"
-msgstr ""
-
-#: builtin/fsck.c:618
 msgid "make index objects head nodes"
-msgstr ""
+msgstr "considérer les objets de l'index comme nœuds tête"
+
+# translated from man page
+#: builtin/fsck.c:618
+msgid "make reflogs head nodes (default)"
+msgstr "considérer les reflogs comme nœuds tête (par défaut)"
 
 #: builtin/fsck.c:619
-msgid "make reflogs head nodes (default)"
-msgstr ""
+msgid "also consider packs and alternate objects"
+msgstr "inspecter aussi les objets pack et alternatifs"
 
 #: builtin/fsck.c:620
-msgid "also consider packs and alternate objects"
-msgstr ""
-
-#: builtin/fsck.c:621
 msgid "enable more strict checking"
-msgstr ""
+msgstr "activer une vérification plus strict"
 
-#: builtin/fsck.c:623
+#: builtin/fsck.c:622
 msgid "write dangling objects in .git/lost-found"
-msgstr ""
+msgstr "écrire les objets en suspens dans .git/lost-found"
 
-#: builtin/fsck.c:624 builtin/prune.c:134
+#: builtin/fsck.c:623 builtin/prune.c:134
 msgid "show progress"
-msgstr ""
+msgstr "afficher la progression"
 
-#: builtin/gc.c:22
+#: builtin/gc.c:23
 msgid "git gc [options]"
-msgstr ""
+msgstr "git gc [options]"
 
-#: builtin/gc.c:63
+#: builtin/gc.c:79
 #, c-format
 msgid "Invalid %s: '%s'"
-msgstr ""
+msgstr "%s invalide : '%s'"
 
-#: builtin/gc.c:90
+#: builtin/gc.c:106
 #, c-format
 msgid "insanely long object directory %.*s"
-msgstr ""
+msgstr "objet répertoire démentiellement long %.*s"
 
-#: builtin/gc.c:179
+#: builtin/gc.c:261
 msgid "prune unreferenced objects"
-msgstr ""
+msgstr "éliminer les objets non référencés"
 
-#: builtin/gc.c:181
+#: builtin/gc.c:263
 msgid "be more thorough (increased runtime)"
-msgstr ""
+msgstr "être plus consciencieux (durée de traitement allongée)"
 
-#: builtin/gc.c:182
+#: builtin/gc.c:264
 msgid "enable auto-gc mode"
-msgstr ""
+msgstr "activer le mode auto-gc"
 
-#: builtin/gc.c:222
+#: builtin/gc.c:265
+msgid "force running gc even if there may be another gc running"
+msgstr "forcer le lancement du ramasse-miettes même si un autre ramasse-miettes tourne déjà"
+
+#: builtin/gc.c:305
 #, c-format
 msgid ""
 "Auto packing the repository for optimum performance. You may also\n"
 "run \"git gc\" manually. See \"git help gc\" for more information.\n"
 msgstr ""
+"Compression automatique du dépôt pour une performance optimum. Vous pouvez "
+"aussi\n"
+"lancer \"git gc\" manuellement. Voir \"git help gc\" pour plus "
+"d'information.\n"
 
-#: builtin/gc.c:249
+#. be quiet on --auto
+#: builtin/gc.c:315
+#, c-format
+msgid ""
+"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
+msgstr "un ramasse-miettes est déjà en cours sur la machine '%s' pid %<PRIuMAX> (utilisez --force si ce n'est pas le cas)"
+
+#: builtin/gc.c:340
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
+"Il y a trop d'objets seuls inaccessibles ; lancez 'git prune' pour les "
+"supprimer."
 
-#: builtin/grep.c:22
+#: builtin/grep.c:23
 msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"
-msgstr ""
+msgstr "git grep [options] [-e] <motif> [<révision>...] [[--] <chemin>...]"
 
-#: builtin/grep.c:217
+#: builtin/grep.c:218
 #, c-format
 msgid "grep: failed to create thread: %s"
-msgstr ""
+msgstr "grep : échec de création du fil: %s"
 
 #: builtin/grep.c:365
 #, c-format
 msgid "Failed to chdir: %s"
-msgstr ""
+msgstr "Échec de chdir: %s"
 
 #: builtin/grep.c:443 builtin/grep.c:478
 #, c-format
 msgid "unable to read tree (%s)"
-msgstr ""
+msgstr "impossible de lire l'arbre (%s)"
 
 #: builtin/grep.c:493
 #, c-format
 msgid "unable to grep from object of type %s"
-msgstr ""
+msgstr "impossible de faire un grep sur un objet de type %s"
 
 #: builtin/grep.c:551
 #, c-format
 msgid "switch `%c' expects a numerical value"
-msgstr ""
+msgstr "l'option '%c' attend un valeur numérique"
 
 #: builtin/grep.c:568
 #, c-format
 msgid "cannot open '%s'"
-msgstr ""
+msgstr "impossible d'ouvrir '%s'"
 
-#: builtin/grep.c:643
+#: builtin/grep.c:642
 msgid "search in index instead of in the work tree"
-msgstr ""
+msgstr "rechercher dans l'index plutôt que dans la copie de travail"
 
-#: builtin/grep.c:645
+#: builtin/grep.c:644
 msgid "find in contents not managed by git"
-msgstr ""
+msgstr "rechercher dans les contenus non gérés par git"
 
-#: builtin/grep.c:647
+#: builtin/grep.c:646
 msgid "search in both tracked and untracked files"
-msgstr ""
+msgstr "rechercher dans les fichiers suivis et non-suivis"
 
-#: builtin/grep.c:649
+#: builtin/grep.c:648
 msgid "search also in ignored files"
-msgstr ""
+msgstr "rechercher aussi dans les fichiers ignorés"
 
-#: builtin/grep.c:652
+#: builtin/grep.c:651
 msgid "show non-matching lines"
-msgstr ""
+msgstr "afficher les lignes qui ne correspondent pas"
 
-#: builtin/grep.c:654
+#: builtin/grep.c:653
 msgid "case insensitive matching"
-msgstr ""
+msgstr "correspondance insensible à la casse"
 
-#: builtin/grep.c:656
+#: builtin/grep.c:655
 msgid "match patterns only at word boundaries"
-msgstr ""
+msgstr "rechercher les motifs aux séparateurs de mots"
 
-#: builtin/grep.c:658
+#: builtin/grep.c:657
 msgid "process binary files as text"
-msgstr ""
+msgstr "traiter les fichiers binaires comme texte"
 
-#: builtin/grep.c:660
+#: builtin/grep.c:659
 msgid "don't match patterns in binary files"
-msgstr ""
+msgstr "ne pas chercher les motifs dans les fichiers binaires"
 
-#: builtin/grep.c:663
+#: builtin/grep.c:662
+msgid "process binary files with textconv filters"
+msgstr "traiter les fichiers binaires avec les filtres textconv"
+
+#: builtin/grep.c:664
 msgid "descend at most <depth> levels"
-msgstr ""
+msgstr "descendre au plus de <profondeur> dans l'arborescence"
 
-#: builtin/grep.c:667
+#: builtin/grep.c:668
 msgid "use extended POSIX regular expressions"
-msgstr ""
+msgstr "utiliser des expressions régulières étendues POSIX"
 
-#: builtin/grep.c:670
+#: builtin/grep.c:671
 msgid "use basic POSIX regular expressions (default)"
-msgstr ""
+msgstr "utiliser des expressions régulières basiques POSIX (par défaut)"
 
-#: builtin/grep.c:673
+#: builtin/grep.c:674
 msgid "interpret patterns as fixed strings"
-msgstr ""
+msgstr "interpréter les motifs comme de chaînes fixes"
 
-#: builtin/grep.c:676
+#: builtin/grep.c:677
 msgid "use Perl-compatible regular expressions"
-msgstr ""
-
-#: builtin/grep.c:679
-msgid "show line numbers"
-msgstr ""
+msgstr "utiliser des expressions régulières compatibles avec Perl"
 
 #: builtin/grep.c:680
-msgid "don't show filenames"
-msgstr ""
+msgid "show line numbers"
+msgstr "afficher les numéros de ligne"
 
 #: builtin/grep.c:681
+msgid "don't show filenames"
+msgstr "ne pas pas afficher les noms de fichier"
+
+#: builtin/grep.c:682
 msgid "show filenames"
-msgstr ""
+msgstr "afficher les noms de fichier"
 
-#: builtin/grep.c:683
+#: builtin/grep.c:684
 msgid "show filenames relative to top directory"
-msgstr ""
+msgstr "afficher les noms de fichiers relativement au répertoire de base"
 
-#: builtin/grep.c:685
+#: builtin/grep.c:686
 msgid "show only filenames instead of matching lines"
-msgstr ""
+msgstr "n'afficher que les noms de fichiers au lieu des lignes correspondant"
 
-#: builtin/grep.c:687
+#: builtin/grep.c:688
 msgid "synonym for --files-with-matches"
-msgstr ""
+msgstr "synonyme pour --files-with-matches"
 
-#: builtin/grep.c:690
+#: builtin/grep.c:691
 msgid "show only the names of files without match"
-msgstr ""
+msgstr "n'afficher que les noms des fichiers sans correspondance"
 
-#: builtin/grep.c:692
+#: builtin/grep.c:693
 msgid "print NUL after filenames"
-msgstr ""
-
-#: builtin/grep.c:694
-msgid "show the number of matches instead of matching lines"
-msgstr ""
+msgstr "imprimer une caractère NUL après le noms de fichier"
 
 #: builtin/grep.c:695
-msgid "highlight matches"
-msgstr ""
+msgid "show the number of matches instead of matching lines"
+msgstr "afficher le nombre de correspondances au lieu des lignes correspondant"
 
-#: builtin/grep.c:697
+#: builtin/grep.c:696
+msgid "highlight matches"
+msgstr "mettre en évidence les correspondances"
+
+#: builtin/grep.c:698
 msgid "print empty line between matches from different files"
 msgstr ""
+"imprimer une ligne vide entre les correspondances de fichiers différents"
 
-#: builtin/grep.c:699
+#: builtin/grep.c:700
 msgid "show filename only once above matches from same file"
 msgstr ""
+"afficher le nom de fichier une fois au dessus des correspondances du même "
+"fichier"
 
-#: builtin/grep.c:702
+#: builtin/grep.c:703
 msgid "show <n> context lines before and after matches"
-msgstr ""
+msgstr "afficher <n> lignes de contexte avant et après les correspondances"
 
-#: builtin/grep.c:705
+#: builtin/grep.c:706
 msgid "show <n> context lines before matches"
-msgstr ""
-
-#: builtin/grep.c:707
-msgid "show <n> context lines after matches"
-msgstr ""
+msgstr "afficher <n> lignes de contexte avant les correspondances"
 
 #: builtin/grep.c:708
-msgid "shortcut for -C NUM"
-msgstr ""
+msgid "show <n> context lines after matches"
+msgstr "afficher <n> lignes de contexte après les correspondances"
 
-#: builtin/grep.c:711
+#: builtin/grep.c:709
+msgid "shortcut for -C NUM"
+msgstr "raccourci pour -C NUM"
+
+#: builtin/grep.c:712
 msgid "show a line with the function name before matches"
 msgstr ""
+"afficher une ligne avec le nom de la fonction avant les correspondances"
 
-#: builtin/grep.c:713
+#: builtin/grep.c:714
 msgid "show the surrounding function"
-msgstr ""
+msgstr "afficher la fonction contenante"
 
-#: builtin/grep.c:716
+#: builtin/grep.c:717
 msgid "read patterns from file"
-msgstr ""
+msgstr "lire les motifs depuis fichier"
 
-#: builtin/grep.c:718
+#: builtin/grep.c:719
 msgid "match <pattern>"
-msgstr ""
+msgstr "rechercher <motif>"
 
-#: builtin/grep.c:720
+#: builtin/grep.c:721
 msgid "combine patterns specified with -e"
-msgstr ""
+msgstr "combiner les motifs spécifiés par -e"
 
-#: builtin/grep.c:732
+#: builtin/grep.c:733
 msgid "indicate hit with exit status without output"
 msgstr ""
+"indiquer des correspondances avec le code de sortie mais sans rien afficher"
 
-#: builtin/grep.c:734
+#: builtin/grep.c:735
 msgid "show only matches from files that match all patterns"
 msgstr ""
+"n'afficher que les correspondances de fichiers qui correspondent à tous les "
+"motifs"
 
-#: builtin/grep.c:736
+#: builtin/grep.c:737
 msgid "show parse tree for grep expression"
-msgstr ""
+msgstr "afficher l'arbre d'analyse pour le motif grep"
 
-#: builtin/grep.c:740
+#: builtin/grep.c:741
 msgid "pager"
-msgstr ""
+msgstr "pagineur"
 
-#: builtin/grep.c:740
+#: builtin/grep.c:741
 msgid "show matching files in the pager"
-msgstr ""
+msgstr "afficher les fichiers correspondant dans le pagineur"
 
-#: builtin/grep.c:743
+#: builtin/grep.c:744
 msgid "allow calling of grep(1) (ignored by this build)"
-msgstr ""
+msgstr "permettre l'appel de grep(1) (ignoré par ce build)"
 
-#: builtin/grep.c:744 builtin/show-ref.c:184
+#: builtin/grep.c:745 builtin/show-ref.c:187
 msgid "show usage"
-msgstr ""
+msgstr "afficher l'usage"
 
-#: builtin/grep.c:811
+#: builtin/grep.c:812
 msgid "no pattern given."
-msgstr ""
+msgstr "aucun motif fourni."
 
-#: builtin/grep.c:866
+#: builtin/grep.c:870
 msgid "--open-files-in-pager only works on the worktree"
-msgstr ""
+msgstr "--open-files-in-pager ne fonctionne que sur la copie de travail"
 
-#: builtin/grep.c:889
+#: builtin/grep.c:893
 msgid "--cached or --untracked cannot be used with --no-index."
-msgstr ""
+msgstr "--cached ou --untracked ne peuvent pas être utilisés avec --no-index."
 
-#: builtin/grep.c:894
+#: builtin/grep.c:898
 msgid "--no-index or --untracked cannot be used with revs."
 msgstr ""
+"--no-index ou --untracked ne peuvent pas être utilisés avec des révisions."
 
-#: builtin/grep.c:897
+#: builtin/grep.c:901
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
 msgstr ""
+"--[no-]exclude-standard ne peut pas être utilisé avec du contenu suivi."
 
-#: builtin/grep.c:905
+#: builtin/grep.c:909
 msgid "both --cached and trees are given."
-msgstr ""
+msgstr "--cached et des arbres sont fournis en même temps."
 
 #: builtin/hash-object.c:60
 msgid ""
 "git hash-object [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] "
 "<file>..."
 msgstr ""
+"git hash-object [-t <type>] [-w] [--path=<fichier>|--no-filters] [--stdin] "
+"[--] <fichier>..."
 
 #: builtin/hash-object.c:61
 msgid "git hash-object  --stdin-paths < <list-of-paths>"
-msgstr ""
+msgstr "git hash-object  --stdin-paths < <liste-de-chemins>"
 
 #: builtin/hash-object.c:72
 msgid "type"
-msgstr ""
+msgstr "type"
 
 #: builtin/hash-object.c:72
 msgid "object type"
-msgstr ""
+msgstr "type d'objet"
 
 #: builtin/hash-object.c:73
 msgid "write the object into the object database"
-msgstr ""
+msgstr "écrire l'objet dans la base de donnée d'objets"
 
 #: builtin/hash-object.c:74
 msgid "read the object from stdin"
-msgstr ""
+msgstr "lire l'objet depuis l'entrée standard"
 
 #: builtin/hash-object.c:76
 msgid "store file as is without filters"
-msgstr ""
+msgstr "stocker le fichier tel quel sans filtrage"
 
 #: builtin/hash-object.c:77
 msgid "process file as it were from this path"
-msgstr ""
+msgstr "traiter le fichier comme s'il venait de ce chemin"
+
+#: builtin/help.c:41
+msgid "print all available commands"
+msgstr "afficher toutes les commandes disponibles"
+
+#: builtin/help.c:42
+msgid "print list of useful guides"
+msgstr "afficher une liste de guides utiles"
 
 #: builtin/help.c:43
-msgid "print all available commands"
-msgstr ""
+msgid "show man page"
+msgstr "afficher la page de manuel"
 
 #: builtin/help.c:44
-msgid "print list of useful guides"
-msgstr ""
-
-#: builtin/help.c:45
-msgid "show man page"
-msgstr ""
+msgid "show manual in web browser"
+msgstr "afficher le manuel dans un navigateur web"
 
 #: builtin/help.c:46
-msgid "show manual in web browser"
-msgstr ""
-
-#: builtin/help.c:48
 msgid "show info page"
-msgstr ""
+msgstr "afficher la page info"
 
-#: builtin/help.c:54
+#: builtin/help.c:52
 msgid "git help [--all] [--guides] [--man|--web|--info] [command]"
-msgstr ""
+msgstr "git help [--all] [--guides] [--man|--web|--info] [commande]"
 
-#: builtin/help.c:66
+#: builtin/help.c:64
 #, c-format
 msgid "unrecognized help format '%s'"
-msgstr ""
+msgstr "format d'aide non reconnu '%s'"
 
-#: builtin/help.c:94
+#: builtin/help.c:92
 msgid "Failed to start emacsclient."
-msgstr ""
+msgstr "échec de démarrage d'emacsclient."
 
-#: builtin/help.c:107
+#: builtin/help.c:105
 msgid "Failed to parse emacsclient version."
-msgstr ""
+msgstr "échec d'analyse de la version d'emacsclient."
 
-#: builtin/help.c:115
+#: builtin/help.c:113
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
-msgstr ""
+msgstr "la version d'emacsclient '%d' est trop ancienne (<22)."
 
-#: builtin/help.c:133 builtin/help.c:161 builtin/help.c:170 builtin/help.c:178
+#: builtin/help.c:131 builtin/help.c:159 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s': %s"
-msgstr ""
+msgstr "échec de l'exécution de '%s' : %s"
 
-#: builtin/help.c:218
+#: builtin/help.c:216
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
 "Please consider using 'man.<tool>.cmd' instead."
 msgstr ""
+"'%s' : chemin pour l'utilitaire de visualisation de manuel non supporté.\n"
+"Veuillez utiliser plutôt 'man.<outil>.cmd'."
 
-#: builtin/help.c:230
+#: builtin/help.c:228
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
 "Please consider using 'man.<tool>.path' instead."
 msgstr ""
+"'%s' : chemin pour l'utilitaire de visualisation de manuel supporté.\n"
+"Veuillez utiliser plutôt 'man.<outil>.cmd'."
 
-#: builtin/help.c:351
+#: builtin/help.c:349
 #, c-format
 msgid "'%s': unknown man viewer."
-msgstr ""
+msgstr "'%s' : visualiseur de manuel inconnu."
 
-#: builtin/help.c:368
+#: builtin/help.c:366
 msgid "no man viewer handled the request"
-msgstr ""
+msgstr "aucun visualiseur de manuel n'a pris en charge la demande"
 
-#: builtin/help.c:376
+#: builtin/help.c:374
 msgid "no info viewer handled the request"
-msgstr ""
+msgstr "aucun visualiseur de 'info' n'a pris en charge la demande"
+
+#: builtin/help.c:420
+msgid "Defining attributes per path"
+msgstr "Définition des attributs par chemin"
+
+#: builtin/help.c:421
+msgid "A Git glossary"
+msgstr "Un glossaire Git"
 
 #: builtin/help.c:422
-msgid "Defining attributes per path"
-msgstr ""
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "Spécifie les fichiers non-suivis à ignorer intentionnellement"
 
 #: builtin/help.c:423
-msgid "A Git glossary"
-msgstr ""
+msgid "Defining submodule properties"
+msgstr "Définition des propriétés de sous-module"
 
 #: builtin/help.c:424
-msgid "Specifies intentionally untracked files to ignore"
-msgstr ""
+msgid "Specifying revisions and ranges for Git"
+msgstr "Spécification des révisions et portées pour Git"
 
 #: builtin/help.c:425
-msgid "Defining submodule properties"
-msgstr ""
-
-#: builtin/help.c:426
-msgid "Specifying revisions and ranges for Git"
-msgstr ""
-
-#: builtin/help.c:427
 msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
 msgstr ""
+"Une introduction pratique à Git (pour les versions 1.5.1 et supérieures)"
 
-#: builtin/help.c:428
+#: builtin/help.c:426
 msgid "An overview of recommended workflows with Git"
-msgstr ""
+msgstr "Un aperçu des flux de travail recommandés avec Git"
 
-#: builtin/help.c:440
+#: builtin/help.c:438
 msgid "The common Git guides are:\n"
-msgstr ""
+msgstr "Les guides Git populaires sont : \n"
 
-#: builtin/help.c:462 builtin/help.c:478
+#: builtin/help.c:460 builtin/help.c:476
 #, c-format
 msgid "usage: %s%s"
-msgstr ""
+msgstr "usage : %s%s"
 
-#: builtin/help.c:494
+#: builtin/help.c:492
 #, c-format
 msgid "`git %s' is aliased to `%s'"
-msgstr ""
+msgstr "`git %s\" est un alias de `%s'"
 
-#: builtin/index-pack.c:182
+#: builtin/index-pack.c:184
 #, c-format
 msgid "object type mismatch at %s"
-msgstr ""
+msgstr "type d'objet non correspondant à %s"
 
-#: builtin/index-pack.c:202
+#: builtin/index-pack.c:204
 msgid "object of unexpected type"
-msgstr ""
+msgstr "objet de type inattendu"
 
-#: builtin/index-pack.c:239
+#: builtin/index-pack.c:244
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "impossible de remplir %d octet"
+msgstr[1] "impossible de remplir %d octets"
 
-#: builtin/index-pack.c:249
+#: builtin/index-pack.c:254
 msgid "early EOF"
-msgstr ""
+msgstr "fin de fichier prématurée"
 
-#: builtin/index-pack.c:250
+#: builtin/index-pack.c:255
 msgid "read error on input"
-msgstr ""
+msgstr "erreur de lecture sur l'entrée"
 
-#: builtin/index-pack.c:262
+#: builtin/index-pack.c:267
 msgid "used more bytes than were available"
-msgstr ""
+msgstr "plus d'octets utilisés que disponibles"
 
-#: builtin/index-pack.c:269
+#: builtin/index-pack.c:274
 msgid "pack too large for current definition of off_t"
-msgstr ""
-
-#: builtin/index-pack.c:285
-#, c-format
-msgid "unable to create '%s'"
-msgstr ""
+msgstr "le paquet est trop grand pour la définition actuelle de off_t"
 
 #: builtin/index-pack.c:290
 #, c-format
+msgid "unable to create '%s'"
+msgstr "impossible de créer '%s'"
+
+#: builtin/index-pack.c:295
+#, c-format
 msgid "cannot open packfile '%s'"
-msgstr ""
+msgstr "impossible d'ouvrir le fichier paquet '%s'"
 
-#: builtin/index-pack.c:304
+#: builtin/index-pack.c:309
 msgid "pack signature mismatch"
-msgstr ""
+msgstr "la signature du paquet ne correspond pas"
 
-#: builtin/index-pack.c:306
+#: builtin/index-pack.c:311
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
-msgstr ""
+msgstr "la version de paquet %<PRIu32> non supportée"
 
-#: builtin/index-pack.c:324
+#: builtin/index-pack.c:329
 #, c-format
 msgid "pack has bad object at offset %lu: %s"
-msgstr ""
+msgstr "le paquet a un mauvais objet à l'offset %lu: %s"
 
-#: builtin/index-pack.c:446
+#: builtin/index-pack.c:451
 #, c-format
 msgid "inflate returned %d"
-msgstr ""
+msgstr "la décompression (inflate) a retourné %d"
 
-#: builtin/index-pack.c:495
+#: builtin/index-pack.c:500
 msgid "offset value overflow for delta base object"
-msgstr ""
+msgstr "dépassement de la valeur d'offset pour l'objet delta de base"
 
-#: builtin/index-pack.c:503
+#: builtin/index-pack.c:508
 msgid "delta base offset is out of bound"
-msgstr ""
+msgstr "l'objet delta de base est hors limite"
 
-#: builtin/index-pack.c:511
+#: builtin/index-pack.c:516
 #, c-format
 msgid "unknown object type %d"
-msgstr ""
+msgstr "type d'objet inconnu %d"
 
-#: builtin/index-pack.c:542
+#: builtin/index-pack.c:547
 msgid "cannot pread pack file"
-msgstr ""
+msgstr "impossible de lire (pread) le fichier paquet"
 
-#: builtin/index-pack.c:544
+#: builtin/index-pack.c:549
 #, 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] ""
+msgstr[0] "fin prématurée du fichier paquet, %lu octet lu"
+msgstr[1] "fin prématurée du fichier paquet, %lu octets lus"
 
-#: builtin/index-pack.c:570
+#: builtin/index-pack.c:575
 msgid "serious inflate inconsistency"
-msgstr ""
+msgstr "grave incohérence dans la décompression (inflate)"
 
-#: builtin/index-pack.c:661 builtin/index-pack.c:667 builtin/index-pack.c:690
-#: builtin/index-pack.c:724 builtin/index-pack.c:733
+#: builtin/index-pack.c:666 builtin/index-pack.c:672 builtin/index-pack.c:695
+#: builtin/index-pack.c:729 builtin/index-pack.c:738
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
-msgstr ""
+msgstr "COLLISION SHA1 TROUVÉE AVEC %s !"
 
-#: builtin/index-pack.c:664 builtin/pack-objects.c:170
-#: builtin/pack-objects.c:262
+#: builtin/index-pack.c:669 builtin/pack-objects.c:171
+#: builtin/pack-objects.c:263
 #, c-format
 msgid "unable to read %s"
-msgstr ""
+msgstr "impossible de lire %s"
 
-#: builtin/index-pack.c:730
+#: builtin/index-pack.c:735
 #, c-format
 msgid "cannot read existing object %s"
-msgstr ""
+msgstr "impossible de lire l'objet existant %s"
 
-#: builtin/index-pack.c:744
+#: builtin/index-pack.c:749
 #, c-format
 msgid "invalid blob object %s"
-msgstr ""
-
-#: builtin/index-pack.c:759
-#, c-format
-msgid "invalid %s"
-msgstr ""
-
-#: builtin/index-pack.c:761
-msgid "Error in object"
-msgstr ""
+msgstr "objet blob invalide %s"
 
 #: builtin/index-pack.c:763
 #, c-format
+msgid "invalid %s"
+msgstr "%s invalide"
+
+#: builtin/index-pack.c:766
+msgid "Error in object"
+msgstr "Erreur dans l'objet"
+
+#: builtin/index-pack.c:768
+#, c-format
 msgid "Not all child objects of %s are reachable"
-msgstr ""
+msgstr "Tous les objets enfants de %s ne sont pas accessibles"
 
-#: builtin/index-pack.c:833 builtin/index-pack.c:863
+#: builtin/index-pack.c:839 builtin/index-pack.c:869
 msgid "failed to apply delta"
-msgstr ""
+msgstr "échec d'application du delta"
 
-#: builtin/index-pack.c:1004
+#: builtin/index-pack.c:1010
 msgid "Receiving objects"
-msgstr ""
+msgstr "Réception d'objets"
 
-#: builtin/index-pack.c:1004
+#: builtin/index-pack.c:1010
 msgid "Indexing objects"
-msgstr ""
+msgstr "Indexation d'objets"
 
-#: builtin/index-pack.c:1030
+#: builtin/index-pack.c:1036
 msgid "pack is corrupted (SHA1 mismatch)"
-msgstr ""
+msgstr "le paquet est corrompu (SHA1 ne correspond pas)"
 
-#: builtin/index-pack.c:1035
+#: builtin/index-pack.c:1041
 msgid "cannot fstat packfile"
-msgstr ""
+msgstr "impossible d'obtenir le statut (fstat) du fichier paquet"
 
-#: builtin/index-pack.c:1038
+#: builtin/index-pack.c:1044
 msgid "pack has junk at the end"
-msgstr ""
+msgstr "le paquet est invalide à la fin"
 
-#: builtin/index-pack.c:1049
+#: builtin/index-pack.c:1055
 msgid "confusion beyond insanity in parse_pack_objects()"
-msgstr ""
+msgstr "confusion extrême dans parse_pack_objects()"
 
-#: builtin/index-pack.c:1072
+#: builtin/index-pack.c:1078
 msgid "Resolving deltas"
-msgstr ""
+msgstr "Résolution des deltas"
 
-#: builtin/index-pack.c:1082
+#: builtin/index-pack.c:1088
 #, c-format
 msgid "unable to create thread: %s"
-msgstr ""
+msgstr "impossible de créer le fil : %s"
 
-#: builtin/index-pack.c:1124
+#: builtin/index-pack.c:1130
 msgid "confusion beyond insanity"
-msgstr ""
+msgstr "confusion extrême"
 
-#: builtin/index-pack.c:1132
+#: builtin/index-pack.c:1138
 #, c-format
 msgid "completed with %d local objects"
-msgstr ""
+msgstr "complété avec %d objets locaux"
 
-#: builtin/index-pack.c:1142
+#: builtin/index-pack.c:1148
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr ""
+"Somme de contrôle de fin inattendue pour %s (corruption sur le disque ?)"
 
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1152
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "le paquet a %d delta non résolu"
+msgstr[1] "le paquet a %d deltas non résolus"
 
-#: builtin/index-pack.c:1171
+#: builtin/index-pack.c:1177
 #, c-format
 msgid "unable to deflate appended object (%d)"
-msgstr ""
+msgstr "impossible de compresser l'objet ajouté (%d)"
 
-#: builtin/index-pack.c:1250
+#: builtin/index-pack.c:1256
 #, c-format
 msgid "local object %s is corrupt"
-msgstr ""
+msgstr "l'objet local %s est corrompu"
 
-#: builtin/index-pack.c:1274
+#: builtin/index-pack.c:1280
 msgid "error while closing pack file"
-msgstr ""
+msgstr "erreur en fermeture du fichier paquet"
 
-#: builtin/index-pack.c:1287
+#: builtin/index-pack.c:1293
 #, c-format
 msgid "cannot write keep file '%s'"
-msgstr ""
+msgstr "impossible d'écrire le fichier \"keep\" '%s'"
 
-#: builtin/index-pack.c:1295
+#: builtin/index-pack.c:1301
 #, c-format
 msgid "cannot close written keep file '%s'"
-msgstr ""
+msgstr "impossible de fermer le fichier \"keep\" '%s'"
 
-#: builtin/index-pack.c:1308
+#: builtin/index-pack.c:1314
 msgid "cannot store pack file"
-msgstr ""
+msgstr "impossible de stocker le fichier paquet"
 
-#: builtin/index-pack.c:1319
+#: builtin/index-pack.c:1325
 msgid "cannot store index file"
-msgstr ""
-
-#: builtin/index-pack.c:1352
-#, c-format
-msgid "bad pack.indexversion=%<PRIu32>"
-msgstr ""
+msgstr "impossible de stocker le fichier d'index"
 
 #: builtin/index-pack.c:1358
 #, c-format
-msgid "invalid number of threads specified (%d)"
-msgstr ""
+msgid "bad pack.indexversion=%<PRIu32>"
+msgstr "mauvais pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1362 builtin/index-pack.c:1535
+#: builtin/index-pack.c:1364
+#, c-format
+msgid "invalid number of threads specified (%d)"
+msgstr "nombre de fils spécifié invalide (%d)"
+
+#: builtin/index-pack.c:1368 builtin/index-pack.c:1546
 #, c-format
 msgid "no threads support, ignoring %s"
-msgstr ""
+msgstr "pas de support des fils, ignore %s"
 
-#: builtin/index-pack.c:1420
+#: builtin/index-pack.c:1426
 #, c-format
 msgid "Cannot open existing pack file '%s'"
-msgstr ""
+msgstr "Impossible d'ouvrir le fichier paquet existant '%s'"
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1428
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
-msgstr ""
+msgstr "Impossible d'ouvrir le fichier paquet d'index existant pour '%s'"
 
-#: builtin/index-pack.c:1469
+#: builtin/index-pack.c:1475
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "pas un delta : %d objet"
+msgstr[1] "pas un delta : %d objets"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1482
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "longueur chaînée = %d : %lu objet"
+msgstr[1] "longueur chaînée = %d : %lu objets"
 
-#: builtin/index-pack.c:1503
+#: builtin/index-pack.c:1510
 msgid "Cannot come back to cwd"
-msgstr ""
+msgstr "Impossible de revenir au répertoire de travail courant"
 
-#: builtin/index-pack.c:1547 builtin/index-pack.c:1550
-#: builtin/index-pack.c:1562 builtin/index-pack.c:1566
+#: builtin/index-pack.c:1558 builtin/index-pack.c:1561
+#: builtin/index-pack.c:1573 builtin/index-pack.c:1577
 #, c-format
 msgid "bad %s"
-msgstr ""
+msgstr "mauvais %s"
 
-#: builtin/index-pack.c:1580
+#: builtin/index-pack.c:1591
 msgid "--fix-thin cannot be used without --stdin"
-msgstr ""
+msgstr "--fix-thin ne peut pas être utilisé sans --stdin"
 
-#: builtin/index-pack.c:1584 builtin/index-pack.c:1594
+#: builtin/index-pack.c:1595 builtin/index-pack.c:1605
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
-msgstr ""
+msgstr "le nom de fichier paquet '%s' ne se termine pas par '.pack'"
 
-#: builtin/index-pack.c:1603
+#: builtin/index-pack.c:1614
 msgid "--verify with no packfile name given"
-msgstr ""
+msgstr "--verify sans nom de fichier paquet donné"
 
 #: builtin/init-db.c:35
 #, c-format
 msgid "Could not make %s writable by group"
-msgstr ""
+msgstr "Impossible de rendre %s inscriptible pour le groupe"
 
 #: builtin/init-db.c:62
 #, c-format
 msgid "insanely long template name %s"
-msgstr ""
+msgstr "nom de modèle démentiellement long %s"
 
 #: builtin/init-db.c:67
 #, c-format
 msgid "cannot stat '%s'"
-msgstr ""
+msgstr "impossible de faire un stat de '%s'"
 
 #: builtin/init-db.c:73
 #, c-format
 msgid "cannot stat template '%s'"
-msgstr ""
+msgstr "impossible de faire un stat du modèle '%s'"
 
 #: builtin/init-db.c:80
 #, c-format
 msgid "cannot opendir '%s'"
-msgstr ""
+msgstr "impossible d'ouvrir (opendir) '%s'"
 
 #: builtin/init-db.c:97
 #, c-format
 msgid "cannot readlink '%s'"
-msgstr ""
+msgstr "impossible de readlink '%s'"
 
 #: builtin/init-db.c:99
 #, c-format
 msgid "insanely long symlink %s"
-msgstr ""
+msgstr "lien symbolique démentiellement long %s"
 
 #: builtin/init-db.c:102
 #, c-format
 msgid "cannot symlink '%s' '%s'"
-msgstr ""
+msgstr "impossible de créer un lien symbolique de '%s' '%s'"
 
 #: builtin/init-db.c:106
 #, c-format
 msgid "cannot copy '%s' to '%s'"
-msgstr ""
+msgstr "impossible de copier '%s' vers '%s'"
 
 #: builtin/init-db.c:110
 #, c-format
 msgid "ignoring template %s"
-msgstr ""
+msgstr "modèle %s ignoré"
 
 #: builtin/init-db.c:133
 #, c-format
 msgid "insanely long template path %s"
-msgstr ""
+msgstr "chemin de modèle %s démentiellement long"
 
 #: builtin/init-db.c:141
 #, c-format
 msgid "templates not found %s"
-msgstr ""
+msgstr "modèles non trouvés %s"
 
 #: builtin/init-db.c:154
 #, c-format
 msgid "not copying templates of a wrong format version %d from '%s'"
 msgstr ""
+"pas de copie des modèles étant dans une mauvaise version du format %d de '%s'"
 
 #: builtin/init-db.c:192
 #, c-format
 msgid "insane git directory %s"
-msgstr ""
+msgstr "répertoire git démentiel %s"
 
 #: builtin/init-db.c:323 builtin/init-db.c:326
 #, c-format
@@ -5620,17 +6272,12 @@
 #: builtin/init-db.c:355
 #, c-format
 msgid "unable to handle file type %d"
-msgstr ""
+msgstr "impossible de traiter le fichier de type %d"
 
 #: builtin/init-db.c:358
 #, c-format
 msgid "unable to move %s to %s"
-msgstr ""
-
-#: builtin/init-db.c:363
-#, c-format
-msgid "Could not create git link %s"
-msgstr ""
+msgstr "impossible de déplacer %s vers %s"
 
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
@@ -5640,51 +6287,53 @@
 #: builtin/init-db.c:420
 #, c-format
 msgid "%s%s Git repository in %s%s\n"
-msgstr "%s%s Dépôt git dans %s%s\n"
+msgstr "Dépôt Git%2$s %1$s dans %3$s%4$s\n"
 
 #: builtin/init-db.c:421
 msgid "Reinitialized existing"
-msgstr ""
+msgstr "existant réinitialisé"
 
 #: builtin/init-db.c:421
 msgid "Initialized empty"
-msgstr ""
+msgstr "vide initialisé"
 
 #: builtin/init-db.c:422
 msgid " shared"
-msgstr ""
+msgstr " partagé"
 
 #: builtin/init-db.c:441
 msgid "cannot tell cwd"
-msgstr ""
+msgstr "impossible de déterminer le répertoire de travail courant"
 
 #: builtin/init-db.c:467
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>] [--"
 "shared[=<permissions>]] [directory]"
 msgstr ""
+"git init [-q | --quiet] [--bare] [--template=<répertoire-modèle>] [--"
+"shared[=<permissions>]] [répertoire]"
 
 #: builtin/init-db.c:490
 msgid "permissions"
-msgstr ""
+msgstr "permissions"
 
 #: builtin/init-db.c:491
 msgid "specify that the git repository is to be shared amongst several users"
-msgstr ""
+msgstr "spécifier que le dépôt git sera partagé entre plusieurs utilisateurs"
 
-#: builtin/init-db.c:493 builtin/prune-packed.c:77
+#: builtin/init-db.c:493 builtin/prune-packed.c:75 builtin/repack.c:155
 msgid "be quiet"
-msgstr ""
+msgstr "être silencieux"
 
 #: builtin/init-db.c:522 builtin/init-db.c:529
 #, c-format
 msgid "cannot mkdir %s"
-msgstr ""
+msgstr "impossible de créer le répertoire (mkdir) %s"
 
 #: builtin/init-db.c:533
 #, c-format
 msgid "cannot chdir to %s"
-msgstr ""
+msgstr "impossible de se déplacer vers le répertoire (chdir) %s"
 
 #: builtin/init-db.c:555
 #, c-format
@@ -5692,562 +6341,591 @@
 "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
 "dir=<directory>)"
 msgstr ""
+"%s (ou --work-tree=<répertoire>) n'est pas autorisé sans spécifier %s (ou --"
+"git-dir=<répertoire>)"
 
 #: builtin/init-db.c:579
 msgid "Cannot access current working directory"
-msgstr ""
+msgstr "Impossible d'accéder au répertoire de travail courant"
 
 #: builtin/init-db.c:586
 #, c-format
 msgid "Cannot access work tree '%s'"
-msgstr ""
-
-#: builtin/log.c:40
-msgid "git log [<options>] [<revision range>] [[--] <path>...]\n"
-msgstr ""
+msgstr "Impossible d'accéder à l'arbre de travail '%s'"
 
 #: builtin/log.c:41
+msgid "git log [<options>] [<revision range>] [[--] <path>...]\n"
+msgstr "git log [<options>] [<page de révisions>] [[--] <chemin>...]\n"
+
+#: builtin/log.c:42
 msgid "   or: git show [options] <object>..."
-msgstr ""
+msgstr "   ou : git show [options] <objet>..."
 
-#: builtin/log.c:103
+#: builtin/log.c:125
 msgid "suppress diff output"
-msgstr ""
+msgstr "supprimer la sortie des différences"
 
-#: builtin/log.c:104
+#: builtin/log.c:126
 msgid "show source"
-msgstr ""
+msgstr "afficher la source"
 
-#: builtin/log.c:105
+#: builtin/log.c:127
 msgid "Use mail map file"
-msgstr ""
+msgstr "Utiliser le fichier de correspondance de mail"
 
-#: builtin/log.c:106
+#: builtin/log.c:128
 msgid "decorate options"
-msgstr ""
+msgstr "décorer les options"
 
-#: builtin/log.c:199
+#: builtin/log.c:231
 #, c-format
 msgid "Final output: %d %s\n"
-msgstr ""
+msgstr "Sortie finale : %d %s\n"
 
-#: builtin/log.c:422 builtin/log.c:514
+#: builtin/log.c:473 builtin/log.c:565
 #, c-format
 msgid "Could not read object %s"
-msgstr ""
+msgstr "Impossible de lire l'objet %s"
 
-#: builtin/log.c:538
+#: builtin/log.c:589
 #, c-format
 msgid "Unknown type: %d"
-msgstr ""
+msgstr "Type inconnu : %d"
 
-#: builtin/log.c:638
+#: builtin/log.c:689
 msgid "format.headers without value"
-msgstr ""
+msgstr "format.headers sans valeur"
 
-#: builtin/log.c:720
+#: builtin/log.c:771
 msgid "name of output directory is too long"
-msgstr ""
+msgstr "le nom du répertoire de sortie est trop long"
 
-#: builtin/log.c:736
+#: builtin/log.c:787
 #, c-format
 msgid "Cannot open patch file %s"
-msgstr ""
+msgstr "Impossible d'ouvrir le fichier correctif %s"
 
-#: builtin/log.c:750
+#: builtin/log.c:801
 msgid "Need exactly one range."
-msgstr ""
+msgstr "Exactement une plage nécessaire."
 
-#: builtin/log.c:758
+#: builtin/log.c:809
 msgid "Not a range."
-msgstr ""
+msgstr "Pas une plage."
 
-#: builtin/log.c:860
+#: builtin/log.c:911
 msgid "Cover letter needs email format"
-msgstr ""
+msgstr "La lettre de motivation doit être au format e-mail"
 
-#: builtin/log.c:936
+#: builtin/log.c:987
 #, c-format
 msgid "insane in-reply-to: %s"
-msgstr ""
+msgstr "in-reply-to aberrant : %s"
 
-#: builtin/log.c:964
+#: builtin/log.c:1015
 msgid "git format-patch [options] [<since> | <revision range>]"
-msgstr ""
+msgstr "git format-patch [options] [<depuis> | <plage de révisions>]"
 
-#: builtin/log.c:1009
+#: builtin/log.c:1060
 msgid "Two output directories?"
-msgstr ""
+msgstr "Deux répertoires de sortie ?"
 
-#: builtin/log.c:1108
+#: builtin/log.c:1175
 msgid "use [PATCH n/m] even with a single patch"
-msgstr ""
+msgstr "utiliser [PATCH n/m] même avec un patch unique"
 
-#: builtin/log.c:1111
+#: builtin/log.c:1178
 msgid "use [PATCH] even with multiple patches"
-msgstr ""
+msgstr "utiliser [PATCH] même avec des patchs multiples"
 
-#: builtin/log.c:1115
+#: builtin/log.c:1182
 msgid "print patches to standard out"
-msgstr ""
+msgstr "afficher les patchs sur la sortie standard"
 
-#: builtin/log.c:1117
+#: builtin/log.c:1184
 msgid "generate a cover letter"
-msgstr ""
+msgstr "générer une lettre de motivation"
 
-#: builtin/log.c:1119
+#: builtin/log.c:1186
 msgid "use simple number sequence for output file names"
 msgstr ""
+"utiliser une séquence simple de nombres pour les nom des fichiers de sortie"
 
-#: builtin/log.c:1120
+#: builtin/log.c:1187
 msgid "sfx"
-msgstr ""
+msgstr "sfx"
 
-#: builtin/log.c:1121
+#: builtin/log.c:1188
 msgid "use <sfx> instead of '.patch'"
-msgstr ""
+msgstr "utiliser <sfx> au lieu de '.patch'"
 
-#: builtin/log.c:1123
+#: builtin/log.c:1190
 msgid "start numbering patches at <n> instead of 1"
-msgstr ""
+msgstr "démarrer la numérotation des patchs à <n> au lieu de 1"
 
-#: builtin/log.c:1125
+#: builtin/log.c:1192
 msgid "mark the series as Nth re-roll"
-msgstr ""
+msgstr "marquer la série comme une Nième réédition"
 
-#: builtin/log.c:1127
+#: builtin/log.c:1194
 msgid "Use [<prefix>] instead of [PATCH]"
-msgstr ""
+msgstr "utiliser [<préfixe>] au lieu de [PATCH]"
 
-#: builtin/log.c:1130
+#: builtin/log.c:1197
 msgid "store resulting files in <dir>"
-msgstr ""
+msgstr "stocker les fichiers résultats dans <répertoire>"
 
-#: builtin/log.c:1133
+#: builtin/log.c:1200
 msgid "don't strip/add [PATCH]"
-msgstr ""
+msgstr "ne pas retirer/ajouter [PATCH]"
 
-#: builtin/log.c:1136
+#: builtin/log.c:1203
 msgid "don't output binary diffs"
-msgstr ""
+msgstr "ne pas imprimer les diffs binaires"
 
-#: builtin/log.c:1138
+#: builtin/log.c:1205
 msgid "don't include a patch matching a commit upstream"
-msgstr ""
+msgstr "ne pas inclure un patch correspondant à un commit amont"
 
-#: builtin/log.c:1140
+#: builtin/log.c:1207
 msgid "show patch format instead of default (patch + stat)"
-msgstr ""
+msgstr "afficher le format du patch au lieu du défaut (patch + stat)"
 
-#: builtin/log.c:1142
+#: builtin/log.c:1209
 msgid "Messaging"
-msgstr ""
+msgstr "Communication"
 
-#: builtin/log.c:1143
+#: builtin/log.c:1210
 msgid "header"
-msgstr ""
+msgstr "en-tête"
 
-#: builtin/log.c:1144
+#: builtin/log.c:1211
 msgid "add email header"
-msgstr ""
+msgstr "ajouter l'en-tête d'e-mail"
 
-#: builtin/log.c:1145 builtin/log.c:1147
+#: builtin/log.c:1212 builtin/log.c:1214
 msgid "email"
-msgstr ""
+msgstr "e-mail"
 
-#: builtin/log.c:1145
+#: builtin/log.c:1212
 msgid "add To: header"
-msgstr ""
+msgstr "ajouter l'en-tête \"To:\""
 
-#: builtin/log.c:1147
+#: builtin/log.c:1214
 msgid "add Cc: header"
-msgstr ""
+msgstr "ajouter l'en-tête \"Cc:\""
 
-#: builtin/log.c:1149
+#: builtin/log.c:1216
+msgid "ident"
+msgstr "ident"
+
+#: builtin/log.c:1217
+msgid "set From address to <ident> (or committer ident if absent)"
+msgstr "renseigner l'adresse From à <ident> (ou à l'ident du validateur si absent)"
+
+#: builtin/log.c:1219
 msgid "message-id"
-msgstr ""
+msgstr "id-message"
 
-#: builtin/log.c:1150
+#: builtin/log.c:1220
 msgid "make first mail a reply to <message-id>"
-msgstr ""
+msgstr "répondre dans le premier message à <id-message>"
 
-#: builtin/log.c:1151 builtin/log.c:1154
+#: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
-msgstr ""
+msgstr "frontière"
 
-#: builtin/log.c:1152
+#: builtin/log.c:1222
 msgid "attach the patch"
-msgstr ""
+msgstr "attacher le patch"
 
-#: builtin/log.c:1155
+#: builtin/log.c:1225
 msgid "inline the patch"
-msgstr ""
+msgstr "patch à l'intérieur"
 
-#: builtin/log.c:1159
+#: builtin/log.c:1229
 msgid "enable message threading, styles: shallow, deep"
 msgstr ""
+"activer l'enfilage de message, styles : shallow (superficiel), deep (profond)"
 
-#: builtin/log.c:1161
+#: builtin/log.c:1231
 msgid "signature"
-msgstr ""
+msgstr "signature"
 
-#: builtin/log.c:1162
+#: builtin/log.c:1232
 msgid "add a signature"
-msgstr ""
+msgstr "ajouter une signature"
 
-#: builtin/log.c:1164
+#: builtin/log.c:1233
 msgid "don't print the patch filenames"
-msgstr ""
+msgstr "ne pas afficher les noms de fichiers des patchs"
 
-#: builtin/log.c:1248
+#: builtin/log.c:1307
+#, c-format
+msgid "invalid ident line: %s"
+msgstr "ligne d'identification invalide : %s"
+
+#: builtin/log.c:1322
 msgid "-n and -k are mutually exclusive."
-msgstr ""
+msgstr "-n et -k sont mutuellement exclusifs."
 
-#: builtin/log.c:1250
+#: builtin/log.c:1324
 msgid "--subject-prefix and -k are mutually exclusive."
-msgstr ""
+msgstr "--subject-prefix et -k sont mutuellement exclusifs."
 
-#: builtin/log.c:1258
+#: builtin/log.c:1332
 msgid "--name-only does not make sense"
-msgstr ""
+msgstr "--name-only n'a pas de sens"
 
-#: builtin/log.c:1260
+#: builtin/log.c:1334
 msgid "--name-status does not make sense"
-msgstr ""
+msgstr "--name-status n'a pas de sens"
 
-#: builtin/log.c:1262
+#: builtin/log.c:1336
 msgid "--check does not make sense"
-msgstr ""
+msgstr "--check n'a pas de sens"
 
-#: builtin/log.c:1285
+#: builtin/log.c:1359
 msgid "standard output, or directory, which one?"
-msgstr ""
+msgstr "sortie standard, ou répertoire, lequel ?"
 
-#: builtin/log.c:1287
+#: builtin/log.c:1361
 #, c-format
 msgid "Could not create directory '%s'"
-msgstr ""
+msgstr "Impossible de créer le répertoire '%s'"
 
-#: builtin/log.c:1435
+#: builtin/log.c:1509
 msgid "Failed to create output files"
-msgstr ""
+msgstr "Échec de création des fichiers en sortie"
 
-#: builtin/log.c:1484
+#: builtin/log.c:1558
 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
-msgstr ""
+msgstr "git cherry [-v] [<branche_amont> [<head> [<limite>]]]"
 
-#: builtin/log.c:1539
+#: builtin/log.c:1613
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr ""
+"Impossible de trouver une branche distante suivie, merci de spécifier "
+"<branche_amont> manuellement.\n"
 
-#: builtin/log.c:1552 builtin/log.c:1554 builtin/log.c:1566
+#: builtin/log.c:1626 builtin/log.c:1628 builtin/log.c:1640
 #, c-format
 msgid "Unknown commit %s"
-msgstr ""
+msgstr "Commit inconnu %s"
 
-#: builtin/ls-files.c:402
+#: builtin/ls-files.c:398
 msgid "git ls-files [options] [<file>...]"
-msgstr ""
+msgstr "git ls-files [options] [<fichier>...]"
+
+#: builtin/ls-files.c:455
+msgid "identify the file status with tags"
+msgstr "identifier le statut de fichier avec les étiquettes"
+
+#: builtin/ls-files.c:457
+msgid "use lowercase letters for 'assume unchanged' files"
+msgstr "utiliser des minuscules pour les fichier 'assumés inchangés'"
 
 #: builtin/ls-files.c:459
-msgid "identify the file status with tags"
-msgstr ""
+msgid "show cached files in the output (default)"
+msgstr "afficher les fichiers mis en cache dans la sortie (défaut)"
 
 #: builtin/ls-files.c:461
-msgid "use lowercase letters for 'assume unchanged' files"
-msgstr ""
+msgid "show deleted files in the output"
+msgstr "afficher les fichiers supprimés dans la sortie"
 
 #: builtin/ls-files.c:463
-msgid "show cached files in the output (default)"
-msgstr ""
+msgid "show modified files in the output"
+msgstr "afficher les fichiers modifiés dans la sortie"
 
 #: builtin/ls-files.c:465
-msgid "show deleted files in the output"
-msgstr ""
+msgid "show other files in the output"
+msgstr "afficher les autres fichiers dans la sortie"
 
 #: builtin/ls-files.c:467
-msgid "show modified files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:469
-msgid "show other files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:471
 msgid "show ignored files in the output"
-msgstr ""
+msgstr "afficher les fichiers ignorés dans la sortie"
 
-#: builtin/ls-files.c:474
+#: builtin/ls-files.c:470
 msgid "show staged contents' object name in the output"
-msgstr ""
+msgstr "afficher les nom des objets indexés dans la sortie"
 
-#: builtin/ls-files.c:476
+#: builtin/ls-files.c:472
 msgid "show files on the filesystem that need to be removed"
 msgstr ""
+"afficher les fichiers du système de fichiers qui ont besoin d'être supprimés"
 
-#: builtin/ls-files.c:478
+#: builtin/ls-files.c:474
 msgid "show 'other' directories' name only"
-msgstr ""
+msgstr "afficher seulement les noms des répertoires 'other'"
 
-#: builtin/ls-files.c:481
+#: builtin/ls-files.c:477
 msgid "don't show empty directories"
-msgstr ""
+msgstr "ne pas afficher les répertoires vides"
+
+#: builtin/ls-files.c:480
+msgid "show unmerged files in the output"
+msgstr "afficher les fichiers non fusionnés dans la sortie"
+
+#: builtin/ls-files.c:482
+msgid "show resolve-undo information"
+msgstr "afficher l'information resolv-undo"
 
 #: builtin/ls-files.c:484
-msgid "show unmerged files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:486
-msgid "show resolve-undo information"
-msgstr ""
-
-#: builtin/ls-files.c:488
 msgid "skip files matching pattern"
-msgstr ""
+msgstr "sauter les fichiers correspondant au motif"
 
-#: builtin/ls-files.c:491
+#: builtin/ls-files.c:487
 msgid "exclude patterns are read from <file>"
-msgstr ""
+msgstr "les motifs d'exclusion sont lus depuis <fichier>"
 
-#: builtin/ls-files.c:494
+#: builtin/ls-files.c:490
 msgid "read additional per-directory exclude patterns in <file>"
-msgstr ""
+msgstr "lire des motifs d'exclusion additionnels par répertoire dans <fichier>"
 
-#: builtin/ls-files.c:496
+#: builtin/ls-files.c:492
 msgid "add the standard git exclusions"
-msgstr ""
+msgstr "ajouter les exclusions git standard"
+
+#: builtin/ls-files.c:495
+msgid "make the output relative to the project top directory"
+msgstr "afficher en relatif par rapport au répertoire racine du projet"
+
+#: builtin/ls-files.c:498
+msgid "if any <file> is not in the index, treat this as an error"
+msgstr "si un <fichier> n'est pas dans l'index, traiter cela comme une erreur"
 
 #: builtin/ls-files.c:499
-msgid "make the output relative to the project top directory"
-msgstr ""
-
-#: builtin/ls-files.c:502
-msgid "if any <file> is not in the index, treat this as an error"
-msgstr ""
-
-#: builtin/ls-files.c:503
 msgid "tree-ish"
-msgstr ""
+msgstr "arbre ou apparenté"
 
-#: builtin/ls-files.c:504
+#: builtin/ls-files.c:500
 msgid "pretend that paths removed since <tree-ish> are still present"
 msgstr ""
+"considérer que les chemins supprimés depuis <arbre ou apparenté> sont "
+"toujours présents"
 
-#: builtin/ls-files.c:506
+#: builtin/ls-files.c:502
 msgid "show debugging data"
-msgstr ""
+msgstr "afficher les données de débogage"
 
-#: builtin/ls-tree.c:27
+#: builtin/ls-tree.c:28
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
-msgstr ""
+msgstr "git ls-tree [<options>] <arbre ou apparenté> [<chemin>...]"
 
-#: builtin/ls-tree.c:125
+#: builtin/ls-tree.c:126
 msgid "only show trees"
-msgstr ""
+msgstr "afficher seulement les arbres"
 
-#: builtin/ls-tree.c:127
+#: builtin/ls-tree.c:128
 msgid "recurse into subtrees"
-msgstr ""
+msgstr "parcourir les sous-arbres"
 
-#: builtin/ls-tree.c:129
+#: builtin/ls-tree.c:130
 msgid "show trees when recursing"
-msgstr ""
-
-#: builtin/ls-tree.c:132
-msgid "terminate entries with NUL byte"
-msgstr ""
+msgstr "afficher les arbres en les parcourant"
 
 #: builtin/ls-tree.c:133
+msgid "terminate entries with NUL byte"
+msgstr "terminer les éléments avec un octet NUL"
+
+#: builtin/ls-tree.c:134
 msgid "include object size"
-msgstr ""
+msgstr "inclure la taille d'objet"
 
-#: builtin/ls-tree.c:135 builtin/ls-tree.c:137
+#: builtin/ls-tree.c:136 builtin/ls-tree.c:138
 msgid "list only filenames"
-msgstr ""
+msgstr "afficher seulement les noms de fichiers"
 
-#: builtin/ls-tree.c:140
+#: builtin/ls-tree.c:141
 msgid "use full path names"
-msgstr ""
+msgstr "utiliser les noms de chemins complets"
 
-#: builtin/ls-tree.c:142
+#: builtin/ls-tree.c:143
 msgid "list entire tree; not just current directory (implies --full-name)"
 msgstr ""
+"afficher l'arbre entier ; pas seulement le répertoire courant (implique --"
+"full-name)"
 
 #: builtin/merge.c:43
 msgid "git merge [options] [<commit>...]"
-msgstr ""
+msgstr "git merge [options] [<commit>...]"
 
 #: builtin/merge.c:44
 msgid "git merge [options] <msg> HEAD <commit>"
-msgstr ""
+msgstr "git merge [options] <message> HEAD <commit>"
 
 #: builtin/merge.c:45
 msgid "git merge --abort"
-msgstr ""
+msgstr "git merge --abort"
 
-#: builtin/merge.c:90
+#: builtin/merge.c:98
 msgid "switch `m' requires a value"
-msgstr ""
+msgstr "le commutateur `m' a besoin d'une valeur"
 
-#: builtin/merge.c:127
+#: builtin/merge.c:135
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
-msgstr ""
+msgstr "Impossible de trouver la stratégie de fusion '%s'.\n"
 
-#: builtin/merge.c:128
+#: builtin/merge.c:136
 #, c-format
 msgid "Available strategies are:"
-msgstr ""
+msgstr "Les stratégies disponibles sont :"
 
-#: builtin/merge.c:133
+#: builtin/merge.c:141
 #, c-format
 msgid "Available custom strategies are:"
-msgstr ""
-
-#: builtin/merge.c:183
-msgid "do not show a diffstat at the end of the merge"
-msgstr ""
-
-#: builtin/merge.c:186
-msgid "show a diffstat at the end of the merge"
-msgstr ""
-
-#: builtin/merge.c:187
-msgid "(synonym to --stat)"
-msgstr ""
-
-#: builtin/merge.c:189
-msgid "add (at most <n>) entries from shortlog to merge commit message"
-msgstr ""
-
-#: builtin/merge.c:192
-msgid "create a single commit instead of doing a merge"
-msgstr ""
-
-#: builtin/merge.c:194
-msgid "perform a commit if the merge succeeds (default)"
-msgstr ""
-
-#: builtin/merge.c:196
-msgid "edit message before committing"
-msgstr ""
+msgstr "Les stratégies personnalisées sont :"
 
 #: builtin/merge.c:198
-msgid "allow fast-forward (default)"
-msgstr ""
+msgid "do not show a diffstat at the end of the merge"
+msgstr "ne pas afficher un diffstat à la fin de la fusion"
 
-#: builtin/merge.c:200
-msgid "abort if fast-forward is not possible"
-msgstr ""
+#: builtin/merge.c:201
+msgid "show a diffstat at the end of the merge"
+msgstr "afficher un diffstat à la fin de la fusion"
 
-#: builtin/merge.c:203
-msgid "Verify that the named commit has a valid GPG signature"
-msgstr ""
+#: builtin/merge.c:202
+msgid "(synonym to --stat)"
+msgstr "(synonyme de --stat)"
 
-#: builtin/merge.c:204 builtin/notes.c:866 builtin/revert.c:112
-msgid "strategy"
+#: builtin/merge.c:204
+msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
-
-#: builtin/merge.c:205
-msgid "merge strategy to use"
-msgstr ""
-
-#: builtin/merge.c:206
-msgid "option=value"
-msgstr ""
+"ajouter (au plus <n>) éléments du journal court au message de validation de "
+"la fusion"
 
 #: builtin/merge.c:207
-msgid "option for selected merge strategy"
-msgstr ""
+msgid "create a single commit instead of doing a merge"
+msgstr "créer une validation unique au lieu de faire une fusion"
 
 #: builtin/merge.c:209
+msgid "perform a commit if the merge succeeds (default)"
+msgstr "effectuer une validation si la fusion réussit (défaut)"
+
+#: builtin/merge.c:211
+msgid "edit message before committing"
+msgstr "éditer le message avant la validation"
+
+#: builtin/merge.c:212
+msgid "allow fast-forward (default)"
+msgstr "autoriser l'avance rapide (défaut)"
+
+#: builtin/merge.c:214
+msgid "abort if fast-forward is not possible"
+msgstr "abandonner si l'avance rapide n'est pas possible"
+
+#: builtin/merge.c:218
+msgid "Verify that the named commit has a valid GPG signature"
+msgstr "Vérifier que la validation a une signature GPG valide"
+
+#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:89
+msgid "strategy"
+msgstr "stratégie"
+
+#: builtin/merge.c:220
+msgid "merge strategy to use"
+msgstr "stratégie de fusion à utiliser"
+
+#: builtin/merge.c:221
+msgid "option=value"
+msgstr "option=valeur"
+
+#: builtin/merge.c:222
+msgid "option for selected merge strategy"
+msgstr "option pour la stratégie de fusion sélectionnée"
+
+#: builtin/merge.c:224
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr ""
+"message de validation de la fusion (pour une fusion sans avance rapide)"
 
-#: builtin/merge.c:213
+#: builtin/merge.c:228
 msgid "abort the current in-progress merge"
-msgstr ""
+msgstr "abandonner la fusion en cours"
 
-#: builtin/merge.c:242
+#: builtin/merge.c:257
 msgid "could not run stash."
-msgstr ""
+msgstr "impossible de lancer le remisage."
 
-#: builtin/merge.c:247
+#: builtin/merge.c:262
 msgid "stash failed"
-msgstr ""
+msgstr "échec du remisage"
 
-#: builtin/merge.c:252
+#: builtin/merge.c:267
 #, c-format
 msgid "not a valid object: %s"
-msgstr ""
+msgstr "pas un objet valide : %s"
 
-#: builtin/merge.c:271 builtin/merge.c:288
+#: builtin/merge.c:286 builtin/merge.c:303
 msgid "read-tree failed"
-msgstr ""
+msgstr "read-tree a échoué"
 
-#: builtin/merge.c:318
+#: builtin/merge.c:333
 msgid " (nothing to squash)"
 msgstr " (rien à compresser)"
 
-#: builtin/merge.c:331
+#: builtin/merge.c:346
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
-msgstr ""
+msgstr "Validation compressée -- HEAD non mise à jour\n"
 
-#: builtin/merge.c:363
+#: builtin/merge.c:378
 msgid "Writing SQUASH_MSG"
-msgstr ""
+msgstr "Écriture de SQUASH_MSG"
 
-#: builtin/merge.c:365
+#: builtin/merge.c:380
 msgid "Finishing SQUASH_MSG"
-msgstr ""
+msgstr "Finition de SQUASH_MSG"
 
-#: builtin/merge.c:388
+#: builtin/merge.c:403
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
-msgstr ""
+msgstr "Pas de message de fusion -- pas de mise à jour de HEAD\n"
 
-#: builtin/merge.c:438
+#: builtin/merge.c:453
 #, c-format
 msgid "'%s' does not point to a commit"
-msgstr ""
+msgstr "'%s' ne pointe pas sur un commit"
 
-#: builtin/merge.c:550
+#: builtin/merge.c:565
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
-msgstr ""
+msgstr "Mauvaise chaîne branch.%s.mergeoptions : %s"
 
-#: builtin/merge.c:643
+#: builtin/merge.c:657
 msgid "git write-tree failed to write a tree"
-msgstr ""
-
-#: builtin/merge.c:671
-msgid "Not handling anything other than two heads merge."
-msgstr ""
+msgstr "git write-tree a échoué à écrire un arbre"
 
 #: builtin/merge.c:685
-#, c-format
-msgid "Unknown option for merge-recursive: -X%s"
-msgstr ""
+msgid "Not handling anything other than two heads merge."
+msgstr "Impossible de gérer autre chose que la fusion de deux têtes."
 
 #: builtin/merge.c:699
 #, c-format
-msgid "unable to write %s"
-msgstr ""
+msgid "Unknown option for merge-recursive: -X%s"
+msgstr "Options inconnue pour merge-recursive : -X%s"
 
-#: builtin/merge.c:788
+#: builtin/merge.c:713
+#, c-format
+msgid "unable to write %s"
+msgstr "impossible d'écrire %s"
+
+#: builtin/merge.c:802
 #, c-format
 msgid "Could not read from '%s'"
-msgstr ""
+msgstr "Impossible de lire depuis '%s'"
 
-#: builtin/merge.c:797
+#: builtin/merge.c:811
 #, c-format
 msgid "Not committing merge; use 'git commit' to complete the merge.\n"
 msgstr ""
+"Pas de validation de la fusion ; utilisez 'git commit' pour terminer la "
+"fusion.\n"
 
-#: builtin/merge.c:803
+#: builtin/merge.c:817
 #, c-format
 msgid ""
 "Please enter a commit message to explain why this merge is necessary,\n"
@@ -6256,897 +6934,932 @@
 "Lines starting with '%c' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
+"Veuillez entrer un message de validation pour expliquer en quoi cette fusion "
+"est\n"
+"nécessaire, surtout si cela fusionne une branche amont mise à jour dans une "
+"branche de sujet.\n"
+"\n"
+"Les lignes commençant par '%c' seront ignorées, et un message vide\n"
+"abandonne la validation.\n"
 
-#: builtin/merge.c:827
+#: builtin/merge.c:841
 msgid "Empty commit message."
-msgstr ""
+msgstr "Message de validation vide."
 
-#: builtin/merge.c:839
+#: builtin/merge.c:853
 #, c-format
 msgid "Wonderful.\n"
-msgstr ""
+msgstr "Merveilleux.\n"
 
-#: builtin/merge.c:904
+#: builtin/merge.c:918
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
+"La fusion automatique a échoué ; réglez les conflits et validez le "
+"résultat.\n"
 
-#: builtin/merge.c:920
+#: builtin/merge.c:934
 #, c-format
 msgid "'%s' is not a commit"
-msgstr ""
+msgstr "'%s' n'est pas une validation"
 
-#: builtin/merge.c:961
+#: builtin/merge.c:975
 msgid "No current branch."
-msgstr ""
+msgstr "Pas de branche courante."
 
-#: builtin/merge.c:963
+#: builtin/merge.c:977
 msgid "No remote for the current branch."
-msgstr ""
+msgstr "Pas de branche distante pour la branche courante."
 
-#: builtin/merge.c:965
+#: builtin/merge.c:979
 msgid "No default upstream defined for the current branch."
-msgstr ""
+msgstr "Pas de branche amont par défaut définie pour la branche courante."
 
-#: builtin/merge.c:970
+#: builtin/merge.c:984
 #, c-format
-msgid "No remote tracking branch for %s from %s"
-msgstr ""
+msgid "No remote-tracking branch for %s from %s"
+msgstr "Pas de branche de suivi pour %s depuis %s"
 
-#: builtin/merge.c:1057 builtin/merge.c:1214
-#, c-format
-msgid "%s - not something we can merge"
-msgstr ""
-
-#: builtin/merge.c:1125
+#: builtin/merge.c:1140
 msgid "There is no merge to abort (MERGE_HEAD missing)."
-msgstr ""
+msgstr "Il n'y a pas de fusion à abandonner (MERGE_HEAD manquant)."
 
-#: builtin/merge.c:1141 git-pull.sh:31
+#: builtin/merge.c:1156 git-pull.sh:31
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you can merge."
 msgstr ""
+"Vous n'avez pas terminé votre fusion (MERGE_HEAD existe).\n"
+"Veuillez valider vos changements avant de pouvoir fusionner."
 
-#: builtin/merge.c:1144 git-pull.sh:34
+#: builtin/merge.c:1159 git-pull.sh:34
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
-msgstr ""
+msgstr "Vous n'avez pas terminé votre fusion (MERGE_HEAD existe)."
 
-#: builtin/merge.c:1148
+#: builtin/merge.c:1163
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you can merge."
 msgstr ""
+"Vous n'avez pas terminé votre picorage (CHERRY_PICK_HEAD existe).\n"
+"Veuillez valider vos changements avant de pouvoir fusionner."
 
-#: builtin/merge.c:1151
+#: builtin/merge.c:1166
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
-msgstr ""
+msgstr "Vous n'avez pas terminé votre picorage (CHERRY_PICK_HEAD existe)."
 
-#: builtin/merge.c:1160
+#: builtin/merge.c:1175
 msgid "You cannot combine --squash with --no-ff."
-msgstr ""
+msgstr "Vous ne pouvez pas combiner --squash avec --no-ff."
 
-#: builtin/merge.c:1165
-msgid "You cannot combine --no-ff with --ff-only."
-msgstr ""
-
-#: builtin/merge.c:1172
+#: builtin/merge.c:1184
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr ""
+"Pas de validation spécifiée et merge.defaultToUpstream n'est pas défini."
 
-#: builtin/merge.c:1204
+#: builtin/merge.c:1216
 msgid "Can merge only exactly one commit into empty head"
 msgstr ""
+"Possible de fusionner exactement une seule validation dans une tête vide"
 
-#: builtin/merge.c:1207
+#: builtin/merge.c:1219
 msgid "Squash commit into empty head not supported yet"
-msgstr ""
+msgstr "La validation compressée vers une tête vide n'est pas encore supportée"
 
-#: builtin/merge.c:1209
+#: builtin/merge.c:1221
 msgid "Non-fast-forward commit does not make sense into an empty head"
-msgstr ""
+msgstr "Une validation sans avance rapide n'a pas de sens dans une tête vide"
 
-#: builtin/merge.c:1265
+#: builtin/merge.c:1226
+#, c-format
+msgid "%s - not something we can merge"
+msgstr "%s - pas possible de fusionner ceci"
+
+#: builtin/merge.c:1277
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
-msgstr ""
+msgstr "La validation %s a une signature GPG non fiable, prétendument par %s."
 
-#: builtin/merge.c:1268
+#: builtin/merge.c:1280
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
-msgstr ""
+msgstr "La validation %s a une mauvaise signature GPG prétendument par %s."
 
 #. 'N'
-#: builtin/merge.c:1271
+#: builtin/merge.c:1283
 #, c-format
 msgid "Commit %s does not have a GPG signature."
-msgstr ""
+msgstr "La validation %s n'a pas de signature GPG."
 
-#: builtin/merge.c:1274
+#: builtin/merge.c:1286
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
-msgstr ""
+msgstr "La validation %s a une signature GPG correcte par %s\n"
 
-#: builtin/merge.c:1358
+#: builtin/merge.c:1370
 #, c-format
 msgid "Updating %s..%s\n"
-msgstr ""
+msgstr "Mise à jour %s..%s\n"
 
-#: builtin/merge.c:1397
+#: builtin/merge.c:1409
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
-msgstr ""
+msgstr "Essai de fusion vraiment triviale dans l'index...\n"
 
-#: builtin/merge.c:1404
+#: builtin/merge.c:1416
 #, c-format
 msgid "Nope.\n"
-msgstr ""
+msgstr "Non.\n"
 
-#: builtin/merge.c:1436
+#: builtin/merge.c:1448
 msgid "Not possible to fast-forward, aborting."
-msgstr ""
+msgstr "Pas possible d'avancer rapidement, abandon."
 
-#: builtin/merge.c:1459 builtin/merge.c:1538
+#: builtin/merge.c:1471 builtin/merge.c:1550
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
-msgstr ""
+msgstr "Retour de l'arbre à l'original...\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1475
 #, c-format
 msgid "Trying merge strategy %s...\n"
-msgstr ""
+msgstr "Essai de la stratégie de fusion %s...\n"
 
-#: builtin/merge.c:1529
+#: builtin/merge.c:1541
 #, c-format
 msgid "No merge strategy handled the merge.\n"
-msgstr ""
+msgstr "Aucune stratégie de fusion n'a pris en charge la fusion.\n"
 
-#: builtin/merge.c:1531
+#: builtin/merge.c:1543
 #, c-format
 msgid "Merge with strategy %s failed.\n"
-msgstr ""
-
-#: builtin/merge.c:1540
-#, c-format
-msgid "Using the %s to prepare resolving by hand.\n"
-msgstr ""
+msgstr "La fusion avec la stratégie %s a échoué.\n"
 
 #: builtin/merge.c:1552
 #, c-format
+msgid "Using the %s to prepare resolving by hand.\n"
+msgstr "Utilisation de %s pour préparer la résolution à la main.\n"
+
+#: builtin/merge.c:1564
+#, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
+"La fusion automatique a réussi ; stoppée avant la validation comme demandé\n"
 
 #: builtin/merge-base.c:26
 msgid "git merge-base [-a|--all] <commit> <commit>..."
-msgstr ""
+msgstr "git merge-base [-a|--all] <validation> <validation>..."
 
 #: builtin/merge-base.c:27
 msgid "git merge-base [-a|--all] --octopus <commit>..."
-msgstr ""
+msgstr "git merge-base [-a|--all] --octopus <validation>..."
 
 #: builtin/merge-base.c:28
 msgid "git merge-base --independent <commit>..."
-msgstr ""
+msgstr "git merge-base --independent <validation>..."
 
 #: builtin/merge-base.c:29
 msgid "git merge-base --is-ancestor <commit> <commit>"
-msgstr ""
+msgstr "git merge-base --is-ancestor <validation> <validation>"
 
 #: builtin/merge-base.c:98
 msgid "output all common ancestors"
-msgstr ""
+msgstr "afficher tous les ancêtres communs"
 
 #: builtin/merge-base.c:99
 msgid "find ancestors for a single n-way merge"
-msgstr ""
+msgstr "trouver les ancêtres pour une fusion simple à n points"
 
 #: builtin/merge-base.c:100
 msgid "list revs not reachable from others"
-msgstr ""
+msgstr "afficher les révisions inaccessibles depuis les autres"
 
 #: builtin/merge-base.c:102
 msgid "is the first one ancestor of the other?"
-msgstr ""
+msgstr "est le premier ancêtre de l'autre ?"
 
 #: builtin/merge-file.c:8
 msgid ""
 "git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file "
 "file2"
 msgstr ""
+"git merge-file [options] [-L nom1 [-L orig [-L nom2]]] fichier1 orig_file "
+"fichier2"
 
 #: builtin/merge-file.c:33
 msgid "send results to standard output"
-msgstr ""
+msgstr "envoyer les résultats sur la sortie standard"
 
 #: builtin/merge-file.c:34
 msgid "use a diff3 based merge"
-msgstr ""
+msgstr "utiliser une fusion basée sur diff3"
 
 #: builtin/merge-file.c:35
 msgid "for conflicts, use our version"
-msgstr ""
+msgstr "pour les conflits, utiliser notre version (our)"
 
 #: builtin/merge-file.c:37
 msgid "for conflicts, use their version"
-msgstr ""
+msgstr "pour les conflits, utiliser leur version (their)"
 
 #: builtin/merge-file.c:39
 msgid "for conflicts, use a union version"
-msgstr ""
+msgstr "pour les conflits, utiliser l'ensemble des versions"
 
 #: builtin/merge-file.c:42
 msgid "for conflicts, use this marker size"
-msgstr ""
+msgstr "pour les conflits, utiliser cette taille de marqueur"
 
 #: builtin/merge-file.c:43
 msgid "do not warn about conflicts"
-msgstr ""
+msgstr "ne pas avertir à propos des conflits"
 
 #: builtin/merge-file.c:45
 msgid "set labels for file1/orig_file/file2"
-msgstr ""
+msgstr "définir les labels pour fichier1/orig_file/fichier2"
 
 #: builtin/mktree.c:67
 msgid "git mktree [-z] [--missing] [--batch]"
-msgstr ""
+msgstr "git mktree [-z] [--missing] [--batch]"
 
 #: builtin/mktree.c:153
 msgid "input is NUL terminated"
-msgstr ""
+msgstr "l'entrée se termine par NUL"
 
 #: builtin/mktree.c:154 builtin/write-tree.c:24
 msgid "allow missing objects"
-msgstr ""
+msgstr "autoriser les objets manquants"
 
 #: builtin/mktree.c:155
 msgid "allow creation of more than one tree"
-msgstr ""
+msgstr "autoriser la création de plus d'un arbre"
 
-#: builtin/mv.c:14
+#: builtin/mv.c:15
 msgid "git mv [options] <source>... <destination>"
-msgstr ""
+msgstr "git mv [options] <source>... <destination>"
 
-#: builtin/mv.c:64
+#: builtin/mv.c:67
 msgid "force move/rename even if target exists"
-msgstr ""
+msgstr "forcer le déplacement/renommage même si la cible existe"
 
-#: builtin/mv.c:65
+#: builtin/mv.c:68
 msgid "skip move/rename errors"
-msgstr ""
+msgstr "sauter les erreurs de déplacement/renommage"
 
-#: builtin/mv.c:108
+#: builtin/mv.c:113
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
-msgstr ""
+msgstr "Vérification du renommage de '%s' en '%s'\n"
 
-#: builtin/mv.c:112
+#: builtin/mv.c:117
 msgid "bad source"
-msgstr ""
+msgstr "mauvaise source"
 
-#: builtin/mv.c:115
+#: builtin/mv.c:120
 msgid "can not move directory into itself"
-msgstr ""
+msgstr "impossible de déplacer un répertoire dans lui-même"
 
-#: builtin/mv.c:118
+#: builtin/mv.c:123
 msgid "cannot move directory over file"
-msgstr ""
+msgstr "impossible de déplacer un répertoire sur un fichier"
 
-#: builtin/mv.c:128
+#: builtin/mv.c:129
+#, c-format
+msgid "Huh? Directory %s is in index and no submodule?"
+msgstr "Hein ? Le répertoire %s est dans l'index et pourtant aucun sous-module ?"
+
+#: builtin/mv.c:131 builtin/rm.c:318
+msgid "Please, stage your changes to .gitmodules or stash them to proceed"
+msgstr "Veuillez indexer vos modifications de .gitmodules ou remisez-les pour continuer"
+
+#: builtin/mv.c:147
 #, c-format
 msgid "Huh? %.*s is in index?"
-msgstr ""
+msgstr "Hein ? %.*s est dans l'index ?"
 
-#: builtin/mv.c:140
+#: builtin/mv.c:159
 msgid "source directory is empty"
-msgstr ""
+msgstr "le répertoire source est vide"
 
-#: builtin/mv.c:171
+#: builtin/mv.c:191
 msgid "not under version control"
-msgstr ""
+msgstr "pas sous le contrôle de version"
 
-#: builtin/mv.c:173
+#: builtin/mv.c:193
 msgid "destination exists"
-msgstr ""
+msgstr "la destination existe"
 
-#: builtin/mv.c:181
+#: builtin/mv.c:201
 #, c-format
 msgid "overwriting '%s'"
-msgstr ""
+msgstr "écrasement de '%s'"
 
-#: builtin/mv.c:184
+#: builtin/mv.c:204
 msgid "Cannot overwrite"
-msgstr ""
+msgstr "Impossible d'écraser"
 
-#: builtin/mv.c:187
+#: builtin/mv.c:207
 msgid "multiple sources for the same target"
-msgstr ""
+msgstr "multiples sources pour la même destination"
 
-#: builtin/mv.c:202
+#: builtin/mv.c:222
 #, c-format
 msgid "%s, source=%s, destination=%s"
 msgstr "%s, source=%s, destination=%s"
 
-#: builtin/mv.c:212
+#: builtin/mv.c:232
 #, c-format
 msgid "Renaming %s to %s\n"
-msgstr ""
+msgstr "Renommage de %s en %s\n"
 
-#: builtin/mv.c:215 builtin/remote.c:731
+#: builtin/mv.c:235 builtin/remote.c:731 builtin/repack.c:330
 #, c-format
 msgid "renaming '%s' failed"
-msgstr ""
+msgstr "le renommage de '%s' a échoué"
 
-#: builtin/name-rev.c:175
+#: builtin/name-rev.c:259
 msgid "git name-rev [options] <commit>..."
-msgstr ""
+msgstr "git name-rev [options] <validation>..."
 
-#: builtin/name-rev.c:176
+#: builtin/name-rev.c:260
 msgid "git name-rev [options] --all"
-msgstr ""
+msgstr "git name-rev [options] --all"
 
-#: builtin/name-rev.c:177
+#: builtin/name-rev.c:261
 msgid "git name-rev [options] --stdin"
-msgstr ""
+msgstr "git name-rev [options] --stdin"
 
-#: builtin/name-rev.c:229
+#: builtin/name-rev.c:313
 msgid "print only names (no SHA-1)"
-msgstr ""
+msgstr "afficher seulement les noms (pas de SHA-1)"
 
-#: builtin/name-rev.c:230
+#: builtin/name-rev.c:314
 msgid "only use tags to name the commits"
-msgstr ""
+msgstr "utiliser seulement les étiquettes pour nommer les validations"
 
-#: builtin/name-rev.c:232
+#: builtin/name-rev.c:316
 msgid "only use refs matching <pattern>"
-msgstr ""
+msgstr "utiliser seulement les références correspondant à <motif>"
 
-#: builtin/name-rev.c:234
+#: builtin/name-rev.c:318
 msgid "list all commits reachable from all refs"
 msgstr ""
+"afficher toutes les validations accessibles depuis toutes les références"
 
-#: builtin/name-rev.c:235
+#: builtin/name-rev.c:319
 msgid "read from stdin"
-msgstr ""
+msgstr "lire depuis l'entrée standard"
 
-#: builtin/name-rev.c:236
-msgid "allow to print `undefined` names"
-msgstr ""
+#: builtin/name-rev.c:320
+msgid "allow to print `undefined` names (default)"
+msgstr "autoriser l'affichage des noms `non définis` (par défaut)"
 
-#: builtin/notes.c:26
+#: builtin/name-rev.c:326
+msgid "dereference tags in the input (internal use)"
+msgstr "déréférencer les étiquettes en entrée (usage interne)"
+
+#: builtin/notes.c:24
 msgid "git notes [--ref <notes_ref>] [list [<object>]]"
-msgstr ""
+msgstr "git notes [--ref <références_notes>] [list [<object>]]"
 
-#: builtin/notes.c:27
+#: builtin/notes.c:25
 msgid ""
 "git notes [--ref <notes_ref>] add [-f] [-m <msg> | -F <file> | (-c | -C) "
 "<object>] [<object>]"
 msgstr ""
+"git notes [--ref <références_notes>] add [-f] [-m <message> | -F <fichier> | "
+"(-c | -C) <objet>] [<objet>]"
 
-#: builtin/notes.c:28
+#: builtin/notes.c:26
 msgid "git notes [--ref <notes_ref>] copy [-f] <from-object> <to-object>"
 msgstr ""
+"git notes [--ref <références_notes>] copy [-f] <depuis-objet> <vers-objet>"
 
-#: builtin/notes.c:29
+#: builtin/notes.c:27
 msgid ""
 "git notes [--ref <notes_ref>] append [-m <msg> | -F <file> | (-c | -C) "
 "<object>] [<object>]"
 msgstr ""
+"git notes [--ref <références_notes>] append [-m <message> | -F <fichier> | (-"
+"c | -C) <objet>] [<objet>]"
+
+#: builtin/notes.c:28
+msgid "git notes [--ref <notes_ref>] edit [<object>]"
+msgstr "git notes [--ref <références_notes>] edit [<objet>]"
+
+#: builtin/notes.c:29
+msgid "git notes [--ref <notes_ref>] show [<object>]"
+msgstr "git notes [--ref <références_notes>] show [<objet>]"
 
 #: builtin/notes.c:30
-msgid "git notes [--ref <notes_ref>] edit [<object>]"
-msgstr ""
-
-#: builtin/notes.c:31
-msgid "git notes [--ref <notes_ref>] show [<object>]"
-msgstr ""
-
-#: builtin/notes.c:32
 msgid ""
 "git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>"
 msgstr ""
+"git notes [--ref <références_notes>] merge [-v | -q] [-s <stratégie> ] "
+"<références_notes>"
+
+#: builtin/notes.c:31
+msgid "git notes merge --commit [-v | -q]"
+msgstr "git notes merge --commit [-v | -q]"
+
+#: builtin/notes.c:32
+msgid "git notes merge --abort [-v | -q]"
+msgstr "git notes merge --abort [-v | -q]"
 
 #: builtin/notes.c:33
-msgid "git notes merge --commit [-v | -q]"
-msgstr ""
+msgid "git notes [--ref <notes_ref>] remove [<object>...]"
+msgstr "git notes [--ref <références_notes>] remove [<objet>...]"
 
 #: builtin/notes.c:34
-msgid "git notes merge --abort [-v | -q]"
-msgstr ""
+msgid "git notes [--ref <notes_ref>] prune [-n | -v]"
+msgstr "git notes [--ref <références_notes>] prune [-n | -v]"
 
 #: builtin/notes.c:35
-msgid "git notes [--ref <notes_ref>] remove [<object>...]"
-msgstr ""
-
-#: builtin/notes.c:36
-msgid "git notes [--ref <notes_ref>] prune [-n | -v]"
-msgstr ""
-
-#: builtin/notes.c:37
 msgid "git notes [--ref <notes_ref>] get-ref"
-msgstr ""
+msgstr "git notes [--ref <références_notes>] get-ref"
 
-#: builtin/notes.c:42
+#: builtin/notes.c:40
 msgid "git notes [list [<object>]]"
-msgstr ""
+msgstr "git notes [list [<objet>]]"
 
-#: builtin/notes.c:47
+#: builtin/notes.c:45
 msgid "git notes add [<options>] [<object>]"
-msgstr ""
+msgstr "git notes add [<options>] [<objet>]"
 
-#: builtin/notes.c:52
+#: builtin/notes.c:50
 msgid "git notes copy [<options>] <from-object> <to-object>"
-msgstr ""
+msgstr "git notes copy [<options>] <depuis-objet> <vers-objet>"
 
-#: builtin/notes.c:53
+#: builtin/notes.c:51
 msgid "git notes copy --stdin [<from-object> <to-object>]..."
-msgstr ""
+msgstr "git notes copy --stdin [<depuis-objet> <vers-objet>]..."
 
-#: builtin/notes.c:58
+#: builtin/notes.c:56
 msgid "git notes append [<options>] [<object>]"
-msgstr ""
+msgstr "git notes append [<options>] [<objet>]"
 
-#: builtin/notes.c:63
+#: builtin/notes.c:61
 msgid "git notes edit [<object>]"
-msgstr ""
+msgstr "git notes edit [<objet>]"
 
-#: builtin/notes.c:68
+#: builtin/notes.c:66
 msgid "git notes show [<object>]"
-msgstr ""
+msgstr "git notes show [<objet>]"
+
+#: builtin/notes.c:71
+msgid "git notes merge [<options>] <notes_ref>"
+msgstr "git notes merge [<options>] <références_notes>"
+
+#: builtin/notes.c:72
+msgid "git notes merge --commit [<options>]"
+msgstr "git notes merge --commit [<options>]"
 
 #: builtin/notes.c:73
-msgid "git notes merge [<options>] <notes_ref>"
-msgstr ""
-
-#: builtin/notes.c:74
-msgid "git notes merge --commit [<options>]"
-msgstr ""
-
-#: builtin/notes.c:75
 msgid "git notes merge --abort [<options>]"
-msgstr ""
+msgstr "git notes merge --abort [<options>]"
 
-#: builtin/notes.c:80
+#: builtin/notes.c:78
 msgid "git notes remove [<object>]"
-msgstr ""
+msgstr "git notes remove [<objet>]"
 
-#: builtin/notes.c:85
+#: builtin/notes.c:83
 msgid "git notes prune [<options>]"
-msgstr ""
+msgstr "git notes prune [<options>]"
 
-#: builtin/notes.c:90
+#: builtin/notes.c:88
 msgid "git notes get-ref"
-msgstr ""
+msgstr "git notes get-ref"
 
-#: builtin/notes.c:139
+#: builtin/notes.c:137
 #, c-format
 msgid "unable to start 'show' for object '%s'"
-msgstr ""
+msgstr "impossible de démarrer 'show' pour l'objet '%s'"
 
-#: builtin/notes.c:143
+#: builtin/notes.c:141
 msgid "could not read 'show' output"
-msgstr ""
+msgstr "impossible de lire la sortie de 'show'"
 
-#: builtin/notes.c:151
+#: builtin/notes.c:149
 #, c-format
 msgid "failed to finish 'show' for object '%s'"
-msgstr ""
+msgstr "impossible de finir 'show' pour l'objet '%s'"
 
-#: builtin/notes.c:169 builtin/tag.c:341
+#: builtin/notes.c:167 builtin/tag.c:341
 #, c-format
 msgid "could not create file '%s'"
-msgstr ""
+msgstr "impossible de créer le fichier '%s'"
 
-#: builtin/notes.c:188
+#: builtin/notes.c:186
 msgid "Please supply the note contents using either -m or -F option"
-msgstr ""
+msgstr "Veuillez fournir le contenu de la note en utilisant l'option -m ou -F"
 
-#: builtin/notes.c:209 builtin/notes.c:972
+#: builtin/notes.c:207 builtin/notes.c:844
 #, c-format
 msgid "Removing note for object %s\n"
-msgstr ""
+msgstr "Suppression de la note pour l'objet %s\n"
+
+#: builtin/notes.c:212
+msgid "unable to write note object"
+msgstr "impossible d'écrire l'objet note"
 
 #: builtin/notes.c:214
-msgid "unable to write note object"
-msgstr ""
-
-#: builtin/notes.c:216
 #, c-format
 msgid "The note contents has been left in %s"
-msgstr ""
+msgstr "Le contenu de la note a été laissé dans %s"
+
+#: builtin/notes.c:248 builtin/tag.c:537
+#, c-format
+msgid "cannot read '%s'"
+msgstr "impossible de lire '%s'"
 
 #: builtin/notes.c:250 builtin/tag.c:540
 #, c-format
-msgid "cannot read '%s'"
-msgstr ""
-
-#: builtin/notes.c:252 builtin/tag.c:543
-#, c-format
 msgid "could not open or read '%s'"
-msgstr ""
+msgstr "impossible d'ouvrir ou lire '%s'"
 
-#: builtin/notes.c:271 builtin/notes.c:444 builtin/notes.c:446
-#: builtin/notes.c:506 builtin/notes.c:560 builtin/notes.c:643
-#: builtin/notes.c:648 builtin/notes.c:723 builtin/notes.c:765
-#: builtin/notes.c:967 builtin/tag.c:556
+#: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318
+#: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515
+#: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637
+#: builtin/notes.c:839 builtin/tag.c:553
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
-msgstr ""
+msgstr "Impossible de résoudre '%s' comme une référence valide."
 
-#: builtin/notes.c:274
+#: builtin/notes.c:272
 #, c-format
 msgid "Failed to read object '%s'."
-msgstr ""
+msgstr "Impossible de lire l'objet '%s'."
 
-#: builtin/notes.c:298
-msgid "Cannot commit uninitialized/unreferenced notes tree"
-msgstr ""
-
-#: builtin/notes.c:339
-#, c-format
-msgid "Bad notes.rewriteMode value: '%s'"
-msgstr ""
-
-#: builtin/notes.c:349
-#, c-format
-msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
-msgstr ""
-
-#. TRANSLATORS: The first %s is the name of the
-#. environment variable, the second %s is its value
-#: builtin/notes.c:376
-#, c-format
-msgid "Bad %s value: '%s'"
-msgstr ""
-
-#: builtin/notes.c:440
+#: builtin/notes.c:312
 #, c-format
 msgid "Malformed input line: '%s'."
-msgstr ""
+msgstr "Ligne en entrée malformée : '%s'."
 
-#: builtin/notes.c:455
+#: builtin/notes.c:327
 #, c-format
 msgid "Failed to copy notes from '%s' to '%s'"
-msgstr ""
+msgstr "Impossible de copier les notes de '%s' vers '%s'"
 
-#: builtin/notes.c:499 builtin/notes.c:553 builtin/notes.c:626
-#: builtin/notes.c:638 builtin/notes.c:711 builtin/notes.c:758
-#: builtin/notes.c:1032
+#: builtin/notes.c:371 builtin/notes.c:425 builtin/notes.c:498
+#: builtin/notes.c:510 builtin/notes.c:583 builtin/notes.c:630
+#: builtin/notes.c:904
 msgid "too many parameters"
-msgstr ""
+msgstr "trop de paramètres"
 
-#: builtin/notes.c:512 builtin/notes.c:771
+#: builtin/notes.c:384 builtin/notes.c:643
 #, c-format
 msgid "No note found for object %s."
-msgstr ""
+msgstr "Pas de note trouvée pour l'objet %s."
 
-#: builtin/notes.c:534 builtin/notes.c:691
+#: builtin/notes.c:406 builtin/notes.c:563
 msgid "note contents as a string"
-msgstr ""
+msgstr "contenu de la note sous forme de chaîne"
 
-#: builtin/notes.c:537 builtin/notes.c:694
+#: builtin/notes.c:409 builtin/notes.c:566
 msgid "note contents in a file"
-msgstr ""
+msgstr "contenu de la note dans un fichier"
 
-#: builtin/notes.c:539 builtin/notes.c:542 builtin/notes.c:696
-#: builtin/notes.c:699 builtin/tag.c:474
+#: builtin/notes.c:411 builtin/notes.c:414 builtin/notes.c:568
+#: builtin/notes.c:571 builtin/tag.c:474
 msgid "object"
-msgstr ""
+msgstr "objet"
 
-#: builtin/notes.c:540 builtin/notes.c:697
+#: builtin/notes.c:412 builtin/notes.c:569
 msgid "reuse and edit specified note object"
-msgstr ""
+msgstr "réutiliser et éditer l'objet de note spécifié"
 
-#: builtin/notes.c:543 builtin/notes.c:700
+#: builtin/notes.c:415 builtin/notes.c:572
 msgid "reuse specified note object"
-msgstr ""
+msgstr "réutiliser l'objet de note spécifié"
 
-#: builtin/notes.c:545 builtin/notes.c:613
+#: builtin/notes.c:417 builtin/notes.c:485
 msgid "replace existing notes"
-msgstr ""
+msgstr "remplacer les notes existantes"
 
-#: builtin/notes.c:579
+#: builtin/notes.c:451
 #, c-format
 msgid ""
 "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite "
 "existing notes"
 msgstr ""
+"Impossible d'ajouter des notes. Des notes ont été trouvées pour l'objet %s. "
+"Utilisez '-f' pour écraser les notes existantes"
 
-#: builtin/notes.c:584 builtin/notes.c:661
+#: builtin/notes.c:456 builtin/notes.c:533
 #, c-format
 msgid "Overwriting existing notes for object %s\n"
-msgstr ""
+msgstr "Écrasement des notes existantes pour l'objet %s\n"
 
-#: builtin/notes.c:614
+#: builtin/notes.c:486
 msgid "read objects from stdin"
-msgstr ""
+msgstr "lire les objets depuis l'entrée standard"
 
-#: builtin/notes.c:616
+#: builtin/notes.c:488
 msgid "load rewriting config for <command> (implies --stdin)"
 msgstr ""
+"charger la configuration de réécriture pour <commande> (implique --stdin)"
 
-#: builtin/notes.c:634
+#: builtin/notes.c:506
 msgid "too few parameters"
-msgstr ""
+msgstr "pas assez de paramètres"
 
-#: builtin/notes.c:655
+#: builtin/notes.c:527
 #, c-format
 msgid ""
 "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite "
 "existing notes"
 msgstr ""
+"Impossible de copier des notes. Des notes ont été trouvées pour l'objet %s. "
+"Utilisez '-f' pour écraser les notes existantes"
 
-#: builtin/notes.c:667
+#: builtin/notes.c:539
 #, c-format
 msgid "Missing notes on source object %s. Cannot copy."
-msgstr ""
+msgstr "Notes manquantes sur l'objet source %s. Impossible de copier."
 
-#: builtin/notes.c:716
+#: builtin/notes.c:588
 #, c-format
 msgid ""
 "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
 "Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
 msgstr ""
+"Les options -m/-F/-c/-C sont obsolètes pour la sous-commande 'edit'.\n"
+"Veuillez utiliser 'git notes add -f -m/-F/-c/-C' à la place.\n"
 
-#: builtin/notes.c:863
+#: builtin/notes.c:735
 msgid "General options"
-msgstr ""
+msgstr "Options générales"
 
-#: builtin/notes.c:865
+#: builtin/notes.c:737
 msgid "Merge options"
-msgstr ""
+msgstr "Options de fusion"
 
-#: builtin/notes.c:867
+#: builtin/notes.c:739
 msgid ""
 "resolve notes conflicts using the given strategy (manual/ours/theirs/union/"
 "cat_sort_uniq)"
 msgstr ""
+"résoudre les conflits de notes en utilisant la stratégie donnée (manual/ours/"
+"theirs/union/cat_sort_uniq)"
 
-#: builtin/notes.c:869
+#: builtin/notes.c:741
 msgid "Committing unmerged notes"
-msgstr ""
+msgstr "Validation des notes non fusionnées"
 
-#: builtin/notes.c:871
+#: builtin/notes.c:743
 msgid "finalize notes merge by committing unmerged notes"
-msgstr ""
+msgstr "finaliser la fusion de notes en validant les notes non fusionnées"
 
-#: builtin/notes.c:873
+#: builtin/notes.c:745
 msgid "Aborting notes merge resolution"
-msgstr ""
+msgstr "Abandon de la résolution de fusion des notes"
 
-#: builtin/notes.c:875
+#: builtin/notes.c:747
 msgid "abort notes merge"
-msgstr ""
+msgstr "abandonner la fusion de notes"
 
-#: builtin/notes.c:970
+#: builtin/notes.c:842
 #, c-format
 msgid "Object %s has no note\n"
-msgstr ""
+msgstr "L'objet %s n'a pas de note\n"
 
-#: builtin/notes.c:982
+#: builtin/notes.c:854
 msgid "attempt to remove non-existent note is not an error"
 msgstr ""
+"la tentative de suppression d'une note non existante n'est pas une erreur"
 
-#: builtin/notes.c:985
+#: builtin/notes.c:857
 msgid "read object names from the standard input"
-msgstr ""
+msgstr "lire les noms d'objet depuis l'entrée standard"
 
-#: builtin/notes.c:1066
+#: builtin/notes.c:938
 msgid "notes_ref"
-msgstr ""
+msgstr "références_notes"
 
-#: builtin/notes.c:1067
+#: builtin/notes.c:939
 msgid "use notes from <notes_ref>"
-msgstr ""
+msgstr "utiliser les notes depuis <références_notes>"
 
-#: builtin/notes.c:1102 builtin/remote.c:1598
+#: builtin/notes.c:974 builtin/remote.c:1598
 #, c-format
 msgid "Unknown subcommand: %s"
-msgstr ""
+msgstr "Sous-commande inconnue : %s"
 
 #: builtin/pack-objects.c:23
 msgid "git pack-objects --stdout [options...] [< ref-list | < object-list]"
 msgstr ""
+"git pack-objects --stdout [options...] [< liste-références | < liste-objets]"
 
 #: builtin/pack-objects.c:24
 msgid "git pack-objects [options...] base-name [< ref-list | < object-list]"
 msgstr ""
+"git pack-objects [options...] base-name [< liste-références | < liste-objets]"
 
-#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#: builtin/pack-objects.c:184 builtin/pack-objects.c:187
 #, c-format
 msgid "deflate error (%d)"
-msgstr ""
+msgstr "erreur de compression (%d)"
 
-#: builtin/pack-objects.c:2397
+#: builtin/pack-objects.c:2398
 #, c-format
 msgid "unsupported index version %s"
-msgstr ""
+msgstr "version d'index non supportée %s"
 
-#: builtin/pack-objects.c:2401
+#: builtin/pack-objects.c:2402
 #, c-format
 msgid "bad index version '%s'"
-msgstr ""
+msgstr "mauvaise version d'index '%s'"
 
-#: builtin/pack-objects.c:2424
+#: builtin/pack-objects.c:2425
 #, c-format
 msgid "option %s does not accept negative form"
-msgstr ""
+msgstr "l'option %s n'accepte pas de valeur négative"
 
-#: builtin/pack-objects.c:2428
+#: builtin/pack-objects.c:2429
 #, c-format
 msgid "unable to parse value '%s' for option %s"
-msgstr ""
+msgstr "impossible d'analyser la valeur '%s' pour l'option %s"
 
-#: builtin/pack-objects.c:2447
+#: builtin/pack-objects.c:2448
 msgid "do not show progress meter"
-msgstr ""
+msgstr "ne pas afficher la barre de progression"
 
-#: builtin/pack-objects.c:2449
+#: builtin/pack-objects.c:2450
 msgid "show progress meter"
-msgstr ""
+msgstr "afficher la barre de progression"
 
-#: builtin/pack-objects.c:2451
+#: builtin/pack-objects.c:2452
 msgid "show progress meter during object writing phase"
-msgstr ""
-
-#: builtin/pack-objects.c:2454
-msgid "similar to --all-progress when progress meter is shown"
-msgstr ""
+msgstr "afficher la barre de progression durant la phase d'écrite des objets"
 
 #: builtin/pack-objects.c:2455
-msgid "version[,offset]"
-msgstr ""
+msgid "similar to --all-progress when progress meter is shown"
+msgstr "similaire à --all-progress quand la barre de progression est affichée"
 
 #: builtin/pack-objects.c:2456
+msgid "version[,offset]"
+msgstr "version[,offset]"
+
+#: builtin/pack-objects.c:2457
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
+"écrire le fichier d'index du paquet dans le format d'index de version "
+"spécifié"
 
-#: builtin/pack-objects.c:2459
+#: builtin/pack-objects.c:2460
 msgid "maximum size of each output pack file"
-msgstr ""
+msgstr "taille maximum de chaque fichier paquet en sortie"
 
-#: builtin/pack-objects.c:2461
+#: builtin/pack-objects.c:2462
 msgid "ignore borrowed objects from alternate object store"
-msgstr ""
+msgstr "ignorer les objets empruntés à un autre magasin d'objets"
 
-#: builtin/pack-objects.c:2463
+#: builtin/pack-objects.c:2464
 msgid "ignore packed objects"
-msgstr ""
+msgstr "ignorer les objets empaquetés"
 
-#: builtin/pack-objects.c:2465
+#: builtin/pack-objects.c:2466
 msgid "limit pack window by objects"
-msgstr ""
+msgstr "limiter la fenêtre d'empaquetage par objets"
 
-#: builtin/pack-objects.c:2467
+#: builtin/pack-objects.c:2468
 msgid "limit pack window by memory in addition to object limit"
 msgstr ""
+"limiter la fenêtre d'empaquetage par mémoire en plus de la limite d'objets"
 
-#: builtin/pack-objects.c:2469
+#: builtin/pack-objects.c:2470
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr ""
+"longueur maximum de la chaîne de delta autorisée dans le paquet résultant"
 
-#: builtin/pack-objects.c:2471
+#: builtin/pack-objects.c:2472
 msgid "reuse existing deltas"
-msgstr ""
+msgstr "réutiliser les deltas existants"
 
-#: builtin/pack-objects.c:2473
+#: builtin/pack-objects.c:2474
 msgid "reuse existing objects"
-msgstr ""
+msgstr "réutiliser les objets existants"
 
-#: builtin/pack-objects.c:2475
+#: builtin/pack-objects.c:2476
 msgid "use OFS_DELTA objects"
-msgstr ""
+msgstr "utiliser les objets OFS_DELTA"
 
-#: builtin/pack-objects.c:2477
+#: builtin/pack-objects.c:2478
 msgid "use threads when searching for best delta matches"
 msgstr ""
+"utiliser des fils lors de la recherche pour une meilleurs correspondance des "
+"deltas"
 
-#: builtin/pack-objects.c:2479
+#: builtin/pack-objects.c:2480
 msgid "do not create an empty pack output"
-msgstr ""
+msgstr "ne pas créer un paquet vide"
 
-#: builtin/pack-objects.c:2481
+#: builtin/pack-objects.c:2482
 msgid "read revision arguments from standard input"
-msgstr ""
+msgstr "lire les paramètres de révision depuis l'entrée standard"
 
-#: builtin/pack-objects.c:2483
+#: builtin/pack-objects.c:2484
 msgid "limit the objects to those that are not yet packed"
-msgstr ""
+msgstr "limiter les objets à ceux qui ne sont pas encore empaquetés"
 
-#: builtin/pack-objects.c:2486
+#: builtin/pack-objects.c:2487
 msgid "include objects reachable from any reference"
-msgstr ""
+msgstr "inclure les objets accessibles depuis toute référence"
 
-#: builtin/pack-objects.c:2489
+#: builtin/pack-objects.c:2490
 msgid "include objects referred by reflog entries"
-msgstr ""
+msgstr "inclure les objets référencés par les éléments de reflog"
 
-#: builtin/pack-objects.c:2492
+#: builtin/pack-objects.c:2493
 msgid "output pack to stdout"
-msgstr ""
+msgstr "afficher l'empaquetage sur la sortie standard"
 
-#: builtin/pack-objects.c:2494
+#: builtin/pack-objects.c:2495
 msgid "include tag objects that refer to objects to be packed"
-msgstr ""
+msgstr "inclure les objets d'étiquettes qui réfèrent à des objets à empaqueter"
 
-#: builtin/pack-objects.c:2496
+#: builtin/pack-objects.c:2497
 msgid "keep unreachable objects"
-msgstr ""
+msgstr "garder les objets inaccessibles"
 
-#: builtin/pack-objects.c:2497 parse-options.h:141
+#: builtin/pack-objects.c:2498 parse-options.h:143
 msgid "time"
-msgstr ""
+msgstr "heure"
 
-#: builtin/pack-objects.c:2498
+#: builtin/pack-objects.c:2499
 msgid "unpack unreachable objects newer than <time>"
-msgstr ""
+msgstr "dépaqueter les objets inaccessibles plus récents que <heure>"
 
-#: builtin/pack-objects.c:2501
+#: builtin/pack-objects.c:2502
 msgid "create thin packs"
-msgstr ""
+msgstr "créer des paquets légers"
 
-#: builtin/pack-objects.c:2503
+#: builtin/pack-objects.c:2504
 msgid "ignore packs that have companion .keep file"
-msgstr ""
+msgstr "ignorer les paquets qui ont un fichier .keep"
 
-#: builtin/pack-objects.c:2505
+#: builtin/pack-objects.c:2506
 msgid "pack compression level"
-msgstr ""
+msgstr "niveau de compression du paquet"
 
-#: builtin/pack-objects.c:2507
+#: builtin/pack-objects.c:2508
 msgid "do not hide commits by grafts"
-msgstr ""
+msgstr "ne pas cacher les validations par greffes"
 
 #: builtin/pack-refs.c:6
 msgid "git pack-refs [options]"
-msgstr ""
+msgstr "git pack-refs [options]"
 
 #: builtin/pack-refs.c:14
 msgid "pack everything"
-msgstr ""
+msgstr "empaqueter tout"
 
 #: builtin/pack-refs.c:15
 msgid "prune loose refs (default)"
-msgstr ""
+msgstr "éliminer les références perdues (défaut)"
 
 #: builtin/prune-packed.c:7
 msgid "git prune-packed [-n|--dry-run] [-q|--quiet]"
-msgstr ""
+msgstr "git prune-packed [-n|--dry-run] [-q|--quiet]"
 
 #: builtin/prune.c:12
 msgid "git prune [-n] [-v] [--expire <time>] [--] [<head>...]"
-msgstr ""
+msgstr "git prune [-n] [-v] [--expire <heure>] [--] [<head>...]"
 
 #: builtin/prune.c:132
 msgid "do not remove, show only"
-msgstr ""
+msgstr "ne pas supprimer, afficher seulement"
 
 #: builtin/prune.c:133
 msgid "report pruned objects"
-msgstr ""
+msgstr "afficher les objets éliminés"
 
 #: builtin/prune.c:136
 msgid "expire objects older than <time>"
-msgstr ""
+msgstr "faire expirer les objets plus vieux que <heure>"
 
 #: builtin/push.c:14
 msgid "git push [<options>] [<repository> [<refspec>...]]"
-msgstr ""
+msgstr "git push [<options>] [<dépôt> [<spécification-de-référence>...]]"
 
-#: builtin/push.c:45
+#: builtin/push.c:47
 msgid "tag shorthand without <tag>"
-msgstr ""
+msgstr "raccourci d'étiquette sans <étiquette>"
 
-#: builtin/push.c:64
+#: builtin/push.c:66
 msgid "--delete only accepts plain target ref names"
-msgstr ""
+msgstr "--delete accepte seulement des noms entiers de références cibles"
 
-#: builtin/push.c:99
+#: builtin/push.c:101
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
 msgstr ""
+"\n"
+"Pour choisir l'option de manière permanente, voir push.default dans 'git "
+"help config'."
 
-#: builtin/push.c:102
+#: builtin/push.c:104
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -7160,8 +7873,18 @@
 "    git push %s %s\n"
 "%s"
 msgstr ""
+"La branche amont de votre branche courante ne correspond pas\n"
+"au nom de votre branche courante.  Pour pousser vers la branche amont\n"
+"sur le serveur distant, utilisez\n"
+"\n"
+"    git push %s HEAD:%s\n"
+"\n"
+"Pour pousser vers la branche du même nom sur le serveur distant, utilisez\n"
+"\n"
+"    git push %s %s\n"
+"%s"
 
-#: builtin/push.c:121
+#: builtin/push.c:119
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -7170,8 +7893,13 @@
 "\n"
 "    git push %s HEAD:<name-of-remote-branch>\n"
 msgstr ""
+"Vous n'êtes actuellement sur aucune branche.\n"
+"Pour pousser l'historique menant à l'état actuel (HEAD détachée),\n"
+"utilisez\n"
+"\n"
+"    git push %s HEAD:<nom-de-la-branche-amont>\n"
 
-#: builtin/push.c:128
+#: builtin/push.c:133
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -7179,21 +7907,30 @@
 "\n"
 "    git push --set-upstream %s %s\n"
 msgstr ""
+"La branche courante %s n'a pas de branche amont.\n"
+"Pour pousser la branche courante et définir la distante comme amont, "
+"utilisez\n"
+"\n"
+"    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:136
+#: builtin/push.c:141
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr ""
+"La branche courante %s a de multiples branches amont, impossible de pousser."
 
-#: builtin/push.c:139
+#: builtin/push.c:144
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
 "your current branch '%s', without telling me what to push\n"
 "to update which remote branch."
 msgstr ""
+"Vous êtes en train de pousser vers la branche distante '%s', qui n'est\n"
+"pas une branche amont de votre branche courante '%s', sans me dire\n"
+"quoi pousser pour mettre à jour quelle branche amont."
 
-#: builtin/push.c:151
+#: builtin/push.c:167
 msgid ""
 "push.default is unset; its implicit value is changing in\n"
 "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -7210,72 +7947,128 @@
 "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n"
 "'current' instead of 'simple' if you sometimes use older versions of Git)"
 msgstr ""
+"push.default n'est pas défini ; sa valeur implicite change dans Git 2.0\n"
+"de 'matching' vers 'simple'. Pour supprimer ce message et maintenir\n"
+"le comportement actuel après les changements par défaut, utilisez :\n"
+"\n"
+"  git config --global push.default matching\n"
+"\n"
+"Pour supprimer ce message et adopter le nouveau comportement maintenant, "
+"utilisez :\n"
+"\n"
+"  git config --global push.default simple\n"
+"\n"
+"Voir 'git help config' et chercher 'push.default' pour plus d'information.\n"
+"(le mode 'simple' a été introduit dans Git 1.7.11. Utilisez le mode "
+"similaire\n"
+"'current' au lieu de 'simple' si vous utilisez de temps en temps d'anciennes "
+"versions de Git)"
 
-#: builtin/push.c:199
+#: builtin/push.c:227
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
+"Vous n'avez pas spécifié de spécifications de référence à pousser, et push."
+"default est \"nothing\"."
 
-#: builtin/push.c:206
+#: builtin/push.c:234
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
-"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
-"before pushing again.\n"
+"its remote counterpart. Integrate the remote changes (e.g.\n"
+"'git pull ...') before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
+"Les mises à jour ont été rejetées car la pointe de la branche courante est "
+"derrière\n"
+"son homologue distant. Intégrez les changements distants (par exemple 'git "
+"pull ...')\n"
+"avant de pousser à nouveau.\n"
+"Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus "
+"d'information."
 
-#: builtin/push.c:212
+#: builtin/push.c:240
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. If you did not intend to push that branch, you may want to\n"
 "specify branches to push or set the 'push.default' configuration variable\n"
 "to 'simple', 'current' or 'upstream' to push only the current branch."
 msgstr ""
+"Les mises à jour ont été rejetées car la pointe de la branche poussée est "
+"derrière\n"
+"son homologue distant. Si vous ne vouliez pas pousser cette branche, vous "
+"pourriez\n"
+"vouloir spécifier les branches à pousser ou définir la variable de "
+"configuration\n"
+"'push.default' à 'simple', 'current' ou 'upstream' pour pousser seulement la "
+"branche courante."
 
-#: builtin/push.c:218
+#: builtin/push.c:246
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
-"counterpart. Check out this branch and merge the remote changes\n"
-"(e.g. 'git pull') before pushing again.\n"
+"counterpart. Check out this branch and integrate the remote changes\n"
+"(e.g. 'git pull ...') before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
+"Les mises à jour ont été rejetées car la pointe de la branche courante est "
+"derrière\n"
+"son homologue distant. Extrayez cette branche et Intégrez les changements "
+"distants\n"
+"(par exemple 'git pull ...') avant de pousser à nouveau.\n"
+"Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus "
+"d'information."
 
-#: builtin/push.c:224
+#: builtin/push.c:252
 msgid ""
 "Updates were rejected because the remote contains work that you do\n"
 "not have locally. This is usually caused by another repository pushing\n"
-"to the same ref. You may want to first merge the remote changes (e.g.,\n"
-"'git pull') before pushing again.\n"
+"to the same ref. You may want to first integrate the remote changes\n"
+"(e.g., 'git pull ...') before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
+"Les mises à jour ont été rejetées car la branche distante contient du "
+"travail que\n"
+"vous n'avez pas en local. Ceci est généralement causé par un autre dépôt "
+"poussé\n"
+"vers la même référence. Vous pourriez intégrer d'abord les changements "
+"distants\n"
+"(par exemple 'git pull ...') avant de pousser à nouveau.\n"
+"Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus "
+"d'information."
 
-#: builtin/push.c:231
+#: builtin/push.c:259
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
+"Les mises à jour ont été rejetées car l'étiquette existe déjà dans la "
+"branche distante."
 
-#: builtin/push.c:234
+#: builtin/push.c:262
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
 "without using the '--force' option.\n"
 msgstr ""
+"Vous ne pouvez pas mettre à jour une référence distante qui pointe sur un "
+"objet qui\n"
+"n'est pas un commit, ou mettre à jour une référence distante pour la faire "
+"pointer\n"
+"vers un objet qui n'est pas un commit, sans utiliser l'option '--force'.\n"
 
-#: builtin/push.c:294
+#: builtin/push.c:328
 #, c-format
 msgid "Pushing to %s\n"
-msgstr ""
-
-#: builtin/push.c:298
-#, c-format
-msgid "failed to push some refs to '%s'"
-msgstr ""
-
-#: builtin/push.c:331
-#, c-format
-msgid "bad repository '%s'"
-msgstr ""
+msgstr "Poussage vers %s\n"
 
 #: builtin/push.c:332
+#, c-format
+msgid "failed to push some refs to '%s'"
+msgstr "impossible de pousser des références vers '%s'"
+
+#: builtin/push.c:365
+#, c-format
+msgid "bad repository '%s'"
+msgstr "mauvais dépôt '%s'"
+
+#: builtin/push.c:366
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -7287,90 +8080,108 @@
 "\n"
 "    git push <name>\n"
 msgstr ""
+"Pas de destination pour pousser.\n"
+"Spécifiez une URL depuis la ligne de commande ou configurez un dépôt distant "
+"en utilisant\n"
+"\n"
+"    git remote add <nom> <url>\n"
+"\n"
+"et poussez alors en utilisant le dépôt distant\n"
+"\n"
+"    git push <nom>\n"
 
-#: builtin/push.c:347
+#: builtin/push.c:381
 msgid "--all and --tags are incompatible"
-msgstr ""
+msgstr "--all et --tags sont incompatibles"
 
-#: builtin/push.c:348
+#: builtin/push.c:382
 msgid "--all can't be combined with refspecs"
-msgstr ""
+msgstr "--all ne peut pas être combiné avec des spécifications de référence"
 
-#: builtin/push.c:353
+#: builtin/push.c:387
 msgid "--mirror and --tags are incompatible"
-msgstr ""
+msgstr "--mirror et --tags sont incompatibles"
 
-#: builtin/push.c:354
+#: builtin/push.c:388
 msgid "--mirror can't be combined with refspecs"
-msgstr ""
+msgstr "--mirror ne peut pas être combiné avec des spécifications de référence"
 
-#: builtin/push.c:359
+#: builtin/push.c:393
 msgid "--all and --mirror are incompatible"
-msgstr ""
+msgstr "--all et --mirror sont incompatibles"
 
-#: builtin/push.c:419
+#: builtin/push.c:453
 msgid "repository"
-msgstr ""
+msgstr "dépôt"
 
-#: builtin/push.c:420
+#: builtin/push.c:454
 msgid "push all refs"
-msgstr ""
+msgstr "pousser toutes les références"
 
-#: builtin/push.c:421
+#: builtin/push.c:455
 msgid "mirror all refs"
-msgstr ""
+msgstr "refléter toutes les références"
 
-#: builtin/push.c:423
+#: builtin/push.c:457
 msgid "delete refs"
-msgstr ""
+msgstr "supprimer les références"
 
-#: builtin/push.c:424
+#: builtin/push.c:458
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr ""
+"pousser les étiquettes (ne peut pas être utilisé avec --all ou --mirror)"
 
-#: builtin/push.c:427
+#: builtin/push.c:461
 msgid "force updates"
-msgstr ""
+msgstr "forcer les mises à jour"
 
-#: builtin/push.c:428
+#: builtin/push.c:463
+msgid "refname>:<expect"
+msgstr "nom de référence>:<attendu"
+
+#: builtin/push.c:464
+msgid "require old value of ref to be at this value"
+msgstr "exiger que l'ancienne valeur de la référence soit à cette valeur"
+
+#: builtin/push.c:466
 msgid "check"
-msgstr ""
+msgstr "check"
 
-#: builtin/push.c:429
+#: builtin/push.c:467
 msgid "control recursive pushing of submodules"
-msgstr ""
+msgstr "contrôler le poussage récursif des sous-modules"
 
-#: builtin/push.c:431
+#: builtin/push.c:469
 msgid "use thin pack"
-msgstr ""
+msgstr "utiliser un empaquetage léger"
 
-#: builtin/push.c:432 builtin/push.c:433
+#: builtin/push.c:470 builtin/push.c:471
 msgid "receive pack program"
-msgstr ""
+msgstr "recevoir le programme d'empaquetage"
 
-#: builtin/push.c:434
+#: builtin/push.c:472
 msgid "set upstream for git pull/status"
-msgstr ""
+msgstr "définir la branche amont pour git pull/status"
 
-#: builtin/push.c:437
+#: builtin/push.c:475
 msgid "prune locally removed refs"
-msgstr ""
+msgstr "éliminer les références locales supprimées"
 
-#: builtin/push.c:439
+#: builtin/push.c:477
 msgid "bypass pre-push hook"
-msgstr ""
+msgstr "éviter d'utiliser le crochet pre-push"
 
-#: builtin/push.c:440
+#: builtin/push.c:478
 msgid "push missing but relevant tags"
-msgstr ""
+msgstr "pousser les étiquettes manquantes mais pertinentes"
 
-#: builtin/push.c:450
+#: builtin/push.c:488
 msgid "--delete is incompatible with --all, --mirror and --tags"
-msgstr ""
+msgstr "--delete est incompatible avec --all, --mirror et --tags"
 
-#: builtin/push.c:452
+#: builtin/push.c:490
 msgid "--delete doesn't make sense without any refs"
-msgstr ""
+msgstr "--delete n'a pas de sens sans aucune référence"
 
 #: builtin/read-tree.c:36
 msgid ""
@@ -7378,70 +8189,84 @@
 "[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
 "index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
 msgstr ""
+"git read-tree [[-m [--trivial] [--aggressive] | --reset | --"
+"prefix=<préfixe>] [-u [--exclude-per-directory=<gitignore>] | -i]] [--no-"
+"sparse-checkout] [--index-output=<fichier>] (--empty | <arbre ou apparenté "
+"1> [<arbre ou apparenté 2> [<arbre ou apparenté 3>]])"
 
-#: builtin/read-tree.c:108
+#: builtin/read-tree.c:109
 msgid "write resulting index to <file>"
-msgstr ""
+msgstr "écrire l'index résultant dans <fichier>"
 
-#: builtin/read-tree.c:111
+#: builtin/read-tree.c:112
 msgid "only empty the index"
-msgstr ""
+msgstr "juste vider l'index"
 
-#: builtin/read-tree.c:113
+#: builtin/read-tree.c:114
 msgid "Merging"
-msgstr ""
+msgstr "Fusion"
 
-#: builtin/read-tree.c:115
+#: builtin/read-tree.c:116
 msgid "perform a merge in addition to a read"
-msgstr ""
+msgstr "effectuer une fusion en plus d'une lecture"
 
-#: builtin/read-tree.c:117
+#: builtin/read-tree.c:118
 msgid "3-way merge if no file level merging required"
-msgstr ""
+msgstr "fusion à 3 points si aucune fusion de niveau fichier n'est requise"
 
-#: builtin/read-tree.c:119
+#: builtin/read-tree.c:120
 msgid "3-way merge in presence of adds and removes"
-msgstr ""
-
-#: builtin/read-tree.c:121
-msgid "same as -m, but discard unmerged entries"
-msgstr ""
+msgstr "fusion à 3 points en présence d'ajouts et suppressions"
 
 #: builtin/read-tree.c:122
-msgid "<subdirectory>/"
-msgstr ""
+msgid "same as -m, but discard unmerged entries"
+msgstr "comme -m, mais annule les éléments non fusionnés"
 
 #: builtin/read-tree.c:123
+msgid "<subdirectory>/"
+msgstr "<sous-répertoire>/"
+
+#: builtin/read-tree.c:124
 msgid "read the tree into the index under <subdirectory>/"
-msgstr ""
+msgstr "lire l'arbre dans l'index dans <sous-répertoire>/"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:127
 msgid "update working tree with merge result"
-msgstr ""
-
-#: builtin/read-tree.c:128
-msgid "gitignore"
-msgstr ""
+msgstr "mettre à jour la copie de travail avec le résultat de la fusion"
 
 #: builtin/read-tree.c:129
-msgid "allow explicitly ignored files to be overwritten"
-msgstr ""
+msgid "gitignore"
+msgstr "gitignore"
 
-#: builtin/read-tree.c:132
-msgid "don't check the working tree after merging"
-msgstr ""
+#: builtin/read-tree.c:130
+msgid "allow explicitly ignored files to be overwritten"
+msgstr "autoriser explicitement les fichiers ignorés à être écrasés"
 
 #: builtin/read-tree.c:133
+msgid "don't check the working tree after merging"
+msgstr "ne pas vérifier la copie de travail après la fusion"
+
+#: builtin/read-tree.c:134
 msgid "don't update the index or the work tree"
-msgstr ""
+msgstr "ne pas mettre à jour l'index ou la copie de travail"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:136
 msgid "skip applying sparse checkout filter"
-msgstr ""
+msgstr "sauter l'application du filtre d'extraction creuse"
 
-#: builtin/read-tree.c:137
+#: builtin/read-tree.c:138
 msgid "debug unpack-trees"
-msgstr ""
+msgstr "déboguer unpack-trees"
+
+#: builtin/reflog.c:499
+#, c-format
+msgid "%s' for '%s' is not a valid timestamp"
+msgstr "%s' pour '%s' n'est pas un horodatage valide"
+
+#: builtin/reflog.c:615 builtin/reflog.c:620
+#, c-format
+msgid "'%s' is not a valid timestamp"
+msgstr "'%s' n'est pas un horodatage valide"
 
 #: builtin/remote.c:11
 msgid "git remote [-v | --verbose]"
@@ -7451,7 +8276,9 @@
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
-msgstr "git remote add [-t <branche>] [-m <maîtresse>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <nom> <URL>"
+msgstr ""
+"git remote add [-t <branche>] [-m <maîtresse>] [-f] [--tags|--no-tags] [--"
+"mirror=<fetch|push>] <nom> <URL>"
 
 #: builtin/remote.c:13 builtin/remote.c:32
 msgid "git remote rename <old> <new>"
@@ -7461,9 +8288,9 @@
 msgid "git remote remove <name>"
 msgstr "git remote remove <nom>"
 
-#: builtin/remote.c:15 builtin/remote.c:42
-msgid "git remote set-head <name> (-a | -d | <branch>)"
-msgstr "git remote set-head <nom> (-a | -d | <branche>)"
+#: builtin/remote.c:15
+msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"
+msgstr "git remote set-head <nom> (-a | --auto | -d | --delete |<branche>)"
 
 #: builtin/remote.c:16
 msgid "git remote [-v | --verbose] show [-n] <name>"
@@ -7476,7 +8303,9 @@
 #: builtin/remote.c:18
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
-msgstr "git remote [-v | --verbose] update [-p | --prune] [(<groupe> | <distante>)...]"
+msgstr ""
+"git remote [-v | --verbose] update [-p | --prune] [(<groupe> | "
+"<distante>)...]"
 
 #: builtin/remote.c:19
 msgid "git remote set-branches [--add] <name> <branch>..."
@@ -7498,6 +8327,10 @@
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<options>] <nom> <URL>"
 
+#: builtin/remote.c:42
+msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
+msgstr "git remote set-head <nom> (-a | --auto | -d | --delete | <branche>)"
+
 #: builtin/remote.c:47
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <nom> <branche>..."
@@ -7542,7 +8375,8 @@
 
 #: builtin/remote.c:165
 msgid "import all tags and associated objects when fetching"
-msgstr "importer toutes les étiquettes et les objets associés lors du rapatriement"
+msgstr ""
+"importer toutes les étiquettes et les objets associés lors du rapatriement"
 
 #: builtin/remote.c:168
 msgid "or do not fetch any tag at all (--no-tags)"
@@ -7562,7 +8396,8 @@
 
 #: builtin/remote.c:173
 msgid "set up remote as a mirror to push to or fetch from"
-msgstr "paramétrer la distante comme miroir pour pousser ou pour rapatrier depuis"
+msgstr ""
+"paramétrer la distante comme miroir pour pousser ou pour rapatrier depuis"
 
 #: builtin/remote.c:185
 msgid "specifying a master branch makes no sense with --mirror"
@@ -7570,7 +8405,9 @@
 
 #: builtin/remote.c:187
 msgid "specifying branches to track makes sense only with fetch mirrors"
-msgstr "spécifier les branches à suivre n'a de sens qu'avec des miroirs de rapatriement"
+msgstr ""
+"spécifier les branches à suivre n'a de sens qu'avec des miroirs de "
+"rapatriement"
 
 #: builtin/remote.c:195 builtin/remote.c:646
 #, c-format
@@ -7596,6 +8433,8 @@
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr ""
+"Impossible d'obtenir une correspondance distante pour la spécification de "
+"référence %s"
 
 #: builtin/remote.c:440 builtin/remote.c:448
 msgid "(matching)"
@@ -7634,7 +8473,7 @@
 msgstr ""
 "Pas de mise à jour du refspec de rapatriement qui n'est pas par défaut\n"
 "\t%s\n"
-"\tMerci de mettre à jour la configuration si nécessaire."
+"\tVeuillez mettre à jour la configuration manuellement si nécessaire."
 
 #: builtin/remote.c:683
 #, c-format
@@ -7672,7 +8511,8 @@
 "Note : Une branche en dehors de refs/remotes/ n'a pas été supprimée ;\n"
 "pour la supprimer, utilisez :"
 msgstr[1] ""
-"Note : Plusieurs branches en dehors de refs/remotes/ n'ont pas été supprimées ;\n"
+"Note : Plusieurs branches en dehors de refs/remotes/ n'ont pas été "
+"supprimées ;\n"
 "pour les supprimer, utilisez :"
 
 #: builtin/remote.c:943
@@ -7792,7 +8632,9 @@
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
-msgstr "  Branche HEAD (la HEAD distante est ambiguë, peut être l'une des suivantes) :\n"
+msgstr ""
+"  Branche HEAD (la HEAD distante est ambiguë, peut être l'une des "
+"suivantes) :\n"
 
 #: builtin/remote.c:1151
 #, c-format
@@ -7836,7 +8678,9 @@
 
 #: builtin/remote.c:1218
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
-msgstr "Il y a de multiples branches HEAD distantes. Merci d'en choisir une explicitement avec :"
+msgstr ""
+"Il y a de multiples branches HEAD distantes. Veuillez en choisir une "
+"explicitement avec :"
 
 #: builtin/remote.c:1228
 #, c-format
@@ -7866,7 +8710,7 @@
 #: builtin/remote.c:1281
 #, c-format
 msgid "Pruning %s"
-msgstr "Élagage de %s"
+msgstr "Élimination de %s"
 
 #: builtin/remote.c:1282
 #, c-format
@@ -7876,16 +8720,16 @@
 #: builtin/remote.c:1295
 #, c-format
 msgid " * [would prune] %s"
-msgstr " * [serait élagué] %s"
+msgstr " * [serait éliminé] %s"
 
 #: builtin/remote.c:1298
 #, c-format
 msgid " * [pruned] %s"
-msgstr " * [élagué] %s"
+msgstr " * [éliminé] %s"
 
 #: builtin/remote.c:1321
 msgid "prune remotes after fetching"
-msgstr "élaguer les distants après le rapatriement"
+msgstr "éliminer les distants après le rapatriement"
 
 #: builtin/remote.c:1387 builtin/remote.c:1461
 #, c-format
@@ -7928,12 +8772,73 @@
 
 #: builtin/remote.c:1497
 msgid "Will not delete all non-push URLs"
-msgstr ""
+msgstr "Pas de suppression de toutes les URLs non-push"
 
 #: builtin/remote.c:1569
 msgid "be verbose; must be placed before a subcommand"
 msgstr "être verbeux : doit être placé avant une sous-commande"
 
+#: builtin/repack.c:15
+msgid "git repack [options]"
+msgstr "git repack [options]"
+
+#: builtin/repack.c:143
+msgid "pack everything in a single pack"
+msgstr "empaqueter tout dans un seul paquet"
+
+#: builtin/repack.c:145
+msgid "same as -a, and turn unreachable objects loose"
+msgstr "identique à -a et transformer les objets inaccessibles en suspens"
+
+#: builtin/repack.c:148
+msgid "remove redundant packs, and run git-prune-packed"
+msgstr "supprimer les paquets redondants et lancer git-prune-packed"
+
+#: builtin/repack.c:150
+msgid "pass --no-reuse-delta to git-pack-objects"
+msgstr "passer --no-reuse-delta à git-pack-objects"
+
+#: builtin/repack.c:152
+msgid "pass --no-reuse-object to git-pack-objects"
+msgstr "passer --no-reuse-object à git-pack-objects"
+
+#: builtin/repack.c:154
+msgid "do not run git-update-server-info"
+msgstr "ne pas lancer git update-server-info"
+
+#: builtin/repack.c:157
+msgid "pass --local to git-pack-objects"
+msgstr "passer --local à git-pack-objects"
+
+#: builtin/repack.c:158
+msgid "approxidate"
+msgstr "date approximative"
+
+#: builtin/repack.c:159
+msgid "with -A, do not loosen objects older than this"
+msgstr "avec -A, ne pas suspendre les objets plus vieux que celui-ci"
+
+#: builtin/repack.c:161
+msgid "size of the window used for delta compression"
+msgstr "taille de la fenêtre utilisée pour la compression des deltas"
+
+#: builtin/repack.c:163
+msgid "same as the above, but limit memory size instead of entries count"
+msgstr "idem ci-dessus, mais limiter la taille mémoire au lieu du nombre d'éléments"
+
+#: builtin/repack.c:165
+msgid "limits the maximum delta depth"
+msgstr "limite la profondeur maximale des deltas"
+
+#: builtin/repack.c:167
+msgid "maximum size of each packfile"
+msgstr "taille maximum de chaque fichier paquet"
+
+#: builtin/repack.c:345
+#, c-format
+msgid "removing '%s' failed"
+msgstr "la suppression de '%s' a échoué"
+
 #: builtin/replace.c:17
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <objet> <remplacement>"
@@ -7946,38 +8851,39 @@
 msgid "git replace -l [<pattern>]"
 msgstr "git replace -l [<motif>]"
 
-#: builtin/replace.c:121
+#: builtin/replace.c:131
 msgid "list replace refs"
 msgstr "afficher les références de remplacement"
 
-#: builtin/replace.c:122
+#: builtin/replace.c:132
 msgid "delete replace refs"
 msgstr "supprimer les références de remplacement"
 
-#: builtin/replace.c:123
+#: builtin/replace.c:133
 msgid "replace the ref if it exists"
 msgstr "remplacer la référence si elle existe"
 
-#: builtin/rerere.c:11
+#: builtin/rerere.c:12
 msgid "git rerere [clear | forget path... | status | remaining | diff | gc]"
 msgstr "git rerere [clear | forget chemin... | status | remaining | diff | gc]"
 
-#: builtin/rerere.c:56
+#: builtin/rerere.c:57
 msgid "register clean resolutions in index"
 msgstr "enregistrer des résolutions propres dans l'index"
 
 #: builtin/reset.c:25
 msgid ""
 "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
-msgstr "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
+msgstr ""
+"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
 
 #: builtin/reset.c:26
 msgid "git reset [-q] <tree-ish> [--] <paths>..."
-msgstr "git reset [-q] <arbre> [--] <chemins>..."
+msgstr "git reset [-q] <arbre ou apparenté> [--] <chemins>..."
 
 #: builtin/reset.c:27
 msgid "git reset --patch [<tree-ish>] [--] [<paths>...]"
-msgstr "git reset --patch [<arbre>] [--] [<chemins>...]"
+msgstr "git reset --patch [<arbre ou apparenté>] [--] [<chemins>...]"
 
 #: builtin/reset.c:33
 msgid "mixed"
@@ -8012,95 +8918,97 @@
 msgid "Failed to find tree of %s."
 msgstr "Impossible de trouver l'arbre pour %s."
 
-#: builtin/reset.c:98
+#: builtin/reset.c:99
 #, c-format
 msgid "HEAD is now at %s"
 msgstr "HEAD est maintenant à %s"
 
-#: builtin/reset.c:169
+#: builtin/reset.c:172
 #, c-format
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr "Impossible de faire un \"reset %s\" au milieu d'une fusion."
 
-#: builtin/reset.c:248
+#: builtin/reset.c:262
 msgid "be quiet, only report errors"
 msgstr "être silencieux, afficher seulement les erreurs"
 
-#: builtin/reset.c:250
+#: builtin/reset.c:264
 msgid "reset HEAD and index"
 msgstr "réinitialiser HEAD et l'index"
 
-#: builtin/reset.c:251
+#: builtin/reset.c:265
 msgid "reset only HEAD"
 msgstr "réinitialiser seulement HEAD"
 
-#: builtin/reset.c:253 builtin/reset.c:255
+#: builtin/reset.c:267 builtin/reset.c:269
 msgid "reset HEAD, index and working tree"
 msgstr "réinitialiser HEAD, l'index et la copie de travail"
 
-#: builtin/reset.c:257
+#: builtin/reset.c:271
 msgid "reset HEAD but keep local changes"
 msgstr "réinitialiser HEAD mais garder les changements locaux"
 
-#: builtin/reset.c:275
+#: builtin/reset.c:289
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
 msgstr "Échec de résolution de '%s' comme une révision valide."
 
-#: builtin/reset.c:278 builtin/reset.c:286
+#: builtin/reset.c:292 builtin/reset.c:300
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "Impossible d'analyser l'objet '%s'."
 
-#: builtin/reset.c:283
+#: builtin/reset.c:297
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
 msgstr "Échec de résolution de '%s' comme un arbre valide."
 
-#: builtin/reset.c:292
+#: builtin/reset.c:306
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch est incompatible avec --{hard,mixed,soft}"
 
-#: builtin/reset.c:301
+#: builtin/reset.c:315
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
-msgstr "--mixed avec des chemins est obsolète ; utilisez 'git reset -- <paths>' à la place."
+msgstr ""
+"--mixed avec des chemins est obsolète ; utilisez 'git reset -- <paths>' à la "
+"place."
 
-#: builtin/reset.c:303
+#: builtin/reset.c:317
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "Impossible de faire un \"%s reset\" avec des chemins."
 
-#: builtin/reset.c:313
+#: builtin/reset.c:327
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr "Le \"%s reset\" n'est pas permis dans un dépôt nu"
 
-#: builtin/reset.c:333
+#: builtin/reset.c:344
+msgid "Unstaged changes after reset:"
+msgstr "Modifications non indexées après reset :"
+
+#: builtin/reset.c:350
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "Impossible de réinitialiser le fichier d'index à la révision '%s'."
 
-#: builtin/reset.c:339
-msgid "Unstaged changes after reset:"
-msgstr "Modifications non indexées après reset :"
-
-#: builtin/reset.c:344
+#: builtin/reset.c:355
 msgid "Could not write new index file."
 msgstr "Impossible d'écrire le nouveau fichier d'index."
 
-#: builtin/rev-parse.c:339
+#: builtin/rev-parse.c:345
 msgid "git rev-parse --parseopt [options] -- [<args>...]"
 msgstr "git rev-parse --parseopt [options] -- [<arguments>...]"
 
-#: builtin/rev-parse.c:344
+#: builtin/rev-parse.c:350
 msgid "keep the `--` passed as an arg"
 msgstr "garder le `--` passé en argument"
 
-#: builtin/rev-parse.c:346
+#: builtin/rev-parse.c:352
 msgid "stop parsing after the first non-option argument"
 msgstr "arrêt de l'analyse après le premier argument qui n'est pas une option"
 
-#: builtin/rev-parse.c:464
+#: builtin/rev-parse.c:470
 msgid ""
 "git rev-parse --parseopt [options] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -8112,11 +9020,12 @@
 "   ou : git rev-parse --sq-quote [<argument>...]\n"
 "   ou : git rev-parse [options] [<argument>...]\n"
 "\n"
-"Lancez \"git rev-parse --parseopt -h\" pour plus d'information sur l'utilisation principale."
+"Lancez \"git rev-parse --parseopt -h\" pour plus d'information sur "
+"l'utilisation principale."
 
 #: builtin/revert.c:22
 msgid "git revert [options] <commit-ish>..."
-msgstr "git revert [options] <commit>..."
+msgstr "git revert [options] <commit ou apparenté>..."
 
 #: builtin/revert.c:23
 msgid "git revert <subcommand>"
@@ -8124,151 +9033,180 @@
 
 #: builtin/revert.c:28
 msgid "git cherry-pick [options] <commit-ish>..."
-msgstr "git cherry-pick [options] <commit>..."
+msgstr "git cherry-pick [options] <commit ou apparenté>..."
 
 #: builtin/revert.c:29
 msgid "git cherry-pick <subcommand>"
 msgstr "git cherry-pick <sous-commande>"
 
-#: builtin/revert.c:70 builtin/revert.c:92
+#: builtin/revert.c:71
 #, c-format
 msgid "%s: %s cannot be used with %s"
 msgstr "%s : %s ne peut pas être utilisé avec %s"
 
-#: builtin/revert.c:103
+#: builtin/revert.c:80
 msgid "end revert or cherry-pick sequence"
 msgstr "mettre fin au retour ou picorage"
 
-#: builtin/revert.c:104
+#: builtin/revert.c:81
 msgid "resume revert or cherry-pick sequence"
 msgstr "reprendre le retour ou picorage"
 
-#: builtin/revert.c:105
+#: builtin/revert.c:82
 msgid "cancel revert or cherry-pick sequence"
 msgstr "annuler le retour ou picorage"
 
-#: builtin/revert.c:106
+#: builtin/revert.c:83
 msgid "don't automatically commit"
 msgstr "ne pas valider automatiquement"
 
-#: builtin/revert.c:107
+#: builtin/revert.c:84
 msgid "edit the commit message"
 msgstr "éditer le message de validation"
 
-#: builtin/revert.c:110
+#: builtin/revert.c:87
 msgid "parent number"
 msgstr "numéro de parent"
 
-#: builtin/revert.c:112
+#: builtin/revert.c:89
 msgid "merge strategy"
 msgstr "stratégie de fusion"
 
-#: builtin/revert.c:113
+#: builtin/revert.c:90
 msgid "option"
 msgstr "option"
 
-#: builtin/revert.c:114
+#: builtin/revert.c:91
 msgid "option for merge strategy"
 msgstr "option pour la stratégie de fusion"
 
-#: builtin/revert.c:125
+#: builtin/revert.c:102
 msgid "append commit name"
 msgstr "ajouter le nom de validation"
 
-#: builtin/revert.c:126
+#: builtin/revert.c:103
 msgid "allow fast-forward"
 msgstr "autoriser l'avance rapide"
 
-#: builtin/revert.c:127
+#: builtin/revert.c:104
 msgid "preserve initially empty commits"
 msgstr "préserver les validations vides initialement"
 
-#: builtin/revert.c:128
+#: builtin/revert.c:105
 msgid "allow commits with empty messages"
 msgstr "autoriser les validations avec des messages vides"
 
-#: builtin/revert.c:129
+#: builtin/revert.c:106
 msgid "keep redundant, empty commits"
 msgstr "garder les validations redondantes, vides"
 
-#: builtin/revert.c:133
+#: builtin/revert.c:110
 msgid "program error"
 msgstr "erreur du programme"
 
-#: builtin/revert.c:223
+#: builtin/revert.c:195
 msgid "revert failed"
 msgstr "revert a échoué"
 
-#: builtin/revert.c:238
+#: builtin/revert.c:210
 msgid "cherry-pick failed"
 msgstr "le picorage a échoué"
 
-#: builtin/rm.c:15
+#: builtin/rm.c:17
 msgid "git rm [options] [--] <file>..."
 msgstr "git rm [options] [--] <fichier>..."
 
-#: builtin/rm.c:64 builtin/rm.c:186
-#, c-format
+#: builtin/rm.c:65
 msgid ""
-"submodule '%s' (or one of its nested submodules) uses a .git directory\n"
+"the following submodule (or one of its nested submodules)\n"
+"uses a .git directory:"
+msgid_plural ""
+"the following submodules (or one of its nested submodules)\n"
+"use a .git directory:"
+msgstr[0] ""
+"le sous-module suivant (ou un de ses sous-modules imbriqués)\n"
+"utilise un répertoire .git :"
+msgstr[1] ""
+"les sous-modules suivants (ou un de ses sous-modules imbriqués)\n"
+"utilisent un répertoire .git :"
+
+#: builtin/rm.c:71
+msgid ""
+"\n"
 "(use 'rm -rf' if you really want to remove it including all of its history)"
 msgstr ""
-"le sous-module '%s' (ou un des sous-modules imbriqués) utilise un répertoire .git\n"
-"(utilisez 'rm -rf' si vous souhaitez vraiment le supprimer avec tout son historique)"
+"\n"
+"(utilisez 'rm -rf' si vous voulez vraiment le supprimer en incluant tout son "
+"historique)"
 
-#: builtin/rm.c:174
-#, c-format
+#: builtin/rm.c:231
 msgid ""
-"'%s' has staged content different from both the file and the HEAD\n"
+"the following file has staged content different from both the\n"
+"file and the HEAD:"
+msgid_plural ""
+"the following files have staged content different from both the\n"
+"file and the HEAD:"
+msgstr[0] ""
+"le fichier suivant a du contenu indexé différent\n"
+"du fichier et de HEAD :"
+msgstr[1] ""
+"les fichiers suivants ont du contenu indexé différent\n"
+"du fichier et de HEAD :"
+
+#: builtin/rm.c:236
+msgid ""
+"\n"
 "(use -f to force removal)"
 msgstr ""
-"'%s' a du contenu indexé différent du fichier et de HEAD\n"
+"\n"
 "(utilisez -f pour forcer la suppression)"
 
-#: builtin/rm.c:180
-#, c-format
+#: builtin/rm.c:240
+msgid "the following file has changes staged in the index:"
+msgid_plural "the following files have changes staged in the index:"
+msgstr[0] "le fichier suivant a des changements indexés :"
+msgstr[1] "les fichiers suivants ont des changements indexés :"
+
+#: builtin/rm.c:244 builtin/rm.c:255
 msgid ""
-"'%s' has changes staged in the index\n"
+"\n"
 "(use --cached to keep the file, or -f to force removal)"
 msgstr ""
-"'%s' a des changements dans l'index\n"
+"\n"
 "(utilisez --cached pour garder le fichier, ou -f pour forcer la suppression)"
 
-#: builtin/rm.c:191
-#, c-format
-msgid ""
-"'%s' has local modifications\n"
-"(use --cached to keep the file, or -f to force removal)"
-msgstr ""
-"'%s' a des modifications locales\n"
-"(utilisez --cached pour garder le fichier, ou -f pour forcer la suppression)"
+#: builtin/rm.c:252
+msgid "the following file has local modifications:"
+msgid_plural "the following files have local modifications:"
+msgstr[0] "le fichier suivant a des modifications locales :"
+msgstr[1] "les fichiers suivants ont des modifications locales :"
 
-#: builtin/rm.c:207
+#: builtin/rm.c:270
 msgid "do not list removed files"
 msgstr "ne pas afficher les fichiers supprimés"
 
-#: builtin/rm.c:208
+#: builtin/rm.c:271
 msgid "only remove from the index"
 msgstr "supprimer seulement de l'index"
 
-#: builtin/rm.c:209
+#: builtin/rm.c:272
 msgid "override the up-to-date check"
 msgstr "outrepasser la vérification des fichiers à jour"
 
-#: builtin/rm.c:210
+#: builtin/rm.c:273
 msgid "allow recursive removal"
 msgstr "autoriser la suppression récursive"
 
-#: builtin/rm.c:212
+#: builtin/rm.c:275
 msgid "exit with a zero status even if nothing matched"
 msgstr "sortir avec un statut zéro même si rien ne correspondait"
 
-#: builtin/rm.c:283
+#: builtin/rm.c:336
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "pas de suppression récursive de '%s' sans -r"
 
-#: builtin/rm.c:322
+#: builtin/rm.c:375
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm : impossible de supprimer %s"
@@ -8282,23 +9220,25 @@
 msgid "Missing author: %s"
 msgstr "Auteur manquant : %s"
 
-#: builtin/shortlog.c:227
+#: builtin/shortlog.c:230
 msgid "sort output according to the number of commits per author"
 msgstr "trier la sortie sur le nombre de validations par auteur"
 
-#: builtin/shortlog.c:229
+#: builtin/shortlog.c:232
 msgid "Suppress commit descriptions, only provides commit count"
-msgstr "Supprimer les descriptions de validation, fournit seulement le nombre de validations"
+msgstr ""
+"Supprimer les descriptions de validation, fournit seulement le nombre de "
+"validations"
 
-#: builtin/shortlog.c:231
+#: builtin/shortlog.c:234
 msgid "Show the email address of each author"
 msgstr "Afficher l'adresse e-mail de chaque auteur"
 
-#: builtin/shortlog.c:232
+#: builtin/shortlog.c:235
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:233
+#: builtin/shortlog.c:236
 msgid "Linewrap output"
 msgstr "Couper les lignes"
 
@@ -8308,7 +9248,11 @@
 "current] [--color[=<when>] | --no-color] [--sparse] [--more=<n> | --list | --"
 "independent | --merge-base] [--no-name | --sha1-name] [--topics] [(<rev> | "
 "<glob>)...]"
-msgstr "git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--current] [--color[=<quand>] | --no-color] [--sparse] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] [--topics] [(<révision> | <glob>)...]"
+msgstr ""
+"git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--"
+"current] [--color[=<quand>] | --no-color] [--sparse] [--more=<n> | --list | "
+"--independent | --merge-base] [--no-name | --sha1-name] [--topics] "
+"[(<révision> | <glob>)...]"
 
 #: builtin/show-branch.c:10
 msgid "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]"
@@ -8336,7 +9280,7 @@
 
 #: builtin/show-branch.c:659
 msgid "suppress naming strings"
-msgstr ""
+msgstr "supprimer les chaînes de nommage"
 
 #: builtin/show-branch.c:661
 msgid "include the current branch"
@@ -8352,73 +9296,82 @@
 
 #: builtin/show-branch.c:667
 msgid "show refs unreachable from any other ref"
-msgstr "afficher les références non accessibles depuis toute autre référence"
+msgstr "afficher les références inaccessibles depuis toute autre référence"
 
 #: builtin/show-branch.c:669
 msgid "show commits in topological order"
 msgstr "afficher les validations dans l'ordre topologique"
 
-#: builtin/show-branch.c:671
+#: builtin/show-branch.c:672
 msgid "show only commits not on the first branch"
-msgstr "afficher seulement les validations qui ne sont pas sur la première branche"
+msgstr ""
+"afficher seulement les validations qui ne sont pas sur la première branche"
 
-#: builtin/show-branch.c:673
+#: builtin/show-branch.c:674
 msgid "show merges reachable from only one tip"
 msgstr "afficher les fusions accessibles depuis une seule pointe"
 
-#: builtin/show-branch.c:675
-msgid "show commits where no parent comes before its children"
-msgstr "afficher les validations où aucun parent ne vient avant ses enfants"
+#: builtin/show-branch.c:676
+msgid "topologically sort, maintaining date order where possible"
+msgstr "tri topologique, maintenant l'ordre par date si possible"
 
-#: builtin/show-branch.c:677
+#: builtin/show-branch.c:679
 msgid "<n>[,<base>]"
 msgstr "<n>[,<base>]"
 
-#: builtin/show-branch.c:678
+#: builtin/show-branch.c:680
 msgid "show <n> most recent ref-log entries starting at base"
-msgstr "afficher les <n> plus récentes entrées de ref-log en commençant à la base"
+msgstr ""
+"afficher les <n> plus récents éléments de ref-log en commençant à la base"
 
 #: builtin/show-ref.c:10
 msgid ""
 "git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--"
 "hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] "
-msgstr "git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [motif*] "
+msgstr ""
+"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--"
+"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [motif*] "
 
 #: builtin/show-ref.c:11
 msgid "git show-ref --exclude-existing[=pattern] < ref-list"
 msgstr "git show-ref --exclude-existing[=motif] < liste-références"
 
-#: builtin/show-ref.c:165
+#: builtin/show-ref.c:168
 msgid "only show tags (can be combined with heads)"
 msgstr "afficher seulement les étiquettes (peut être combiné avec des têtes)"
 
-#: builtin/show-ref.c:166
+#: builtin/show-ref.c:169
 msgid "only show heads (can be combined with tags)"
 msgstr "afficher seulement les têtes (peut être combiné avec des étiquettes)"
 
-#: builtin/show-ref.c:167
+#: builtin/show-ref.c:170
 msgid "stricter reference checking, requires exact ref path"
-msgstr "vérification de référence plus stricte, requiert un chemin de référence exact"
+msgstr ""
+"vérification de référence plus stricte, nécessite un chemin de référence "
+"exact"
 
-#: builtin/show-ref.c:170 builtin/show-ref.c:172
-msgid "show the HEAD reference"
-msgstr "afficher la référence HEAD"
+#: builtin/show-ref.c:173 builtin/show-ref.c:175
+msgid "show the HEAD reference, even if it would be filtered out"
+msgstr "afficher la référence HEAD, même si elle serait filtrée"
 
-#: builtin/show-ref.c:174
+#: builtin/show-ref.c:177
 msgid "dereference tags into object IDs"
 msgstr "déréférencer les étiquettes en IDs d'objet"
 
-#: builtin/show-ref.c:176
+#: builtin/show-ref.c:179
 msgid "only show SHA1 hash using <n> digits"
 msgstr "afficher seulement le hachage SHA1 en utilisant <n> chiffres"
 
-#: builtin/show-ref.c:180
+#: builtin/show-ref.c:183
 msgid "do not print results to stdout (useful with --verify)"
-msgstr "ne pas afficher les résultats sur la sortie standard (pratique avec --verify)"
+msgstr ""
+"ne pas afficher les résultats sur la sortie standard (pratique avec --verify)"
 
-#: builtin/show-ref.c:182
+#: builtin/show-ref.c:185
 msgid "show refs from stdin that aren't in local repository"
-msgstr "afficher les références de l'entrée standard qui ne sont pas dans le dépôt local"
+msgstr ""
+"afficher les références de l'entrée standard qui ne sont pas dans le dépôt "
+"local"
 
 #: builtin/symbolic-ref.c:7
 msgid "git symbolic-ref [options] name [ref]"
@@ -8430,7 +9383,8 @@
 
 #: builtin/symbolic-ref.c:40
 msgid "suppress error message for non-symbolic (detached) refs"
-msgstr "supprimer le message d'erreur pour une référence non symbolique (détachée)"
+msgstr ""
+"supprimer le message d'erreur pour une référence non symbolique (détachée)"
 
 #: builtin/symbolic-ref.c:41
 msgid "delete symbolic ref"
@@ -8440,18 +9394,20 @@
 msgid "shorten ref output"
 msgstr "raccourcir l'affichage de la référence"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason"
 msgstr "raison"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason of the update"
 msgstr "raison de la mise à jour"
 
 #: builtin/tag.c:22
 msgid ""
 "git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]"
-msgstr "git tag [-a|-s|-u <id-clé>] [-f] [-m <msg>|-F <file>] <nométiquette> [<head>]"
+msgstr ""
+"git tag [-a|-s|-u <id-clé>] [-f] [-m <message>|-F <file>] <nométiquette> "
+"[<head>]"
 
 #: builtin/tag.c:23
 msgid "git tag -d <tagname>..."
@@ -8515,7 +9471,8 @@
 msgstr ""
 "\n"
 "Écrire un message pour l'étiquette\n"
-"Les lignes commençant par '%c' seront gardées ; vous pouvez les retirer vous-même si vous le souhaitez.\n"
+"Les lignes commençant par '%c' seront gardées ; vous pouvez les retirer vous-"
+"même si vous le souhaitez.\n"
 
 #: builtin/tag.c:292
 msgid "unable to sign the tag"
@@ -8544,7 +9501,7 @@
 
 #: builtin/tag.c:423
 msgid "switch 'points-at' requires an object"
-msgstr "le commutateur 'points-at' requiert un objet"
+msgstr "le commutateur 'points-at' a besoin d'un objet"
 
 #: builtin/tag.c:425
 #, c-format
@@ -8607,182 +9564,200 @@
 msgid "print only tags of the object"
 msgstr "afficher seulement les étiquettes de l'objet"
 
-#: builtin/tag.c:504
+#: builtin/tag.c:501
 msgid "--column and -n are incompatible"
 msgstr "--column et -n sont incompatibles"
 
-#: builtin/tag.c:521
+#: builtin/tag.c:518
 msgid "-n option is only allowed with -l."
 msgstr "l'option -n est autorisée seulement avec -l."
 
-#: builtin/tag.c:523
+#: builtin/tag.c:520
 msgid "--contains option is only allowed with -l."
 msgstr "l'option --contains est autorisée seulement avec -l."
 
-#: builtin/tag.c:525
+#: builtin/tag.c:522
 msgid "--points-at option is only allowed with -l."
 msgstr "l'option --points-at est autorisée seulement avec -l."
 
-#: builtin/tag.c:533
+#: builtin/tag.c:530
 msgid "only one -F or -m option is allowed."
 msgstr "une seule option -F ou -m est autorisée."
 
-#: builtin/tag.c:553
+#: builtin/tag.c:550
 msgid "too many params"
 msgstr "trop de paramètres"
 
-#: builtin/tag.c:559
+#: builtin/tag.c:556
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "'%s' n'est pas un nom d'étiquette valide."
 
-#: builtin/tag.c:564
+#: builtin/tag.c:561
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "l'étiquette '%s' existe déjà"
 
-#: builtin/tag.c:582
+#: builtin/tag.c:579
 #, c-format
 msgid "%s: cannot lock the ref"
 msgstr "%s : impossible de verrouiller la référence"
 
-#: builtin/tag.c:584
+#: builtin/tag.c:581
 #, c-format
 msgid "%s: cannot update the ref"
 msgstr "%s : impossible de mettre à jour la référence"
 
-#: builtin/tag.c:586
+#: builtin/tag.c:583
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Étiquette '%s' mise à jour (elle était %s)\n"
 
-#: builtin/update-index.c:401
+#: builtin/update-index.c:402
 msgid "git update-index [options] [--] [<file>...]"
 msgstr "git update-index [options] [--] [<fichier>...]"
 
-#: builtin/update-index.c:718
+#: builtin/update-index.c:720
 msgid "continue refresh even when index needs update"
 msgstr "continuer de rafraîchir même si l'index a besoin d'une mise à jour"
 
-#: builtin/update-index.c:721
+#: builtin/update-index.c:723
 msgid "refresh: ignore submodules"
 msgstr "rafraîchir : ignorer les sous-modules"
 
-#: builtin/update-index.c:724
+#: builtin/update-index.c:726
 msgid "do not ignore new files"
 msgstr "ne pas ignorer les nouveaux fichiers"
 
-#: builtin/update-index.c:726
+#: builtin/update-index.c:728
 msgid "let files replace directories and vice-versa"
 msgstr "laisser les fichiers remplacer des répertoires et vice-versa"
 
-#: builtin/update-index.c:728
+#: builtin/update-index.c:730
 msgid "notice files missing from worktree"
 msgstr "aviser des fichiers manquants dans la copie de travail"
 
-#: builtin/update-index.c:730
+#: builtin/update-index.c:732
 msgid "refresh even if index contains unmerged entries"
-msgstr "rafraîchir même si l'index contient des entrées non fusionnées"
+msgstr "rafraîchir même si l'index contient des éléments non fusionnés"
 
-#: builtin/update-index.c:733
+#: builtin/update-index.c:735
 msgid "refresh stat information"
 msgstr "rafraîchir l'information de stat"
 
-#: builtin/update-index.c:737
+#: builtin/update-index.c:739
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "comme --refresh, mais en ignorant l'option assume-unchanged"
 
-#: builtin/update-index.c:741
+#: builtin/update-index.c:743
 msgid "<mode> <object> <path>"
 msgstr "<mode> <objet> <chemin>"
 
-#: builtin/update-index.c:742
+#: builtin/update-index.c:744
 msgid "add the specified entry to the index"
-msgstr "ajouter l'entrée spécifiée dans l'index"
+msgstr "ajouter l'élément spécifié dans l'index"
 
-#: builtin/update-index.c:746
+#: builtin/update-index.c:748
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/update-index.c:747
+#: builtin/update-index.c:749
 msgid "override the executable bit of the listed files"
 msgstr "outrepasser le bit exécutable pour les fichiers listés"
 
-#: builtin/update-index.c:751
+#: builtin/update-index.c:753
 msgid "mark files as \"not changing\""
 msgstr "marquer les fichiers comme \"non changeants\""
 
-#: builtin/update-index.c:754
+#: builtin/update-index.c:756
 msgid "clear assumed-unchanged bit"
-msgstr ""
+msgstr "mettre à zéro le bit supposé-non-modifié"
 
-#: builtin/update-index.c:757
+#: builtin/update-index.c:759
 msgid "mark files as \"index-only\""
 msgstr "marquer les fichiers comme \"index seulement\""
 
-#: builtin/update-index.c:760
+#: builtin/update-index.c:762
 msgid "clear skip-worktree bit"
-msgstr ""
-
-#: builtin/update-index.c:763
-msgid "add to index only; do not add content to object database"
-msgstr "ajouter seulement à l'index ; ne pas ajouter le contenu dans la base de données des objets"
+msgstr "mettre à zéro le bit sauter-la-copie-de travail"
 
 #: builtin/update-index.c:765
-msgid "remove named paths even if present in worktree"
-msgstr "supprimer les chemins nommés même s'ils sont présents dans la copie de travail"
+msgid "add to index only; do not add content to object database"
+msgstr ""
+"ajouter seulement à l'index ; ne pas ajouter le contenu dans la base de "
+"données des objets"
 
 #: builtin/update-index.c:767
+msgid "remove named paths even if present in worktree"
+msgstr ""
+"supprimer les chemins nommés même s'ils sont présents dans la copie de "
+"travail"
+
+#: builtin/update-index.c:769
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "avec --stdin : les lignes en entrée sont terminées par des octets nuls"
 
-#: builtin/update-index.c:769
+#: builtin/update-index.c:771
 msgid "read list of paths to be updated from standard input"
 msgstr "lire la liste des chemins à mettre à jour depuis l'entrée standard"
 
-#: builtin/update-index.c:773
+#: builtin/update-index.c:775
 msgid "add entries from standard input to the index"
-msgstr "ajouter les entrées depuis l'entrée standard à l'index"
+msgstr "ajouter les éléments depuis l'entrée standard à l'index"
 
-#: builtin/update-index.c:777
+#: builtin/update-index.c:779
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "repeupler les étapes n°2 et n°3 pour les chemins listés"
 
-#: builtin/update-index.c:781
+#: builtin/update-index.c:783
 msgid "only update entries that differ from HEAD"
-msgstr "mettre à jour seulement les entrées qui diffèrent de HEAD"
+msgstr "mettre à jour seulement les éléments qui diffèrent de HEAD"
 
-#: builtin/update-index.c:785
+#: builtin/update-index.c:787
 msgid "ignore files missing from worktree"
 msgstr "ignorer les fichiers manquants dans la copie de travail"
 
-#: builtin/update-index.c:788
+#: builtin/update-index.c:790
 msgid "report actions to standard output"
 msgstr "afficher les actions sur la sortie standard"
 
-#: builtin/update-index.c:790
+#: builtin/update-index.c:792
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(pour porcelaines) oublier les conflits sauvés et non résolus"
 
-#: builtin/update-index.c:794
+#: builtin/update-index.c:796
 msgid "write index in this format"
 msgstr "écrire l'index dans ce format"
 
-#: builtin/update-ref.c:7
+#: builtin/update-ref.c:9
 msgid "git update-ref [options] -d <refname> [<oldval>]"
 msgstr "git update-ref [options] -d <nomréférence> [<anciennevaleur>]"
 
-#: builtin/update-ref.c:8
+#: builtin/update-ref.c:10
 msgid "git update-ref [options]    <refname> <newval> [<oldval>]"
-msgstr "git update-ref [options]    <nomréférence> <nouvellevaleur> [<anciennevaleur>]"
+msgstr ""
+"git update-ref [options]    <nomréférence> <nouvellevaleur> "
+"[<anciennevaleur>]"
 
-#: builtin/update-ref.c:19
+#: builtin/update-ref.c:11
+msgid "git update-ref [options] --stdin [-z]"
+msgstr "git update-ref [options] --stdin [-z]"
+
+#: builtin/update-ref.c:255
 msgid "delete the reference"
 msgstr "supprimer la référence"
 
-#: builtin/update-ref.c:21
+#: builtin/update-ref.c:257
 msgid "update <refname> not the one it points to"
-msgstr ""
+msgstr "mettre à jour <nomréférence> et non la référence pointée par lui"
+
+#: builtin/update-ref.c:258
+msgid "stdin has NUL-terminated arguments"
+msgstr "l'entrée standard a des arguments qui se terminent par NUL"
+
+#: builtin/update-ref.c:259
+msgid "read updates from stdin"
+msgstr "lire les mises à jour depuis l'entrée standard"
 
 #: builtin/update-server-info.c:6
 msgid "git update-server-info [--force]"
@@ -8828,7 +9803,7 @@
 msgid "only useful for debugging"
 msgstr "seulement utile pour le débogage"
 
-#: git.c:16
+#: git.c:17
 msgid ""
 "'git help -a' and 'git help -g' lists available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -8838,29 +9813,33 @@
 "quelques concepts. Voir 'git help <command>' ou 'git help <concept>'\n"
 "pour en lire plus à propos d'une commande spécifique ou d'un concept."
 
-#: parse-options.h:156
+#: parse-options.h:146
+msgid "expiry date"
+msgstr "date d'expiration"
+
+#: parse-options.h:161
 msgid "no-op (backward compatibility)"
 msgstr "sans action (rétrocompatibilité)"
 
-#: parse-options.h:232
+#: parse-options.h:238
 msgid "be more verbose"
 msgstr "être plus verbeux"
 
-#: parse-options.h:234
+#: parse-options.h:240
 msgid "be more quiet"
 msgstr "être plus silencieux"
 
-#: parse-options.h:240
+#: parse-options.h:246
 msgid "use <n> digits to display SHA-1s"
 msgstr "utiliser <n> chiffres pour afficher les SHA-1s"
 
 #: common-cmds.h:8
 msgid "Add file contents to the index"
-msgstr "Ajouter le contenu du fichier dans l'index"
+msgstr "Ajouter le contenu de fichiers dans l'index"
 
 #: common-cmds.h:9
 msgid "Find by binary search the change that introduced a bug"
-msgstr "Rechercher de manière binaire le changement qui a introduit un bogue"
+msgstr "Trouver par recherche binaire la modification qui a introduit un bogue"
 
 #: common-cmds.h:10
 msgid "List, create, or delete branches"
@@ -8876,11 +9855,13 @@
 
 #: common-cmds.h:13
 msgid "Record changes to the repository"
-msgstr "Enregistrer les changements dans le dépôt"
+msgstr "Enregistrer les modifications dans le dépôt"
 
 #: common-cmds.h:14
 msgid "Show changes between commits, commit and working tree, etc"
-msgstr "Afficher les changements entre les validations, entre validation et copie de travail, etc"
+msgstr ""
+"Afficher les changements entre les validations, entre validation et copie de "
+"travail, etc"
 
 #: common-cmds.h:15
 msgid "Download objects and refs from another repository"
@@ -8900,15 +9881,15 @@
 
 #: common-cmds.h:19
 msgid "Join two or more development histories together"
-msgstr "Joindre deux ou plusieurs historiques de développement ensemble"
+msgstr "Fusionner deux ou plusieurs historiques de développement ensemble"
 
 #: common-cmds.h:20
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "Déplacer ou renommer un fichier, un répertoire, ou un lien symbolique"
 
 #: common-cmds.h:21
-msgid "Fetch from and merge with another repository or a local branch"
-msgstr "Rapatrier et fusionner avec un autre dépôt ou une branche locale"
+msgid "Fetch from and integrate with another repository or a local branch"
+msgstr "Rapatrier et intégrer un autre dépôt ou une branche locale"
 
 #: common-cmds.h:22
 msgid "Update remote refs along with associated objects"
@@ -8916,7 +9897,8 @@
 
 #: common-cmds.h:23
 msgid "Forward-port local commits to the updated upstream head"
-msgstr "Reporter en avant les validations locales dans la tête en amont mise à jour"
+msgstr ""
+"Reporter les validations locales sur le sommet mis à jour d'une branche amont"
 
 #: common-cmds.h:24
 msgid "Reset current HEAD to the specified state"
@@ -8924,11 +9906,11 @@
 
 #: common-cmds.h:25
 msgid "Remove files from the working tree and from the index"
-msgstr "Supprimer les fichiers de la copie de travail et de l'index"
+msgstr "Supprimer des fichiers de la copie de travail et de l'index"
 
 #: common-cmds.h:26
 msgid "Show various types of objects"
-msgstr "Afficher différents types d'objects"
+msgstr "Afficher différents types d'objets"
 
 #: common-cmds.h:27
 msgid "Show the working tree status"
@@ -8936,7 +9918,8 @@
 
 #: common-cmds.h:28
 msgid "Create, list, delete or verify a tag object signed with GPG"
-msgstr "Créer, lister, supprimer ou vérifier un objet d'étiquette signé avec GPG"
+msgstr ""
+"Créer, lister, supprimer ou vérifier un objet d'étiquette signé avec GPG"
 
 #: git-am.sh:50
 msgid "You need to set your committer info first"
@@ -8953,25 +9936,29 @@
 #: git-am.sh:105
 #, sh-format
 msgid ""
-"When you have resolved this problem, run \"$cmdline --resolved\".\n"
+"When you have resolved this problem, run \"$cmdline --continue\".\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 ""
-"Lorsque vous aurez résolu ce problème, lancez \"$cmdline --resolved\".\n"
+"Lorsque vous aurez résolu ce problème, lancez \"$cmdline --continue\".\n"
 "Si vous préférez sauter ce patch, lancez \"$cmdline --skip\" à la place.\n"
-"Pour restaurer la branche d'origine et stopper le patchage, lancez \"$cmdline --abort\"."
+"Pour restaurer la branche d'origine et stopper le patchage, lancez "
+"\"$cmdline --abort\"."
 
 #: git-am.sh:121
 msgid "Cannot fall back to three-way merge."
-msgstr "Impossible de retourner à une fusion 3-way."
+msgstr "Impossible de retourner à une fusion à 3 points."
 
 #: git-am.sh:137
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
-msgstr "Le dépôt n'a pas les blobs nécessaires pour un retour à une fusion 3-way."
+msgstr ""
+"Le dépôt n'a pas les blobs nécessaires pour un retour à une fusion à 3 "
+"points."
 
 #: git-am.sh:139
 msgid "Using index info to reconstruct a base tree..."
-msgstr "Utilisation de l'information de l'index pour reconstruire un arbre de base..."
+msgstr ""
+"Utilisation de l'information de l'index pour reconstruire un arbre de base..."
 
 #: git-am.sh:154
 msgid ""
@@ -8983,15 +9970,15 @@
 
 #: git-am.sh:163
 msgid "Falling back to patching base and 3-way merge..."
-msgstr "Retour à un patch de la base et fusion 3-way..."
+msgstr "Retour à un patch de la base et fusion à 3 points..."
 
 #: git-am.sh:179
 msgid "Failed to merge in the changes."
-msgstr "Échec de fusion dans les changements."
+msgstr "Échec d'intégration des modifications."
 
 #: git-am.sh:274
 msgid "Only one StGIT patch series can be applied at once"
-msgstr "Seulement une série de patches StGIT peut être appliquée à la fois"
+msgstr "Seulement une série de patchs StGIT peut être appliquée à la fois"
 
 #: git-am.sh:361
 #, sh-format
@@ -9008,27 +9995,39 @@
 "it will be removed. Please do not use it anymore."
 msgstr ""
 "L'option -b/--binary ne fait plus rien depuis longtemps,\n"
-"et elle sera supprimée. Merci de ne plus l'utiliser."
+"et elle sera supprimée. Veuillez ne plus l'utiliser."
 
-#: git-am.sh:477
+#: git-am.sh:479
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
-msgstr "le répertoire précédent de rebasage $dotest existe toujours mais mbox donnée."
+msgstr ""
+"le répertoire précédent de rebasage $dotest existe toujours mais mbox donnée."
 
-#: git-am.sh:482
+#: git-am.sh:484
 msgid "Please make up your mind. --skip or --abort?"
 msgstr "Décidez-vous. --skip ou --abort ?"
 
-#: git-am.sh:509
-msgid "Resolve operation not in progress, we are not resuming."
-msgstr "Pas de résolution de l'opération en cours, nous ne sommes pas dans une reprise."
+#: git-am.sh:520
+#, sh-format
+msgid ""
+"Stray $dotest directory found.\n"
+"Use \"git am --abort\" to remove it."
+msgstr ""
+"Répertoire abandonné $dotest trouvé.\n"
+"Utilisez \"git am --abort\" pour le supprimer."
 
-#: git-am.sh:575
+#: git-am.sh:528
+msgid "Resolve operation not in progress, we are not resuming."
+msgstr ""
+"Pas de résolution de l'opération en cours, nous ne sommes pas dans une "
+"reprise."
+
+#: git-am.sh:594
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
-msgstr "Index sale : impossible d'appliquer des patches (sales : $files)"
+msgstr "Index sale : impossible d'appliquer des patchs (sales : $files)"
 
-#: git-am.sh:679
+#: git-am.sh:698
 #, sh-format
 msgid ""
 "Patch is empty.  Was it split wrong?\n"
@@ -9037,40 +10036,46 @@
 msgstr ""
 "Le patch est vide.  Était-il mal découpé ?\n"
 "Si vous préférez sauter ce patch, lancez plutôt \"$cmdline --skip\".\n"
-"Pour restaurer la branche d'origine et stopper le patchage, lancez \"$cmdline --abort\"."
+"Pour restaurer la branche d'origine et stopper le patchage, lancez "
+"\"$cmdline --abort\"."
 
-#: git-am.sh:706
+#: git-am.sh:725
 msgid "Patch does not have a valid e-mail address."
 msgstr "Le patch n'a pas d'adresse e-mail valide."
 
-#: git-am.sh:753
+#: git-am.sh:772
 msgid "cannot be interactive without stdin connected to a terminal."
-msgstr "impossible d'être interactif sans entrée standard connectée à un terminal."
+msgstr ""
+"impossible d'être interactif sans entrée standard connectée à un terminal."
 
-#: git-am.sh:757
+#: git-am.sh:776
 msgid "Commit Body is:"
 msgstr "Le corps de la validation est :"
 
 #. 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:764
+#: git-am.sh:783
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr "Appliquer ? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 
-#: git-am.sh:800
+#: git-am.sh:819
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr "Application : $FIRSTLINE"
 
-#: git-am.sh:821
+#: git-am.sh:840
 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 ""
+"Aucun changement - avez-vous oublié d'utiliser 'git add' ?\n"
+"S'il n'y a plus rien à indexer, il se peut qu'autre chose ait déjà\n"
+"introduit les mêmes changements ; vous pourriez avoir envie de sauter ce "
+"patch."
 
-#: git-am.sh:829
+#: git-am.sh:848
 msgid ""
 "You still have unmerged paths in your index\n"
 "did you forget to use 'git add'?"
@@ -9078,16 +10083,16 @@
 "Vous avez toujours des chemins non fusionnés dans votre index\n"
 "auriez-vous oublié de faire 'git add' ?"
 
-#: git-am.sh:845
+#: git-am.sh:864
 msgid "No changes -- Patch already applied."
 msgstr "Pas de changement -- Patch déjà appliqué."
 
-#: git-am.sh:855
+#: git-am.sh:874
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
 msgstr "Le patch a échoué à $msgnum $FIRSTLINE"
 
-#: git-am.sh:858
+#: git-am.sh:877
 #, sh-format
 msgid ""
 "The copy of the patch that failed is found in:\n"
@@ -9096,7 +10101,7 @@
 "La copie du patch qui a échoué se trouve dans :\n"
 "   $dotest/patch"
 
-#: git-am.sh:876
+#: git-am.sh:895
 msgid "applying to an empty history"
 msgstr "application à un historique vide"
 
@@ -9129,11 +10134,13 @@
 #, sh-format
 msgid ""
 "Checking out '$start_head' failed. Try 'git bisect reset <validbranch>'."
-msgstr "L'extraction de '$start_head' a échoué. Essayez 'git bisect reset <branchevalide>'."
+msgstr ""
+"L'extraction de '$start_head' a échoué. Essayez 'git bisect reset "
+"<branchevalide>'."
 
 #: git-bisect.sh:140
 msgid "won't bisect on seeked tree"
-msgstr ""
+msgstr "refus de bissecter sur un arbre 'seeked'"
 
 #: git-bisect.sh:144
 msgid "Bad HEAD - strange symbolic ref"
@@ -9151,7 +10158,7 @@
 
 #: git-bisect.sh:232
 msgid "Please call 'bisect_state' with at least one argument."
-msgstr "Merci d'appeler 'bisect_state' avec au moins un argument."
+msgstr "Veuillez appeler 'bisect_state' avec au moins un argument."
 
 #: git-bisect.sh:244
 #, sh-format
@@ -9262,22 +10269,25 @@
 "as appropriate to mark resolution, or use 'git commit -a'."
 msgstr ""
 "Le pull n'est pas possible car vous avez des fichiers non fusionnés.\n"
-"Merci de corriger dans votre copie de travail, et utilisez alors 'git add/rm <file>'\n"
+"Veuillez les corriger dans votre copie de travail, et utilisez alors 'git "
+"add/rm <file>'\n"
 "si nécessaire pour marquer comme résolu, ou utilisez 'git commit -a'."
 
 #: git-pull.sh:25
 msgid "Pull is not possible because you have unmerged files."
 msgstr "Le pull n'est pas possible car vous avez des fichiers non fusionnés."
 
-#: git-pull.sh:203
+#: git-pull.sh:223
 msgid "updating an unborn branch with changes added to the index"
-msgstr "mise à jour d'une branche non encore créée avec les changements ajoutés dans l'index"
+msgstr ""
+"mise à jour d'une branche non encore créée avec les changements ajoutés dans "
+"l'index"
 
 #. The fetch involved updating the current branch.
 #. The working tree and the index file is still based on the
 #. $orig_head commit, but we are merging into $curr_head.
 #. First update the working tree to match $curr_head.
-#: git-pull.sh:235
+#: git-pull.sh:255
 #, sh-format
 msgid ""
 "Warning: fetch updated the current branch head.\n"
@@ -9288,15 +10298,15 @@
 "Attention : mise à jour en avance rapide de votre copie de travail\n"
 "Attention : depuis la validation $orig_head."
 
-#: git-pull.sh:260
+#: git-pull.sh:280
 msgid "Cannot merge multiple branches into empty head"
 msgstr "Impossible de fusionner de multiples branches sur une tête vide"
 
-#: git-pull.sh:264
+#: git-pull.sh:284
 msgid "Cannot rebase onto multiple branches"
 msgstr "Impossible de rebaser sur de multiples branches"
 
-#: git-rebase.sh:53
+#: git-rebase.sh:54
 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"
@@ -9305,33 +10315,55 @@
 msgstr ""
 "Lorsque vous aurez résolu ce problème, lancez \"git rebase --continue\".\n"
 "Si vous préférez sauter ce patch, lancez \"git rebase --skip\" à la place.\n"
-"Pour extraire la branche d'origine et stopper le rebasage, lancez \"git rebase --abort\"."
+"Pour extraire la branche d'origine et stopper le rebasage, lancez \"git "
+"rebase --abort\"."
+
+#: git-rebase.sh:156
+msgid "Applied autostash."
+msgstr "Autoremisage appliqué."
+
+#: git-rebase.sh:159
+#, sh-format
+msgid "Cannot store $stash_sha1"
+msgstr "Impossible de stocker $stash_sha1"
 
 #: git-rebase.sh:160
-msgid "The pre-rebase hook refused to rebase."
-msgstr "Le hook pre-rebase a refusé de rebaser."
+msgid ""
+"Applying autostash resulted in conflicts.\n"
+"Your changes are safe in the stash.\n"
+"You can run \"git stash pop\" or \"git stash drop\" at any time.\n"
+msgstr ""
+"L'application de l'autoremisage a provoqué des conflits\n"
+"Vos  modifications sont à l'abri dans la remise.\n"
+"Vous pouvez lancer \"git stash pop\" ou \"git stash drop\" à tout moment.\n"
 
-#: git-rebase.sh:165
+#: git-rebase.sh:199
+msgid "The pre-rebase hook refused to rebase."
+msgstr "Le crochet pre-rebase a refusé de rebaser."
+
+#: git-rebase.sh:204
 msgid "It looks like git-am is in progress. Cannot rebase."
 msgstr "Il semble que git-am soit en cours. Impossible de rebaser."
 
-#: git-rebase.sh:296
+#: git-rebase.sh:338
 msgid "The --exec option must be used with the --interactive option"
 msgstr "L'option --exec doit être utilisée avec l'option --interactive"
 
-#: git-rebase.sh:301
+#: git-rebase.sh:343
 msgid "No rebase in progress?"
 msgstr "Pas de rebasage en cours ?"
 
-#: git-rebase.sh:312
+#: git-rebase.sh:354
 msgid "The --edit-todo action can only be used during interactive rebase."
-msgstr "L'action --edit-todo peut seulement être utilisée lors d'un rebasage interactif."
+msgstr ""
+"L'action --edit-todo peut seulement être utilisée lors d'un rebasage "
+"interactif."
 
-#: git-rebase.sh:319
+#: git-rebase.sh:361
 msgid "Cannot read HEAD"
 msgstr "Impossible de lire HEAD"
 
-#: git-rebase.sh:322
+#: git-rebase.sh:364
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -9339,12 +10371,12 @@
 "Vous devez éditer tous les conflits de fusion et\n"
 "les marquer comme résolus avec git add"
 
-#: git-rebase.sh:340
+#: git-rebase.sh:382
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Impossible de revenir à $head_name"
 
-#: git-rebase.sh:359
+#: git-rebase.sh:401
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -9357,64 +10389,75 @@
 "valuable there."
 msgstr ""
 "Il semble qu'il y ait déjà un répertoire $state_dir_base, et je me demande\n"
-"si vous n'êtes pas au milieu d'un autre rebasage.  Si c'est le cas,\n"
-"merci d'essayer\n"
+"si un autre rebasage n'est pas déjà en cours. Si c'est le cas,\n"
+"essayez\n"
 "\t$cmd_live_rebase\n"
-"Si ça n'est pas le cas, merci de\n"
+"Sinon, essayez\n"
 "\t$cmd_clear_stale_rebase\n"
-"et relancer à nouveau.  Je m'arrête au cas où vous auriez quelque chose\n"
+"puis relancez-moi à nouveau.  Je m'arrête au cas où vous auriez quelque "
+"chose\n"
 "d'important ici."
 
-#: git-rebase.sh:404
+#: git-rebase.sh:446
 #, sh-format
 msgid "invalid upstream $upstream_name"
 msgstr "invalide $upstream_name en amont"
 
-#: git-rebase.sh:428
+#: git-rebase.sh:470
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name : il y a plus d'une base de fusion"
 
-#: git-rebase.sh:431 git-rebase.sh:435
+#: git-rebase.sh:473 git-rebase.sh:477
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name : il n'y a pas de base de fusion"
 
-#: git-rebase.sh:440
+#: git-rebase.sh:482
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "Ne pointe pas sur une validation valide : $onto_name"
 
-#: git-rebase.sh:463
+#: git-rebase.sh:505
 #, sh-format
 msgid "fatal: no such branch: $branch_name"
 msgstr "fatal : pas de branche : $branch_name"
 
-#: git-rebase.sh:483
-msgid "Please commit or stash them."
-msgstr "Merci de les valider ou de les remiser."
+#: git-rebase.sh:528
+msgid "Cannot autostash"
+msgstr "Autoremisage impossible"
 
-#: git-rebase.sh:501
+#: git-rebase.sh:533
+#, sh-format
+msgid "Created autostash: $stash_abbrev"
+msgstr "Autoremisage créé : $stash_abbrev"
+
+#: git-rebase.sh:537
+msgid "Please commit or stash them."
+msgstr "Veuillez les valider ou les remiser."
+
+#: git-rebase.sh:557
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "La branche courante $branch_name est à jour."
 
-#: git-rebase.sh:504
+#: git-rebase.sh:561
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "La branche courante $branch_name est à jour, rebasage forcé."
 
-#: git-rebase.sh:515
+#: git-rebase.sh:572
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Changements de $mb sur $onto :"
 
 #. Detach HEAD and reset the tree
-#: git-rebase.sh:524
+#: git-rebase.sh:581
 msgid "First, rewinding head to replay your work on top of it..."
-msgstr "Premièrement, retour de head pour rejouer votre travail par-dessus..."
+msgstr ""
+"Premièrement, rembobinons head pour rejouer votre travail par-dessus..."
 
-#: git-rebase.sh:532
+#: git-rebase.sh:591
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "$branch_name mise à jour en avance rapide sur $onto_name."
@@ -9447,6 +10490,11 @@
 msgid "Cannot record working tree state"
 msgstr "Impossible d'enregistrer l'état de la copie de travail"
 
+#: git-stash.sh:190
+#, sh-format
+msgid "Cannot update $ref_stash with $w_commit"
+msgstr "Impossible de mettre à jour $ref_stash avec $w_commit"
+
 #. TRANSLATORS: $option is an invalid option, like
 #. `--blah-blah'. The 7 spaces at the beginning of the
 #. second line correspond to "error: ". So you should line
@@ -9457,7 +10505,7 @@
 #. $ git stash save --blah-blah 2>&1 | head -n 2
 #. error: unknown option for 'stash save': --blah-blah
 #. To provide a message, use git stash save -- '--blah-blah'
-#: git-stash.sh:202
+#: git-stash.sh:237
 #, sh-format
 msgid ""
 "error: unknown option for 'stash save': $option\n"
@@ -9466,119 +10514,129 @@
 "erreur: option inconnue pour 'stash save': $option\n"
 "        Pour fournir un message, utilisez git stash save -- '$option'"
 
-#: git-stash.sh:223
+#: git-stash.sh:258
 msgid "No local changes to save"
-msgstr "Pas de changements en local à sauver"
+msgstr "Pas de modifications locales à sauver"
 
-#: git-stash.sh:227
+#: git-stash.sh:262
 msgid "Cannot initialize stash"
 msgstr "Impossible d'initialiser le remisage"
 
-#: git-stash.sh:235
+#: git-stash.sh:266
 msgid "Cannot save the current status"
 msgstr "Impossible de sauver le statut courant"
 
-#: git-stash.sh:253
+#: git-stash.sh:284
 msgid "Cannot remove worktree changes"
 msgstr "Impossible de supprimer les changements de la copie de travail"
 
-#: git-stash.sh:352
+#: git-stash.sh:383
 msgid "No stash found."
 msgstr "Pas de remisage trouvé."
 
-#: git-stash.sh:359
+#: git-stash.sh:390
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "Trop de révisions spécifiées : $REV"
 
-#: git-stash.sh:365
+#: git-stash.sh:396
 #, sh-format
 msgid "$reference is not valid reference"
 msgstr "$reference n'est pas une référence valide"
 
-#: git-stash.sh:393
+#: git-stash.sh:424
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "'$args' n'est pas une validation de type remisage"
 
-#: git-stash.sh:404
+#: git-stash.sh:435
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "'$args' n'est pas une référence de remisage"
 
-#: git-stash.sh:412
+#: git-stash.sh:443
 msgid "unable to refresh index"
 msgstr "impossible de rafraîchir l'index"
 
-#: git-stash.sh:416
+#: git-stash.sh:447
 msgid "Cannot apply a stash in the middle of a merge"
-msgstr "Impossible d'appliquer un remisage au milieu d'une fusion"
+msgstr "Impossible d'appliquer un remisage en cours de fusion"
 
-#: git-stash.sh:424
+#: git-stash.sh:455
 msgid "Conflicts in index. Try without --index."
 msgstr "Conflits dans l'index. Essayez sans --index."
 
-#: git-stash.sh:426
+#: git-stash.sh:457
 msgid "Could not save index tree"
 msgstr "Impossible de sauver l'arbre d'index"
 
-#: git-stash.sh:460
+#: git-stash.sh:491
 msgid "Cannot unstage modified files"
 msgstr "Impossible de désindexer les fichiers modifiés"
 
-#: git-stash.sh:475
+#: git-stash.sh:506
 msgid "Index was not unstashed."
-msgstr ""
+msgstr "L'index n'a pas été sorti de remise."
 
-#: git-stash.sh:492
+#: git-stash.sh:523
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "${REV} supprimé ($s)"
 
-#: git-stash.sh:493
+#: git-stash.sh:524
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
-msgstr "${REV}: Impossible de supprimer l'entrée de stash"
+msgstr "${REV}: Impossible de supprimer l'élément de stash"
 
-#: git-stash.sh:500
+#: git-stash.sh:531
 msgid "No branch name specified"
 msgstr "Aucune branche spécifiée"
 
-#: git-stash.sh:571
+#: git-stash.sh:603
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(Pour les restaurer tapez \"git stash apply\")"
 
-#: git-submodule.sh:91
+#: git-submodule.sh:95
 #, sh-format
 msgid "cannot strip one component off url '$remoteurl'"
 msgstr "impossible de supprimer un composant de l'URL '$remoteurl'"
 
-#: git-submodule.sh:196
+#: git-submodule.sh:237
 #, sh-format
 msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
-msgstr "Pas de mappage du sous-module trouvé dans .gitmodules pour le chemin '$sm_path'"
+msgstr ""
+"Pas de mise en correspondance du sous-module trouvé dans .gitmodules pour le "
+"chemin '$sm_path'"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:281
 #, sh-format
 msgid "Clone of '$url' into submodule path '$sm_path' failed"
 msgstr "Le clonage de '$url' dans le chemin de sous-module '$sm_path' a échoué"
 
-#: git-submodule.sh:251
+#: git-submodule.sh:293
 #, sh-format
 msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
-msgstr "Le répertoire Git '$a' fait partie du chemin de sous-module '$b' ou vice-versa"
+msgstr ""
+"Le répertoire Git '$a' fait partie du chemin de sous-module '$b' ou vice-"
+"versa"
 
-#: git-submodule.sh:349
+#: git-submodule.sh:403
+msgid "Relative path can only be used from the toplevel of the working tree"
+msgstr ""
+"Un chemin relatif ne peut être utilisé que depuis la racine de la copie de "
+"travail"
+
+#: git-submodule.sh:413
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "L'URL de dépôt '$repo' doit être absolu ou commencer par ./|../"
 
-#: git-submodule.sh:366
+#: git-submodule.sh:430
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path' existe déjà dans l'index"
 
-#: git-submodule.sh:370
+#: git-submodule.sh:434
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -9589,235 +10647,286 @@
 "$sm_path\n"
 "Utilisez -f si vous voulez vraiment l'ajouter."
 
-#: git-submodule.sh:388
+#: git-submodule.sh:452
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Ajout du dépôt existant à '$sm_path' dans l'index"
 
-#: git-submodule.sh:390
+#: git-submodule.sh:454
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path' existe déjà et n'est pas un dépôt git valide"
 
-#: git-submodule.sh:398
+#: git-submodule.sh:462
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
-msgstr "Un répertoire git pour '$sm_name' est trouvé en local avec le(s) serveur(s) distant(s) :"
+msgstr ""
+"Un répertoire git pour '$sm_name' est trouvé en local avec le(s) serveur(s) "
+"distant(s) :"
 
-#: git-submodule.sh:400
+#: git-submodule.sh:464
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from"
-msgstr "Si vous voulez réutiliser ce répertoire git local au lieu de cloner à nouveau depuis"
+msgstr ""
+"Si vous voulez réutiliser ce répertoire git local au lieu de cloner à "
+"nouveau depuis"
 
-#: git-submodule.sh:402
+#: git-submodule.sh:466
 #, sh-format
 msgid ""
 "use the '--force' option. If the local git directory is not the correct repo"
-msgstr "utilisez l'option '--force'. Si le répertoire local git n'est pas le dépôt correct"
+msgstr ""
+"utilisez l'option '--force'. Si le répertoire local git n'est pas le dépôt "
+"correct"
 
-#: git-submodule.sh:403
+#: git-submodule.sh:467
 #, sh-format
 msgid ""
 "or you are unsure what this means choose another name with the '--name' "
 "option."
-msgstr "ou vous ne savez pas ce que cela signifie de choisir un autre nom avec l'option '--name'."
+msgstr ""
+"ou vous ne savez pas ce que cela signifie de choisir un autre nom avec "
+"l'option '--name'."
 
-#: git-submodule.sh:405
+#: git-submodule.sh:469
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr "Réactivation du répertoire git local pour le sous-module '$sm_name'."
 
-#: git-submodule.sh:417
+#: git-submodule.sh:481
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Impossible d'extraire le sous-module '$sm_path'"
 
-#: git-submodule.sh:422
+#: git-submodule.sh:486
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Échec d'ajout du sous-module '$sm_path'"
 
-#: git-submodule.sh:431
+#: git-submodule.sh:495
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Échec d'enregistrement du sous-module '$sm_path'"
 
-#: git-submodule.sh:474
+#: git-submodule.sh:539
 #, sh-format
-msgid "Entering '$prefix$sm_path'"
-msgstr "Entrée dans '$prefix$sm_path'"
+msgid "Entering '$prefix$displaypath'"
+msgstr "Entrée dans '$prefix$displaypath'"
 
-#: git-submodule.sh:488
+#: git-submodule.sh:554
 #, sh-format
-msgid "Stopping at '$sm_path'; script returned non-zero status."
-msgstr "Arrêt sur '$sm_path' ; le script a retourné un statut non nul."
+msgid "Stopping at '$prefix$displaypath'; script returned non-zero status."
+msgstr ""
+"Arrêt sur '$prefix$displaypath' ; le script a retourné un statut non nul."
 
-#: git-submodule.sh:532
+#: git-submodule.sh:600
 #, sh-format
-msgid "No url found for submodule path '$sm_path' in .gitmodules"
-msgstr "URL non trouvé pour le chemin de sous-module '$sm_path' dans .gitmodules"
+msgid "No url found for submodule path '$displaypath' in .gitmodules"
+msgstr ""
+"URL non trouvé pour le chemin de sous-module '$displaypath' dans .gitmodules"
 
-#: git-submodule.sh:541
+#: git-submodule.sh:609
 #, sh-format
-msgid "Failed to register url for submodule path '$sm_path'"
-msgstr "Échec d'enregistrement de l'URL pour le chemin de sous-module '$sm_path'"
+msgid "Failed to register url for submodule path '$displaypath'"
+msgstr ""
+"Échec d'enregistrement de l'URL pour le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:543
+#: git-submodule.sh:611
 #, sh-format
-msgid "Submodule '$name' ($url) registered for path '$sm_path'"
-msgstr "Sous-module '$name' ($url) enregistré pour le chemin '$sm_path'"
+msgid "Submodule '$name' ($url) registered for path '$displaypath'"
+msgstr "Sous-module '$name' ($url) enregistré pour le chemin '$displaypath'"
 
-#: git-submodule.sh:551
+#: git-submodule.sh:619
 #, sh-format
-msgid "Failed to register update mode for submodule path '$sm_path'"
-msgstr "Échec d'enregistrement du mode de mise à jour pour le chemin de sous-module '$sm_path'"
+msgid "Failed to register update mode for submodule path '$displaypath'"
+msgstr ""
+"Échec d'enregistrement du mode de mise à jour pour le chemin de sous-module "
+"'$displaypath'"
 
-#: git-submodule.sh:588
+#: git-submodule.sh:656
 #, sh-format
 msgid "Use '.' if you really want to deinitialize all submodules"
-msgstr "Utilisez '.' si vous voulez vraiment réinitialiser tous les sous-modules"
+msgstr ""
+"Utilisez '.' si vous voulez vraiment réinitialiser tous les sous-modules"
 
-#: git-submodule.sh:603
+#: git-submodule.sh:673
 #, sh-format
-msgid "Submodule work tree '$sm_path' contains a .git directory"
-msgstr "La copie de travail du sous-module '$sm_path' contient un répertoire .git"
+msgid "Submodule work tree '$displaypath' contains a .git directory"
+msgstr ""
+"La copie de travail du sous-module '$displaypath' contient un répertoire .git"
 
-#: git-submodule.sh:604
+#: git-submodule.sh:674
 #, sh-format
 msgid ""
 "(use 'rm -rf' if you really want to remove it including all of its history)"
-msgstr "(utilisez 'rm -rf' si vous voulez vraiment le supprimer en incluant tout son historique)"
+msgstr ""
+"(utilisez 'rm -rf' si vous voulez vraiment le supprimer en incluant tout son "
+"historique)"
 
-#: git-submodule.sh:610
+#: git-submodule.sh:680
 #, sh-format
 msgid ""
-"Submodule work tree '$sm_path' contains local modifications; use '-f' to "
+"Submodule work tree '$displaypath' contains local modifications; use '-f' to "
 "discard them"
-msgstr "La copie de travail du sous-module '$sm_path' contient des modifications locales; utilisez '-f' pour les annuler"
+msgstr ""
+"La copie de travail du sous-module '$displaypath' contient des modifications "
+"locales ; utilisez '-f' pour les annuler"
 
-#: git-submodule.sh:613
+#: git-submodule.sh:683
 #, sh-format
-msgid "Cleared directory '$sm_path'"
-msgstr "Répertoire '$sm_path' nettoyé"
+msgid "Cleared directory '$displaypath'"
+msgstr "Répertoire '$displaypath' nettoyé"
 
-#: git-submodule.sh:614
+#: git-submodule.sh:684
 #, sh-format
-msgid "Could not remove submodule work tree '$sm_path'"
-msgstr "Impossible de supprimer la copie de travail du sous-module '$sm_path'"
+msgid "Could not remove submodule work tree '$displaypath'"
+msgstr ""
+"Impossible de supprimer la copie de travail du sous-module '$displaypath'"
 
-#: git-submodule.sh:617
+#: git-submodule.sh:687
 #, sh-format
-msgid "Could not create empty submodule directory '$sm_path'"
-msgstr "Impossible de créer le répertoire vide du sous-module '$sm_path'"
+msgid "Could not create empty submodule directory '$displaypath'"
+msgstr "Impossible de créer le répertoire vide du sous-module '$displaypath'"
 
-#: git-submodule.sh:626
+#: git-submodule.sh:696
 #, sh-format
-msgid "Submodule '$name' ($url) unregistered for path '$sm_path'"
-msgstr "Le sous-module '$name' ($url) n'est pas enregistré pour le chemin '$sm_path'"
+msgid "Submodule '$name' ($url) unregistered for path '$displaypath'"
+msgstr ""
+"Le sous-module '$name' ($url) n'est pas enregistré pour le chemin "
+"'$displaypath'"
 
-#: git-submodule.sh:731
+#: git-submodule.sh:811
 #, sh-format
 msgid ""
-"Submodule path '$prefix$sm_path' not initialized\n"
+"Submodule path '$displaypath' not initialized\n"
 "Maybe you want to use 'update --init'?"
 msgstr ""
-"Chemin de sous-module '$prefix$sm_path' non initialisé\n"
+"Chemin de sous-module '$displaypath' non initialisé\n"
 "Peut-être souhaitez-vous utiliser 'update --init' ?"
 
-#: git-submodule.sh:744
+#: git-submodule.sh:824
 #, sh-format
-msgid "Unable to find current revision in submodule path '$prefix$sm_path'"
-msgstr "Impossible de trouver la révision courante dans le chemin de sous-module '$prefix$sm_path'"
+msgid "Unable to find current revision in submodule path '$displaypath'"
+msgstr ""
+"Impossible de trouver la révision courante dans le chemin de sous-module "
+"'$displaypath'"
 
-#: git-submodule.sh:753
+#: git-submodule.sh:833
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Impossible de rapatrier dans le chemin de sous-module '$sm_path'"
 
-#: git-submodule.sh:777
+#: git-submodule.sh:857
 #, sh-format
-msgid "Unable to fetch in submodule path '$prefix$sm_path'"
-msgstr "Impossible de rapatrier dans le chemin de sous-module '$prefix$sm_path'"
+msgid "Unable to fetch in submodule path '$displaypath'"
+msgstr "Impossible de rapatrier dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:791
+#: git-submodule.sh:871
 #, sh-format
-msgid "Unable to rebase '$sha1' in submodule path '$prefix$sm_path'"
-msgstr "Impossible de rebaser '$sha1' dans le chemin de sous-module '$prefix$sm_path'"
+msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
+msgstr ""
+"Impossible de rebaser '$sha1' dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:792
+#: git-submodule.sh:872
 #, sh-format
-msgid "Submodule path '$prefix$sm_path': rebased into '$sha1'"
-msgstr "Chemin de sous-module '$prefix$sm_path' : rebasé dans '$sha1'"
+msgid "Submodule path '$displaypath': rebased into '$sha1'"
+msgstr "Chemin de sous-module '$displaypath' : rebasé dans '$sha1'"
 
-#: git-submodule.sh:797
+#: git-submodule.sh:877
 #, sh-format
-msgid "Unable to merge '$sha1' in submodule path '$prefix$sm_path'"
-msgstr "Impossible de fusionner '$sha1' dans le chemin de sous-module '$prefix$sm_path'"
+msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
+msgstr ""
+"Impossible de fusionner '$sha1' dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:798
+#: git-submodule.sh:878
 #, sh-format
-msgid "Submodule path '$prefix$sm_path': merged in '$sha1'"
-msgstr "Chemin de sous-module '$prefix$sm_path' : fusionné dans '$sha1'"
+msgid "Submodule path '$displaypath': merged in '$sha1'"
+msgstr "Chemin de sous-module '$displaypath' : fusionné dans '$sha1'"
 
-#: git-submodule.sh:803
+#: git-submodule.sh:883
 #, sh-format
-msgid "Unable to checkout '$sha1' in submodule path '$prefix$sm_path'"
-msgstr "Impossible d'extraire '$sha1' dans le chemin de sous-module '$prefix$sm_path'"
+msgid ""
+"Execution of '$command $sha1' failed in submodule  path '$prefix$sm_path'"
+msgstr ""
+"L'exécution de '$command $sha1' a échoué dans le chemin de sous-module "
+"'$prefix$sm_path'"
 
-#: git-submodule.sh:804
+#: git-submodule.sh:884
 #, sh-format
-msgid "Submodule path '$prefix$sm_path': checked out '$sha1'"
-msgstr "Chemin de sous-module '$prefix$sm_path' : '$sha1' extrait"
+msgid "Submodule path '$prefix$sm_path': '$command $sha1'"
+msgstr "Chemin de sous-module '$prefix$sm_path' : '$command $sha1'"
 
-#: git-submodule.sh:831
+#: git-submodule.sh:889
 #, sh-format
-msgid "Failed to recurse into submodule path '$prefix$sm_path'"
-msgstr "Échec de parcours dans le chemin du sous-module '$prefix$sm_path'"
+msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
+msgstr ""
+"Impossible d'extraire '$sha1' dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:939
+#: git-submodule.sh:890
+#, sh-format
+msgid "Submodule path '$displaypath': checked out '$sha1'"
+msgstr "Chemin de sous-module '$displaypath' : '$sha1' extrait"
+
+#: git-submodule.sh:917
+#, sh-format
+msgid "Failed to recurse into submodule path '$displaypath'"
+msgstr "Échec de parcours dans le chemin du sous-module '$displaypath'"
+
+#: git-submodule.sh:1025
 msgid "The --cached option cannot be used with the --files option"
 msgstr "L'option --cached ne peut pas être utilisée avec l'option --files"
 
 #. unexpected type
-#: git-submodule.sh:979
+#: git-submodule.sh:1073
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "mode $mod_dst inattendu"
 
-#: git-submodule.sh:997
+#: git-submodule.sh:1093
 #, sh-format
-msgid "  Warn: $name doesn't contain commit $sha1_src"
-msgstr "  Attention : $name ne contient pas la validation $sha1_src"
+msgid "  Warn: $display_name doesn't contain commit $sha1_src"
+msgstr "  Attention : $display_name ne contient pas la validation $sha1_src"
 
-#: git-submodule.sh:1000
+#: git-submodule.sh:1096
 #, sh-format
-msgid "  Warn: $name doesn't contain commit $sha1_dst"
-msgstr "  Attention : $name ne contient pas la validation $sha1_dst"
+msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
+msgstr "  Attention : $display_name ne contient pas la validation $sha1_dst"
 
-#: git-submodule.sh:1003
+#: git-submodule.sh:1099
 #, sh-format
-msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
-msgstr "  Attention : $name ne contient pas les validations $sha1_src et $sha1_dst"
+msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
+msgstr ""
+"  Attention : $display_name ne contient pas les validations $sha1_src et "
+"$sha1_dst"
 
-#: git-submodule.sh:1028
+#: git-submodule.sh:1124
 msgid "blob"
 msgstr "blob"
 
-#: git-submodule.sh:1066
-msgid "Submodules changed but not updated:"
-msgstr "Sous-modules modifiés mais non mis à jour :"
-
-#: git-submodule.sh:1068
-msgid "Submodule changes to be committed:"
-msgstr "Changements du sous-module à valider :"
-
-#: git-submodule.sh:1153
+#: git-submodule.sh:1238
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "Échec de parcours dans le chemin du sous-module '$sm_path'"
 
-#: git-submodule.sh:1216
+#: git-submodule.sh:1302
 #, sh-format
-msgid "Synchronizing submodule url for '$prefix$sm_path'"
-msgstr "Synchronisation de l'URL sous-module pour '$prefix$sm_path'"
+msgid "Synchronizing submodule url for '$displaypath'"
+msgstr "Synchronisation de l'URL sous-module pour '$displaypath'"
+
+#~ msgid "input paths are terminated by a null character"
+#~ msgstr "les chemins en entrée sont terminés par le caractère nul"
+
+#~ msgid "done\n"
+#~ msgstr "fait\n"
+
+#~ msgid ""
+#~ "The following untracked files would NOT be saved but need to be removed "
+#~ "by stash save:"
+#~ msgstr ""
+#~ "Les fichiers suivants non suivis ne seront PAS sauvés mais doivent être "
+#~ "supprimés par le remisage :"
+
+#~ msgid ""
+#~ "Aborting. Consider using either the --force or --include-untracked option."
+#~ msgstr "Abandon. Utilisez l'option --force ou --include-untracked."
diff --git a/po/git.pot b/po/git.pot
index cf1e446..58af01a 100644
--- a/po/git.pot
+++ b/po/git.pot
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2013-08-06 14:10+0800\n"
+"POT-Creation-Date: 2013-11-02 08:06+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"
@@ -52,71 +52,76 @@
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr ""
 
-#: archive.c:323
+#: archive.c:242 builtin/add.c:240 builtin/add.c:556 builtin/rm.c:328
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr ""
+
+#: archive.c:327
 msgid "fmt"
 msgstr ""
 
-#: archive.c:323
+#: archive.c:327
 msgid "archive format"
 msgstr ""
 
-#: archive.c:324 builtin/log.c:1173
+#: archive.c:328 builtin/log.c:1193
 msgid "prefix"
 msgstr ""
 
-#: archive.c:325
+#: archive.c:329
 msgid "prepend prefix to each pathname in the archive"
 msgstr ""
 
-#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2292
-#: builtin/blame.c:2293 builtin/config.c:56 builtin/fast-export.c:673
-#: builtin/fast-export.c:675 builtin/grep.c:714 builtin/hash-object.c:77
-#: builtin/ls-files.c:496 builtin/ls-files.c:499 builtin/notes.c:408
-#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:152
+#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2264
+#: builtin/blame.c:2265 builtin/config.c:58 builtin/fast-export.c:680
+#: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77
+#: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408
+#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154
 msgid "file"
 msgstr ""
 
-#: archive.c:327 builtin/archive.c:89
+#: archive.c:331 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr ""
 
-#: archive.c:329
+#: archive.c:333
 msgid "read .gitattributes in working directory"
 msgstr ""
 
-#: archive.c:330
+#: archive.c:334
 msgid "report archived files on stderr"
 msgstr ""
 
-#: archive.c:331
+#: archive.c:335
 msgid "store only"
 msgstr ""
 
-#: archive.c:332
+#: archive.c:336
 msgid "compress faster"
 msgstr ""
 
-#: archive.c:340
+#: archive.c:344
 msgid "compress better"
 msgstr ""
 
-#: archive.c:343
+#: archive.c:347
 msgid "list supported archive formats"
 msgstr ""
 
-#: archive.c:345 builtin/archive.c:90 builtin/clone.c:85
+#: archive.c:349 builtin/archive.c:90 builtin/clone.c:84
 msgid "repo"
 msgstr ""
 
-#: archive.c:346 builtin/archive.c:91
+#: archive.c:350 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr ""
 
-#: archive.c:347 builtin/archive.c:92 builtin/notes.c:487
+#: archive.c:351 builtin/archive.c:92 builtin/notes.c:487
 msgid "command"
 msgstr ""
 
-#: archive.c:348 builtin/archive.c:93
+#: archive.c:352 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr ""
 
@@ -195,17 +200,17 @@
 msgid "Cannot force update the current branch."
 msgstr ""
 
-#: branch.c:216
+#: branch.c:215
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
 
-#: branch.c:218
+#: branch.c:217
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr ""
 
-#: branch.c:220
+#: branch.c:219
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -217,26 +222,26 @@
 "\"git push -u\" to set the upstream config as you push."
 msgstr ""
 
-#: branch.c:265
+#: branch.c:264
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr ""
 
-#: branch.c:285
+#: branch.c:284
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr ""
 
-#: branch.c:290
+#: branch.c:289
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr ""
 
-#: branch.c:296
+#: branch.c:295
 msgid "Failed to lock ref for update"
 msgstr ""
 
-#: branch.c:314
+#: branch.c:313
 msgid "Failed to write ref"
 msgstr ""
 
@@ -250,7 +255,7 @@
 msgid "unrecognized header: %s%s (%d)"
 msgstr ""
 
-#: bundle.c:89 builtin/commit.c:697
+#: bundle.c:89 builtin/commit.c:706
 #, c-format
 msgid "could not open '%s'"
 msgstr ""
@@ -259,9 +264,9 @@
 msgid "Repository lacks these prerequisite commits:"
 msgstr ""
 
-#: bundle.c:164 sequencer.c:661 sequencer.c:1111 builtin/log.c:331
-#: builtin/log.c:801 builtin/log.c:1399 builtin/log.c:1625 builtin/merge.c:364
-#: builtin/shortlog.c:156
+#: bundle.c:164 sequencer.c:662 sequencer.c:1112 builtin/log.c:332
+#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:364
+#: builtin/shortlog.c:158
 msgid "revision walk setup failed"
 msgstr ""
 
@@ -287,7 +292,7 @@
 msgid "rev-list died"
 msgstr ""
 
-#: bundle.c:300 builtin/log.c:1310 builtin/shortlog.c:259
+#: bundle.c:300 builtin/log.c:1329 builtin/shortlog.c:261
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr ""
@@ -435,14 +440,14 @@
 "%s"
 msgstr ""
 
-#: diff.c:3487
+#: diff.c:3490
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
 "%s"
 msgstr ""
 
-#: diff.c:3501
+#: diff.c:3504
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr ""
@@ -469,17 +474,17 @@
 msgid "failed writing detached signature to '%s': %s"
 msgstr ""
 
-#: grep.c:1623
+#: grep.c:1695
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr ""
 
-#: grep.c:1640
+#: grep.c:1712
 #, c-format
 msgid "'%s': %s"
 msgstr ""
 
-#: grep.c:1651
+#: grep.c:1723
 #, c-format
 msgid "'%s': short read %s"
 msgstr ""
@@ -544,8 +549,8 @@
 msgid "failed to read the cache"
 msgstr ""
 
-#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566
-#: builtin/clone.c:656
+#: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559
+#: builtin/clone.c:655
 msgid "unable to write new index file"
 msgstr ""
 
@@ -594,7 +599,7 @@
 msgid "blob expected for %s '%s'"
 msgstr ""
 
-#: merge-recursive.c:774 builtin/clone.c:312
+#: merge-recursive.c:774 builtin/clone.c:311
 #, c-format
 msgid "failed to open '%s'"
 msgstr ""
@@ -721,7 +726,7 @@
 msgid "Auto-merging %s"
 msgstr ""
 
-#: merge-recursive.c:1634 git-submodule.sh:1118
+#: merge-recursive.c:1634 git-submodule.sh:1125
 msgid "submodule"
 msgstr ""
 
@@ -816,58 +821,121 @@
 msgid "Bad %s value: '%s'"
 msgstr ""
 
-#: object.c:204
+#: object.c:202
 #, c-format
 msgid "unable to parse object: %s"
 msgstr ""
 
-#: parse-options.c:489
+#: parse-options.c:537
 msgid "..."
 msgstr ""
 
-#: parse-options.c:507
+#: parse-options.c:555
 #, c-format
 msgid "usage: %s"
 msgstr ""
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:511
+#: parse-options.c:559
 #, c-format
 msgid "   or: %s"
 msgstr ""
 
-#: parse-options.c:514
+#: parse-options.c:562
 #, c-format
 msgid "    %s"
 msgstr ""
 
-#: parse-options.c:548
+#: parse-options.c:596
 msgid "-NUM"
 msgstr ""
 
-#: pathspec.c:83
-#, c-format
-msgid "Path '%s' is in submodule '%.*s'"
+#: pathspec.c:118
+msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
 msgstr ""
 
-#: pathspec.c:99
-#, c-format
-msgid "'%s' is beyond a symbolic link"
+#: pathspec.c:128
+msgid ""
+"global 'literal' pathspec setting is incompatible with all other global "
+"pathspec settings"
 msgstr ""
 
-#: remote.c:1788
+#: pathspec.c:158
+msgid "invalid parameter for pathspec magic 'prefix'"
+msgstr ""
+
+#: pathspec.c:164
+#, c-format
+msgid "Invalid pathspec magic '%.*s' in '%s'"
+msgstr ""
+
+#: pathspec.c:168
+#, c-format
+msgid "Missing ')' at the end of pathspec magic in '%s'"
+msgstr ""
+
+#: pathspec.c:186
+#, c-format
+msgid "Unimplemented pathspec magic '%c' in '%s'"
+msgstr ""
+
+#: pathspec.c:211
+#, c-format
+msgid "%s: 'literal' and 'glob' are incompatible"
+msgstr ""
+
+#: pathspec.c:222
+#, c-format
+msgid "%s: '%s' is outside repository"
+msgstr ""
+
+#: pathspec.c:278
+#, c-format
+msgid "Pathspec '%s' is in submodule '%.*s'"
+msgstr ""
+
+#.
+#. * We may want to substitute "this command" with a command
+#. * name. E.g. when add--interactive dies when running
+#. * "checkout -p"
+#.
+#: pathspec.c:340
+#, c-format
+msgid "%s: pathspec magic not supported by this command: %s"
+msgstr ""
+
+#: pathspec.c:415
+#, c-format
+msgid "pathspec '%s' is beyond a symbolic link"
+msgstr ""
+
+#: remote.c:1833
+#, c-format
+msgid "Your branch is based on '%s', but the upstream is gone.\n"
+msgstr ""
+
+#: remote.c:1837
+msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
+msgstr ""
+
+#: remote.c:1840
+#, c-format
+msgid "Your branch is up-to-date with '%s'.\n"
+msgstr ""
+
+#: remote.c:1844
 #, 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:1794
+#: remote.c:1850
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr ""
 
-#: remote.c:1797
+#: remote.c:1853
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -875,11 +943,11 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: remote.c:1805
+#: remote.c:1861
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr ""
 
-#: remote.c:1808
+#: remote.c:1864
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -890,7 +958,7 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: remote.c:1818
+#: remote.c:1874
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr ""
 
@@ -928,7 +996,7 @@
 "and commit the result with 'git commit'"
 msgstr ""
 
-#: sequencer.c:245 sequencer.c:869 sequencer.c:952
+#: sequencer.c:245 sequencer.c:870 sequencer.c:953
 #, c-format
 msgid "Could not write to %s"
 msgstr ""
@@ -951,197 +1019,197 @@
 msgstr ""
 
 #. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:324
+#: sequencer.c:325
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr ""
 
-#: sequencer.c:355
+#: sequencer.c:356
 msgid "Could not resolve HEAD commit\n"
 msgstr ""
 
-#: sequencer.c:377
+#: sequencer.c:378
 msgid "Unable to update cache tree\n"
 msgstr ""
 
-#: sequencer.c:422
+#: sequencer.c:423
 #, c-format
 msgid "Could not parse commit %s\n"
 msgstr ""
 
-#: sequencer.c:427
+#: sequencer.c:428
 #, c-format
 msgid "Could not parse parent commit %s\n"
 msgstr ""
 
-#: sequencer.c:493
+#: sequencer.c:494
 msgid "Your index file is unmerged."
 msgstr ""
 
-#: sequencer.c:512
+#: sequencer.c:513
 #, c-format
 msgid "Commit %s is a merge but no -m option was given."
 msgstr ""
 
-#: sequencer.c:520
+#: sequencer.c:521
 #, c-format
 msgid "Commit %s does not have parent %d"
 msgstr ""
 
-#: sequencer.c:524
+#: sequencer.c:525
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
 msgstr ""
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
-#: sequencer.c:537
+#: sequencer.c:538
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr ""
 
-#: sequencer.c:541
+#: sequencer.c:542
 #, c-format
 msgid "Cannot get commit message for %s"
 msgstr ""
 
-#: sequencer.c:627
+#: sequencer.c:628
 #, c-format
 msgid "could not revert %s... %s"
 msgstr ""
 
-#: sequencer.c:628
+#: sequencer.c:629
 #, c-format
 msgid "could not apply %s... %s"
 msgstr ""
 
-#: sequencer.c:664
+#: sequencer.c:665
 msgid "empty commit set passed"
 msgstr ""
 
-#: sequencer.c:672
+#: sequencer.c:673
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr ""
 
-#: sequencer.c:677
+#: sequencer.c:678
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr ""
 
-#: sequencer.c:735
+#: sequencer.c:736
 #, c-format
 msgid "Cannot %s during a %s"
 msgstr ""
 
-#: sequencer.c:757
+#: sequencer.c:758
 #, c-format
 msgid "Could not parse line %d."
 msgstr ""
 
-#: sequencer.c:762
+#: sequencer.c:763
 msgid "No commits parsed."
 msgstr ""
 
-#: sequencer.c:775
+#: sequencer.c:776
 #, c-format
 msgid "Could not open %s"
 msgstr ""
 
-#: sequencer.c:779
+#: sequencer.c:780
 #, c-format
 msgid "Could not read %s."
 msgstr ""
 
-#: sequencer.c:786
+#: sequencer.c:787
 #, c-format
 msgid "Unusable instruction sheet: %s"
 msgstr ""
 
-#: sequencer.c:814
+#: sequencer.c:815
 #, c-format
 msgid "Invalid key: %s"
 msgstr ""
 
-#: sequencer.c:817
+#: sequencer.c:818
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr ""
 
-#: sequencer.c:829
+#: sequencer.c:830
 #, c-format
 msgid "Malformed options sheet: %s"
 msgstr ""
 
-#: sequencer.c:850
+#: sequencer.c:851
 msgid "a cherry-pick or revert is already in progress"
 msgstr ""
 
-#: sequencer.c:851
+#: sequencer.c:852
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr ""
 
-#: sequencer.c:855
+#: sequencer.c:856
 #, c-format
 msgid "Could not create sequencer directory %s"
 msgstr ""
 
-#: sequencer.c:871 sequencer.c:956
+#: sequencer.c:872 sequencer.c:957
 #, c-format
 msgid "Error wrapping up %s."
 msgstr ""
 
-#: sequencer.c:890 sequencer.c:1024
+#: sequencer.c:891 sequencer.c:1025
 msgid "no cherry-pick or revert in progress"
 msgstr ""
 
-#: sequencer.c:892
+#: sequencer.c:893
 msgid "cannot resolve HEAD"
 msgstr ""
 
-#: sequencer.c:894
+#: sequencer.c:895
 msgid "cannot abort from a branch yet to be born"
 msgstr ""
 
-#: sequencer.c:916 builtin/apply.c:4061
+#: sequencer.c:917 builtin/apply.c:4061
 #, c-format
 msgid "cannot open %s: %s"
 msgstr ""
 
-#: sequencer.c:919
+#: sequencer.c:920
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: sequencer.c:920
+#: sequencer.c:921
 msgid "unexpected end of file"
 msgstr ""
 
-#: sequencer.c:926
+#: sequencer.c:927
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr ""
 
-#: sequencer.c:949
+#: sequencer.c:950
 #, c-format
 msgid "Could not format %s."
 msgstr ""
 
-#: sequencer.c:1092
+#: sequencer.c:1093
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr ""
 
-#: sequencer.c:1095
+#: sequencer.c:1096
 #, c-format
 msgid "%s: bad revision"
 msgstr ""
 
-#: sequencer.c:1129
+#: sequencer.c:1130
 msgid "Can't revert as initial commit"
 msgstr ""
 
-#: sequencer.c:1130
+#: sequencer.c:1131
 msgid "Can't cherry-pick into empty head"
 msgstr ""
 
@@ -1158,360 +1226,453 @@
 "running \"git config advice.objectNameWarning false\""
 msgstr ""
 
-#: sha1_name.c:1097
+#: sha1_name.c:1112
 msgid "HEAD does not point to a branch"
 msgstr ""
 
-#: sha1_name.c:1100
+#: sha1_name.c:1115
 #, c-format
 msgid "No such branch: '%s'"
 msgstr ""
 
-#: sha1_name.c:1102
+#: sha1_name.c:1117
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr ""
 
-#: sha1_name.c:1106
+#: sha1_name.c:1121
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr ""
 
-#: wrapper.c:408
+#: submodule.c:64 submodule.c:98
+msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
+msgstr ""
+
+#: submodule.c:68 submodule.c:102
+#, c-format
+msgid "Could not find section in .gitmodules where path=%s"
+msgstr ""
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:76
+#, c-format
+msgid "Could not update .gitmodules entry %s"
+msgstr ""
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:109
+#, c-format
+msgid "Could not remove .gitmodules entry for %s"
+msgstr ""
+
+#: submodule.c:127
+msgid "could not find .gitmodules in index"
+msgstr ""
+
+#: submodule.c:133
+msgid "reading updated .gitmodules failed"
+msgstr ""
+
+#: submodule.c:135
+msgid "unable to stat updated .gitmodules"
+msgstr ""
+
+#: submodule.c:139
+msgid "unable to remove .gitmodules from index"
+msgstr ""
+
+#: submodule.c:141
+msgid "adding updated .gitmodules failed"
+msgstr ""
+
+#: submodule.c:143
+msgid "staging updated .gitmodules failed"
+msgstr ""
+
+#: submodule.c:1144 builtin/init-db.c:363
+#, c-format
+msgid "Could not create git link %s"
+msgstr ""
+
+#: submodule.c:1155
+#, c-format
+msgid "Could not set core.worktree in %s"
+msgstr ""
+
+#: urlmatch.c:120
+msgid "invalid URL scheme name or missing '://' suffix"
+msgstr ""
+
+#: urlmatch.c:144 urlmatch.c:297 urlmatch.c:356
+#, c-format
+msgid "invalid %XX escape sequence"
+msgstr ""
+
+#: urlmatch.c:172
+msgid "missing host and scheme is not 'file:'"
+msgstr ""
+
+#: urlmatch.c:189
+msgid "a 'file:' URL may not have a port number"
+msgstr ""
+
+#: urlmatch.c:199
+msgid "invalid characters in host name"
+msgstr ""
+
+#: urlmatch.c:244 urlmatch.c:255
+msgid "invalid port number"
+msgstr ""
+
+#: urlmatch.c:322
+msgid "invalid '..' path segment"
+msgstr ""
+
+#: wrapper.c:422
 #, c-format
 msgid "unable to access '%s': %s"
 msgstr ""
 
-#: wrapper.c:429
+#: wrapper.c:443
 #, c-format
 msgid "unable to access '%s'"
 msgstr ""
 
-#: wrapper.c:440
+#: wrapper.c:454
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
 msgstr ""
 
-#: wrapper.c:441
+#: wrapper.c:455
 msgid "no such user"
 msgstr ""
 
-#: wt-status.c:141
+#: wt-status.c:146
 msgid "Unmerged paths:"
 msgstr ""
 
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:173 wt-status.c:200
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr ""
 
-#: wt-status.c:170 wt-status.c:197
+#: wt-status.c:175 wt-status.c:202
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr ""
 
-#: wt-status.c:174
+#: wt-status.c:179
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr ""
 
-#: wt-status.c:176 wt-status.c:180
+#: wt-status.c:181 wt-status.c:185
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 
-#: wt-status.c:178
+#: wt-status.c:183
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr ""
 
-#: wt-status.c:189
+#: wt-status.c:194
 msgid "Changes to be committed:"
 msgstr ""
 
-#: wt-status.c:207
+#: wt-status.c:212
 msgid "Changes not staged for commit:"
 msgstr ""
 
-#: wt-status.c:211
+#: wt-status.c:216
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 
-#: wt-status.c:213
+#: wt-status.c:218
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 
-#: wt-status.c:214
+#: wt-status.c:219
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 
-#: wt-status.c:216
+#: wt-status.c:221
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 
-#: wt-status.c:228
+#: wt-status.c:233
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 
-#: wt-status.c:245
+#: wt-status.c:250
 msgid "bug"
 msgstr ""
 
-#: wt-status.c:250
+#: wt-status.c:255
 msgid "both deleted:"
 msgstr ""
 
-#: wt-status.c:251
+#: wt-status.c:256
 msgid "added by us:"
 msgstr ""
 
-#: wt-status.c:252
+#: wt-status.c:257
 msgid "deleted by them:"
 msgstr ""
 
-#: wt-status.c:253
+#: wt-status.c:258
 msgid "added by them:"
 msgstr ""
 
-#: wt-status.c:254
+#: wt-status.c:259
 msgid "deleted by us:"
 msgstr ""
 
-#: wt-status.c:255
+#: wt-status.c:260
 msgid "both added:"
 msgstr ""
 
-#: wt-status.c:256
+#: wt-status.c:261
 msgid "both modified:"
 msgstr ""
 
-#: wt-status.c:286
+#: wt-status.c:291
 msgid "new commits, "
 msgstr ""
 
-#: wt-status.c:288
+#: wt-status.c:293
 msgid "modified content, "
 msgstr ""
 
-#: wt-status.c:290
+#: wt-status.c:295
 msgid "untracked content, "
 msgstr ""
 
-#: wt-status.c:307
+#: wt-status.c:312
 #, c-format
 msgid "new file:   %s"
 msgstr ""
 
-#: wt-status.c:310
+#: wt-status.c:315
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr ""
 
-#: wt-status.c:313
+#: wt-status.c:318
 #, c-format
 msgid "deleted:    %s"
 msgstr ""
 
-#: wt-status.c:316
+#: wt-status.c:321
 #, c-format
 msgid "modified:   %s"
 msgstr ""
 
-#: wt-status.c:319
+#: wt-status.c:324
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr ""
 
-#: wt-status.c:322
+#: wt-status.c:327
 #, c-format
 msgid "typechange: %s"
 msgstr ""
 
-#: wt-status.c:325
+#: wt-status.c:330
 #, c-format
 msgid "unknown:    %s"
 msgstr ""
 
-#: wt-status.c:328
+#: wt-status.c:333
 #, c-format
 msgid "unmerged:   %s"
 msgstr ""
 
-#: wt-status.c:331
+#: wt-status.c:336
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr ""
 
-#: wt-status.c:803
+#: wt-status.c:703
+msgid "Submodules changed but not updated:"
+msgstr ""
+
+#: wt-status.c:705
+msgid "Submodule changes to be committed:"
+msgstr ""
+
+#: wt-status.c:848
 msgid "You have unmerged paths."
 msgstr ""
 
-#: wt-status.c:806
+#: wt-status.c:851
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr ""
 
-#: wt-status.c:809
+#: wt-status.c:854
 msgid "All conflicts fixed but you are still merging."
 msgstr ""
 
-#: wt-status.c:812
+#: wt-status.c:857
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr ""
 
-#: wt-status.c:822
+#: wt-status.c:867
 msgid "You are in the middle of an am session."
 msgstr ""
 
-#: wt-status.c:825
+#: wt-status.c:870
 msgid "The current patch is empty."
 msgstr ""
 
-#: wt-status.c:829
+#: wt-status.c:874
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr ""
 
-#: wt-status.c:831
+#: wt-status.c:876
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr ""
 
-#: wt-status.c:833
+#: wt-status.c:878
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr ""
 
-#: wt-status.c:893 wt-status.c:910
+#: wt-status.c:938 wt-status.c:955
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr ""
 
-#: wt-status.c:898 wt-status.c:915
+#: wt-status.c:943 wt-status.c:960
 msgid "You are currently rebasing."
 msgstr ""
 
-#: wt-status.c:901
+#: wt-status.c:946
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:903
+#: wt-status.c:948
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr ""
 
-#: wt-status.c:905
+#: wt-status.c:950
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr ""
 
-#: wt-status.c:918
+#: wt-status.c:963
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:922
+#: wt-status.c:967
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 
-#: wt-status.c:927
+#: wt-status.c:972
 msgid "You are currently splitting a commit during a rebase."
 msgstr ""
 
-#: wt-status.c:930
+#: wt-status.c:975
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:934
+#: wt-status.c:979
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 
-#: wt-status.c:939
+#: wt-status.c:984
 msgid "You are currently editing a commit during a rebase."
 msgstr ""
 
-#: wt-status.c:942
+#: wt-status.c:987
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 
-#: wt-status.c:944
+#: wt-status.c:989
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 
-#: wt-status.c:954
-msgid "You are currently cherry-picking."
+#: wt-status.c:999
+#, c-format
+msgid "You are currently cherry-picking commit %s."
 msgstr ""
 
-#: wt-status.c:958
+#: wt-status.c:1004
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr ""
 
-#: wt-status.c:961
+#: wt-status.c:1007
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 
-#: wt-status.c:963
+#: wt-status.c:1009
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
 
-#: wt-status.c:972
+#: wt-status.c:1018
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr ""
 
-#: wt-status.c:977
+#: wt-status.c:1023
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr ""
 
-#: wt-status.c:980
+#: wt-status.c:1026
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr ""
 
-#: wt-status.c:982
+#: wt-status.c:1028
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr ""
 
-#: wt-status.c:993
+#: wt-status.c:1039
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr ""
 
-#: wt-status.c:997
+#: wt-status.c:1043
 msgid "You are currently bisecting."
 msgstr ""
 
-#: wt-status.c:1000
+#: wt-status.c:1046
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
 
-#: wt-status.c:1173
+#: wt-status.c:1221
 msgid "On branch "
 msgstr ""
 
-#: wt-status.c:1180
+#: wt-status.c:1228
 msgid "rebase in progress; onto "
 msgstr ""
 
-#: wt-status.c:1187
+#: wt-status.c:1235
 msgid "HEAD detached at "
 msgstr ""
 
-#: wt-status.c:1189
+#: wt-status.c:1237
 msgid "HEAD detached from "
 msgstr ""
 
-#: wt-status.c:1192
+#: wt-status.c:1240
 msgid "Not currently on any branch."
 msgstr ""
 
-#: wt-status.c:1209
+#: wt-status.c:1257
 msgid "Initial commit"
 msgstr ""
 
-#: wt-status.c:1223
+#: wt-status.c:1271
 msgid "Untracked files"
 msgstr ""
 
-#: wt-status.c:1225
+#: wt-status.c:1273
 msgid "Ignored files"
 msgstr ""
 
-#: wt-status.c:1229
+#: wt-status.c:1277
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -1519,82 +1680,86 @@
 "new files yourself (see 'git help status')."
 msgstr ""
 
-#: wt-status.c:1235
+#: wt-status.c:1283
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr ""
 
-#: wt-status.c:1237
+#: wt-status.c:1285
 msgid " (use -u option to show untracked files)"
 msgstr ""
 
-#: wt-status.c:1243
+#: wt-status.c:1291
 msgid "No changes"
 msgstr ""
 
-#: wt-status.c:1248
+#: wt-status.c:1296
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 
-#: wt-status.c:1251
+#: wt-status.c:1299
 #, c-format
 msgid "no changes added to commit\n"
 msgstr ""
 
-#: wt-status.c:1254
+#: wt-status.c:1302
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
 "track)\n"
 msgstr ""
 
-#: wt-status.c:1257
+#: wt-status.c:1305
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr ""
 
-#: wt-status.c:1260
+#: wt-status.c:1308
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 
-#: wt-status.c:1263 wt-status.c:1268
+#: wt-status.c:1311 wt-status.c:1316
 #, c-format
 msgid "nothing to commit\n"
 msgstr ""
 
-#: wt-status.c:1266
+#: wt-status.c:1314
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
 
-#: wt-status.c:1270
+#: wt-status.c:1318
 #, c-format
 msgid "nothing to commit, working directory clean\n"
 msgstr ""
 
-#: wt-status.c:1378
+#: wt-status.c:1427
 msgid "HEAD (no branch)"
 msgstr ""
 
-#: wt-status.c:1384
+#: wt-status.c:1433
 msgid "Initial commit on "
 msgstr ""
 
-#: wt-status.c:1399
+#: wt-status.c:1463
+msgid "gone"
+msgstr ""
+
+#: wt-status.c:1465
 msgid "behind "
 msgstr ""
 
-#: wt-status.c:1402 wt-status.c:1405
+#: wt-status.c:1468 wt-status.c:1471
 msgid "ahead "
 msgstr ""
 
-#: wt-status.c:1407
+#: wt-status.c:1473
 msgid ", behind "
 msgstr ""
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:351
+#: compat/precompose_utf8.c:55 builtin/clone.c:350
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr ""
@@ -1654,7 +1819,7 @@
 msgid "unexpected diff status %c"
 msgstr ""
 
-#: builtin/add.c:149 builtin/commit.c:252
+#: builtin/add.c:149 builtin/commit.c:260
 msgid "updating files failed"
 msgstr ""
 
@@ -1663,140 +1828,135 @@
 msgid "remove '%s'\n"
 msgstr ""
 
-#: builtin/add.c:253
+#: builtin/add.c:237
 msgid "Unstaged changes after refreshing the index:"
 msgstr ""
 
-#: builtin/add.c:256 builtin/add.c:573 builtin/rm.c:337
-#, c-format
-msgid "pathspec '%s' did not match any files"
-msgstr ""
-
-#: builtin/add.c:339
+#: builtin/add.c:299
 msgid "Could not read the index"
 msgstr ""
 
-#: builtin/add.c:350
+#: builtin/add.c:310
 #, c-format
 msgid "Could not open '%s' for writing."
 msgstr ""
 
-#: builtin/add.c:354
+#: builtin/add.c:314
 msgid "Could not write patch"
 msgstr ""
 
-#: builtin/add.c:359
+#: builtin/add.c:319
 #, c-format
 msgid "Could not stat '%s'"
 msgstr ""
 
-#: builtin/add.c:361
+#: builtin/add.c:321
 msgid "Empty patch. Aborted."
 msgstr ""
 
-#: builtin/add.c:367
+#: builtin/add.c:327
 #, c-format
 msgid "Could not apply '%s'"
 msgstr ""
 
-#: builtin/add.c:377
+#: builtin/add.c:337
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
 
-#: builtin/add.c:394 builtin/clean.c:875 builtin/fetch.c:78 builtin/mv.c:63
-#: builtin/prune-packed.c:73 builtin/push.c:451 builtin/remote.c:1253
-#: builtin/rm.c:268
+#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:92 builtin/mv.c:66
+#: builtin/prune-packed.c:73 builtin/push.c:459 builtin/remote.c:1253
+#: builtin/rm.c:269
 msgid "dry run"
 msgstr ""
 
-#: builtin/add.c:395 builtin/apply.c:4410 builtin/check-ignore.c:19
-#: builtin/commit.c:1220 builtin/count-objects.c:95 builtin/fsck.c:613
-#: builtin/log.c:1573 builtin/mv.c:62 builtin/read-tree.c:113
+#: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19
+#: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612
+#: builtin/log.c:1592 builtin/mv.c:65 builtin/read-tree.c:113
 msgid "be verbose"
 msgstr ""
 
-#: builtin/add.c:397
+#: builtin/add.c:357
 msgid "interactive picking"
 msgstr ""
 
-#: builtin/add.c:398 builtin/checkout.c:1073 builtin/reset.c:261
+#: builtin/add.c:358 builtin/checkout.c:1109 builtin/reset.c:272
 msgid "select hunks interactively"
 msgstr ""
 
-#: builtin/add.c:399
+#: builtin/add.c:359
 msgid "edit current diff and apply"
 msgstr ""
 
-#: builtin/add.c:400
+#: builtin/add.c:360
 msgid "allow adding otherwise ignored files"
 msgstr ""
 
-#: builtin/add.c:401
+#: builtin/add.c:361
 msgid "update tracked files"
 msgstr ""
 
-#: builtin/add.c:402
+#: builtin/add.c:362
 msgid "record only the fact that the path will be added later"
 msgstr ""
 
-#: builtin/add.c:403
+#: builtin/add.c:363
 msgid "add changes from all tracked and untracked files"
 msgstr ""
 
 #. takes no arguments
-#: builtin/add.c:406
+#: builtin/add.c:366
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr ""
 
-#: builtin/add.c:408
+#: builtin/add.c:368
 msgid "don't add, only refresh the index"
 msgstr ""
 
-#: builtin/add.c:409
+#: builtin/add.c:369
 msgid "just skip files which cannot be added because of errors"
 msgstr ""
 
-#: builtin/add.c:410
+#: builtin/add.c:370
 msgid "check if - even missing - files are ignored in dry run"
 msgstr ""
 
-#: builtin/add.c:432
+#: builtin/add.c:392
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr ""
 
-#: builtin/add.c:433
+#: builtin/add.c:393
 msgid "no files added"
 msgstr ""
 
-#: builtin/add.c:439
+#: builtin/add.c:399
 msgid "adding files failed"
 msgstr ""
 
-#: builtin/add.c:478
+#: builtin/add.c:438
 msgid "-A and -u are mutually incompatible"
 msgstr ""
 
-#: builtin/add.c:496
+#: builtin/add.c:456
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr ""
 
-#: builtin/add.c:526
+#: builtin/add.c:486
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr ""
 
-#: builtin/add.c:527
+#: builtin/add.c:487
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr ""
 
-#: builtin/add.c:533 builtin/check-ignore.c:161 builtin/clean.c:919
-#: builtin/commit.c:312 builtin/mv.c:82 builtin/rm.c:297
+#: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919
+#: builtin/commit.c:320 builtin/mv.c:86 builtin/reset.c:224 builtin/rm.c:299
 msgid "index file corrupt"
 msgstr ""
 
-#: builtin/add.c:605 builtin/apply.c:4506 builtin/mv.c:229 builtin/rm.c:432
+#: builtin/add.c:589 builtin/apply.c:4506 builtin/mv.c:259 builtin/rm.c:432
 msgid "Unable to write new index file"
 msgstr ""
 
@@ -2042,7 +2202,7 @@
 msgid "Checking patch %s..."
 msgstr ""
 
-#: builtin/apply.c:3680 builtin/checkout.c:216 builtin/reset.c:127
+#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:127
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr ""
@@ -2122,8 +2282,8 @@
 msgid "unable to read index file"
 msgstr ""
 
-#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:91
-#: builtin/fetch.c:63
+#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90
+#: builtin/fetch.c:77
 msgid "path"
 msgstr ""
 
@@ -2183,7 +2343,7 @@
 msgid "build a temporary index based on embedded index information"
 msgstr ""
 
-#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:462
+#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:452
 msgid "paths are separated with NUL character"
 msgstr ""
 
@@ -2313,103 +2473,103 @@
 msgid "update BISECT_HEAD instead of checking out the current commit"
 msgstr ""
 
-#: builtin/blame.c:26
+#: builtin/blame.c:27
 msgid "git blame [options] [rev-opts] [rev] [--] file"
 msgstr ""
 
-#: builtin/blame.c:31
+#: builtin/blame.c:32
 msgid "[rev-opts] are documented in git-rev-list(1)"
 msgstr ""
 
-#: builtin/blame.c:2276
+#: builtin/blame.c:2248
 msgid "Show blame entries as we find them, incrementally"
 msgstr ""
 
-#: builtin/blame.c:2277
+#: builtin/blame.c:2249
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2278
+#: builtin/blame.c:2250
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2279
+#: builtin/blame.c:2251
 msgid "Show work cost statistics"
 msgstr ""
 
-#: builtin/blame.c:2280
+#: builtin/blame.c:2252
 msgid "Show output score for blame entries"
 msgstr ""
 
-#: builtin/blame.c:2281
+#: builtin/blame.c:2253
 msgid "Show original filename (Default: auto)"
 msgstr ""
 
-#: builtin/blame.c:2282
+#: builtin/blame.c:2254
 msgid "Show original linenumber (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2283
+#: builtin/blame.c:2255
 msgid "Show in a format designed for machine consumption"
 msgstr ""
 
-#: builtin/blame.c:2284
+#: builtin/blame.c:2256
 msgid "Show porcelain format with per-line commit information"
 msgstr ""
 
-#: builtin/blame.c:2285
+#: builtin/blame.c:2257
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2286
+#: builtin/blame.c:2258
 msgid "Show raw timestamp (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2287
+#: builtin/blame.c:2259
 msgid "Show long commit SHA1 (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2288
+#: builtin/blame.c:2260
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2289
+#: builtin/blame.c:2261
 msgid "Show author email instead of name (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:2290
+#: builtin/blame.c:2262
 msgid "Ignore whitespace differences"
 msgstr ""
 
-#: builtin/blame.c:2291
+#: builtin/blame.c:2263
 msgid "Spend extra cycles to find better match"
 msgstr ""
 
-#: builtin/blame.c:2292
+#: builtin/blame.c:2264
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr ""
 
-#: builtin/blame.c:2293
+#: builtin/blame.c:2265
 msgid "Use <file>'s contents as the final image"
 msgstr ""
 
-#: builtin/blame.c:2294 builtin/blame.c:2295
+#: builtin/blame.c:2266 builtin/blame.c:2267
 msgid "score"
 msgstr ""
 
-#: builtin/blame.c:2294
+#: builtin/blame.c:2266
 msgid "Find line copies within and across files"
 msgstr ""
 
-#: builtin/blame.c:2295
+#: builtin/blame.c:2267
 msgid "Find line movements within and across files"
 msgstr ""
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "n,m"
 msgstr ""
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "Process only line range n,m, counting from 1"
 msgstr ""
 
@@ -2509,280 +2669,290 @@
 
 #: builtin/branch.c:453
 #, c-format
-msgid "[%s: behind %d]"
+msgid "[%s: gone]"
 msgstr ""
 
-#: builtin/branch.c:455
+#: builtin/branch.c:456
 #, c-format
-msgid "[behind %d]"
+msgid "[%s]"
 msgstr ""
 
 #: builtin/branch.c:459
 #, c-format
-msgid "[%s: ahead %d]"
+msgid "[%s: behind %d]"
 msgstr ""
 
 #: builtin/branch.c:461
 #, c-format
-msgid "[ahead %d]"
+msgid "[behind %d]"
 msgstr ""
 
-#: builtin/branch.c:464
+#: builtin/branch.c:465
 #, c-format
-msgid "[%s: ahead %d, behind %d]"
+msgid "[%s: ahead %d]"
 msgstr ""
 
 #: builtin/branch.c:467
 #, c-format
+msgid "[ahead %d]"
+msgstr ""
+
+#: builtin/branch.c:470
+#, c-format
+msgid "[%s: ahead %d, behind %d]"
+msgstr ""
+
+#: builtin/branch.c:473
+#, c-format
 msgid "[ahead %d, behind %d]"
 msgstr ""
 
-#: builtin/branch.c:490
+#: builtin/branch.c:496
 msgid " **** invalid ref ****"
 msgstr ""
 
-#: builtin/branch.c:582
-#, c-format
-msgid "(no branch, rebasing %s)"
-msgstr ""
-
-#: builtin/branch.c:585
-#, c-format
-msgid "(no branch, bisect started on %s)"
-msgstr ""
-
 #: builtin/branch.c:588
 #, c-format
-msgid "(detached from %s)"
+msgid "(no branch, rebasing %s)"
 msgstr ""
 
 #: builtin/branch.c:591
+#, c-format
+msgid "(no branch, bisect started on %s)"
+msgstr ""
+
+#: builtin/branch.c:594
+#, c-format
+msgid "(detached from %s)"
+msgstr ""
+
+#: builtin/branch.c:597
 msgid "(no branch)"
 msgstr ""
 
-#: builtin/branch.c:637
+#: builtin/branch.c:643
 #, c-format
 msgid "object '%s' does not point to a commit"
 msgstr ""
 
-#: builtin/branch.c:669
+#: builtin/branch.c:675
 msgid "some refs could not be read"
 msgstr ""
 
-#: builtin/branch.c:682
+#: builtin/branch.c:688
 msgid "cannot rename the current branch while not on any."
 msgstr ""
 
-#: builtin/branch.c:692
+#: builtin/branch.c:698
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr ""
 
-#: builtin/branch.c:707
+#: builtin/branch.c:713
 msgid "Branch rename failed"
 msgstr ""
 
-#: builtin/branch.c:711
+#: builtin/branch.c:717
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr ""
 
-#: builtin/branch.c:715
+#: builtin/branch.c:721
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr ""
 
-#: builtin/branch.c:722
+#: builtin/branch.c:728
 msgid "Branch is renamed, but update of config-file failed"
 msgstr ""
 
-#: builtin/branch.c:737
+#: builtin/branch.c:743
 #, c-format
 msgid "malformed object name %s"
 msgstr ""
 
-#: builtin/branch.c:761
+#: builtin/branch.c:767
 #, c-format
 msgid "could not write branch description template: %s"
 msgstr ""
 
-#: builtin/branch.c:791
+#: builtin/branch.c:797
 msgid "Generic options"
 msgstr ""
 
-#: builtin/branch.c:793
+#: builtin/branch.c:799
 msgid "show hash and subject, give twice for upstream branch"
 msgstr ""
 
-#: builtin/branch.c:794
+#: builtin/branch.c:800
 msgid "suppress informational messages"
 msgstr ""
 
-#: builtin/branch.c:795
+#: builtin/branch.c:801
 msgid "set up tracking mode (see git-pull(1))"
 msgstr ""
 
-#: builtin/branch.c:797
+#: builtin/branch.c:803
 msgid "change upstream info"
 msgstr ""
 
-#: builtin/branch.c:801
+#: builtin/branch.c:807
 msgid "use colored output"
 msgstr ""
 
-#: builtin/branch.c:802
+#: builtin/branch.c:808
 msgid "act on remote-tracking branches"
 msgstr ""
 
-#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832
-#: builtin/branch.c:838 builtin/commit.c:1433 builtin/commit.c:1434
-#: builtin/commit.c:1435 builtin/commit.c:1436 builtin/tag.c:468
+#: builtin/branch.c:811 builtin/branch.c:817 builtin/branch.c:838
+#: builtin/branch.c:844 builtin/commit.c:1460 builtin/commit.c:1461
+#: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468
 msgid "commit"
 msgstr ""
 
-#: builtin/branch.c:806 builtin/branch.c:812
+#: builtin/branch.c:812 builtin/branch.c:818
 msgid "print only branches that contain the commit"
 msgstr ""
 
-#: builtin/branch.c:818
+#: builtin/branch.c:824
 msgid "Specific git-branch actions:"
 msgstr ""
 
-#: builtin/branch.c:819
+#: builtin/branch.c:825
 msgid "list both remote-tracking and local branches"
 msgstr ""
 
-#: builtin/branch.c:821
+#: builtin/branch.c:827
 msgid "delete fully merged branch"
 msgstr ""
 
-#: builtin/branch.c:822
+#: builtin/branch.c:828
 msgid "delete branch (even if not merged)"
 msgstr ""
 
-#: builtin/branch.c:823
+#: builtin/branch.c:829
 msgid "move/rename a branch and its reflog"
 msgstr ""
 
-#: builtin/branch.c:824
+#: builtin/branch.c:830
 msgid "move/rename a branch, even if target exists"
 msgstr ""
 
-#: builtin/branch.c:825
+#: builtin/branch.c:831
 msgid "list branch names"
 msgstr ""
 
-#: builtin/branch.c:826
+#: builtin/branch.c:832
 msgid "create the branch's reflog"
 msgstr ""
 
-#: builtin/branch.c:828
+#: builtin/branch.c:834
 msgid "edit the description for the branch"
 msgstr ""
 
-#: builtin/branch.c:829
+#: builtin/branch.c:835
 msgid "force creation (when already exists)"
 msgstr ""
 
-#: builtin/branch.c:832
+#: builtin/branch.c:838
 msgid "print only not merged branches"
 msgstr ""
 
-#: builtin/branch.c:838
+#: builtin/branch.c:844
 msgid "print only merged branches"
 msgstr ""
 
-#: builtin/branch.c:842
+#: builtin/branch.c:848
 msgid "list branches in columns"
 msgstr ""
 
-#: builtin/branch.c:855
+#: builtin/branch.c:861
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr ""
 
-#: builtin/branch.c:860 builtin/clone.c:630
+#: builtin/branch.c:866 builtin/clone.c:629
 msgid "HEAD not found below refs/heads!"
 msgstr ""
 
-#: builtin/branch.c:883
+#: builtin/branch.c:890
 msgid "--column and --verbose are incompatible"
 msgstr ""
 
-#: builtin/branch.c:889 builtin/branch.c:928
+#: builtin/branch.c:896 builtin/branch.c:935
 msgid "branch name required"
 msgstr ""
 
-#: builtin/branch.c:904
+#: builtin/branch.c:911
 msgid "Cannot give description to detached HEAD"
 msgstr ""
 
-#: builtin/branch.c:909
+#: builtin/branch.c:916
 msgid "cannot edit description of more than one branch"
 msgstr ""
 
-#: builtin/branch.c:916
+#: builtin/branch.c:923
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr ""
 
-#: builtin/branch.c:919
+#: builtin/branch.c:926
 #, c-format
 msgid "No branch named '%s'."
 msgstr ""
 
-#: builtin/branch.c:934
+#: builtin/branch.c:941
 msgid "too many branches for a rename operation"
 msgstr ""
 
-#: builtin/branch.c:939
+#: builtin/branch.c:946
 msgid "too many branches to set new upstream"
 msgstr ""
 
-#: builtin/branch.c:943
+#: builtin/branch.c:950
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr ""
 
-#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990
+#: builtin/branch.c:953 builtin/branch.c:975 builtin/branch.c:997
 #, c-format
 msgid "no such branch '%s'"
 msgstr ""
 
-#: builtin/branch.c:950
+#: builtin/branch.c:957
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr ""
 
-#: builtin/branch.c:962
+#: builtin/branch.c:969
 msgid "too many branches to unset upstream"
 msgstr ""
 
-#: builtin/branch.c:966
+#: builtin/branch.c:973
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 
-#: builtin/branch.c:972
+#: builtin/branch.c:979
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr ""
 
-#: builtin/branch.c:987
+#: builtin/branch.c:994
 msgid "it does not make sense to create 'HEAD' manually"
 msgstr ""
 
-#: builtin/branch.c:993
+#: builtin/branch.c:1000
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 
-#: builtin/branch.c:996
+#: builtin/branch.c:1003
 #, c-format
 msgid ""
 "The --set-upstream flag is deprecated and will be removed. Consider using --"
 "track or --set-upstream-to\n"
 msgstr ""
 
-#: builtin/branch.c:1013
+#: builtin/branch.c:1020
 #, c-format
 msgid ""
 "\n"
@@ -2790,12 +2960,12 @@
 "\n"
 msgstr ""
 
-#: builtin/branch.c:1014
+#: builtin/branch.c:1021
 #, c-format
 msgid "    git branch -d %s\n"
 msgstr ""
 
-#: builtin/branch.c:1015
+#: builtin/branch.c:1022
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
 msgstr ""
@@ -2813,43 +2983,43 @@
 msgid "Need a repository to unbundle."
 msgstr ""
 
-#: builtin/cat-file.c:285
+#: builtin/cat-file.c:312
 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"
 msgstr ""
 
-#: builtin/cat-file.c:286
+#: builtin/cat-file.c:313
 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>"
 msgstr ""
 
-#: builtin/cat-file.c:323
+#: builtin/cat-file.c:350
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr ""
 
-#: builtin/cat-file.c:324
+#: builtin/cat-file.c:351
 msgid "show object type"
 msgstr ""
 
-#: builtin/cat-file.c:325
+#: builtin/cat-file.c:352
 msgid "show object size"
 msgstr ""
 
-#: builtin/cat-file.c:327
+#: builtin/cat-file.c:354
 msgid "exit with zero when there's no error"
 msgstr ""
 
-#: builtin/cat-file.c:328
+#: builtin/cat-file.c:355
 msgid "pretty-print object's content"
 msgstr ""
 
-#: builtin/cat-file.c:330
+#: builtin/cat-file.c:357
 msgid "for blob objects, run textconv on object's content"
 msgstr ""
 
-#: builtin/cat-file.c:332
+#: builtin/cat-file.c:359
 msgid "show info and content of objects fed from the standard input"
 msgstr ""
 
-#: builtin/cat-file.c:335
+#: builtin/cat-file.c:362
 msgid "show info about objects fed from the standard input"
 msgstr ""
 
@@ -2874,10 +3044,10 @@
 msgstr ""
 
 #: builtin/check-attr.c:23 builtin/check-ignore.c:24
-msgid "input paths are terminated by a null character"
+msgid "terminate input and output records by a NUL character"
 msgstr ""
 
-#: builtin/check-ignore.c:18 builtin/checkout.c:1054 builtin/gc.c:177
+#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:259
 msgid "suppress progress reporting"
 msgstr ""
 
@@ -2885,27 +3055,31 @@
 msgid "show non-matching input paths"
 msgstr ""
 
-#: builtin/check-ignore.c:143
-msgid "cannot specify pathnames with --stdin"
-msgstr ""
-
-#: builtin/check-ignore.c:146
-msgid "-z only makes sense with --stdin"
-msgstr ""
-
-#: builtin/check-ignore.c:148
-msgid "no path specified"
-msgstr ""
-
-#: builtin/check-ignore.c:152
-msgid "--quiet is only valid with a single pathname"
+#: builtin/check-ignore.c:28
+msgid "ignore index when checking"
 msgstr ""
 
 #: builtin/check-ignore.c:154
-msgid "cannot have both --quiet and --verbose"
+msgid "cannot specify pathnames with --stdin"
 msgstr ""
 
 #: builtin/check-ignore.c:157
+msgid "-z only makes sense with --stdin"
+msgstr ""
+
+#: builtin/check-ignore.c:159
+msgid "no path specified"
+msgstr ""
+
+#: builtin/check-ignore.c:163
+msgid "--quiet is only valid with a single pathname"
+msgstr ""
+
+#: builtin/check-ignore.c:165
+msgid "cannot have both --quiet and --verbose"
+msgstr ""
+
+#: builtin/check-ignore.c:168
 msgid "--non-matching is only valid with --verbose"
 msgstr ""
 
@@ -2978,106 +3152,106 @@
 msgid "git checkout [options] [<branch>] -- <file>..."
 msgstr ""
 
-#: builtin/checkout.c:117 builtin/checkout.c:150
+#: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr ""
 
-#: builtin/checkout.c:119 builtin/checkout.c:152
+#: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr ""
 
-#: builtin/checkout.c:135
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr ""
 
-#: builtin/checkout.c:179
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr ""
 
-#: builtin/checkout.c:196
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr ""
 
-#: builtin/checkout.c:213
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr ""
 
-#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243
-#: builtin/checkout.c:246
+#: builtin/checkout.c:232 builtin/checkout.c:235 builtin/checkout.c:238
+#: builtin/checkout.c:241
 #, c-format
 msgid "'%s' cannot be used with updating paths"
 msgstr ""
 
-#: builtin/checkout.c:249 builtin/checkout.c:252
+#: builtin/checkout.c:244 builtin/checkout.c:247
 #, c-format
 msgid "'%s' cannot be used with %s"
 msgstr ""
 
-#: builtin/checkout.c:255
+#: builtin/checkout.c:250
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
 msgstr ""
 
-#: builtin/checkout.c:266 builtin/checkout.c:458
+#: builtin/checkout.c:261 builtin/checkout.c:451
 msgid "corrupt index file"
 msgstr ""
 
-#: builtin/checkout.c:329 builtin/checkout.c:336
+#: builtin/checkout.c:322 builtin/checkout.c:329
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr ""
 
-#: builtin/checkout.c:480
+#: builtin/checkout.c:473
 msgid "you need to resolve your current index first"
 msgstr ""
 
-#: builtin/checkout.c:601
+#: builtin/checkout.c:594
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:639
+#: builtin/checkout.c:632
 msgid "HEAD is now at"
 msgstr ""
 
-#: builtin/checkout.c:646
+#: builtin/checkout.c:639
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:649
+#: builtin/checkout.c:642
 #, c-format
 msgid "Already on '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:653
+#: builtin/checkout.c:646
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:655 builtin/checkout.c:997
+#: builtin/checkout.c:648 builtin/checkout.c:1033
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:657
+#: builtin/checkout.c:650
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:713
+#: builtin/checkout.c:706
 #, c-format
 msgid " ... and %d more.\n"
 msgstr ""
 
 #. The singular version
-#: builtin/checkout.c:719
+#: builtin/checkout.c:712
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -3092,7 +3266,7 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/checkout.c:737
+#: builtin/checkout.c:730
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -3102,184 +3276,188 @@
 "\n"
 msgstr ""
 
-#: builtin/checkout.c:767
+#: builtin/checkout.c:760
 msgid "internal error in revision walk"
 msgstr ""
 
-#: builtin/checkout.c:771
+#: builtin/checkout.c:764
 msgid "Previous HEAD position was"
 msgstr ""
 
-#: builtin/checkout.c:798 builtin/checkout.c:992
+#: builtin/checkout.c:791 builtin/checkout.c:1028
 msgid "You are on a branch yet to be born"
 msgstr ""
 
-#. case (1)
-#: builtin/checkout.c:928
+#: builtin/checkout.c:935
+#, c-format
+msgid "only one reference expected, %d given."
+msgstr ""
+
+#: builtin/checkout.c:974
 #, c-format
 msgid "invalid reference: %s"
 msgstr ""
 
 #. case (1): want a tree
-#: builtin/checkout.c:967
+#: builtin/checkout.c:1003
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr ""
 
-#: builtin/checkout.c:1006
+#: builtin/checkout.c:1042
 msgid "paths cannot be used with switching branches"
 msgstr ""
 
-#: builtin/checkout.c:1009 builtin/checkout.c:1013
+#: builtin/checkout.c:1045 builtin/checkout.c:1049
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr ""
 
-#: builtin/checkout.c:1017 builtin/checkout.c:1020 builtin/checkout.c:1025
-#: builtin/checkout.c:1028
+#: builtin/checkout.c:1053 builtin/checkout.c:1056 builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr ""
 
-#: builtin/checkout.c:1033
+#: builtin/checkout.c:1069
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr ""
 
-#: builtin/checkout.c:1055 builtin/checkout.c:1057 builtin/clone.c:89
+#: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88
 #: builtin/remote.c:169 builtin/remote.c:171
 msgid "branch"
 msgstr ""
 
-#: builtin/checkout.c:1056
+#: builtin/checkout.c:1092
 msgid "create and checkout a new branch"
 msgstr ""
 
-#: builtin/checkout.c:1058
+#: builtin/checkout.c:1094
 msgid "create/reset and checkout a branch"
 msgstr ""
 
-#: builtin/checkout.c:1059
+#: builtin/checkout.c:1095
 msgid "create reflog for new branch"
 msgstr ""
 
-#: builtin/checkout.c:1060
+#: builtin/checkout.c:1096
 msgid "detach the HEAD at named commit"
 msgstr ""
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1097
 msgid "set upstream info for new branch"
 msgstr ""
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new branch"
 msgstr ""
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new unparented branch"
 msgstr ""
 
-#: builtin/checkout.c:1064
+#: builtin/checkout.c:1100
 msgid "checkout our version for unmerged files"
 msgstr ""
 
-#: builtin/checkout.c:1066
+#: builtin/checkout.c:1102
 msgid "checkout their version for unmerged files"
 msgstr ""
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1104
 msgid "force checkout (throw away local modifications)"
 msgstr ""
 
-#: builtin/checkout.c:1069
+#: builtin/checkout.c:1105
 msgid "perform a 3-way merge with the new branch"
 msgstr ""
 
-#: builtin/checkout.c:1070 builtin/merge.c:232
+#: builtin/checkout.c:1106 builtin/merge.c:232
 msgid "update ignored files (default)"
 msgstr ""
 
-#: builtin/checkout.c:1071 builtin/log.c:1208 parse-options.h:249
+#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:251
 msgid "style"
 msgstr ""
 
-#: builtin/checkout.c:1072
+#: builtin/checkout.c:1108
 msgid "conflict style (merge or diff3)"
 msgstr ""
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1111
 msgid "do not limit pathspecs to sparse entries only"
 msgstr ""
 
-#: builtin/checkout.c:1077
+#: builtin/checkout.c:1113
 msgid "second guess 'git checkout no-such-branch'"
 msgstr ""
 
-#: builtin/checkout.c:1101
+#: builtin/checkout.c:1136
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr ""
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1153
 msgid "--track needs a branch name"
 msgstr ""
 
-#: builtin/checkout.c:1125
+#: builtin/checkout.c:1160
 msgid "Missing branch name; try -b"
 msgstr ""
 
-#: builtin/checkout.c:1160
+#: builtin/checkout.c:1197
 msgid "invalid path specification"
 msgstr ""
 
-#: builtin/checkout.c:1167
+#: builtin/checkout.c:1204
 #, c-format
 msgid ""
 "Cannot update paths and switch to branch '%s' at the same time.\n"
 "Did you intend to checkout '%s' which can not be resolved as commit?"
 msgstr ""
 
-#: builtin/checkout.c:1172
+#: builtin/checkout.c:1209
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr ""
 
-#: builtin/checkout.c:1176
+#: builtin/checkout.c:1213
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
 
-#: builtin/clean.c:25
+#: builtin/clean.c:26
 msgid ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
 msgstr ""
 
-#: builtin/clean.c:29
+#: builtin/clean.c:30
 #, c-format
 msgid "Removing %s\n"
 msgstr ""
 
-#: builtin/clean.c:30
+#: builtin/clean.c:31
 #, c-format
 msgid "Would remove %s\n"
 msgstr ""
 
-#: builtin/clean.c:31
+#: builtin/clean.c:32
 #, c-format
 msgid "Skipping repository %s\n"
 msgstr ""
 
-#: builtin/clean.c:32
+#: builtin/clean.c:33
 #, c-format
 msgid "Would skip repository %s\n"
 msgstr ""
 
-#: builtin/clean.c:33
+#: builtin/clean.c:34
 #, c-format
 msgid "failed to remove %s"
 msgstr ""
 
-#: builtin/clean.c:293
+#: builtin/clean.c:294
 msgid ""
 "Prompt help:\n"
 "1          - select a numbered item\n"
@@ -3287,7 +3465,7 @@
 "           - (empty) select nothing"
 msgstr ""
 
-#: builtin/clean.c:297
+#: builtin/clean.c:298
 msgid ""
 "Prompt help:\n"
 "1          - select a single item\n"
@@ -3299,35 +3477,35 @@
 "           - (empty) finish selecting"
 msgstr ""
 
-#: builtin/clean.c:515
+#: builtin/clean.c:516
 #, c-format
 msgid "Huh (%s)?"
 msgstr ""
 
-#: builtin/clean.c:658
+#: builtin/clean.c:659
 #, c-format
 msgid "Input ignore patterns>> "
 msgstr ""
 
-#: builtin/clean.c:695
+#: builtin/clean.c:696
 #, c-format
 msgid "WARNING: Cannot find items matched by: %s"
 msgstr ""
 
-#: builtin/clean.c:716
+#: builtin/clean.c:717
 msgid "Select items to delete"
 msgstr ""
 
-#: builtin/clean.c:756
+#: builtin/clean.c:757
 #, c-format
 msgid "remove %s? "
 msgstr ""
 
-#: builtin/clean.c:781
+#: builtin/clean.c:782
 msgid "Bye."
 msgstr ""
 
-#: builtin/clean.c:789
+#: builtin/clean.c:790
 msgid ""
 "clean               - start cleaning\n"
 "filter by pattern   - exclude items from deletion\n"
@@ -3338,21 +3516,21 @@
 "?                   - help for prompt selection"
 msgstr ""
 
-#: builtin/clean.c:816
+#: builtin/clean.c:817
 msgid "*** Commands ***"
 msgstr ""
 
-#: builtin/clean.c:817
+#: builtin/clean.c:818
 msgid "What now"
 msgstr ""
 
-#: builtin/clean.c:825
+#: builtin/clean.c:826
 msgid "Would remove the following item:"
 msgid_plural "Would remove the following items:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/clean.c:842
+#: builtin/clean.c:843
 msgid "No more files to clean, exiting."
 msgstr ""
 
@@ -3372,8 +3550,8 @@
 msgid "remove whole directories"
 msgstr ""
 
-#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:716
-#: builtin/ls-files.c:493 builtin/name-rev.c:315 builtin/show-ref.c:186
+#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718
+#: builtin/ls-files.c:483 builtin/name-rev.c:315 builtin/show-ref.c:185
 msgid "pattern"
 msgstr ""
 
@@ -3409,8 +3587,8 @@
 msgid "git clone [options] [--] <repo> [<dir>]"
 msgstr ""
 
-#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:229
-#: builtin/push.c:462
+#: builtin/clone.c:64 builtin/fetch.c:96 builtin/merge.c:229
+#: builtin/push.c:474
 msgid "force progress reporting"
 msgstr ""
 
@@ -3422,227 +3600,222 @@
 msgid "create a bare repository"
 msgstr ""
 
-#: builtin/clone.c:72
+#: builtin/clone.c:71
 msgid "create a mirror repository (implies bare)"
 msgstr ""
 
-#: builtin/clone.c:74
+#: builtin/clone.c:73
 msgid "to clone from a local repository"
 msgstr ""
 
-#: builtin/clone.c:76
+#: builtin/clone.c:75
 msgid "don't use local hardlinks, always copy"
 msgstr ""
 
-#: builtin/clone.c:78
+#: builtin/clone.c:77
 msgid "setup as shared repository"
 msgstr ""
 
-#: builtin/clone.c:80 builtin/clone.c:82
+#: builtin/clone.c:79 builtin/clone.c:81
 msgid "initialize submodules in the clone"
 msgstr ""
 
-#: builtin/clone.c:83 builtin/init-db.c:485
+#: builtin/clone.c:82 builtin/init-db.c:485
 msgid "template-directory"
 msgstr ""
 
-#: builtin/clone.c:84 builtin/init-db.c:486
+#: builtin/clone.c:83 builtin/init-db.c:486
 msgid "directory from which templates will be used"
 msgstr ""
 
-#: builtin/clone.c:86
+#: builtin/clone.c:85
 msgid "reference repository"
 msgstr ""
 
-#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44
+#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44
 msgid "name"
 msgstr ""
 
-#: builtin/clone.c:88
+#: builtin/clone.c:87
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr ""
 
-#: builtin/clone.c:90
+#: builtin/clone.c:89
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr ""
 
-#: builtin/clone.c:92
+#: builtin/clone.c:91
 msgid "path to git-upload-pack on the remote"
 msgstr ""
 
-#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:661
+#: builtin/clone.c:92 builtin/fetch.c:97 builtin/grep.c:663
 msgid "depth"
 msgstr ""
 
-#: builtin/clone.c:94
+#: builtin/clone.c:93
 msgid "create a shallow clone of that depth"
 msgstr ""
 
-#: builtin/clone.c:96
+#: builtin/clone.c:95
 msgid "clone only one branch, HEAD or --branch"
 msgstr ""
 
-#: builtin/clone.c:97 builtin/init-db.c:494
+#: builtin/clone.c:96 builtin/init-db.c:494
 msgid "gitdir"
 msgstr ""
 
-#: builtin/clone.c:98 builtin/init-db.c:495
+#: builtin/clone.c:97 builtin/init-db.c:495
 msgid "separate git dir from working tree"
 msgstr ""
 
-#: builtin/clone.c:99
+#: builtin/clone.c:98
 msgid "key=value"
 msgstr ""
 
-#: builtin/clone.c:100
+#: builtin/clone.c:99
 msgid "set config inside the new repository"
 msgstr ""
 
-#: builtin/clone.c:253
+#: builtin/clone.c:252
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr ""
 
-#: builtin/clone.c:316
+#: builtin/clone.c:315
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr ""
 
-#: builtin/clone.c:318 builtin/diff.c:77
+#: builtin/clone.c:317 builtin/diff.c:77
 #, c-format
 msgid "failed to stat '%s'"
 msgstr ""
 
-#: builtin/clone.c:320
+#: builtin/clone.c:319
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr ""
 
-#: builtin/clone.c:334
+#: builtin/clone.c:333
 #, c-format
 msgid "failed to stat %s\n"
 msgstr ""
 
-#: builtin/clone.c:356
+#: builtin/clone.c:355
 #, c-format
 msgid "failed to create link '%s'"
 msgstr ""
 
-#: builtin/clone.c:360
+#: builtin/clone.c:359
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr ""
 
-#: builtin/clone.c:383
+#: builtin/clone.c:382 builtin/clone.c:559
 #, c-format
 msgid "done.\n"
 msgstr ""
 
-#: builtin/clone.c:396
+#: builtin/clone.c:395
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
 "and retry the checkout with 'git checkout -f HEAD'\n"
 msgstr ""
 
-#: builtin/clone.c:475
+#: builtin/clone.c:474
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr ""
 
-#: builtin/clone.c:555
+#: builtin/clone.c:554
 #, c-format
 msgid "Checking connectivity... "
 msgstr ""
 
-#: builtin/clone.c:558
+#: builtin/clone.c:557
 msgid "remote did not send all necessary objects"
 msgstr ""
 
-#: builtin/clone.c:560
-#, c-format
-msgid "done\n"
-msgstr ""
-
-#: builtin/clone.c:621
+#: builtin/clone.c:620
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 
-#: builtin/clone.c:652
+#: builtin/clone.c:651
 msgid "unable to checkout working tree"
 msgstr ""
 
-#: builtin/clone.c:760
+#: builtin/clone.c:759
 msgid "Too many arguments."
 msgstr ""
 
-#: builtin/clone.c:764
+#: builtin/clone.c:763
 msgid "You must specify a repository to clone."
 msgstr ""
 
-#: builtin/clone.c:775
+#: builtin/clone.c:774
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr ""
 
-#: builtin/clone.c:778
+#: builtin/clone.c:777
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr ""
 
-#: builtin/clone.c:791
+#: builtin/clone.c:790
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr ""
 
-#: builtin/clone.c:796
+#: builtin/clone.c:795
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr ""
 
-#: builtin/clone.c:798
+#: builtin/clone.c:797
 msgid "--local is ignored"
 msgstr ""
 
-#: builtin/clone.c:808
+#: builtin/clone.c:807
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr ""
 
-#: builtin/clone.c:818
+#: builtin/clone.c:817
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr ""
 
-#: builtin/clone.c:831 builtin/clone.c:843
+#: builtin/clone.c:830 builtin/clone.c:842
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr ""
 
-#: builtin/clone.c:834
+#: builtin/clone.c:833
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr ""
 
-#: builtin/clone.c:853
+#: builtin/clone.c:852
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr ""
 
-#: builtin/clone.c:855
+#: builtin/clone.c:854
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr ""
 
-#: builtin/clone.c:890
+#: builtin/clone.c:888
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr ""
 
-#: builtin/clone.c:942
+#: builtin/clone.c:939 builtin/clone.c:947
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr ""
 
-#: builtin/clone.c:949
+#: builtin/clone.c:950
 msgid "You appear to have cloned an empty repository."
 msgstr ""
 
@@ -3678,15 +3851,15 @@
 msgid "--command must be the first argument"
 msgstr ""
 
-#: builtin/commit.c:35
+#: builtin/commit.c:36
 msgid "git commit [options] [--] <pathspec>..."
 msgstr ""
 
-#: builtin/commit.c:40
+#: builtin/commit.c:41
 msgid "git status [options] [--] <pathspec>..."
 msgstr ""
 
-#: builtin/commit.c:45
+#: builtin/commit.c:46
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3700,14 +3873,14 @@
 "    git commit --amend --reset-author\n"
 msgstr ""
 
-#: builtin/commit.c:57
+#: builtin/commit.c:58
 msgid ""
 "You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
 "remove the commit entirely with \"git reset HEAD^\".\n"
 msgstr ""
 
-#: builtin/commit.c:62
+#: builtin/commit.c:63
 msgid ""
 "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 "If you wish to commit it anyway, use:\n"
@@ -3716,11 +3889,11 @@
 "\n"
 msgstr ""
 
-#: builtin/commit.c:69
+#: builtin/commit.c:70
 msgid "Otherwise, please use 'git reset'\n"
 msgstr ""
 
-#: builtin/commit.c:72
+#: builtin/commit.c:73
 msgid ""
 "If you wish to skip this commit, use:\n"
 "\n"
@@ -3730,93 +3903,93 @@
 "the remaining commits.\n"
 msgstr ""
 
-#: builtin/commit.c:279
+#: builtin/commit.c:287
 msgid "failed to unpack HEAD tree object"
 msgstr ""
 
-#: builtin/commit.c:321
+#: builtin/commit.c:329
 msgid "unable to create temporary index"
 msgstr ""
 
-#: builtin/commit.c:327
+#: builtin/commit.c:335
 msgid "interactive add failed"
 msgstr ""
 
-#: builtin/commit.c:360 builtin/commit.c:381 builtin/commit.c:431
+#: builtin/commit.c:368 builtin/commit.c:389 builtin/commit.c:439
 msgid "unable to write new_index file"
 msgstr ""
 
-#: builtin/commit.c:412
+#: builtin/commit.c:420
 msgid "cannot do a partial commit during a merge."
 msgstr ""
 
-#: builtin/commit.c:414
+#: builtin/commit.c:422
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr ""
 
-#: builtin/commit.c:424
+#: builtin/commit.c:432
 msgid "cannot read the index"
 msgstr ""
 
-#: builtin/commit.c:444
+#: builtin/commit.c:452
 msgid "unable to write temporary index file"
 msgstr ""
 
-#: builtin/commit.c:535 builtin/commit.c:541
+#: builtin/commit.c:543 builtin/commit.c:549
 #, c-format
 msgid "invalid commit: %s"
 msgstr ""
 
-#: builtin/commit.c:563
+#: builtin/commit.c:571
 msgid "malformed --author parameter"
 msgstr ""
 
-#: builtin/commit.c:583
+#: builtin/commit.c:591
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr ""
 
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:982
+#: builtin/commit.c:630 builtin/commit.c:663 builtin/commit.c:1007
 #, c-format
 msgid "could not lookup commit %s"
 msgstr ""
 
-#: builtin/commit.c:633 builtin/shortlog.c:271
+#: builtin/commit.c:642 builtin/shortlog.c:273
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr ""
 
-#: builtin/commit.c:635
+#: builtin/commit.c:644
 msgid "could not read log from standard input"
 msgstr ""
 
-#: builtin/commit.c:639
+#: builtin/commit.c:648
 #, c-format
 msgid "could not read log file '%s'"
 msgstr ""
 
-#: builtin/commit.c:645
+#: builtin/commit.c:654
 msgid "commit has empty message"
 msgstr ""
 
-#: builtin/commit.c:661
+#: builtin/commit.c:670
 msgid "could not read MERGE_MSG"
 msgstr ""
 
-#: builtin/commit.c:665
+#: builtin/commit.c:674
 msgid "could not read SQUASH_MSG"
 msgstr ""
 
-#: builtin/commit.c:669
+#: builtin/commit.c:678
 #, c-format
 msgid "could not read '%s'"
 msgstr ""
 
-#: builtin/commit.c:730
+#: builtin/commit.c:749
 msgid "could not write commit template"
 msgstr ""
 
-#: builtin/commit.c:741
+#: builtin/commit.c:760
 #, c-format
 msgid ""
 "\n"
@@ -3826,7 +3999,7 @@
 "and try again.\n"
 msgstr ""
 
-#: builtin/commit.c:746
+#: builtin/commit.c:765
 #, c-format
 msgid ""
 "\n"
@@ -3836,14 +4009,14 @@
 "and try again.\n"
 msgstr ""
 
-#: builtin/commit.c:758
+#: builtin/commit.c:777
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '%c' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 
-#: builtin/commit.c:763
+#: builtin/commit.c:782
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -3851,478 +4024,482 @@
 "An empty message aborts the commit.\n"
 msgstr ""
 
-#: builtin/commit.c:776
+#: builtin/commit.c:795
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr ""
 
-#: builtin/commit.c:783
+#: builtin/commit.c:802
 #, c-format
 msgid "%sCommitter: %s"
 msgstr ""
 
-#: builtin/commit.c:803
+#: builtin/commit.c:822
 msgid "Cannot read index"
 msgstr ""
 
-#: builtin/commit.c:845
+#: builtin/commit.c:865
 msgid "Error building trees"
 msgstr ""
 
-#: builtin/commit.c:860 builtin/tag.c:359
+#: builtin/commit.c:880 builtin/tag.c:359
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr ""
 
-#: builtin/commit.c:957
+#: builtin/commit.c:982
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr ""
 
-#: builtin/commit.c:972 builtin/commit.c:1208
+#: builtin/commit.c:997 builtin/commit.c:1237
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr ""
 
-#: builtin/commit.c:1009
+#: builtin/commit.c:1034
 msgid "--long and -z are incompatible"
 msgstr ""
 
-#: builtin/commit.c:1039
+#: builtin/commit.c:1064
 msgid "Using both --reset-author and --author does not make sense"
 msgstr ""
 
-#: builtin/commit.c:1050
+#: builtin/commit.c:1075
 msgid "You have nothing to amend."
 msgstr ""
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1078
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr ""
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1080
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr ""
 
-#: builtin/commit.c:1058
+#: builtin/commit.c:1083
 msgid "Options --squash and --fixup cannot be used together"
 msgstr ""
 
-#: builtin/commit.c:1068
+#: builtin/commit.c:1093
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr ""
 
-#: builtin/commit.c:1070
+#: builtin/commit.c:1095
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr ""
 
-#: builtin/commit.c:1078
+#: builtin/commit.c:1103
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
 
-#: builtin/commit.c:1095
+#: builtin/commit.c:1120
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1122
 msgid "No paths with --include/--only does not make sense."
 msgstr ""
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1124
 msgid "Clever... amending the last one with dirty index."
 msgstr ""
 
-#: builtin/commit.c:1101
+#: builtin/commit.c:1126
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
 msgstr ""
 
-#: builtin/commit.c:1111 builtin/tag.c:575
+#: builtin/commit.c:1136 builtin/tag.c:572
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr ""
 
-#: builtin/commit.c:1116
+#: builtin/commit.c:1141
 msgid "Paths with -a does not make sense."
 msgstr ""
 
-#: builtin/commit.c:1222 builtin/commit.c:1455
+#: builtin/commit.c:1251 builtin/commit.c:1482
 msgid "show status concisely"
 msgstr ""
 
-#: builtin/commit.c:1224 builtin/commit.c:1457
+#: builtin/commit.c:1253 builtin/commit.c:1484
 msgid "show branch information"
 msgstr ""
 
-#: builtin/commit.c:1226 builtin/commit.c:1459 builtin/push.c:452
+#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:460
 msgid "machine-readable output"
 msgstr ""
 
-#: builtin/commit.c:1229 builtin/commit.c:1461
+#: builtin/commit.c:1258 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr ""
 
-#: builtin/commit.c:1232 builtin/commit.c:1464
+#: builtin/commit.c:1261 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr ""
 
-#: builtin/commit.c:1234 builtin/commit.c:1467 builtin/fast-export.c:667
-#: builtin/fast-export.c:670 builtin/tag.c:459
+#: builtin/commit.c:1263 builtin/commit.c:1494 builtin/fast-export.c:674
+#: builtin/fast-export.c:677 builtin/tag.c:459
 msgid "mode"
 msgstr ""
 
-#: builtin/commit.c:1235 builtin/commit.c:1467
+#: builtin/commit.c:1264 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 
-#: builtin/commit.c:1238
+#: builtin/commit.c:1267
 msgid "show ignored files"
 msgstr ""
 
-#: builtin/commit.c:1239 parse-options.h:154
+#: builtin/commit.c:1268 parse-options.h:156
 msgid "when"
 msgstr ""
 
-#: builtin/commit.c:1240
+#: builtin/commit.c:1269
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
 msgstr ""
 
-#: builtin/commit.c:1242
+#: builtin/commit.c:1271
 msgid "list untracked files in columns"
 msgstr ""
 
-#: builtin/commit.c:1313
+#: builtin/commit.c:1340
 msgid "couldn't look up newly created commit"
 msgstr ""
 
-#: builtin/commit.c:1315
+#: builtin/commit.c:1342
 msgid "could not parse newly created commit"
 msgstr ""
 
-#: builtin/commit.c:1356
+#: builtin/commit.c:1383
 msgid "detached HEAD"
 msgstr ""
 
-#: builtin/commit.c:1358
+#: builtin/commit.c:1385
 msgid " (root-commit)"
 msgstr ""
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1452
 msgid "suppress summary after successful commit"
 msgstr ""
 
-#: builtin/commit.c:1426
+#: builtin/commit.c:1453
 msgid "show diff in commit message template"
 msgstr ""
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1455
 msgid "Commit message options"
 msgstr ""
 
-#: builtin/commit.c:1429 builtin/tag.c:457
+#: builtin/commit.c:1456 builtin/tag.c:457
 msgid "read message from file"
 msgstr ""
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "author"
 msgstr ""
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "override author for commit"
 msgstr ""
 
-#: builtin/commit.c:1431 builtin/gc.c:178
+#: builtin/commit.c:1458 builtin/gc.c:260
 msgid "date"
 msgstr ""
 
-#: builtin/commit.c:1431
+#: builtin/commit.c:1458
 msgid "override date for commit"
 msgstr ""
 
-#: builtin/commit.c:1432 builtin/merge.c:223 builtin/notes.c:405
+#: builtin/commit.c:1459 builtin/merge.c:223 builtin/notes.c:405
 #: builtin/notes.c:562 builtin/tag.c:455
 msgid "message"
 msgstr ""
 
-#: builtin/commit.c:1432
+#: builtin/commit.c:1459
 msgid "commit message"
 msgstr ""
 
-#: builtin/commit.c:1433
+#: builtin/commit.c:1460
 msgid "reuse and edit message from specified commit"
 msgstr ""
 
-#: builtin/commit.c:1434
+#: builtin/commit.c:1461
 msgid "reuse message from specified commit"
 msgstr ""
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1462
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1463
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1464
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr ""
 
-#: builtin/commit.c:1438 builtin/log.c:1160 builtin/revert.c:111
+#: builtin/commit.c:1465 builtin/log.c:1180 builtin/revert.c:86
 msgid "add Signed-off-by:"
 msgstr ""
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1466
 msgid "use specified template file"
 msgstr ""
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1467
 msgid "force edit of commit"
 msgstr ""
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1468
 msgid "default"
 msgstr ""
 
-#: builtin/commit.c:1441 builtin/tag.c:460
+#: builtin/commit.c:1468 builtin/tag.c:460
 msgid "how to strip spaces and #comments from message"
 msgstr ""
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1469
 msgid "include status in commit message template"
 msgstr ""
 
-#: builtin/commit.c:1443 builtin/merge.c:230 builtin/tag.c:461
+#: builtin/commit.c:1470 builtin/merge.c:230 builtin/tag.c:461
 msgid "key id"
 msgstr ""
 
-#: builtin/commit.c:1444 builtin/merge.c:231
+#: builtin/commit.c:1471 builtin/merge.c:231
 msgid "GPG sign commit"
 msgstr ""
 
 #. end commit message options
-#: builtin/commit.c:1447
+#: builtin/commit.c:1474
 msgid "Commit contents options"
 msgstr ""
 
-#: builtin/commit.c:1448
+#: builtin/commit.c:1475
 msgid "commit all changed files"
 msgstr ""
 
-#: builtin/commit.c:1449
+#: builtin/commit.c:1476
 msgid "add specified files to index for commit"
 msgstr ""
 
-#: builtin/commit.c:1450
+#: builtin/commit.c:1477
 msgid "interactively add files"
 msgstr ""
 
-#: builtin/commit.c:1451
+#: builtin/commit.c:1478
 msgid "interactively add changes"
 msgstr ""
 
-#: builtin/commit.c:1452
+#: builtin/commit.c:1479
 msgid "commit only specified files"
 msgstr ""
 
-#: builtin/commit.c:1453
+#: builtin/commit.c:1480
 msgid "bypass pre-commit hook"
 msgstr ""
 
-#: builtin/commit.c:1454
+#: builtin/commit.c:1481
 msgid "show what would be committed"
 msgstr ""
 
-#: builtin/commit.c:1465
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr ""
 
-#: builtin/commit.c:1466
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr ""
 
-#: builtin/commit.c:1471
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr ""
 
-#: builtin/commit.c:1474
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr ""
 
-#: builtin/commit.c:1507
+#: builtin/commit.c:1529
 msgid "could not parse HEAD commit"
 msgstr ""
 
-#: builtin/commit.c:1545 builtin/merge.c:525
+#: builtin/commit.c:1567 builtin/merge.c:525
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr ""
 
-#: builtin/commit.c:1552
+#: builtin/commit.c:1574
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr ""
 
-#: builtin/commit.c:1559
+#: builtin/commit.c:1581
 msgid "could not read MERGE_MODE"
 msgstr ""
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1600
 #, c-format
 msgid "could not read commit message: %s"
 msgstr ""
 
-#: builtin/commit.c:1592
+#: builtin/commit.c:1614
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr ""
 
-#: builtin/commit.c:1597
+#: builtin/commit.c:1619
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr ""
 
-#: builtin/commit.c:1612 builtin/merge.c:861 builtin/merge.c:886
+#: builtin/commit.c:1634 builtin/merge.c:861 builtin/merge.c:886
 msgid "failed to write commit object"
 msgstr ""
 
-#: builtin/commit.c:1633
+#: builtin/commit.c:1655
 msgid "cannot lock HEAD ref"
 msgstr ""
 
-#: builtin/commit.c:1637
+#: builtin/commit.c:1659
 msgid "cannot update HEAD ref"
 msgstr ""
 
-#: builtin/commit.c:1648
+#: builtin/commit.c:1670
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
 "not exceeded, and then \"git reset HEAD\" to recover."
 msgstr ""
 
-#: builtin/config.c:7
+#: builtin/config.c:8
 msgid "git config [options]"
 msgstr ""
 
-#: builtin/config.c:52
+#: builtin/config.c:54
 msgid "Config file location"
 msgstr ""
 
-#: builtin/config.c:53
+#: builtin/config.c:55
 msgid "use global config file"
 msgstr ""
 
-#: builtin/config.c:54
+#: builtin/config.c:56
 msgid "use system config file"
 msgstr ""
 
-#: builtin/config.c:55
+#: builtin/config.c:57
 msgid "use repository config file"
 msgstr ""
 
-#: builtin/config.c:56
+#: builtin/config.c:58
 msgid "use given config file"
 msgstr ""
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "blob-id"
 msgstr ""
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "read config from given blob object"
 msgstr ""
 
-#: builtin/config.c:58
+#: builtin/config.c:60
 msgid "Action"
 msgstr ""
 
-#: builtin/config.c:59
+#: builtin/config.c:61
 msgid "get value: name [value-regex]"
 msgstr ""
 
-#: builtin/config.c:60
+#: builtin/config.c:62
 msgid "get all values: key [value-regex]"
 msgstr ""
 
-#: builtin/config.c:61
+#: builtin/config.c:63
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr ""
 
-#: builtin/config.c:62
-msgid "replace all matching variables: name value [value_regex]"
-msgstr ""
-
-#: builtin/config.c:63
-msgid "add a new variable: name value"
-msgstr ""
-
 #: builtin/config.c:64
-msgid "remove a variable: name [value-regex]"
+msgid "get value specific for the URL: section[.var] URL"
 msgstr ""
 
 #: builtin/config.c:65
-msgid "remove all matches: name [value-regex]"
+msgid "replace all matching variables: name value [value_regex]"
 msgstr ""
 
 #: builtin/config.c:66
-msgid "rename section: old-name new-name"
+msgid "add a new variable: name value"
 msgstr ""
 
 #: builtin/config.c:67
-msgid "remove a section: name"
+msgid "remove a variable: name [value-regex]"
 msgstr ""
 
 #: builtin/config.c:68
-msgid "list all"
+msgid "remove all matches: name [value-regex]"
 msgstr ""
 
 #: builtin/config.c:69
-msgid "open an editor"
-msgstr ""
-
-#: builtin/config.c:70 builtin/config.c:71
-msgid "slot"
+msgid "rename section: old-name new-name"
 msgstr ""
 
 #: builtin/config.c:70
-msgid "find the color configured: [default]"
+msgid "remove a section: name"
 msgstr ""
 
 #: builtin/config.c:71
-msgid "find the color setting: [stdout-is-tty]"
+msgid "list all"
 msgstr ""
 
 #: builtin/config.c:72
-msgid "Type"
+msgid "open an editor"
+msgstr ""
+
+#: builtin/config.c:73 builtin/config.c:74
+msgid "slot"
 msgstr ""
 
 #: builtin/config.c:73
-msgid "value is \"true\" or \"false\""
+msgid "find the color configured: [default]"
 msgstr ""
 
 #: builtin/config.c:74
-msgid "value is decimal number"
+msgid "find the color setting: [stdout-is-tty]"
 msgstr ""
 
 #: builtin/config.c:75
-msgid "value is --bool or --int"
+msgid "Type"
 msgstr ""
 
 #: builtin/config.c:76
-msgid "value is a path (file or directory name)"
+msgid "value is \"true\" or \"false\""
 msgstr ""
 
 #: builtin/config.c:77
-msgid "Other"
+msgid "value is decimal number"
 msgstr ""
 
 #: builtin/config.c:78
-msgid "terminate values with NUL byte"
+msgid "value is --bool or --int"
 msgstr ""
 
 #: builtin/config.c:79
+msgid "value is a path (file or directory name)"
+msgstr ""
+
+#: builtin/config.c:80
+msgid "Other"
+msgstr ""
+
+#: builtin/config.c:81
+msgid "terminate values with NUL byte"
+msgstr ""
+
+#: builtin/config.c:82
 msgid "respect include directives on lookup"
 msgstr ""
 
@@ -4335,7 +4512,7 @@
 msgstr ""
 
 #: builtin/describe.c:16
-msgid "git describe [options] <committish>*"
+msgid "git describe [options] <commit-ish>*"
 msgstr ""
 
 #: builtin/describe.c:17
@@ -4465,7 +4642,7 @@
 msgstr ""
 
 #: builtin/describe.c:489
-msgid "--dirty is incompatible with committishes"
+msgid "--dirty is incompatible with commit-ishes"
 msgstr ""
 
 #: builtin/diff.c:79
@@ -4501,39 +4678,39 @@
 msgid "git fast-export [rev-list-opts]"
 msgstr ""
 
-#: builtin/fast-export.c:666
+#: builtin/fast-export.c:673
 msgid "show progress after <n> objects"
 msgstr ""
 
-#: builtin/fast-export.c:668
+#: builtin/fast-export.c:675
 msgid "select handling of signed tags"
 msgstr ""
 
-#: builtin/fast-export.c:671
+#: builtin/fast-export.c:678
 msgid "select handling of tags that tag filtered objects"
 msgstr ""
 
-#: builtin/fast-export.c:674
+#: builtin/fast-export.c:681
 msgid "Dump marks to this file"
 msgstr ""
 
-#: builtin/fast-export.c:676
+#: builtin/fast-export.c:683
 msgid "Import marks from this file"
 msgstr ""
 
-#: builtin/fast-export.c:678
+#: builtin/fast-export.c:685
 msgid "Fake a tagger when tags lack one"
 msgstr ""
 
-#: builtin/fast-export.c:680
+#: builtin/fast-export.c:687
 msgid "Output full tree for each commit"
 msgstr ""
 
-#: builtin/fast-export.c:682
+#: builtin/fast-export.c:689
 msgid "Use the done feature to terminate the stream"
 msgstr ""
 
-#: builtin/fast-export.c:683
+#: builtin/fast-export.c:690
 msgid "Skip output of blob data"
 msgstr ""
 
@@ -4553,230 +4730,230 @@
 msgid "git fetch --all [<options>]"
 msgstr ""
 
-#: builtin/fetch.c:60
+#: builtin/fetch.c:74
 msgid "fetch from all remotes"
 msgstr ""
 
-#: builtin/fetch.c:62
+#: builtin/fetch.c:76
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr ""
 
-#: builtin/fetch.c:64
+#: builtin/fetch.c:78
 msgid "path to upload pack on remote end"
 msgstr ""
 
-#: builtin/fetch.c:65
+#: builtin/fetch.c:79
 msgid "force overwrite of local branch"
 msgstr ""
 
-#: builtin/fetch.c:67
+#: builtin/fetch.c:81
 msgid "fetch from multiple remotes"
 msgstr ""
 
-#: builtin/fetch.c:69
+#: builtin/fetch.c:83
 msgid "fetch all tags and associated objects"
 msgstr ""
 
-#: builtin/fetch.c:71
+#: builtin/fetch.c:85
 msgid "do not fetch all tags (--no-tags)"
 msgstr ""
 
-#: builtin/fetch.c:73
+#: builtin/fetch.c:87
 msgid "prune remote-tracking branches no longer on remote"
 msgstr ""
 
-#: builtin/fetch.c:74
+#: builtin/fetch.c:88
 msgid "on-demand"
 msgstr ""
 
-#: builtin/fetch.c:75
+#: builtin/fetch.c:89
 msgid "control recursive fetching of submodules"
 msgstr ""
 
-#: builtin/fetch.c:79
+#: builtin/fetch.c:93
 msgid "keep downloaded pack"
 msgstr ""
 
-#: builtin/fetch.c:81
+#: builtin/fetch.c:95
 msgid "allow updating of HEAD ref"
 msgstr ""
 
-#: builtin/fetch.c:84
+#: builtin/fetch.c:98
 msgid "deepen history of shallow clone"
 msgstr ""
 
-#: builtin/fetch.c:86
+#: builtin/fetch.c:100
 msgid "convert to a complete repository"
 msgstr ""
 
-#: builtin/fetch.c:88 builtin/log.c:1177
+#: builtin/fetch.c:102 builtin/log.c:1197
 msgid "dir"
 msgstr ""
 
-#: builtin/fetch.c:89
+#: builtin/fetch.c:103
 msgid "prepend this to submodule path output"
 msgstr ""
 
-#: builtin/fetch.c:92
+#: builtin/fetch.c:106
 msgid "default mode for recursion"
 msgstr ""
 
-#: builtin/fetch.c:220
+#: builtin/fetch.c:236
 msgid "Couldn't find remote ref HEAD"
 msgstr ""
 
-#: builtin/fetch.c:273
+#: builtin/fetch.c:290
 #, c-format
 msgid "object %s not found"
 msgstr ""
 
-#: builtin/fetch.c:278
+#: builtin/fetch.c:295
 msgid "[up to date]"
 msgstr ""
 
-#: builtin/fetch.c:292
+#: builtin/fetch.c:309
 #, c-format
 msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
 msgstr ""
 
-#: builtin/fetch.c:293 builtin/fetch.c:379
+#: builtin/fetch.c:310 builtin/fetch.c:396
 msgid "[rejected]"
 msgstr ""
 
-#: builtin/fetch.c:304
+#: builtin/fetch.c:321
 msgid "[tag update]"
 msgstr ""
 
-#: builtin/fetch.c:306 builtin/fetch.c:341 builtin/fetch.c:359
+#: builtin/fetch.c:323 builtin/fetch.c:358 builtin/fetch.c:376
 msgid "  (unable to update local ref)"
 msgstr ""
 
-#: builtin/fetch.c:324
+#: builtin/fetch.c:341
 msgid "[new tag]"
 msgstr ""
 
-#: builtin/fetch.c:327
+#: builtin/fetch.c:344
 msgid "[new branch]"
 msgstr ""
 
-#: builtin/fetch.c:330
+#: builtin/fetch.c:347
 msgid "[new ref]"
 msgstr ""
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "unable to update local ref"
 msgstr ""
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "forced update"
 msgstr ""
 
-#: builtin/fetch.c:381
+#: builtin/fetch.c:398
 msgid "(non-fast-forward)"
 msgstr ""
 
-#: builtin/fetch.c:412 builtin/fetch.c:718
+#: builtin/fetch.c:429 builtin/fetch.c:735
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr ""
 
-#: builtin/fetch.c:421
+#: builtin/fetch.c:438
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr ""
 
-#: builtin/fetch.c:520
+#: builtin/fetch.c:537
 #, c-format
 msgid "From %.*s\n"
 msgstr ""
 
-#: builtin/fetch.c:531
+#: builtin/fetch.c:548
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
 " 'git remote prune %s' to remove any old, conflicting branches"
 msgstr ""
 
-#: builtin/fetch.c:581
+#: builtin/fetch.c:598
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr ""
 
-#: builtin/fetch.c:582
+#: builtin/fetch.c:599
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr ""
 
-#: builtin/fetch.c:589
+#: builtin/fetch.c:606
 msgid "[deleted]"
 msgstr ""
 
-#: builtin/fetch.c:590 builtin/remote.c:1055
+#: builtin/fetch.c:607 builtin/remote.c:1055
 msgid "(none)"
 msgstr ""
 
-#: builtin/fetch.c:708
+#: builtin/fetch.c:725
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr ""
 
-#: builtin/fetch.c:742
-#, c-format
-msgid "Don't know how to fetch from %s"
-msgstr ""
-
-#: builtin/fetch.c:823
+#: builtin/fetch.c:744
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr ""
 
-#: builtin/fetch.c:826
+#: builtin/fetch.c:747
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr ""
 
-#: builtin/fetch.c:928
+#: builtin/fetch.c:801
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr ""
+
+#: builtin/fetch.c:976
 #, c-format
 msgid "Fetching %s\n"
 msgstr ""
 
-#: builtin/fetch.c:930 builtin/remote.c:100
+#: builtin/fetch.c:978 builtin/remote.c:100
 #, c-format
 msgid "Could not fetch %s"
 msgstr ""
 
-#: builtin/fetch.c:949
+#: builtin/fetch.c:997
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
 msgstr ""
 
-#: builtin/fetch.c:969
+#: builtin/fetch.c:1020
 msgid "You need to specify a tag name."
 msgstr ""
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1068
 msgid "--depth and --unshallow cannot be used together"
 msgstr ""
 
-#: builtin/fetch.c:1017
+#: builtin/fetch.c:1070
 msgid "--unshallow on a complete repository does not make sense"
 msgstr ""
 
-#: builtin/fetch.c:1036
+#: builtin/fetch.c:1089
 msgid "fetch --all does not take a repository argument"
 msgstr ""
 
-#: builtin/fetch.c:1038
+#: builtin/fetch.c:1091
 msgid "fetch --all does not make sense with refspecs"
 msgstr ""
 
-#: builtin/fetch.c:1049
+#: builtin/fetch.c:1102
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr ""
 
-#: builtin/fetch.c:1057
+#: builtin/fetch.c:1110
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr ""
 
@@ -4784,9 +4961,9 @@
 msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]"
 msgstr ""
 
-#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:700
-#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:179
-#: builtin/tag.c:446 parse-options.h:133 parse-options.h:243
+#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:702
+#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:178
+#: builtin/tag.c:446 parse-options.h:135 parse-options.h:245
 msgid "n"
 msgstr ""
 
@@ -4810,158 +4987,169 @@
 msgid "file to read from"
 msgstr ""
 
-#: builtin/for-each-ref.c:979
+#: builtin/for-each-ref.c:995
 msgid "git for-each-ref [options] [<pattern>]"
 msgstr ""
 
-#: builtin/for-each-ref.c:994
+#: builtin/for-each-ref.c:1010
 msgid "quote placeholders suitably for shells"
 msgstr ""
 
-#: builtin/for-each-ref.c:996
+#: builtin/for-each-ref.c:1012
 msgid "quote placeholders suitably for perl"
 msgstr ""
 
-#: builtin/for-each-ref.c:998
+#: builtin/for-each-ref.c:1014
 msgid "quote placeholders suitably for python"
 msgstr ""
 
-#: builtin/for-each-ref.c:1000
+#: builtin/for-each-ref.c:1016
 msgid "quote placeholders suitably for tcl"
 msgstr ""
 
-#: builtin/for-each-ref.c:1003
+#: builtin/for-each-ref.c:1019
 msgid "show only <n> matched refs"
 msgstr ""
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format"
 msgstr ""
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format to use for the output"
 msgstr ""
 
-#: builtin/for-each-ref.c:1005
+#: builtin/for-each-ref.c:1021
 msgid "key"
 msgstr ""
 
-#: builtin/for-each-ref.c:1006
+#: builtin/for-each-ref.c:1022
 msgid "field name to sort on"
 msgstr ""
 
-#: builtin/fsck.c:608
+#: builtin/fsck.c:607
 msgid "git fsck [options] [<object>...]"
 msgstr ""
 
-#: builtin/fsck.c:614
+#: builtin/fsck.c:613
 msgid "show unreachable objects"
 msgstr ""
 
-#: builtin/fsck.c:615
+#: builtin/fsck.c:614
 msgid "show dangling objects"
 msgstr ""
 
-#: builtin/fsck.c:616
+#: builtin/fsck.c:615
 msgid "report tags"
 msgstr ""
 
-#: builtin/fsck.c:617
+#: builtin/fsck.c:616
 msgid "report root nodes"
 msgstr ""
 
-#: builtin/fsck.c:618
+#: builtin/fsck.c:617
 msgid "make index objects head nodes"
 msgstr ""
 
-#: builtin/fsck.c:619
+#: builtin/fsck.c:618
 msgid "make reflogs head nodes (default)"
 msgstr ""
 
-#: builtin/fsck.c:620
+#: builtin/fsck.c:619
 msgid "also consider packs and alternate objects"
 msgstr ""
 
-#: builtin/fsck.c:621
+#: builtin/fsck.c:620
 msgid "enable more strict checking"
 msgstr ""
 
-#: builtin/fsck.c:623
+#: builtin/fsck.c:622
 msgid "write dangling objects in .git/lost-found"
 msgstr ""
 
-#: builtin/fsck.c:624 builtin/prune.c:134
+#: builtin/fsck.c:623 builtin/prune.c:134
 msgid "show progress"
 msgstr ""
 
-#: builtin/gc.c:22
+#: builtin/gc.c:23
 msgid "git gc [options]"
 msgstr ""
 
-#: builtin/gc.c:63
+#: builtin/gc.c:79
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr ""
 
-#: builtin/gc.c:90
+#: builtin/gc.c:106
 #, c-format
 msgid "insanely long object directory %.*s"
 msgstr ""
 
-#: builtin/gc.c:179
+#: builtin/gc.c:261
 msgid "prune unreferenced objects"
 msgstr ""
 
-#: builtin/gc.c:181
+#: builtin/gc.c:263
 msgid "be more thorough (increased runtime)"
 msgstr ""
 
-#: builtin/gc.c:182
+#: builtin/gc.c:264
 msgid "enable auto-gc mode"
 msgstr ""
 
-#: builtin/gc.c:222
+#: builtin/gc.c:265
+msgid "force running gc even if there may be another gc running"
+msgstr ""
+
+#: builtin/gc.c:305
 #, c-format
 msgid ""
 "Auto packing the repository for optimum performance. You may also\n"
 "run \"git gc\" manually. See \"git help gc\" for more information.\n"
 msgstr ""
 
-#: builtin/gc.c:249
+#. be quiet on --auto
+#: builtin/gc.c:315
+#, c-format
+msgid ""
+"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
+msgstr ""
+
+#: builtin/gc.c:340
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 
-#: builtin/grep.c:22
+#: builtin/grep.c:23
 msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr ""
 
-#: builtin/grep.c:217
+#: builtin/grep.c:218
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr ""
 
-#: builtin/grep.c:364
+#: builtin/grep.c:365
 #, c-format
 msgid "Failed to chdir: %s"
 msgstr ""
 
-#: builtin/grep.c:442 builtin/grep.c:477
+#: builtin/grep.c:443 builtin/grep.c:478
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr ""
 
-#: builtin/grep.c:492
+#: builtin/grep.c:493
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr ""
 
-#: builtin/grep.c:550
+#: builtin/grep.c:551
 #, c-format
 msgid "switch `%c' expects a numerical value"
 msgstr ""
 
-#: builtin/grep.c:567
+#: builtin/grep.c:568
 #, c-format
 msgid "cannot open '%s'"
 msgstr ""
@@ -5003,158 +5191,162 @@
 msgstr ""
 
 #: builtin/grep.c:662
+msgid "process binary files with textconv filters"
+msgstr ""
+
+#: builtin/grep.c:664
 msgid "descend at most <depth> levels"
 msgstr ""
 
-#: builtin/grep.c:666
+#: builtin/grep.c:668
 msgid "use extended POSIX regular expressions"
 msgstr ""
 
-#: builtin/grep.c:669
+#: builtin/grep.c:671
 msgid "use basic POSIX regular expressions (default)"
 msgstr ""
 
-#: builtin/grep.c:672
+#: builtin/grep.c:674
 msgid "interpret patterns as fixed strings"
 msgstr ""
 
-#: builtin/grep.c:675
+#: builtin/grep.c:677
 msgid "use Perl-compatible regular expressions"
 msgstr ""
 
-#: builtin/grep.c:678
+#: builtin/grep.c:680
 msgid "show line numbers"
 msgstr ""
 
-#: builtin/grep.c:679
+#: builtin/grep.c:681
 msgid "don't show filenames"
 msgstr ""
 
-#: builtin/grep.c:680
+#: builtin/grep.c:682
 msgid "show filenames"
 msgstr ""
 
-#: builtin/grep.c:682
+#: builtin/grep.c:684
 msgid "show filenames relative to top directory"
 msgstr ""
 
-#: builtin/grep.c:684
+#: builtin/grep.c:686
 msgid "show only filenames instead of matching lines"
 msgstr ""
 
-#: builtin/grep.c:686
+#: builtin/grep.c:688
 msgid "synonym for --files-with-matches"
 msgstr ""
 
-#: builtin/grep.c:689
+#: builtin/grep.c:691
 msgid "show only the names of files without match"
 msgstr ""
 
-#: builtin/grep.c:691
+#: builtin/grep.c:693
 msgid "print NUL after filenames"
 msgstr ""
 
-#: builtin/grep.c:693
+#: builtin/grep.c:695
 msgid "show the number of matches instead of matching lines"
 msgstr ""
 
-#: builtin/grep.c:694
+#: builtin/grep.c:696
 msgid "highlight matches"
 msgstr ""
 
-#: builtin/grep.c:696
+#: builtin/grep.c:698
 msgid "print empty line between matches from different files"
 msgstr ""
 
-#: builtin/grep.c:698
+#: builtin/grep.c:700
 msgid "show filename only once above matches from same file"
 msgstr ""
 
-#: builtin/grep.c:701
+#: builtin/grep.c:703
 msgid "show <n> context lines before and after matches"
 msgstr ""
 
-#: builtin/grep.c:704
+#: builtin/grep.c:706
 msgid "show <n> context lines before matches"
 msgstr ""
 
-#: builtin/grep.c:706
+#: builtin/grep.c:708
 msgid "show <n> context lines after matches"
 msgstr ""
 
-#: builtin/grep.c:707
+#: builtin/grep.c:709
 msgid "shortcut for -C NUM"
 msgstr ""
 
-#: builtin/grep.c:710
+#: builtin/grep.c:712
 msgid "show a line with the function name before matches"
 msgstr ""
 
-#: builtin/grep.c:712
+#: builtin/grep.c:714
 msgid "show the surrounding function"
 msgstr ""
 
-#: builtin/grep.c:715
+#: builtin/grep.c:717
 msgid "read patterns from file"
 msgstr ""
 
-#: builtin/grep.c:717
+#: builtin/grep.c:719
 msgid "match <pattern>"
 msgstr ""
 
-#: builtin/grep.c:719
+#: builtin/grep.c:721
 msgid "combine patterns specified with -e"
 msgstr ""
 
-#: builtin/grep.c:731
+#: builtin/grep.c:733
 msgid "indicate hit with exit status without output"
 msgstr ""
 
-#: builtin/grep.c:733
+#: builtin/grep.c:735
 msgid "show only matches from files that match all patterns"
 msgstr ""
 
-#: builtin/grep.c:735
+#: builtin/grep.c:737
 msgid "show parse tree for grep expression"
 msgstr ""
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "pager"
 msgstr ""
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "show matching files in the pager"
 msgstr ""
 
-#: builtin/grep.c:742
+#: builtin/grep.c:744
 msgid "allow calling of grep(1) (ignored by this build)"
 msgstr ""
 
-#: builtin/grep.c:743 builtin/show-ref.c:188
+#: builtin/grep.c:745 builtin/show-ref.c:187
 msgid "show usage"
 msgstr ""
 
-#: builtin/grep.c:810
+#: builtin/grep.c:812
 msgid "no pattern given."
 msgstr ""
 
-#: builtin/grep.c:865
+#: builtin/grep.c:870
 msgid "--open-files-in-pager only works on the worktree"
 msgstr ""
 
-#: builtin/grep.c:888
+#: builtin/grep.c:893
 msgid "--cached or --untracked cannot be used with --no-index."
 msgstr ""
 
-#: builtin/grep.c:893
+#: builtin/grep.c:898
 msgid "--no-index or --untracked cannot be used with revs."
 msgstr ""
 
-#: builtin/grep.c:896
+#: builtin/grep.c:901
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
 msgstr ""
 
-#: builtin/grep.c:904
+#: builtin/grep.c:909
 msgid "both --cached and trees are given."
 msgstr ""
 
@@ -5403,8 +5595,8 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr ""
 
-#: builtin/index-pack.c:669 builtin/pack-objects.c:170
-#: builtin/pack-objects.c:262
+#: builtin/index-pack.c:669 builtin/pack-objects.c:171
+#: builtin/pack-objects.c:263
 #, c-format
 msgid "unable to read %s"
 msgstr ""
@@ -5433,155 +5625,155 @@
 msgid "Not all child objects of %s are reachable"
 msgstr ""
 
-#: builtin/index-pack.c:838 builtin/index-pack.c:868
+#: builtin/index-pack.c:839 builtin/index-pack.c:869
 msgid "failed to apply delta"
 msgstr ""
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Receiving objects"
 msgstr ""
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Indexing objects"
 msgstr ""
 
-#: builtin/index-pack.c:1035
+#: builtin/index-pack.c:1036
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr ""
 
-#: builtin/index-pack.c:1040
+#: builtin/index-pack.c:1041
 msgid "cannot fstat packfile"
 msgstr ""
 
-#: builtin/index-pack.c:1043
+#: builtin/index-pack.c:1044
 msgid "pack has junk at the end"
 msgstr ""
 
-#: builtin/index-pack.c:1054
+#: builtin/index-pack.c:1055
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr ""
 
-#: builtin/index-pack.c:1077
+#: builtin/index-pack.c:1078
 msgid "Resolving deltas"
 msgstr ""
 
-#: builtin/index-pack.c:1087
+#: builtin/index-pack.c:1088
 #, c-format
 msgid "unable to create thread: %s"
 msgstr ""
 
-#: builtin/index-pack.c:1129
+#: builtin/index-pack.c:1130
 msgid "confusion beyond insanity"
 msgstr ""
 
-#: builtin/index-pack.c:1137
+#: builtin/index-pack.c:1138
 #, c-format
 msgid "completed with %d local objects"
 msgstr ""
 
-#: builtin/index-pack.c:1147
+#: builtin/index-pack.c:1148
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr ""
 
-#: builtin/index-pack.c:1151
+#: builtin/index-pack.c:1152
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1176
+#: builtin/index-pack.c:1177
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr ""
 
-#: builtin/index-pack.c:1255
+#: builtin/index-pack.c:1256
 #, c-format
 msgid "local object %s is corrupt"
 msgstr ""
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1280
 msgid "error while closing pack file"
 msgstr ""
 
-#: builtin/index-pack.c:1292
+#: builtin/index-pack.c:1293
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1300
+#: builtin/index-pack.c:1301
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1313
+#: builtin/index-pack.c:1314
 msgid "cannot store pack file"
 msgstr ""
 
-#: builtin/index-pack.c:1324
+#: builtin/index-pack.c:1325
 msgid "cannot store index file"
 msgstr ""
 
-#: builtin/index-pack.c:1357
+#: builtin/index-pack.c:1358
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr ""
 
-#: builtin/index-pack.c:1363
+#: builtin/index-pack.c:1364
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr ""
 
-#: builtin/index-pack.c:1367 builtin/index-pack.c:1545
+#: builtin/index-pack.c:1368 builtin/index-pack.c:1546
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr ""
 
-#: builtin/index-pack.c:1425
+#: builtin/index-pack.c:1426
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1427
+#: builtin/index-pack.c:1428
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1474
+#: builtin/index-pack.c:1475
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1481
+#: builtin/index-pack.c:1482
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1509
+#: builtin/index-pack.c:1510
 msgid "Cannot come back to cwd"
 msgstr ""
 
-#: builtin/index-pack.c:1557 builtin/index-pack.c:1560
-#: builtin/index-pack.c:1572 builtin/index-pack.c:1576
+#: builtin/index-pack.c:1558 builtin/index-pack.c:1561
+#: builtin/index-pack.c:1573 builtin/index-pack.c:1577
 #, c-format
 msgid "bad %s"
 msgstr ""
 
-#: builtin/index-pack.c:1590
+#: builtin/index-pack.c:1591
 msgid "--fix-thin cannot be used without --stdin"
 msgstr ""
 
-#: builtin/index-pack.c:1594 builtin/index-pack.c:1604
+#: builtin/index-pack.c:1595 builtin/index-pack.c:1605
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr ""
 
-#: builtin/index-pack.c:1613
+#: builtin/index-pack.c:1614
 msgid "--verify with no packfile name given"
 msgstr ""
 
@@ -5670,11 +5862,6 @@
 msgid "unable to move %s to %s"
 msgstr ""
 
-#: builtin/init-db.c:363
-#, c-format
-msgid "Could not create git link %s"
-msgstr ""
-
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
 #. * existing" or "Initialized empty", the second " shared" or
@@ -5715,7 +5902,7 @@
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr ""
 
-#: builtin/init-db.c:493 builtin/prune-packed.c:75
+#: builtin/init-db.c:493 builtin/prune-packed.c:75 builtin/repack.c:155
 msgid "be quiet"
 msgstr ""
 
@@ -5753,381 +5940,381 @@
 msgid "   or: git show [options] <object>..."
 msgstr ""
 
-#: builtin/log.c:124
+#: builtin/log.c:125
 msgid "suppress diff output"
 msgstr ""
 
-#: builtin/log.c:125
+#: builtin/log.c:126
 msgid "show source"
 msgstr ""
 
-#: builtin/log.c:126
+#: builtin/log.c:127
 msgid "Use mail map file"
 msgstr ""
 
-#: builtin/log.c:127
+#: builtin/log.c:128
 msgid "decorate options"
 msgstr ""
 
-#: builtin/log.c:230
+#: builtin/log.c:231
 #, c-format
 msgid "Final output: %d %s\n"
 msgstr ""
 
-#: builtin/log.c:453 builtin/log.c:545
+#: builtin/log.c:473 builtin/log.c:565
 #, c-format
 msgid "Could not read object %s"
 msgstr ""
 
-#: builtin/log.c:569
+#: builtin/log.c:589
 #, c-format
 msgid "Unknown type: %d"
 msgstr ""
 
-#: builtin/log.c:669
+#: builtin/log.c:689
 msgid "format.headers without value"
 msgstr ""
 
-#: builtin/log.c:751
+#: builtin/log.c:771
 msgid "name of output directory is too long"
 msgstr ""
 
-#: builtin/log.c:767
+#: builtin/log.c:787
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr ""
 
-#: builtin/log.c:781
+#: builtin/log.c:801
 msgid "Need exactly one range."
 msgstr ""
 
-#: builtin/log.c:789
+#: builtin/log.c:809
 msgid "Not a range."
 msgstr ""
 
-#: builtin/log.c:891
+#: builtin/log.c:911
 msgid "Cover letter needs email format"
 msgstr ""
 
-#: builtin/log.c:967
+#: builtin/log.c:987
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr ""
 
-#: builtin/log.c:995
+#: builtin/log.c:1015
 msgid "git format-patch [options] [<since> | <revision range>]"
 msgstr ""
 
-#: builtin/log.c:1040
+#: builtin/log.c:1060
 msgid "Two output directories?"
 msgstr ""
 
-#: builtin/log.c:1155
+#: builtin/log.c:1175
 msgid "use [PATCH n/m] even with a single patch"
 msgstr ""
 
-#: builtin/log.c:1158
+#: builtin/log.c:1178
 msgid "use [PATCH] even with multiple patches"
 msgstr ""
 
-#: builtin/log.c:1162
+#: builtin/log.c:1182
 msgid "print patches to standard out"
 msgstr ""
 
-#: builtin/log.c:1164
+#: builtin/log.c:1184
 msgid "generate a cover letter"
 msgstr ""
 
-#: builtin/log.c:1166
+#: builtin/log.c:1186
 msgid "use simple number sequence for output file names"
 msgstr ""
 
-#: builtin/log.c:1167
+#: builtin/log.c:1187
 msgid "sfx"
 msgstr ""
 
-#: builtin/log.c:1168
+#: builtin/log.c:1188
 msgid "use <sfx> instead of '.patch'"
 msgstr ""
 
-#: builtin/log.c:1170
+#: builtin/log.c:1190
 msgid "start numbering patches at <n> instead of 1"
 msgstr ""
 
-#: builtin/log.c:1172
+#: builtin/log.c:1192
 msgid "mark the series as Nth re-roll"
 msgstr ""
 
-#: builtin/log.c:1174
+#: builtin/log.c:1194
 msgid "Use [<prefix>] instead of [PATCH]"
 msgstr ""
 
-#: builtin/log.c:1177
+#: builtin/log.c:1197
 msgid "store resulting files in <dir>"
 msgstr ""
 
-#: builtin/log.c:1180
+#: builtin/log.c:1200
 msgid "don't strip/add [PATCH]"
 msgstr ""
 
-#: builtin/log.c:1183
+#: builtin/log.c:1203
 msgid "don't output binary diffs"
 msgstr ""
 
-#: builtin/log.c:1185
+#: builtin/log.c:1205
 msgid "don't include a patch matching a commit upstream"
 msgstr ""
 
-#: builtin/log.c:1187
+#: builtin/log.c:1207
 msgid "show patch format instead of default (patch + stat)"
 msgstr ""
 
-#: builtin/log.c:1189
+#: builtin/log.c:1209
 msgid "Messaging"
 msgstr ""
 
-#: builtin/log.c:1190
+#: builtin/log.c:1210
 msgid "header"
 msgstr ""
 
-#: builtin/log.c:1191
+#: builtin/log.c:1211
 msgid "add email header"
 msgstr ""
 
-#: builtin/log.c:1192 builtin/log.c:1194
+#: builtin/log.c:1212 builtin/log.c:1214
 msgid "email"
 msgstr ""
 
-#: builtin/log.c:1192
+#: builtin/log.c:1212
 msgid "add To: header"
 msgstr ""
 
-#: builtin/log.c:1194
+#: builtin/log.c:1214
 msgid "add Cc: header"
 msgstr ""
 
-#: builtin/log.c:1196
+#: builtin/log.c:1216
 msgid "ident"
 msgstr ""
 
-#: builtin/log.c:1197
+#: builtin/log.c:1217
 msgid "set From address to <ident> (or committer ident if absent)"
 msgstr ""
 
-#: builtin/log.c:1199
+#: builtin/log.c:1219
 msgid "message-id"
 msgstr ""
 
-#: builtin/log.c:1200
+#: builtin/log.c:1220
 msgid "make first mail a reply to <message-id>"
 msgstr ""
 
-#: builtin/log.c:1201 builtin/log.c:1204
+#: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
 msgstr ""
 
-#: builtin/log.c:1202
+#: builtin/log.c:1222
 msgid "attach the patch"
 msgstr ""
 
-#: builtin/log.c:1205
+#: builtin/log.c:1225
 msgid "inline the patch"
 msgstr ""
 
-#: builtin/log.c:1209
+#: builtin/log.c:1229
 msgid "enable message threading, styles: shallow, deep"
 msgstr ""
 
-#: builtin/log.c:1211
+#: builtin/log.c:1231
 msgid "signature"
 msgstr ""
 
-#: builtin/log.c:1212
+#: builtin/log.c:1232
 msgid "add a signature"
 msgstr ""
 
-#: builtin/log.c:1214
+#: builtin/log.c:1233
 msgid "don't print the patch filenames"
 msgstr ""
 
-#: builtin/log.c:1288
+#: builtin/log.c:1307
 #, c-format
 msgid "invalid ident line: %s"
 msgstr ""
 
-#: builtin/log.c:1303
+#: builtin/log.c:1322
 msgid "-n and -k are mutually exclusive."
 msgstr ""
 
-#: builtin/log.c:1305
+#: builtin/log.c:1324
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr ""
 
-#: builtin/log.c:1313
+#: builtin/log.c:1332
 msgid "--name-only does not make sense"
 msgstr ""
 
-#: builtin/log.c:1315
+#: builtin/log.c:1334
 msgid "--name-status does not make sense"
 msgstr ""
 
-#: builtin/log.c:1317
+#: builtin/log.c:1336
 msgid "--check does not make sense"
 msgstr ""
 
-#: builtin/log.c:1340
+#: builtin/log.c:1359
 msgid "standard output, or directory, which one?"
 msgstr ""
 
-#: builtin/log.c:1342
+#: builtin/log.c:1361
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr ""
 
-#: builtin/log.c:1490
+#: builtin/log.c:1509
 msgid "Failed to create output files"
 msgstr ""
 
-#: builtin/log.c:1539
+#: builtin/log.c:1558
 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
 msgstr ""
 
-#: builtin/log.c:1594
+#: builtin/log.c:1613
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr ""
 
-#: builtin/log.c:1607 builtin/log.c:1609 builtin/log.c:1621
+#: builtin/log.c:1626 builtin/log.c:1628 builtin/log.c:1640
 #, c-format
 msgid "Unknown commit %s"
 msgstr ""
 
-#: builtin/ls-files.c:408
+#: builtin/ls-files.c:398
 msgid "git ls-files [options] [<file>...]"
 msgstr ""
 
-#: builtin/ls-files.c:465
+#: builtin/ls-files.c:455
 msgid "identify the file status with tags"
 msgstr ""
 
-#: builtin/ls-files.c:467
+#: builtin/ls-files.c:457
 msgid "use lowercase letters for 'assume unchanged' files"
 msgstr ""
 
-#: builtin/ls-files.c:469
+#: builtin/ls-files.c:459
 msgid "show cached files in the output (default)"
 msgstr ""
 
-#: builtin/ls-files.c:471
+#: builtin/ls-files.c:461
 msgid "show deleted files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:473
+#: builtin/ls-files.c:463
 msgid "show modified files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:475
+#: builtin/ls-files.c:465
 msgid "show other files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:477
+#: builtin/ls-files.c:467
 msgid "show ignored files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:480
+#: builtin/ls-files.c:470
 msgid "show staged contents' object name in the output"
 msgstr ""
 
-#: builtin/ls-files.c:482
+#: builtin/ls-files.c:472
 msgid "show files on the filesystem that need to be removed"
 msgstr ""
 
-#: builtin/ls-files.c:484
+#: builtin/ls-files.c:474
 msgid "show 'other' directories' name only"
 msgstr ""
 
-#: builtin/ls-files.c:487
+#: builtin/ls-files.c:477
 msgid "don't show empty directories"
 msgstr ""
 
-#: builtin/ls-files.c:490
+#: builtin/ls-files.c:480
 msgid "show unmerged files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:492
+#: builtin/ls-files.c:482
 msgid "show resolve-undo information"
 msgstr ""
 
-#: builtin/ls-files.c:494
+#: builtin/ls-files.c:484
 msgid "skip files matching pattern"
 msgstr ""
 
-#: builtin/ls-files.c:497
+#: builtin/ls-files.c:487
 msgid "exclude patterns are read from <file>"
 msgstr ""
 
-#: builtin/ls-files.c:500
+#: builtin/ls-files.c:490
 msgid "read additional per-directory exclude patterns in <file>"
 msgstr ""
 
-#: builtin/ls-files.c:502
+#: builtin/ls-files.c:492
 msgid "add the standard git exclusions"
 msgstr ""
 
-#: builtin/ls-files.c:505
+#: builtin/ls-files.c:495
 msgid "make the output relative to the project top directory"
 msgstr ""
 
-#: builtin/ls-files.c:508
+#: builtin/ls-files.c:498
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr ""
 
-#: builtin/ls-files.c:509
+#: builtin/ls-files.c:499
 msgid "tree-ish"
 msgstr ""
 
-#: builtin/ls-files.c:510
+#: builtin/ls-files.c:500
 msgid "pretend that paths removed since <tree-ish> are still present"
 msgstr ""
 
-#: builtin/ls-files.c:512
+#: builtin/ls-files.c:502
 msgid "show debugging data"
 msgstr ""
 
-#: builtin/ls-tree.c:27
+#: builtin/ls-tree.c:28
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr ""
 
-#: builtin/ls-tree.c:125
+#: builtin/ls-tree.c:126
 msgid "only show trees"
 msgstr ""
 
-#: builtin/ls-tree.c:127
+#: builtin/ls-tree.c:128
 msgid "recurse into subtrees"
 msgstr ""
 
-#: builtin/ls-tree.c:129
+#: builtin/ls-tree.c:130
 msgid "show trees when recursing"
 msgstr ""
 
-#: builtin/ls-tree.c:132
+#: builtin/ls-tree.c:133
 msgid "terminate entries with NUL byte"
 msgstr ""
 
-#: builtin/ls-tree.c:133
+#: builtin/ls-tree.c:134
 msgid "include object size"
 msgstr ""
 
-#: builtin/ls-tree.c:135 builtin/ls-tree.c:137
+#: builtin/ls-tree.c:136 builtin/ls-tree.c:138
 msgid "list only filenames"
 msgstr ""
 
-#: builtin/ls-tree.c:140
+#: builtin/ls-tree.c:141
 msgid "use full path names"
 msgstr ""
 
-#: builtin/ls-tree.c:142
+#: builtin/ls-tree.c:143
 msgid "list entire tree; not just current directory (implies --full-name)"
 msgstr ""
 
@@ -6202,7 +6389,7 @@
 msgid "Verify that the named commit has a valid GPG signature"
 msgstr ""
 
-#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:114
+#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:89
 msgid "strategy"
 msgstr ""
 
@@ -6554,76 +6741,85 @@
 msgid "allow creation of more than one tree"
 msgstr ""
 
-#: builtin/mv.c:14
+#: builtin/mv.c:15
 msgid "git mv [options] <source>... <destination>"
 msgstr ""
 
-#: builtin/mv.c:64
+#: builtin/mv.c:67
 msgid "force move/rename even if target exists"
 msgstr ""
 
-#: builtin/mv.c:65
+#: builtin/mv.c:68
 msgid "skip move/rename errors"
 msgstr ""
 
-#: builtin/mv.c:108
+#: builtin/mv.c:113
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
 msgstr ""
 
-#: builtin/mv.c:112
+#: builtin/mv.c:117
 msgid "bad source"
 msgstr ""
 
-#: builtin/mv.c:115
+#: builtin/mv.c:120
 msgid "can not move directory into itself"
 msgstr ""
 
-#: builtin/mv.c:118
+#: builtin/mv.c:123
 msgid "cannot move directory over file"
 msgstr ""
 
-#: builtin/mv.c:128
+#: builtin/mv.c:129
+#, c-format
+msgid "Huh? Directory %s is in index and no submodule?"
+msgstr ""
+
+#: builtin/mv.c:131 builtin/rm.c:318
+msgid "Please, stage your changes to .gitmodules or stash them to proceed"
+msgstr ""
+
+#: builtin/mv.c:147
 #, c-format
 msgid "Huh? %.*s is in index?"
 msgstr ""
 
-#: builtin/mv.c:140
+#: builtin/mv.c:159
 msgid "source directory is empty"
 msgstr ""
 
-#: builtin/mv.c:171
+#: builtin/mv.c:191
 msgid "not under version control"
 msgstr ""
 
-#: builtin/mv.c:173
+#: builtin/mv.c:193
 msgid "destination exists"
 msgstr ""
 
-#: builtin/mv.c:181
+#: builtin/mv.c:201
 #, c-format
 msgid "overwriting '%s'"
 msgstr ""
 
-#: builtin/mv.c:184
+#: builtin/mv.c:204
 msgid "Cannot overwrite"
 msgstr ""
 
-#: builtin/mv.c:187
+#: builtin/mv.c:207
 msgid "multiple sources for the same target"
 msgstr ""
 
-#: builtin/mv.c:202
+#: builtin/mv.c:222
 #, c-format
 msgid "%s, source=%s, destination=%s"
 msgstr ""
 
-#: builtin/mv.c:212
+#: builtin/mv.c:232
 #, c-format
 msgid "Renaming %s to %s\n"
 msgstr ""
 
-#: builtin/mv.c:215 builtin/remote.c:731
+#: builtin/mv.c:235 builtin/remote.c:731 builtin/repack.c:330
 #, c-format
 msgid "renaming '%s' failed"
 msgstr ""
@@ -6661,7 +6857,7 @@
 msgstr ""
 
 #: builtin/name-rev.c:320
-msgid "allow to print `undefined` names"
+msgid "allow to print `undefined` names (default)"
 msgstr ""
 
 #: builtin/name-rev.c:326
@@ -6810,12 +7006,12 @@
 msgid "The note contents has been left in %s"
 msgstr ""
 
-#: builtin/notes.c:248 builtin/tag.c:540
+#: builtin/notes.c:248 builtin/tag.c:537
 #, c-format
 msgid "cannot read '%s'"
 msgstr ""
 
-#: builtin/notes.c:250 builtin/tag.c:543
+#: builtin/notes.c:250 builtin/tag.c:540
 #, c-format
 msgid "could not open or read '%s'"
 msgstr ""
@@ -6823,7 +7019,7 @@
 #: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318
 #: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515
 #: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637
-#: builtin/notes.c:839 builtin/tag.c:556
+#: builtin/notes.c:839 builtin/tag.c:553
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr ""
@@ -6986,148 +7182,148 @@
 msgid "git pack-objects [options...] base-name [< ref-list | < object-list]"
 msgstr ""
 
-#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#: builtin/pack-objects.c:184 builtin/pack-objects.c:187
 #, c-format
 msgid "deflate error (%d)"
 msgstr ""
 
-#: builtin/pack-objects.c:2397
+#: builtin/pack-objects.c:2398
 #, c-format
 msgid "unsupported index version %s"
 msgstr ""
 
-#: builtin/pack-objects.c:2401
+#: builtin/pack-objects.c:2402
 #, c-format
 msgid "bad index version '%s'"
 msgstr ""
 
-#: builtin/pack-objects.c:2424
+#: builtin/pack-objects.c:2425
 #, c-format
 msgid "option %s does not accept negative form"
 msgstr ""
 
-#: builtin/pack-objects.c:2428
+#: builtin/pack-objects.c:2429
 #, c-format
 msgid "unable to parse value '%s' for option %s"
 msgstr ""
 
-#: builtin/pack-objects.c:2447
+#: builtin/pack-objects.c:2448
 msgid "do not show progress meter"
 msgstr ""
 
-#: builtin/pack-objects.c:2449
+#: builtin/pack-objects.c:2450
 msgid "show progress meter"
 msgstr ""
 
-#: builtin/pack-objects.c:2451
+#: builtin/pack-objects.c:2452
 msgid "show progress meter during object writing phase"
 msgstr ""
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:2455
 msgid "similar to --all-progress when progress meter is shown"
 msgstr ""
 
-#: builtin/pack-objects.c:2455
+#: builtin/pack-objects.c:2456
 msgid "version[,offset]"
 msgstr ""
 
-#: builtin/pack-objects.c:2456
+#: builtin/pack-objects.c:2457
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
 
-#: builtin/pack-objects.c:2459
+#: builtin/pack-objects.c:2460
 msgid "maximum size of each output pack file"
 msgstr ""
 
-#: builtin/pack-objects.c:2461
+#: builtin/pack-objects.c:2462
 msgid "ignore borrowed objects from alternate object store"
 msgstr ""
 
-#: builtin/pack-objects.c:2463
+#: builtin/pack-objects.c:2464
 msgid "ignore packed objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2465
+#: builtin/pack-objects.c:2466
 msgid "limit pack window by objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2467
+#: builtin/pack-objects.c:2468
 msgid "limit pack window by memory in addition to object limit"
 msgstr ""
 
-#: builtin/pack-objects.c:2469
+#: builtin/pack-objects.c:2470
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr ""
 
-#: builtin/pack-objects.c:2471
+#: builtin/pack-objects.c:2472
 msgid "reuse existing deltas"
 msgstr ""
 
-#: builtin/pack-objects.c:2473
+#: builtin/pack-objects.c:2474
 msgid "reuse existing objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2475
+#: builtin/pack-objects.c:2476
 msgid "use OFS_DELTA objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2477
+#: builtin/pack-objects.c:2478
 msgid "use threads when searching for best delta matches"
 msgstr ""
 
-#: builtin/pack-objects.c:2479
+#: builtin/pack-objects.c:2480
 msgid "do not create an empty pack output"
 msgstr ""
 
-#: builtin/pack-objects.c:2481
+#: builtin/pack-objects.c:2482
 msgid "read revision arguments from standard input"
 msgstr ""
 
-#: builtin/pack-objects.c:2483
+#: builtin/pack-objects.c:2484
 msgid "limit the objects to those that are not yet packed"
 msgstr ""
 
-#: builtin/pack-objects.c:2486
+#: builtin/pack-objects.c:2487
 msgid "include objects reachable from any reference"
 msgstr ""
 
-#: builtin/pack-objects.c:2489
+#: builtin/pack-objects.c:2490
 msgid "include objects referred by reflog entries"
 msgstr ""
 
-#: builtin/pack-objects.c:2492
+#: builtin/pack-objects.c:2493
 msgid "output pack to stdout"
 msgstr ""
 
-#: builtin/pack-objects.c:2494
+#: builtin/pack-objects.c:2495
 msgid "include tag objects that refer to objects to be packed"
 msgstr ""
 
-#: builtin/pack-objects.c:2496
+#: builtin/pack-objects.c:2497
 msgid "keep unreachable objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2497 parse-options.h:141
+#: builtin/pack-objects.c:2498 parse-options.h:143
 msgid "time"
 msgstr ""
 
-#: builtin/pack-objects.c:2498
+#: builtin/pack-objects.c:2499
 msgid "unpack unreachable objects newer than <time>"
 msgstr ""
 
-#: builtin/pack-objects.c:2501
+#: builtin/pack-objects.c:2502
 msgid "create thin packs"
 msgstr ""
 
-#: builtin/pack-objects.c:2503
+#: builtin/pack-objects.c:2504
 msgid "ignore packs that have companion .keep file"
 msgstr ""
 
-#: builtin/pack-objects.c:2505
+#: builtin/pack-objects.c:2506
 msgid "pack compression level"
 msgstr ""
 
-#: builtin/pack-objects.c:2507
+#: builtin/pack-objects.c:2508
 msgid "do not hide commits by grafts"
 msgstr ""
 
@@ -7167,21 +7363,21 @@
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr ""
 
-#: builtin/push.c:45
+#: builtin/push.c:47
 msgid "tag shorthand without <tag>"
 msgstr ""
 
-#: builtin/push.c:64
+#: builtin/push.c:66
 msgid "--delete only accepts plain target ref names"
 msgstr ""
 
-#: builtin/push.c:99
+#: builtin/push.c:101
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
 msgstr ""
 
-#: builtin/push.c:102
+#: builtin/push.c:104
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -7196,7 +7392,7 @@
 "%s"
 msgstr ""
 
-#: builtin/push.c:117
+#: builtin/push.c:119
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -7206,7 +7402,7 @@
 "    git push %s HEAD:<name-of-remote-branch>\n"
 msgstr ""
 
-#: builtin/push.c:131
+#: builtin/push.c:133
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -7215,12 +7411,12 @@
 "    git push --set-upstream %s %s\n"
 msgstr ""
 
-#: builtin/push.c:139
+#: builtin/push.c:141
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr ""
 
-#: builtin/push.c:142
+#: builtin/push.c:144
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -7228,7 +7424,7 @@
 "to update which remote branch."
 msgstr ""
 
-#: builtin/push.c:165
+#: builtin/push.c:167
 msgid ""
 "push.default is unset; its implicit value is changing in\n"
 "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -7246,12 +7442,12 @@
 "'current' instead of 'simple' if you sometimes use older versions of Git)"
 msgstr ""
 
-#: builtin/push.c:225
+#: builtin/push.c:227
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 
-#: builtin/push.c:232
+#: builtin/push.c:234
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -7259,7 +7455,7 @@
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
 
-#: builtin/push.c:238
+#: builtin/push.c:240
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. If you did not intend to push that branch, you may want to\n"
@@ -7267,7 +7463,7 @@
 "to 'simple', 'current' or 'upstream' to push only the current branch."
 msgstr ""
 
-#: builtin/push.c:244
+#: builtin/push.c:246
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. Check out this branch and integrate the remote changes\n"
@@ -7275,7 +7471,7 @@
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
 
-#: builtin/push.c:250
+#: builtin/push.c:252
 msgid ""
 "Updates were rejected because the remote contains work that you do\n"
 "not have locally. This is usually caused by another repository pushing\n"
@@ -7284,33 +7480,33 @@
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
 
-#: builtin/push.c:257
+#: builtin/push.c:259
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
 
-#: builtin/push.c:260
+#: builtin/push.c:262
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
 "without using the '--force' option.\n"
 msgstr ""
 
-#: builtin/push.c:320
+#: builtin/push.c:328
 #, c-format
 msgid "Pushing to %s\n"
 msgstr ""
 
-#: builtin/push.c:324
+#: builtin/push.c:332
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr ""
 
-#: builtin/push.c:357
+#: builtin/push.c:365
 #, c-format
 msgid "bad repository '%s'"
 msgstr ""
 
-#: builtin/push.c:358
+#: builtin/push.c:366
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -7323,87 +7519,95 @@
 "    git push <name>\n"
 msgstr ""
 
-#: builtin/push.c:373
+#: builtin/push.c:381
 msgid "--all and --tags are incompatible"
 msgstr ""
 
-#: builtin/push.c:374
+#: builtin/push.c:382
 msgid "--all can't be combined with refspecs"
 msgstr ""
 
-#: builtin/push.c:379
+#: builtin/push.c:387
 msgid "--mirror and --tags are incompatible"
 msgstr ""
 
-#: builtin/push.c:380
+#: builtin/push.c:388
 msgid "--mirror can't be combined with refspecs"
 msgstr ""
 
-#: builtin/push.c:385
+#: builtin/push.c:393
 msgid "--all and --mirror are incompatible"
 msgstr ""
 
-#: builtin/push.c:445
+#: builtin/push.c:453
 msgid "repository"
 msgstr ""
 
-#: builtin/push.c:446
+#: builtin/push.c:454
 msgid "push all refs"
 msgstr ""
 
-#: builtin/push.c:447
+#: builtin/push.c:455
 msgid "mirror all refs"
 msgstr ""
 
-#: builtin/push.c:449
+#: builtin/push.c:457
 msgid "delete refs"
 msgstr ""
 
-#: builtin/push.c:450
+#: builtin/push.c:458
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr ""
 
-#: builtin/push.c:453
+#: builtin/push.c:461
 msgid "force updates"
 msgstr ""
 
-#: builtin/push.c:454
-msgid "check"
-msgstr ""
-
-#: builtin/push.c:455
-msgid "control recursive pushing of submodules"
-msgstr ""
-
-#: builtin/push.c:457
-msgid "use thin pack"
-msgstr ""
-
-#: builtin/push.c:458 builtin/push.c:459
-msgid "receive pack program"
-msgstr ""
-
-#: builtin/push.c:460
-msgid "set upstream for git pull/status"
-msgstr ""
-
 #: builtin/push.c:463
-msgid "prune locally removed refs"
+msgid "refname>:<expect"
 msgstr ""
 
-#: builtin/push.c:465
-msgid "bypass pre-push hook"
+#: builtin/push.c:464
+msgid "require old value of ref to be at this value"
 msgstr ""
 
 #: builtin/push.c:466
-msgid "push missing but relevant tags"
+msgid "check"
 msgstr ""
 
-#: builtin/push.c:476
-msgid "--delete is incompatible with --all, --mirror and --tags"
+#: builtin/push.c:467
+msgid "control recursive pushing of submodules"
+msgstr ""
+
+#: builtin/push.c:469
+msgid "use thin pack"
+msgstr ""
+
+#: builtin/push.c:470 builtin/push.c:471
+msgid "receive pack program"
+msgstr ""
+
+#: builtin/push.c:472
+msgid "set upstream for git pull/status"
+msgstr ""
+
+#: builtin/push.c:475
+msgid "prune locally removed refs"
+msgstr ""
+
+#: builtin/push.c:477
+msgid "bypass pre-push hook"
 msgstr ""
 
 #: builtin/push.c:478
+msgid "push missing but relevant tags"
+msgstr ""
+
+#: builtin/push.c:488
+msgid "--delete is incompatible with --all, --mirror and --tags"
+msgstr ""
+
+#: builtin/push.c:490
 msgid "--delete doesn't make sense without any refs"
 msgstr ""
 
@@ -7478,12 +7682,12 @@
 msgid "debug unpack-trees"
 msgstr ""
 
-#: builtin/reflog.c:500
+#: builtin/reflog.c:499
 #, c-format
 msgid "%s' for '%s' is not a valid timestamp"
 msgstr ""
 
-#: builtin/reflog.c:616 builtin/reflog.c:621
+#: builtin/reflog.c:615 builtin/reflog.c:620
 #, c-format
 msgid "'%s' is not a valid timestamp"
 msgstr ""
@@ -7506,8 +7710,8 @@
 msgid "git remote remove <name>"
 msgstr ""
 
-#: builtin/remote.c:15 builtin/remote.c:42
-msgid "git remote set-head <name> (-a | -d | <branch>)"
+#: builtin/remote.c:15
+msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"
 msgstr ""
 
 #: builtin/remote.c:16
@@ -7543,6 +7747,10 @@
 msgid "git remote add [<options>] <name> <url>"
 msgstr ""
 
+#: builtin/remote.c:42
+msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
+msgstr ""
+
 #: builtin/remote.c:47
 msgid "git remote set-branches <name> <branch>..."
 msgstr ""
@@ -7970,6 +8178,67 @@
 msgid "be verbose; must be placed before a subcommand"
 msgstr ""
 
+#: builtin/repack.c:15
+msgid "git repack [options]"
+msgstr ""
+
+#: builtin/repack.c:143
+msgid "pack everything in a single pack"
+msgstr ""
+
+#: builtin/repack.c:145
+msgid "same as -a, and turn unreachable objects loose"
+msgstr ""
+
+#: builtin/repack.c:148
+msgid "remove redundant packs, and run git-prune-packed"
+msgstr ""
+
+#: builtin/repack.c:150
+msgid "pass --no-reuse-delta to git-pack-objects"
+msgstr ""
+
+#: builtin/repack.c:152
+msgid "pass --no-reuse-object to git-pack-objects"
+msgstr ""
+
+#: builtin/repack.c:154
+msgid "do not run git-update-server-info"
+msgstr ""
+
+#: builtin/repack.c:157
+msgid "pass --local to git-pack-objects"
+msgstr ""
+
+#: builtin/repack.c:158
+msgid "approxidate"
+msgstr ""
+
+#: builtin/repack.c:159
+msgid "with -A, do not loosen objects older than this"
+msgstr ""
+
+#: builtin/repack.c:161
+msgid "size of the window used for delta compression"
+msgstr ""
+
+#: builtin/repack.c:163
+msgid "same as the above, but limit memory size instead of entries count"
+msgstr ""
+
+#: builtin/repack.c:165
+msgid "limits the maximum delta depth"
+msgstr ""
+
+#: builtin/repack.c:167
+msgid "maximum size of each packfile"
+msgstr ""
+
+#: builtin/repack.c:345
+#, c-format
+msgid "removing '%s' failed"
+msgstr ""
+
 #: builtin/replace.c:17
 msgid "git replace [-f] <object> <replacement>"
 msgstr ""
@@ -7982,23 +8251,23 @@
 msgid "git replace -l [<pattern>]"
 msgstr ""
 
-#: builtin/replace.c:121
+#: builtin/replace.c:131
 msgid "list replace refs"
 msgstr ""
 
-#: builtin/replace.c:122
+#: builtin/replace.c:132
 msgid "delete replace refs"
 msgstr ""
 
-#: builtin/replace.c:123
+#: builtin/replace.c:133
 msgid "replace the ref if it exists"
 msgstr ""
 
-#: builtin/rerere.c:11
+#: builtin/rerere.c:12
 msgid "git rerere [clear | forget path... | status | remaining | diff | gc]"
 msgstr ""
 
-#: builtin/rerere.c:56
+#: builtin/rerere.c:57
 msgid "register clean resolutions in index"
 msgstr ""
 
@@ -8058,69 +8327,69 @@
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr ""
 
-#: builtin/reset.c:251
+#: builtin/reset.c:262
 msgid "be quiet, only report errors"
 msgstr ""
 
-#: builtin/reset.c:253
+#: builtin/reset.c:264
 msgid "reset HEAD and index"
 msgstr ""
 
-#: builtin/reset.c:254
+#: builtin/reset.c:265
 msgid "reset only HEAD"
 msgstr ""
 
-#: builtin/reset.c:256 builtin/reset.c:258
+#: builtin/reset.c:267 builtin/reset.c:269
 msgid "reset HEAD, index and working tree"
 msgstr ""
 
-#: builtin/reset.c:260
+#: builtin/reset.c:271
 msgid "reset HEAD but keep local changes"
 msgstr ""
 
-#: builtin/reset.c:278
+#: builtin/reset.c:289
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
 msgstr ""
 
-#: builtin/reset.c:281 builtin/reset.c:289
+#: builtin/reset.c:292 builtin/reset.c:300
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr ""
 
-#: builtin/reset.c:286
+#: builtin/reset.c:297
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
 msgstr ""
 
-#: builtin/reset.c:295
+#: builtin/reset.c:306
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr ""
 
-#: builtin/reset.c:304
+#: builtin/reset.c:315
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
 
-#: builtin/reset.c:306
+#: builtin/reset.c:317
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr ""
 
-#: builtin/reset.c:316
+#: builtin/reset.c:327
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr ""
 
-#: builtin/reset.c:336
+#: builtin/reset.c:344
+msgid "Unstaged changes after reset:"
+msgstr ""
+
+#: builtin/reset.c:350
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr ""
 
-#: builtin/reset.c:342
-msgid "Unstaged changes after reset:"
-msgstr ""
-
-#: builtin/reset.c:347
+#: builtin/reset.c:355
 msgid "Could not write new index file."
 msgstr ""
 
@@ -8161,84 +8430,84 @@
 msgid "git cherry-pick <subcommand>"
 msgstr ""
 
-#: builtin/revert.c:71 builtin/revert.c:94
+#: builtin/revert.c:71
 #, c-format
 msgid "%s: %s cannot be used with %s"
 msgstr ""
 
-#: builtin/revert.c:105
+#: builtin/revert.c:80
 msgid "end revert or cherry-pick sequence"
 msgstr ""
 
-#: builtin/revert.c:106
+#: builtin/revert.c:81
 msgid "resume revert or cherry-pick sequence"
 msgstr ""
 
-#: builtin/revert.c:107
+#: builtin/revert.c:82
 msgid "cancel revert or cherry-pick sequence"
 msgstr ""
 
-#: builtin/revert.c:108
+#: builtin/revert.c:83
 msgid "don't automatically commit"
 msgstr ""
 
-#: builtin/revert.c:109
+#: builtin/revert.c:84
 msgid "edit the commit message"
 msgstr ""
 
-#: builtin/revert.c:112
+#: builtin/revert.c:87
 msgid "parent number"
 msgstr ""
 
-#: builtin/revert.c:114
+#: builtin/revert.c:89
 msgid "merge strategy"
 msgstr ""
 
-#: builtin/revert.c:115
+#: builtin/revert.c:90
 msgid "option"
 msgstr ""
 
-#: builtin/revert.c:116
+#: builtin/revert.c:91
 msgid "option for merge strategy"
 msgstr ""
 
-#: builtin/revert.c:127
+#: builtin/revert.c:102
 msgid "append commit name"
 msgstr ""
 
-#: builtin/revert.c:128
+#: builtin/revert.c:103
 msgid "allow fast-forward"
 msgstr ""
 
-#: builtin/revert.c:129
+#: builtin/revert.c:104
 msgid "preserve initially empty commits"
 msgstr ""
 
-#: builtin/revert.c:130
+#: builtin/revert.c:105
 msgid "allow commits with empty messages"
 msgstr ""
 
-#: builtin/revert.c:131
+#: builtin/revert.c:106
 msgid "keep redundant, empty commits"
 msgstr ""
 
-#: builtin/revert.c:135
+#: builtin/revert.c:110
 msgid "program error"
 msgstr ""
 
-#: builtin/revert.c:225
+#: builtin/revert.c:195
 msgid "revert failed"
 msgstr ""
 
-#: builtin/revert.c:240
+#: builtin/revert.c:210
 msgid "cherry-pick failed"
 msgstr ""
 
-#: builtin/rm.c:16
+#: builtin/rm.c:17
 msgid "git rm [options] [--] <file>..."
 msgstr ""
 
-#: builtin/rm.c:64
+#: builtin/rm.c:65
 msgid ""
 "the following submodule (or one of its nested submodules)\n"
 "uses a .git directory:"
@@ -8248,13 +8517,13 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/rm.c:70
+#: builtin/rm.c:71
 msgid ""
 "\n"
 "(use 'rm -rf' if you really want to remove it including all of its history)"
 msgstr ""
 
-#: builtin/rm.c:230
+#: builtin/rm.c:231
 msgid ""
 "the following file has staged content different from both the\n"
 "file and the HEAD:"
@@ -8264,56 +8533,56 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/rm.c:235
+#: builtin/rm.c:236
 msgid ""
 "\n"
 "(use -f to force removal)"
 msgstr ""
 
-#: builtin/rm.c:239
+#: builtin/rm.c:240
 msgid "the following file has changes staged in the index:"
 msgid_plural "the following files have changes staged in the index:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/rm.c:243 builtin/rm.c:254
+#: builtin/rm.c:244 builtin/rm.c:255
 msgid ""
 "\n"
 "(use --cached to keep the file, or -f to force removal)"
 msgstr ""
 
-#: builtin/rm.c:251
+#: builtin/rm.c:252
 msgid "the following file has local modifications:"
 msgid_plural "the following files have local modifications:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/rm.c:269
+#: builtin/rm.c:270
 msgid "do not list removed files"
 msgstr ""
 
-#: builtin/rm.c:270
+#: builtin/rm.c:271
 msgid "only remove from the index"
 msgstr ""
 
-#: builtin/rm.c:271
+#: builtin/rm.c:272
 msgid "override the up-to-date check"
 msgstr ""
 
-#: builtin/rm.c:272
+#: builtin/rm.c:273
 msgid "allow recursive removal"
 msgstr ""
 
-#: builtin/rm.c:274
+#: builtin/rm.c:275
 msgid "exit with a zero status even if nothing matched"
 msgstr ""
 
-#: builtin/rm.c:345
+#: builtin/rm.c:336
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr ""
 
-#: builtin/rm.c:384
+#: builtin/rm.c:375
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr ""
@@ -8327,23 +8596,23 @@
 msgid "Missing author: %s"
 msgstr ""
 
-#: builtin/shortlog.c:228
+#: builtin/shortlog.c:230
 msgid "sort output according to the number of commits per author"
 msgstr ""
 
-#: builtin/shortlog.c:230
+#: builtin/shortlog.c:232
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr ""
 
-#: builtin/shortlog.c:232
+#: builtin/shortlog.c:234
 msgid "Show the email address of each author"
 msgstr ""
 
-#: builtin/shortlog.c:233
+#: builtin/shortlog.c:235
 msgid "w[,i1[,i2]]"
 msgstr ""
 
-#: builtin/shortlog.c:234
+#: builtin/shortlog.c:236
 msgid "Linewrap output"
 msgstr ""
 
@@ -8445,23 +8714,23 @@
 msgid "stricter reference checking, requires exact ref path"
 msgstr ""
 
-#: builtin/show-ref.c:173 builtin/show-ref.c:176
+#: builtin/show-ref.c:173 builtin/show-ref.c:175
 msgid "show the HEAD reference, even if it would be filtered out"
 msgstr ""
 
-#: builtin/show-ref.c:178
+#: builtin/show-ref.c:177
 msgid "dereference tags into object IDs"
 msgstr ""
 
-#: builtin/show-ref.c:180
+#: builtin/show-ref.c:179
 msgid "only show SHA1 hash using <n> digits"
 msgstr ""
 
-#: builtin/show-ref.c:184
+#: builtin/show-ref.c:183
 msgid "do not print results to stdout (useful with --verify)"
 msgstr ""
 
-#: builtin/show-ref.c:186
+#: builtin/show-ref.c:185
 msgid "show refs from stdin that aren't in local repository"
 msgstr ""
 
@@ -8485,11 +8754,11 @@
 msgid "shorten ref output"
 msgstr ""
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason"
 msgstr ""
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason of the update"
 msgstr ""
 
@@ -8644,183 +8913,195 @@
 msgid "print only tags of the object"
 msgstr ""
 
-#: builtin/tag.c:504
+#: builtin/tag.c:501
 msgid "--column and -n are incompatible"
 msgstr ""
 
-#: builtin/tag.c:521
+#: builtin/tag.c:518
 msgid "-n option is only allowed with -l."
 msgstr ""
 
-#: builtin/tag.c:523
+#: builtin/tag.c:520
 msgid "--contains option is only allowed with -l."
 msgstr ""
 
-#: builtin/tag.c:525
+#: builtin/tag.c:522
 msgid "--points-at option is only allowed with -l."
 msgstr ""
 
-#: builtin/tag.c:533
+#: builtin/tag.c:530
 msgid "only one -F or -m option is allowed."
 msgstr ""
 
-#: builtin/tag.c:553
+#: builtin/tag.c:550
 msgid "too many params"
 msgstr ""
 
-#: builtin/tag.c:559
+#: builtin/tag.c:556
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr ""
 
-#: builtin/tag.c:564
+#: builtin/tag.c:561
 #, c-format
 msgid "tag '%s' already exists"
 msgstr ""
 
-#: builtin/tag.c:582
+#: builtin/tag.c:579
 #, c-format
 msgid "%s: cannot lock the ref"
 msgstr ""
 
-#: builtin/tag.c:584
+#: builtin/tag.c:581
 #, c-format
 msgid "%s: cannot update the ref"
 msgstr ""
 
-#: builtin/tag.c:586
+#: builtin/tag.c:583
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr ""
 
-#: builtin/update-index.c:401
+#: builtin/update-index.c:402
 msgid "git update-index [options] [--] [<file>...]"
 msgstr ""
 
-#: builtin/update-index.c:718
+#: builtin/update-index.c:720
 msgid "continue refresh even when index needs update"
 msgstr ""
 
-#: builtin/update-index.c:721
+#: builtin/update-index.c:723
 msgid "refresh: ignore submodules"
 msgstr ""
 
-#: builtin/update-index.c:724
+#: builtin/update-index.c:726
 msgid "do not ignore new files"
 msgstr ""
 
-#: builtin/update-index.c:726
+#: builtin/update-index.c:728
 msgid "let files replace directories and vice-versa"
 msgstr ""
 
-#: builtin/update-index.c:728
+#: builtin/update-index.c:730
 msgid "notice files missing from worktree"
 msgstr ""
 
-#: builtin/update-index.c:730
+#: builtin/update-index.c:732
 msgid "refresh even if index contains unmerged entries"
 msgstr ""
 
-#: builtin/update-index.c:733
+#: builtin/update-index.c:735
 msgid "refresh stat information"
 msgstr ""
 
-#: builtin/update-index.c:737
+#: builtin/update-index.c:739
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr ""
 
-#: builtin/update-index.c:741
+#: builtin/update-index.c:743
 msgid "<mode> <object> <path>"
 msgstr ""
 
-#: builtin/update-index.c:742
+#: builtin/update-index.c:744
 msgid "add the specified entry to the index"
 msgstr ""
 
-#: builtin/update-index.c:746
+#: builtin/update-index.c:748
 msgid "(+/-)x"
 msgstr ""
 
-#: builtin/update-index.c:747
+#: builtin/update-index.c:749
 msgid "override the executable bit of the listed files"
 msgstr ""
 
-#: builtin/update-index.c:751
+#: builtin/update-index.c:753
 msgid "mark files as \"not changing\""
 msgstr ""
 
-#: builtin/update-index.c:754
+#: builtin/update-index.c:756
 msgid "clear assumed-unchanged bit"
 msgstr ""
 
-#: builtin/update-index.c:757
+#: builtin/update-index.c:759
 msgid "mark files as \"index-only\""
 msgstr ""
 
-#: builtin/update-index.c:760
+#: builtin/update-index.c:762
 msgid "clear skip-worktree bit"
 msgstr ""
 
-#: builtin/update-index.c:763
+#: builtin/update-index.c:765
 msgid "add to index only; do not add content to object database"
 msgstr ""
 
-#: builtin/update-index.c:765
+#: builtin/update-index.c:767
 msgid "remove named paths even if present in worktree"
 msgstr ""
 
-#: builtin/update-index.c:767
+#: builtin/update-index.c:769
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr ""
 
-#: builtin/update-index.c:769
+#: builtin/update-index.c:771
 msgid "read list of paths to be updated from standard input"
 msgstr ""
 
-#: builtin/update-index.c:773
+#: builtin/update-index.c:775
 msgid "add entries from standard input to the index"
 msgstr ""
 
-#: builtin/update-index.c:777
+#: builtin/update-index.c:779
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr ""
 
-#: builtin/update-index.c:781
+#: builtin/update-index.c:783
 msgid "only update entries that differ from HEAD"
 msgstr ""
 
-#: builtin/update-index.c:785
+#: builtin/update-index.c:787
 msgid "ignore files missing from worktree"
 msgstr ""
 
-#: builtin/update-index.c:788
+#: builtin/update-index.c:790
 msgid "report actions to standard output"
 msgstr ""
 
-#: builtin/update-index.c:790
+#: builtin/update-index.c:792
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr ""
 
-#: builtin/update-index.c:794
+#: builtin/update-index.c:796
 msgid "write index in this format"
 msgstr ""
 
-#: builtin/update-ref.c:7
+#: builtin/update-ref.c:9
 msgid "git update-ref [options] -d <refname> [<oldval>]"
 msgstr ""
 
-#: builtin/update-ref.c:8
+#: builtin/update-ref.c:10
 msgid "git update-ref [options]    <refname> <newval> [<oldval>]"
 msgstr ""
 
-#: builtin/update-ref.c:19
+#: builtin/update-ref.c:11
+msgid "git update-ref [options] --stdin [-z]"
+msgstr ""
+
+#: builtin/update-ref.c:255
 msgid "delete the reference"
 msgstr ""
 
-#: builtin/update-ref.c:21
+#: builtin/update-ref.c:257
 msgid "update <refname> not the one it points to"
 msgstr ""
 
+#: builtin/update-ref.c:258
+msgid "stdin has NUL-terminated arguments"
+msgstr ""
+
+#: builtin/update-ref.c:259
+msgid "read updates from stdin"
+msgstr ""
+
 #: builtin/update-server-info.c:6
 msgid "git update-server-info [--force]"
 msgstr ""
@@ -8872,23 +9153,23 @@
 "to read about a specific subcommand or concept."
 msgstr ""
 
-#: parse-options.h:144
+#: parse-options.h:146
 msgid "expiry date"
 msgstr ""
 
-#: parse-options.h:159
+#: parse-options.h:161
 msgid "no-op (backward compatibility)"
 msgstr ""
 
-#: parse-options.h:236
+#: parse-options.h:238
 msgid "be more verbose"
 msgstr ""
 
-#: parse-options.h:238
+#: parse-options.h:240
 msgid "be more quiet"
 msgstr ""
 
-#: parse-options.h:244
+#: parse-options.h:246
 msgid "use <n> digits to display SHA-1s"
 msgstr ""
 
@@ -9284,7 +9565,7 @@
 msgid "Pull is not possible because you have unmerged files."
 msgstr ""
 
-#: git-pull.sh:203
+#: git-pull.sh:223
 msgid "updating an unborn branch with changes added to the index"
 msgstr ""
 
@@ -9292,7 +9573,7 @@
 #. The working tree and the index file is still based on the
 #. $orig_head commit, but we are merging into $curr_head.
 #. First update the working tree to match $curr_head.
-#: git-pull.sh:235
+#: git-pull.sh:255
 #, sh-format
 msgid ""
 "Warning: fetch updated the current branch head.\n"
@@ -9300,11 +9581,11 @@
 "Warning: commit $orig_head."
 msgstr ""
 
-#: git-pull.sh:260
+#: git-pull.sh:280
 msgid "Cannot merge multiple branches into empty head"
 msgstr ""
 
-#: git-pull.sh:264
+#: git-pull.sh:284
 msgid "Cannot rebase onto multiple branches"
 msgstr ""
 
@@ -9332,42 +9613,42 @@
 "You can run \"git stash pop\" or \"git stash drop\" at any time.\n"
 msgstr ""
 
-#: git-rebase.sh:190
+#: git-rebase.sh:199
 msgid "The pre-rebase hook refused to rebase."
 msgstr ""
 
-#: git-rebase.sh:195
+#: git-rebase.sh:204
 msgid "It looks like git-am is in progress. Cannot rebase."
 msgstr ""
 
-#: git-rebase.sh:329
+#: git-rebase.sh:338
 msgid "The --exec option must be used with the --interactive option"
 msgstr ""
 
-#: git-rebase.sh:334
+#: git-rebase.sh:343
 msgid "No rebase in progress?"
 msgstr ""
 
-#: git-rebase.sh:345
+#: git-rebase.sh:354
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 
-#: git-rebase.sh:352
+#: git-rebase.sh:361
 msgid "Cannot read HEAD"
 msgstr ""
 
-#: git-rebase.sh:355
+#: git-rebase.sh:364
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
 msgstr ""
 
-#: git-rebase.sh:373
+#: git-rebase.sh:382
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr ""
 
-#: git-rebase.sh:392
+#: git-rebase.sh:401
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -9380,65 +9661,65 @@
 "valuable there."
 msgstr ""
 
-#: git-rebase.sh:437
+#: git-rebase.sh:446
 #, sh-format
 msgid "invalid upstream $upstream_name"
 msgstr ""
 
-#: git-rebase.sh:461
+#: git-rebase.sh:470
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr ""
 
-#: git-rebase.sh:464 git-rebase.sh:468
+#: git-rebase.sh:473 git-rebase.sh:477
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr ""
 
-#: git-rebase.sh:473
+#: git-rebase.sh:482
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr ""
 
-#: git-rebase.sh:496
+#: git-rebase.sh:505
 #, sh-format
 msgid "fatal: no such branch: $branch_name"
 msgstr ""
 
-#: git-rebase.sh:519
+#: git-rebase.sh:528
 msgid "Cannot autostash"
 msgstr ""
 
-#: git-rebase.sh:524
+#: git-rebase.sh:533
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr ""
 
-#: git-rebase.sh:528
+#: git-rebase.sh:537
 msgid "Please commit or stash them."
 msgstr ""
 
-#: git-rebase.sh:548
+#: git-rebase.sh:557
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr ""
 
-#: git-rebase.sh:552
+#: git-rebase.sh:561
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr ""
 
-#: git-rebase.sh:563
+#: git-rebase.sh:572
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr ""
 
 #. Detach HEAD and reset the tree
-#: git-rebase.sh:572
+#: git-rebase.sh:581
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
 
-#: git-rebase.sh:582
+#: git-rebase.sh:591
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr ""
@@ -9486,103 +9767,92 @@
 #. $ git stash save --blah-blah 2>&1 | head -n 2
 #. error: unknown option for 'stash save': --blah-blah
 #. To provide a message, use git stash save -- '--blah-blah'
-#: git-stash.sh:241
+#: git-stash.sh:237
 #, sh-format
 msgid ""
 "error: unknown option for 'stash save': $option\n"
 "       To provide a message, use git stash save -- '$option'"
 msgstr ""
 
-#: git-stash.sh:262
+#: git-stash.sh:258
 msgid "No local changes to save"
 msgstr ""
 
-#: git-stash.sh:268
-msgid ""
-"The following untracked files would NOT be saved but need to be removed by "
-"stash save:"
-msgstr ""
-
-#: git-stash.sh:270
-msgid ""
-"Aborting. Consider using either the --force or --include-untracked option."
-msgstr ""
-
-#: git-stash.sh:274
+#: git-stash.sh:262
 msgid "Cannot initialize stash"
 msgstr ""
 
-#: git-stash.sh:278
+#: git-stash.sh:266
 msgid "Cannot save the current status"
 msgstr ""
 
-#: git-stash.sh:296
+#: git-stash.sh:284
 msgid "Cannot remove worktree changes"
 msgstr ""
 
-#: git-stash.sh:395
+#: git-stash.sh:383
 msgid "No stash found."
 msgstr ""
 
-#: git-stash.sh:402
+#: git-stash.sh:390
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr ""
 
-#: git-stash.sh:408
+#: git-stash.sh:396
 #, sh-format
 msgid "$reference is not valid reference"
 msgstr ""
 
-#: git-stash.sh:436
+#: git-stash.sh:424
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr ""
 
-#: git-stash.sh:447
+#: git-stash.sh:435
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr ""
 
-#: git-stash.sh:455
+#: git-stash.sh:443
 msgid "unable to refresh index"
 msgstr ""
 
-#: git-stash.sh:459
+#: git-stash.sh:447
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr ""
 
-#: git-stash.sh:467
+#: git-stash.sh:455
 msgid "Conflicts in index. Try without --index."
 msgstr ""
 
-#: git-stash.sh:469
+#: git-stash.sh:457
 msgid "Could not save index tree"
 msgstr ""
 
-#: git-stash.sh:503
+#: git-stash.sh:491
 msgid "Cannot unstage modified files"
 msgstr ""
 
-#: git-stash.sh:518
+#: git-stash.sh:506
 msgid "Index was not unstashed."
 msgstr ""
 
-#: git-stash.sh:535
+#: git-stash.sh:523
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr ""
 
-#: git-stash.sh:536
+#: git-stash.sh:524
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr ""
 
-#: git-stash.sh:543
+#: git-stash.sh:531
 msgid "No branch name specified"
 msgstr ""
 
-#: git-stash.sh:615
+#: git-stash.sh:603
 msgid "(To restore them type \"git stash apply\")"
 msgstr ""
 
@@ -9828,44 +10098,36 @@
 msgstr ""
 
 #. unexpected type
-#: git-submodule.sh:1066
+#: git-submodule.sh:1073
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr ""
 
-#: git-submodule.sh:1086
+#: git-submodule.sh:1093
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr ""
 
-#: git-submodule.sh:1089
+#: git-submodule.sh:1096
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr ""
 
-#: git-submodule.sh:1092
+#: git-submodule.sh:1099
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
 
-#: git-submodule.sh:1117
+#: git-submodule.sh:1124
 msgid "blob"
 msgstr ""
 
-#: git-submodule.sh:1155
-msgid "Submodules changed but not updated:"
-msgstr ""
-
-#: git-submodule.sh:1157
-msgid "Submodule changes to be committed:"
-msgstr ""
-
-#: git-submodule.sh:1242
+#: git-submodule.sh:1238
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:1306
+#: git-submodule.sh:1302
 #, sh-format
 msgid "Synchronizing submodule url for '$displaypath'"
 msgstr ""
diff --git a/po/it.po b/po/it.po
index fe61f1a..9080219 100644
--- a/po/it.po
+++ b/po/it.po
@@ -2476,7 +2476,7 @@
 msgstr ""
 
 #: builtin/describe.c:482
-msgid "--dirty is incompatible with committishes"
+msgid "--dirty is incompatible with commit-ishes"
 msgstr ""
 
 #: builtin/diff.c:77
diff --git a/po/nl.po b/po/nl.po
index e1399e2..ad31c66 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -1669,7 +1669,7 @@
 msgstr ""
 
 #: builtin/describe.c:482
-msgid "--dirty is incompatible with committishes"
+msgid "--dirty is incompatible with commit-ishes"
 msgstr ""
 
 #: builtin/diff.c:77
diff --git a/po/pt_PT.po b/po/pt_PT.po
index 517ec29..689ad1b 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -2312,7 +2312,7 @@
 msgstr "Nenhum nome encontrado, não descreve nada."
 
 #: builtin/describe.c:482
-msgid "--dirty is incompatible with committishes"
+msgid "--dirty is incompatible with commit-ishes"
 msgstr ""
 
 #: builtin/diff.c:77
diff --git a/po/sv.po b/po/sv.po
index 12dfca9..50cc8cb 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,8 +7,8 @@
 msgstr ""
 "Project-Id-Version: git 1.8.4\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2013-08-06 14:10+0800\n"
-"PO-Revision-Date: 2013-08-06 12:37+0100\n"
+"POT-Creation-Date: 2013-11-02 08:06+0800\n"
+"PO-Revision-Date: 2013-11-09 19:02+0100\n"
 "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -57,71 +57,76 @@
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <arkiv> [--exec <kmd>] --list"
 
-#: archive.c:323
+#: archive.c:242 builtin/add.c:240 builtin/add.c:556 builtin/rm.c:328
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr "sökvägsangivelsen \"%s\" motsvarade inte några filer"
+
+#: archive.c:327
 msgid "fmt"
 msgstr "fmt"
 
-#: archive.c:323
+#: archive.c:327
 msgid "archive format"
 msgstr "arkivformat"
 
-#: archive.c:324 builtin/log.c:1173
+#: archive.c:328 builtin/log.c:1193
 msgid "prefix"
 msgstr "prefix"
 
-#: archive.c:325
+#: archive.c:329
 msgid "prepend prefix to each pathname in the archive"
 msgstr "lägg till prefix till varje sökväg i arkivet"
 
-#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2292
-#: builtin/blame.c:2293 builtin/config.c:56 builtin/fast-export.c:673
-#: builtin/fast-export.c:675 builtin/grep.c:714 builtin/hash-object.c:77
-#: builtin/ls-files.c:496 builtin/ls-files.c:499 builtin/notes.c:408
-#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:152
+#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2264
+#: builtin/blame.c:2265 builtin/config.c:58 builtin/fast-export.c:680
+#: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77
+#: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408
+#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154
 msgid "file"
 msgstr "fil"
 
-#: archive.c:327 builtin/archive.c:89
+#: archive.c:331 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "skriv arkivet till filen"
 
-#: archive.c:329
+#: archive.c:333
 msgid "read .gitattributes in working directory"
 msgstr "läs .gitattributes i arbetskatalogen"
 
-#: archive.c:330
+#: archive.c:334
 msgid "report archived files on stderr"
 msgstr "rapportera arkiverade filer på standard fel"
 
-#: archive.c:331
+#: archive.c:335
 msgid "store only"
 msgstr "endast spara"
 
-#: archive.c:332
+#: archive.c:336
 msgid "compress faster"
 msgstr "komprimera snabbare"
 
-#: archive.c:340
+#: archive.c:344
 msgid "compress better"
 msgstr "komprimera bättre"
 
-#: archive.c:343
+#: archive.c:347
 msgid "list supported archive formats"
 msgstr "visa understödda arkivformat"
 
-#: archive.c:345 builtin/archive.c:90 builtin/clone.c:85
+#: archive.c:349 builtin/archive.c:90 builtin/clone.c:84
 msgid "repo"
 msgstr "arkiv"
 
-#: archive.c:346 builtin/archive.c:91
+#: archive.c:350 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "hämta arkivet från fjärrarkivet <arkiv>"
 
-#: archive.c:347 builtin/archive.c:92 builtin/notes.c:487
+#: archive.c:351 builtin/archive.c:92 builtin/notes.c:487
 msgid "command"
 msgstr "kommando"
 
-#: archive.c:348 builtin/archive.c:93
+#: archive.c:352 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "sökväg till kommandot git-upload-archive på fjärren"
 
@@ -204,17 +209,17 @@
 msgid "Cannot force update the current branch."
 msgstr "Kan inte tvinga uppdatering av aktuell gren."
 
-#: branch.c:216
+#: branch.c:215
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr "Kan inte ställa in spårning; startpunkten \"%s\" är inte en gren."
 
-#: branch.c:218
+#: branch.c:217
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "den efterfrågade uppströmsgrenen \"%s\" finns inte"
 
-#: branch.c:220
+#: branch.c:219
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -234,26 +239,26 @@
 "spåra dess fjärrmotsvarighet kan du använda \"git push -u\"\n"
 "för att ställa in uppströmskonfigurationen när du sänder in."
 
-#: branch.c:265
+#: branch.c:264
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Objektnamnet är inte giltigt: \"%s\"."
 
-#: branch.c:285
+#: branch.c:284
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Objektnamnet är tvetydigt: \"%s\"."
 
-#: branch.c:290
+#: branch.c:289
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Avgreningspunkten är inte giltig: \"%s\""
 
-#: branch.c:296
+#: branch.c:295
 msgid "Failed to lock ref for update"
 msgstr "Misslyckades låsa referens för uppdatering"
 
-#: branch.c:314
+#: branch.c:313
 msgid "Failed to write ref"
 msgstr "Misslyckades skriva referens"
 
@@ -267,7 +272,7 @@
 msgid "unrecognized header: %s%s (%d)"
 msgstr "okänt huvud: %s%s (%d)"
 
-#: bundle.c:89 builtin/commit.c:697
+#: bundle.c:89 builtin/commit.c:706
 #, c-format
 msgid "could not open '%s'"
 msgstr "kunde inte öppna \"%s\""
@@ -276,9 +281,9 @@
 msgid "Repository lacks these prerequisite commits:"
 msgstr "Arkivet saknar dessa nödvändiga incheckningar:"
 
-#: bundle.c:164 sequencer.c:661 sequencer.c:1111 builtin/log.c:331
-#: builtin/log.c:801 builtin/log.c:1399 builtin/log.c:1625 builtin/merge.c:364
-#: builtin/shortlog.c:156
+#: bundle.c:164 sequencer.c:662 sequencer.c:1112 builtin/log.c:332
+#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:364
+#: builtin/shortlog.c:158
 msgid "revision walk setup failed"
 msgstr "misslyckades skapa revisionstraversering"
 
@@ -304,7 +309,7 @@
 msgid "rev-list died"
 msgstr "rev-list dog"
 
-#: bundle.c:300 builtin/log.c:1310 builtin/shortlog.c:259
+#: bundle.c:300 builtin/log.c:1329 builtin/shortlog.c:261
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "okänt argument: %s"
@@ -454,7 +459,7 @@
 "Hittade fel i konfigurationsvariabeln \"diff.dirstat\":\n"
 "%s"
 
-#: diff.c:3487
+#: diff.c:3490
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -463,7 +468,7 @@
 "Misslyckades tolka argument till flaggan --dirstat/-X;\n"
 "%s"
 
-#: diff.c:3501
+#: diff.c:3504
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Misslyckades tolka argument till flaggan --submodule: \"%s\""
@@ -490,17 +495,17 @@
 msgid "failed writing detached signature to '%s': %s"
 msgstr "misslyckades skriva fristående signatur till \"%s\": %s"
 
-#: grep.c:1623
+#: grep.c:1695
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "\"%s\" kunde inte läsa %s"
 
-#: grep.c:1640
+#: grep.c:1712
 #, c-format
 msgid "'%s': %s"
 msgstr "\"%s\": %s"
 
-#: grep.c:1651
+#: grep.c:1723
 #, c-format
 msgid "'%s': short read %s"
 msgstr "\"%s\": kort läsning %s"
@@ -573,8 +578,8 @@
 msgid "failed to read the cache"
 msgstr "misslyckads läsa cachen"
 
-#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566
-#: builtin/clone.c:656
+#: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559
+#: builtin/clone.c:655
 msgid "unable to write new index file"
 msgstr "kunde inte skriva ny indexfil"
 
@@ -623,7 +628,7 @@
 msgid "blob expected for %s '%s'"
 msgstr "blob förväntades för %s \"%s\""
 
-#: merge-recursive.c:774 builtin/clone.c:312
+#: merge-recursive.c:774 builtin/clone.c:311
 #, c-format
 msgid "failed to open '%s'"
 msgstr "misslyckades öppna \"%s\""
@@ -757,7 +762,7 @@
 msgid "Auto-merging %s"
 msgstr "Slår ihop %s automatiskt"
 
-#: merge-recursive.c:1634 git-submodule.sh:1118
+#: merge-recursive.c:1634 git-submodule.sh:1125
 msgid "submodule"
 msgstr "undermodul"
 
@@ -853,58 +858,124 @@
 msgid "Bad %s value: '%s'"
 msgstr "Felaktigt värde på %s: \"%s\""
 
-#: object.c:204
+#: object.c:202
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "kunde inte tolka objektet: %s"
 
-#: parse-options.c:489
+#: parse-options.c:537
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:507
+#: parse-options.c:555
 #, 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:511
+#: parse-options.c:559
 #, c-format
 msgid "   or: %s"
 msgstr "     eller: %s"
 
-#: parse-options.c:514
+#: parse-options.c:562
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:548
+#: parse-options.c:596
 msgid "-NUM"
 msgstr "-TAL"
 
-#: pathspec.c:83
-#, c-format
-msgid "Path '%s' is in submodule '%.*s'"
-msgstr "Sökvägen \"%s\" är i undermodulen \"%.*s\""
+#: pathspec.c:118
+msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
+msgstr ""
+"de globala sökvägsinställningarna \"glob\" och \"noglob\" är inkompatibla"
 
-#: pathspec.c:99
-#, c-format
-msgid "'%s' is beyond a symbolic link"
-msgstr "\"%s\" är på andra sidan av en symbolisk länk"
+#: pathspec.c:128
+msgid ""
+"global 'literal' pathspec setting is incompatible with all other global "
+"pathspec settings"
+msgstr ""
+"den globala sökvägsinställningen \"literal\" är inkompatibel med alla andra "
+"globala sökvägsinställningar"
 
-#: remote.c:1788
+#: pathspec.c:158
+msgid "invalid parameter for pathspec magic 'prefix'"
+msgstr "ogiltig parameter för sökvägsuttrycket för \"prefix\""
+
+#: pathspec.c:164
+#, c-format
+msgid "Invalid pathspec magic '%.*s' in '%s'"
+msgstr "felaktigt sökvägsuttryck \"%.*s\" i \"%s\""
+
+#: pathspec.c:168
+#, c-format
+msgid "Missing ')' at the end of pathspec magic in '%s'"
+msgstr "\")\" saknas i slutet av sökvägsuttrycket för \"%s\""
+
+#: pathspec.c:186
+#, c-format
+msgid "Unimplemented pathspec magic '%c' in '%s'"
+msgstr "Tecknet \"%c\" i sökvägsuttrycket i \"%s\" har inte implementerats"
+
+#: pathspec.c:211
+#, c-format
+msgid "%s: 'literal' and 'glob' are incompatible"
+msgstr "%s: \"literal\" och \"glob\" är inkompatibla"
+
+#: pathspec.c:222
+#, c-format
+msgid "%s: '%s' is outside repository"
+msgstr "%s: \"%s\" är utanför arkivet"
+
+#: pathspec.c:278
+#, c-format
+msgid "Pathspec '%s' is in submodule '%.*s'"
+msgstr "Sökvägsangivelsen \"%s\" är i undermodulen \"%.*s\""
+
+#.
+#. * We may want to substitute "this command" with a command
+#. * name. E.g. when add--interactive dies when running
+#. * "checkout -p"
+#.
+#: pathspec.c:340
+#, c-format
+msgid "%s: pathspec magic not supported by this command: %s"
+msgstr "%s: sökvägsuttrycket hanteras inte av det här kommandot: %s"
+
+#: pathspec.c:415
+#, c-format
+msgid "pathspec '%s' is beyond a symbolic link"
+msgstr "sökvägsangivelsen \"%s\" är på andra sidan av en symbolisk länk"
+
+#: remote.c:1833
+#, c-format
+msgid "Your branch is based on '%s', but the upstream is gone.\n"
+msgstr "Din gren är baserad på \"%s\", men den har försvunnit uppströms.\n"
+
+#: remote.c:1837
+msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
+msgstr "  (använd \"git branch --unset-upstream\" för att rätta)\n"
+
+#: remote.c:1840
+#, c-format
+msgid "Your branch is up-to-date with '%s'.\n"
+msgstr "Din gren är à jour med \"%s\".\n"
+
+#: remote.c:1844
 #, 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:1794
+#: remote.c:1850
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (använd \"git push\" för att publicera dina lokala incheckningar)\n"
 
-#: remote.c:1797
+#: remote.c:1853
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -914,11 +985,11 @@
 msgstr[1] ""
 "Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n"
 
-#: remote.c:1805
+#: remote.c:1861
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (använd \"git pull\" för att uppdatera din lokala gren)\n"
 
-#: remote.c:1808
+#: remote.c:1864
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -933,7 +1004,7 @@
 "Din gren och \"%s\" har divergerat,\n"
 "och har %d respektive %d olika incheckningar.\n"
 
-#: remote.c:1818
+#: remote.c:1874
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (använd \"git pull\" för att slå ihop fjärrgrenen med din egen)\n"
 
@@ -976,7 +1047,7 @@
 "med \"git add <sökvägar>\" eller \"git rm <sökvägar>\"\n"
 "och checka in resultatet med \"git commit\""
 
-#: sequencer.c:245 sequencer.c:869 sequencer.c:952
+#: sequencer.c:245 sequencer.c:870 sequencer.c:953
 #, c-format
 msgid "Could not write to %s"
 msgstr "Kunde inte skriva till %s"
@@ -999,197 +1070,197 @@
 msgstr "Checka in dina ändringar eller använd \"stash\" för att fortsätta."
 
 #. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:324
+#: sequencer.c:325
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: Kunde inte skriva ny indexfil"
 
-#: sequencer.c:355
+#: sequencer.c:356
 msgid "Could not resolve HEAD commit\n"
 msgstr "Kunde inte bestämma HEAD:s incheckning\n"
 
-#: sequencer.c:377
+#: sequencer.c:378
 msgid "Unable to update cache tree\n"
 msgstr "Kan inte uppdatera cacheträd\n"
 
-#: sequencer.c:422
+#: sequencer.c:423
 #, c-format
 msgid "Could not parse commit %s\n"
 msgstr "Kunde inte tolka incheckningen %s\n"
 
-#: sequencer.c:427
+#: sequencer.c:428
 #, c-format
 msgid "Could not parse parent commit %s\n"
 msgstr "Kunde inte tolka föräldraincheckningen %s\n"
 
-#: sequencer.c:493
+#: sequencer.c:494
 msgid "Your index file is unmerged."
 msgstr "Din indexfil har inte slagits ihop."
 
-#: sequencer.c:512
+#: sequencer.c:513
 #, c-format
 msgid "Commit %s is a merge but no -m option was given."
 msgstr "Incheckning %s är en sammanslagning, men flaggan -m angavs inte."
 
-#: sequencer.c:520
+#: sequencer.c:521
 #, c-format
 msgid "Commit %s does not have parent %d"
 msgstr "Incheckning %s har inte förälder %d"
 
-#: sequencer.c:524
+#: sequencer.c:525
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
 msgstr "Huvudlinje angavs, men incheckningen %s är inte en sammanslagning"
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
-#: sequencer.c:537
+#: sequencer.c:538
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: kan inte tolka föräldraincheckningen %s"
 
-#: sequencer.c:541
+#: sequencer.c:542
 #, c-format
 msgid "Cannot get commit message for %s"
 msgstr "Kan inte hämta incheckningsmeddelande för %s"
 
-#: sequencer.c:627
+#: sequencer.c:628
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "kunde inte ångra %s... %s"
 
-#: sequencer.c:628
+#: sequencer.c:629
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "kunde inte tillämpa %s... %s"
 
-#: sequencer.c:664
+#: sequencer.c:665
 msgid "empty commit set passed"
 msgstr "den angivna uppsättningen incheckningar är tom"
 
-#: sequencer.c:672
+#: sequencer.c:673
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: misslyckades läsa indexet"
 
-#: sequencer.c:677
+#: sequencer.c:678
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s: misslyckades uppdatera indexet"
 
-#: sequencer.c:735
+#: sequencer.c:736
 #, c-format
 msgid "Cannot %s during a %s"
 msgstr "kan inte %s under en %s"
 
-#: sequencer.c:757
+#: sequencer.c:758
 #, c-format
 msgid "Could not parse line %d."
 msgstr "Kan inte tolka rad %d."
 
-#: sequencer.c:762
+#: sequencer.c:763
 msgid "No commits parsed."
 msgstr "Inga incheckningar lästes."
 
-#: sequencer.c:775
+#: sequencer.c:776
 #, c-format
 msgid "Could not open %s"
 msgstr "Kunde inte öppna %s"
 
-#: sequencer.c:779
+#: sequencer.c:780
 #, c-format
 msgid "Could not read %s."
 msgstr "kunde inte läsa %s."
 
-#: sequencer.c:786
+#: sequencer.c:787
 #, c-format
 msgid "Unusable instruction sheet: %s"
 msgstr "Oanvändbart manus: %s"
 
-#: sequencer.c:814
+#: sequencer.c:815
 #, c-format
 msgid "Invalid key: %s"
 msgstr "Felaktig nyckel: %s"
 
-#: sequencer.c:817
+#: sequencer.c:818
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Felaktigt värde för %s: %s"
 
-#: sequencer.c:829
+#: sequencer.c:830
 #, c-format
 msgid "Malformed options sheet: %s"
 msgstr "Trasigt manus: %s"
 
-#: sequencer.c:850
+#: sequencer.c:851
 msgid "a cherry-pick or revert is already in progress"
 msgstr "en \"cherry-pick\" eller \"revert\" pågår redan"
 
-#: sequencer.c:851
+#: sequencer.c:852
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "testa \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:855
+#: sequencer.c:856
 #, c-format
 msgid "Could not create sequencer directory %s"
 msgstr "Kunde inte skapa \"sequencer\"-katalogen \"%s\""
 
-#: sequencer.c:871 sequencer.c:956
+#: sequencer.c:872 sequencer.c:957
 #, c-format
 msgid "Error wrapping up %s."
 msgstr "Fel vid ombrytning av %s."
 
-#: sequencer.c:890 sequencer.c:1024
+#: sequencer.c:891 sequencer.c:1025
 msgid "no cherry-pick or revert in progress"
 msgstr "ingen \"cherry-pick\" eller \"revert\" pågår"
 
-#: sequencer.c:892
+#: sequencer.c:893
 msgid "cannot resolve HEAD"
 msgstr "kan inte bestämma HEAD"
 
-#: sequencer.c:894
+#: sequencer.c:895
 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:916 builtin/apply.c:4061
+#: sequencer.c:917 builtin/apply.c:4061
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "kan inte öppna %s: %s"
 
-#: sequencer.c:919
+#: sequencer.c:920
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "kan inte läsa %s: %s"
 
-#: sequencer.c:920
+#: sequencer.c:921
 msgid "unexpected end of file"
 msgstr "oväntat filslut"
 
-#: sequencer.c:926
+#: sequencer.c:927
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "sparad HEAD-fil från före \"cherry-pick\", \"%s\", är trasig"
 
-#: sequencer.c:949
+#: sequencer.c:950
 #, c-format
 msgid "Could not format %s."
 msgstr "Kunde inte formatera %s."
 
-#: sequencer.c:1092
+#: sequencer.c:1093
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: kan inte göra \"cherry-pick\" på typen \"%s\""
 
-#: sequencer.c:1095
+#: sequencer.c:1096
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: felaktig revision"
 
-#: sequencer.c:1129
+#: sequencer.c:1130
 msgid "Can't revert as initial commit"
 msgstr "Kan inte ångra som första incheckning"
 
-#: sequencer.c:1130
+#: sequencer.c:1131
 msgid "Can't cherry-pick into empty head"
 msgstr "Kan inte göra \"cherry-pick\" i ett tomt huvud"
 
@@ -1215,256 +1286,350 @@
 "Undersök referenserna och ta kanske bort dem. Stäng av meddelandet\n"
 "genom att köra \"git config advice.objectNameWarning false\""
 
-#: sha1_name.c:1097
+#: sha1_name.c:1112
 msgid "HEAD does not point to a branch"
 msgstr "HEAD pekar inte på en gren"
 
-#: sha1_name.c:1100
+#: sha1_name.c:1115
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "Okänd gren: \"%s\""
 
-#: sha1_name.c:1102
+#: sha1_name.c:1117
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "Ingen standarduppström angiven för grenen \"%s\""
 
-#: sha1_name.c:1106
+#: sha1_name.c:1121
 #, 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"
 
-#: wrapper.c:408
+#: submodule.c:64 submodule.c:98
+msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
+msgstr ""
+"Kan inte ändra .gitmodules-fil som inte slagits ihop, lös "
+"sammanslagningskonflikter först"
+
+#: submodule.c:68 submodule.c:102
+#, c-format
+msgid "Could not find section in .gitmodules where path=%s"
+msgstr "Hittade inte någon sektion i .gitmodules där sökväg=%s"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:76
+#, c-format
+msgid "Could not update .gitmodules entry %s"
+msgstr "Kunde inte uppdatera .gitmodules-posten %s"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:109
+#, c-format
+msgid "Could not remove .gitmodules entry for %s"
+msgstr "Kunde inte ta bort .gitmodules-posten för %s"
+
+#: submodule.c:127
+msgid "could not find .gitmodules in index"
+msgstr "kunde inte hitta .gitmodules i indexet"
+
+#: submodule.c:133
+msgid "reading updated .gitmodules failed"
+msgstr "misslyckades läsa uppdaterad .gitmodules"
+
+#: submodule.c:135
+msgid "unable to stat updated .gitmodules"
+msgstr "kan inte ta status på uppdaterad .gitmodules"
+
+#: submodule.c:139
+msgid "unable to remove .gitmodules from index"
+msgstr "kan inte ta bort .gitmodules från indexet"
+
+#: submodule.c:141
+msgid "adding updated .gitmodules failed"
+msgstr "misslyckades lägga till uppdaterad .gitmodules"
+
+#: submodule.c:143
+msgid "staging updated .gitmodules failed"
+msgstr "misslyckades köa uppdaterad .gitmodules"
+
+#: submodule.c:1144 builtin/init-db.c:363
+#, c-format
+msgid "Could not create git link %s"
+msgstr "Kunde inte skapa gitlänk %s"
+
+#: submodule.c:1155
+#, c-format
+msgid "Could not set core.worktree in %s"
+msgstr "Kunde inte sätta core.worktree i %s"
+
+#: urlmatch.c:120
+msgid "invalid URL scheme name or missing '://' suffix"
+msgstr "ogiltig URL-schemanamn eller saknat \"://\"-suffix"
+
+#: urlmatch.c:144 urlmatch.c:297 urlmatch.c:356
+#, c-format
+msgid "invalid %XX escape sequence"
+msgstr "ogiltig %XX-teckensekvens"
+
+#: urlmatch.c:172
+msgid "missing host and scheme is not 'file:'"
+msgstr "värd saknas och schemat är inte \"file:\""
+
+#: urlmatch.c:189
+msgid "a 'file:' URL may not have a port number"
+msgstr "en \"file:\"-URL kan inte innehålla portnummer"
+
+#: urlmatch.c:199
+msgid "invalid characters in host name"
+msgstr "ogiltiga tecken i värdnamnet"
+
+#: urlmatch.c:244 urlmatch.c:255
+msgid "invalid port number"
+msgstr "felaktigt portnummer"
+
+#: urlmatch.c:322
+msgid "invalid '..' path segment"
+msgstr "felaktit \"..\"-sökvägssegment"
+
+#: wrapper.c:422
 #, c-format
 msgid "unable to access '%s': %s"
 msgstr "kan inte komma åt \"%s\": %s"
 
-#: wrapper.c:429
+#: wrapper.c:443
 #, c-format
 msgid "unable to access '%s'"
 msgstr "kan inte komma åt \"%s\""
 
-#: wrapper.c:440
+#: wrapper.c:454
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
 msgstr "kan inte slå upp aktuell användare i passwd-filen: %s"
 
-#: wrapper.c:441
+#: wrapper.c:455
 msgid "no such user"
 msgstr "okänd användare"
 
-#: wt-status.c:141
+#: wt-status.c:146
 msgid "Unmerged paths:"
 msgstr "Ej sammanslagna sökvägar:"
 
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:173 wt-status.c:200
 #, 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:175 wt-status.c:202
 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:179
 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:181 wt-status.c:185
 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:183
 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:194
 msgid "Changes to be committed:"
 msgstr "Ändringar att checka in:"
 
-#: wt-status.c:207
+#: wt-status.c:212
 msgid "Changes not staged for commit:"
 msgstr "Ändringar ej i incheckningskön:"
 
-#: wt-status.c:211
+#: wt-status.c:216
 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:218
 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:219
 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:221
 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)"
 
-#: wt-status.c:228
+#: wt-status.c:233
 #, 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 det som skall checkas in)"
 
-#: wt-status.c:245
+#: wt-status.c:250
 msgid "bug"
 msgstr "programfel"
 
-#: wt-status.c:250
+#: wt-status.c:255
 msgid "both deleted:"
 msgstr "borttaget av bägge:"
 
-#: wt-status.c:251
+#: wt-status.c:256
 msgid "added by us:"
 msgstr "tillagt av oss:"
 
-#: wt-status.c:252
+#: wt-status.c:257
 msgid "deleted by them:"
 msgstr "borttaget av dem:"
 
-#: wt-status.c:253
+#: wt-status.c:258
 msgid "added by them:"
 msgstr "tillagt av dem:"
 
-#: wt-status.c:254
+#: wt-status.c:259
 msgid "deleted by us:"
 msgstr "borttaget av oss:"
 
-#: wt-status.c:255
+#: wt-status.c:260
 msgid "both added:"
 msgstr "tillagt av bägge:"
 
-#: wt-status.c:256
+#: wt-status.c:261
 msgid "both modified:"
 msgstr "ändrat av bägge:"
 
-#: wt-status.c:286
+#: wt-status.c:291
 msgid "new commits, "
 msgstr "nya incheckningar, "
 
-#: wt-status.c:288
+#: wt-status.c:293
 msgid "modified content, "
 msgstr "ändrat innehåll, "
 
-#: wt-status.c:290
+#: wt-status.c:295
 msgid "untracked content, "
 msgstr "ospårat innehåll, "
 
-#: wt-status.c:307
+#: wt-status.c:312
 #, c-format
 msgid "new file:   %s"
 msgstr "ny fil:     %s"
 
-#: wt-status.c:310
+#: wt-status.c:315
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "kopierad:   %s -> %s"
 
-#: wt-status.c:313
+#: wt-status.c:318
 #, c-format
 msgid "deleted:    %s"
 msgstr "borttagen:  %s"
 
-#: wt-status.c:316
+#: wt-status.c:321
 #, c-format
 msgid "modified:   %s"
 msgstr "ändrad:     %s"
 
-#: wt-status.c:319
+#: wt-status.c:324
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "namnbyte:   %s -> %s"
 
-#: wt-status.c:322
+#: wt-status.c:327
 #, c-format
 msgid "typechange: %s"
 msgstr "typbyte:    %s"
 
-#: wt-status.c:325
+#: wt-status.c:330
 #, c-format
 msgid "unknown:    %s"
 msgstr "okänd:      %s"
 
-#: wt-status.c:328
+#: wt-status.c:333
 #, c-format
 msgid "unmerged:   %s"
 msgstr "osammansl.: %s"
 
-#: wt-status.c:331
+#: wt-status.c:336
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "programfel: diff-status %c ej hanterad"
 
-#: wt-status.c:803
+#: wt-status.c:703
+msgid "Submodules changed but not updated:"
+msgstr "Undermoduler ändrade men inte uppdaterade:"
+
+#: wt-status.c:705
+msgid "Submodule changes to be committed:"
+msgstr "Undermodulers ändringar att checka in:"
+
+#: wt-status.c:848
 msgid "You have unmerged paths."
 msgstr "Du har ej sammanslagna sökvägar."
 
-#: wt-status.c:806
+#: wt-status.c:851
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (rätta konflikter och kör \"git commit\")"
 
-#: wt-status.c:809
+#: wt-status.c:854
 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:812
+#: wt-status.c:857
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (använd \"git commit\" för att slutföra sammanslagningen)"
 
-#: wt-status.c:822
+#: wt-status.c:867
 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:825
+#: wt-status.c:870
 msgid "The current patch is empty."
 msgstr "Aktuell patch är tom."
 
-#: wt-status.c:829
+#: wt-status.c:874
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git am --continue\")"
 
-#: wt-status.c:831
+#: wt-status.c:876
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (använd \"git am --skip\" för att hoppa över patchen)"
 
-#: wt-status.c:833
+#: wt-status.c:878
 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:893 wt-status.c:910
+#: wt-status.c:938 wt-status.c:955
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "Du håller på att ombasera grenen \"%s\" ovanpå \"%s\"."
 
-#: wt-status.c:898 wt-status.c:915
+#: wt-status.c:943 wt-status.c:960
 msgid "You are currently rebasing."
 msgstr "Du håller på med en ombasering."
 
-#: wt-status.c:901
+#: wt-status.c:946
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git rebase --continue\")"
 
-#: wt-status.c:903
+#: wt-status.c:948
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (använd \"git rebase --skip\" för att hoppa över patchen)"
 
-#: wt-status.c:905
+#: wt-status.c:950
 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:918
+#: wt-status.c:963
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (alla konflikter rättade: kör \"git rebase --continue\")"
 
-#: wt-status.c:922
+#: wt-status.c:967
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
@@ -1472,117 +1637,118 @@
 "Du håller på att dela upp en incheckning medan du ombaserar grenen \"%s\" "
 "ovanpå \"%s\"."
 
-#: wt-status.c:927
+#: wt-status.c:972
 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:930
+#: wt-status.c:975
 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:934
+#: wt-status.c:979
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 "Du håller på att redigera en incheckning medan du ombaserar grenen \"%s\" "
 "ovanpå \"%s\"."
 
-#: wt-status.c:939
+#: wt-status.c:984
 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:942
+#: wt-status.c:987
 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:944
+#: wt-status.c:989
 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:954
-msgid "You are currently cherry-picking."
-msgstr "Du håller på med en \"cherry-pick\"."
+#: wt-status.c:999
+#, c-format
+msgid "You are currently cherry-picking commit %s."
+msgstr "Du håller på med en \"cherry-pick\" av incheckningen %s."
 
-#: wt-status.c:958
+#: wt-status.c:1004
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git cherry-pick --continue\")"
 
-#: wt-status.c:961
+#: wt-status.c:1007
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr "  (alla konflikter rättade: kör \"git cherry-pick --continue\")"
 
-#: wt-status.c:963
+#: wt-status.c:1009
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
 "  (använd \"git cherry-pick --abort\" för att avbryta \"cherry-pick\"-"
 "operationen)"
 
-#: wt-status.c:972
+#: wt-status.c:1018
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "Du håller på med att ångra incheckningen %s."
 
-#: wt-status.c:977
+#: wt-status.c:1023
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git revert --continue\")"
 
-#: wt-status.c:980
+#: wt-status.c:1026
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (alla konflikter rättade: kör \"git revert --continue\")"
 
-#: wt-status.c:982
+#: wt-status.c:1028
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (använd \"git revert --abort\" för att avbryta ångrandet)"
 
-#: wt-status.c:993
+#: wt-status.c:1039
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "Du håller på med en \"bisect\", startad från grenen \"%s\"."
 
-#: wt-status.c:997
+#: wt-status.c:1043
 msgid "You are currently bisecting."
 msgstr "Du håller på med en \"bisect\"."
 
-#: wt-status.c:1000
+#: wt-status.c:1046
 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:1173
+#: wt-status.c:1221
 msgid "On branch "
 msgstr "På grenen "
 
-#: wt-status.c:1180
+#: wt-status.c:1228
 msgid "rebase in progress; onto "
 msgstr "ombasering pågår; ovanpå"
 
-#: wt-status.c:1187
+#: wt-status.c:1235
 msgid "HEAD detached at "
 msgstr "HEAD frånkopplad vid "
 
-#: wt-status.c:1189
+#: wt-status.c:1237
 msgid "HEAD detached from "
 msgstr "HEAD frånkopplad från "
 
-#: wt-status.c:1192
+#: wt-status.c:1240
 msgid "Not currently on any branch."
 msgstr "Inte på någon gren för närvarande."
 
-#: wt-status.c:1209
+#: wt-status.c:1257
 msgid "Initial commit"
 msgstr "Första incheckning"
 
-#: wt-status.c:1223
+#: wt-status.c:1271
 msgid "Untracked files"
 msgstr "Ospårade filer"
 
-#: wt-status.c:1225
+#: wt-status.c:1273
 msgid "Ignored files"
 msgstr "Ignorerade filer"
 
-#: wt-status.c:1229
+#: wt-status.c:1277
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -1594,32 +1760,32 @@
 "lägga till nya filer själv (se \"git help status\")."
 
 # %s är nästa sträng eller tom.
-#: wt-status.c:1235
+#: wt-status.c:1283
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Ospårade filer visas ej%s"
 
-#: wt-status.c:1237
+#: wt-status.c:1285
 msgid " (use -u option to show untracked files)"
 msgstr " (använd flaggan -u för att visa ospårade filer)"
 
-#: wt-status.c:1243
+#: wt-status.c:1291
 msgid "No changes"
 msgstr "Inga ändringar"
 
-#: wt-status.c:1248
+#: wt-status.c:1296
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 "inga ändringar att checka in (använd \"git add\" och/eller \"git commit -a"
 "\")\n"
 
-#: wt-status.c:1251
+#: wt-status.c:1299
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "inga ändringar att checka in\n"
 
-#: wt-status.c:1254
+#: wt-status.c:1302
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -1628,52 +1794,56 @@
 "inget köat för incheckning, men ospårade filer finns (spåra med \"git add"
 "\")\n"
 
-#: wt-status.c:1257
+#: wt-status.c:1305
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr "inget köat för incheckning, men ospårade filer finns\n"
 
-#: wt-status.c:1260
+#: wt-status.c:1308
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr "inget att checka in (skapa/kopiera filer och spåra med \"git add\")\n"
 
-#: wt-status.c:1263 wt-status.c:1268
+#: wt-status.c:1311 wt-status.c:1316
 #, c-format
 msgid "nothing to commit\n"
 msgstr "inget att checka in\n"
 
-#: wt-status.c:1266
+#: wt-status.c:1314
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr "inget att checka in (använd -u för att visa ospårade filer)\n"
 
-#: wt-status.c:1270
+#: wt-status.c:1318
 #, c-format
 msgid "nothing to commit, working directory clean\n"
 msgstr "inget att checka in, arbetskatalogen ren\n"
 
-#: wt-status.c:1378
+#: wt-status.c:1427
 msgid "HEAD (no branch)"
 msgstr "HEAD (ingen gren)"
 
-#: wt-status.c:1384
+#: wt-status.c:1433
 msgid "Initial commit on "
 msgstr "Första incheckning på "
 
-#: wt-status.c:1399
+#: wt-status.c:1463
+msgid "gone"
+msgstr "försvunnen"
+
+#: wt-status.c:1465
 msgid "behind "
 msgstr "efter "
 
-#: wt-status.c:1402 wt-status.c:1405
+#: wt-status.c:1468 wt-status.c:1471
 msgid "ahead "
 msgstr "före "
 
-#: wt-status.c:1407
+#: wt-status.c:1473
 msgid ", behind "
 msgstr ", efter "
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:351
+#: compat/precompose_utf8.c:55 builtin/clone.c:350
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "misslyckades ta bort länken \"%s\""
@@ -1759,7 +1929,7 @@
 msgid "unexpected diff status %c"
 msgstr "diff-status %c förväntades inte"
 
-#: builtin/add.c:149 builtin/commit.c:252
+#: builtin/add.c:149 builtin/commit.c:260
 msgid "updating files failed"
 msgstr "misslyckades uppdatera filer"
 
@@ -1768,140 +1938,135 @@
 msgid "remove '%s'\n"
 msgstr "ta bort \"%s\"\n"
 
-#: builtin/add.c:253
+#: builtin/add.c:237
 msgid "Unstaged changes after refreshing the index:"
 msgstr "Ospårade ändringar efter att ha uppdaterat indexet:"
 
-#: builtin/add.c:256 builtin/add.c:573 builtin/rm.c:337
-#, c-format
-msgid "pathspec '%s' did not match any files"
-msgstr "sökvägsangivelsen \"%s\" motsvarade inte några filer"
-
-#: builtin/add.c:339
+#: builtin/add.c:299
 msgid "Could not read the index"
 msgstr "Kunde inte läsa indexet"
 
-#: builtin/add.c:350
+#: builtin/add.c:310
 #, c-format
 msgid "Could not open '%s' for writing."
 msgstr "Kunde inte öppna \"%s\" för skrivning"
 
-#: builtin/add.c:354
+#: builtin/add.c:314
 msgid "Could not write patch"
 msgstr "Kunde inte skriva patch"
 
-#: builtin/add.c:359
+#: builtin/add.c:319
 #, c-format
 msgid "Could not stat '%s'"
 msgstr "Kunde inte ta status på \"%s\""
 
-#: builtin/add.c:361
+#: builtin/add.c:321
 msgid "Empty patch. Aborted."
 msgstr "Tom patch. Avbryter."
 
-#: builtin/add.c:367
+#: builtin/add.c:327
 #, c-format
 msgid "Could not apply '%s'"
 msgstr "Kunde inte tillämpa \"%s\""
 
-#: builtin/add.c:377
+#: builtin/add.c:337
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr "Följande sökvägar ignoreras av en av dina .gitignore-filer:\n"
 
-#: builtin/add.c:394 builtin/clean.c:875 builtin/fetch.c:78 builtin/mv.c:63
-#: builtin/prune-packed.c:73 builtin/push.c:451 builtin/remote.c:1253
-#: builtin/rm.c:268
+#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:92 builtin/mv.c:66
+#: builtin/prune-packed.c:73 builtin/push.c:459 builtin/remote.c:1253
+#: builtin/rm.c:269
 msgid "dry run"
 msgstr "testkörning"
 
-#: builtin/add.c:395 builtin/apply.c:4410 builtin/check-ignore.c:19
-#: builtin/commit.c:1220 builtin/count-objects.c:95 builtin/fsck.c:613
-#: builtin/log.c:1573 builtin/mv.c:62 builtin/read-tree.c:113
+#: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19
+#: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612
+#: builtin/log.c:1592 builtin/mv.c:65 builtin/read-tree.c:113
 msgid "be verbose"
 msgstr "var pratsam"
 
-#: builtin/add.c:397
+#: builtin/add.c:357
 msgid "interactive picking"
 msgstr "plocka interaktivt"
 
-#: builtin/add.c:398 builtin/checkout.c:1073 builtin/reset.c:261
+#: builtin/add.c:358 builtin/checkout.c:1109 builtin/reset.c:272
 msgid "select hunks interactively"
 msgstr "välj stycken interaktivt"
 
-#: builtin/add.c:399
+#: builtin/add.c:359
 msgid "edit current diff and apply"
 msgstr "redigera aktuell diff och applicera"
 
-#: builtin/add.c:400
+#: builtin/add.c:360
 msgid "allow adding otherwise ignored files"
 msgstr "tillåt lägga till annars ignorerade filer"
 
-#: builtin/add.c:401
+#: builtin/add.c:361
 msgid "update tracked files"
 msgstr "uppdatera spårade filer"
 
-#: builtin/add.c:402
+#: builtin/add.c:362
 msgid "record only the fact that the path will be added later"
 msgstr "registrera endast att sökvägen kommer läggas till senare"
 
-#: builtin/add.c:403
+#: builtin/add.c:363
 msgid "add changes from all tracked and untracked files"
 msgstr "lägg till ändringar från alla spårade och ospårade filer"
 
 #. takes no arguments
-#: builtin/add.c:406
+#: builtin/add.c:366
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr "ignorera sökvägar borttagna i arbetskatalogen (samma som --no-all)"
 
-#: builtin/add.c:408
+#: builtin/add.c:368
 msgid "don't add, only refresh the index"
 msgstr "lägg inte till, uppdatera endast indexet"
 
-#: builtin/add.c:409
+#: builtin/add.c:369
 msgid "just skip files which cannot be added because of errors"
 msgstr "hoppa bara över filer som inte kan läggas till på grund av fel"
 
-#: builtin/add.c:410
+#: builtin/add.c:370
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "se om - även saknade - filer ignoreras i testkörning"
 
-#: builtin/add.c:432
+#: builtin/add.c:392
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Använd -f om du verkligen vill lägga till dem.\n"
 
-#: builtin/add.c:433
+#: builtin/add.c:393
 msgid "no files added"
 msgstr "inga filer har lagts till"
 
-#: builtin/add.c:439
+#: builtin/add.c:399
 msgid "adding files failed"
 msgstr "misslyckades lägga till filer"
 
-#: builtin/add.c:478
+#: builtin/add.c:438
 msgid "-A and -u are mutually incompatible"
 msgstr "-A och -u är ömsesidigt inkompatibla"
 
-#: builtin/add.c:496
+#: builtin/add.c:456
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "Flaggan --ignore-missing kan endast användas tillsammans med --dry-run"
 
-#: builtin/add.c:526
+#: builtin/add.c:486
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Inget angivet, inget tillagt.\n"
 
-#: builtin/add.c:527
+#: builtin/add.c:487
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Kanske menade du att skriva \"git add .\"?\n"
 
-#: builtin/add.c:533 builtin/check-ignore.c:161 builtin/clean.c:919
-#: builtin/commit.c:312 builtin/mv.c:82 builtin/rm.c:297
+#: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919
+#: builtin/commit.c:320 builtin/mv.c:86 builtin/reset.c:224 builtin/rm.c:299
 msgid "index file corrupt"
 msgstr "indexfilen trasig"
 
-#: builtin/add.c:605 builtin/apply.c:4506 builtin/mv.c:229 builtin/rm.c:432
+#: builtin/add.c:589 builtin/apply.c:4506 builtin/mv.c:259 builtin/rm.c:432
 msgid "Unable to write new index file"
 msgstr "Kunde inte skriva ny indexfil"
 
@@ -2154,7 +2319,7 @@
 msgid "Checking patch %s..."
 msgstr "Kontrollerar patchen %s..."
 
-#: builtin/apply.c:3680 builtin/checkout.c:216 builtin/reset.c:127
+#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:127
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "make_cache_entry misslyckades för sökvägen \"%s\""
@@ -2234,8 +2399,8 @@
 msgid "unable to read index file"
 msgstr "kan inte läsa indexfilen"
 
-#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:91
-#: builtin/fetch.c:63
+#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90
+#: builtin/fetch.c:77
 msgid "path"
 msgstr "sökväg"
 
@@ -2295,7 +2460,7 @@
 msgid "build a temporary index based on embedded index information"
 msgstr "bygg ett temporärt index baserat på inbyggd indexinformation"
 
-#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:462
+#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:452
 msgid "paths are separated with NUL character"
 msgstr "sökvägar avdelas med NUL-tecken"
 
@@ -2425,103 +2590,103 @@
 msgid "update BISECT_HEAD instead of checking out the current commit"
 msgstr "uppdatera BISECT_HEAD istället för att checka ut aktuell incheckning"
 
-#: builtin/blame.c:26
+#: builtin/blame.c:27
 msgid "git blame [options] [rev-opts] [rev] [--] file"
 msgstr "git blame [flaggor] [rev-flaggor] [rev] [--] fil"
 
-#: builtin/blame.c:31
+#: builtin/blame.c:32
 msgid "[rev-opts] are documented in git-rev-list(1)"
 msgstr "[rev-flaggor] dokumenteras i git-rev-list(1)"
 
-#: builtin/blame.c:2276
+#: builtin/blame.c:2248
 msgid "Show blame entries as we find them, incrementally"
 msgstr "Visa klandringsposter när vi hittar dem, interaktivt"
 
-#: builtin/blame.c:2277
+#: builtin/blame.c:2249
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "Visa blank SHA-1 för gränsincheckningar (Standard: av)"
 
-#: builtin/blame.c:2278
+#: builtin/blame.c:2250
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "Behandla inte rotincheckningar som gränser (Standard: av)"
 
-#: builtin/blame.c:2279
+#: builtin/blame.c:2251
 msgid "Show work cost statistics"
 msgstr "Visa statistik över arbetskostnad"
 
-#: builtin/blame.c:2280
+#: builtin/blame.c:2252
 msgid "Show output score for blame entries"
 msgstr "Visa utdatapoäng för klandringsposter"
 
-#: builtin/blame.c:2281
+#: builtin/blame.c:2253
 msgid "Show original filename (Default: auto)"
 msgstr "Visa originalfilnamn (Standard: auto)"
 
-#: builtin/blame.c:2282
+#: builtin/blame.c:2254
 msgid "Show original linenumber (Default: off)"
 msgstr "Visa ursprungligt radnummer (Standard: av)"
 
-#: builtin/blame.c:2283
+#: builtin/blame.c:2255
 msgid "Show in a format designed for machine consumption"
 msgstr "Visa i ett format avsett för maskinkonsumtion"
 
-#: builtin/blame.c:2284
+#: builtin/blame.c:2256
 msgid "Show porcelain format with per-line commit information"
 msgstr "Visa porslinsformat med per-rad-incheckningsinformation"
 
-#: builtin/blame.c:2285
+#: builtin/blame.c:2257
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "Använd samma utdataläge som git-annotate (Standard: av)"
 
-#: builtin/blame.c:2286
+#: builtin/blame.c:2258
 msgid "Show raw timestamp (Default: off)"
 msgstr "Visa rå tidsstämpel (Standard: av)"
 
-#: builtin/blame.c:2287
+#: builtin/blame.c:2259
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Visa lång inchecknings-SHA1 (Standard: av)"
 
-#: builtin/blame.c:2288
+#: builtin/blame.c:2260
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Undertryck författarnamn och tidsstämpel (Standard: av)"
 
-#: builtin/blame.c:2289
+#: builtin/blame.c:2261
 msgid "Show author email instead of name (Default: off)"
 msgstr "Visa författarens e-post istället för namn (Standard: av)"
 
-#: builtin/blame.c:2290
+#: builtin/blame.c:2262
 msgid "Ignore whitespace differences"
 msgstr "Ignorera ändringar i blanksteg"
 
-#: builtin/blame.c:2291
+#: builtin/blame.c:2263
 msgid "Spend extra cycles to find better match"
 msgstr "Slösa extra cykler med att hitta bättre träff"
 
-#: builtin/blame.c:2292
+#: builtin/blame.c:2264
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "Använd revisioner från <fil> istället för att anropa git-rev-list"
 
-#: builtin/blame.c:2293
+#: builtin/blame.c:2265
 msgid "Use <file>'s contents as the final image"
 msgstr "Använd <fil>s innehåll som slutgiltig bild"
 
-#: builtin/blame.c:2294 builtin/blame.c:2295
+#: builtin/blame.c:2266 builtin/blame.c:2267
 msgid "score"
 msgstr "poäng"
 
-#: builtin/blame.c:2294
+#: builtin/blame.c:2266
 msgid "Find line copies within and across files"
 msgstr "Hitta kopierade rader inuti och mellan filer"
 
-#: builtin/blame.c:2295
+#: builtin/blame.c:2267
 msgid "Find line movements within and across files"
 msgstr "Hitta flyttade rader inuti och mellan filer"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "Process only line range n,m, counting from 1"
 msgstr "Behandla endast radintervallet n,m, med början på 1"
 
@@ -2627,278 +2792,288 @@
 
 #: builtin/branch.c:453
 #, c-format
+msgid "[%s: gone]"
+msgstr "[%s: försvunnen]"
+
+#: builtin/branch.c:456
+#, c-format
+msgid "[%s]"
+msgstr "[%s]"
+
+#: builtin/branch.c:459
+#, c-format
 msgid "[%s: behind %d]"
 msgstr "[%s: bakom %d] "
 
-#: builtin/branch.c:455
+#: builtin/branch.c:461
 #, c-format
 msgid "[behind %d]"
 msgstr "[bakom %d] "
 
-#: builtin/branch.c:459
+#: builtin/branch.c:465
 #, c-format
 msgid "[%s: ahead %d]"
 msgstr "[%s: före %d] "
 
-#: builtin/branch.c:461
+#: builtin/branch.c:467
 #, c-format
 msgid "[ahead %d]"
 msgstr "[före %d] "
 
-#: builtin/branch.c:464
+#: builtin/branch.c:470
 #, c-format
 msgid "[%s: ahead %d, behind %d]"
 msgstr "[%s: före %d, bakom %d] "
 
-#: builtin/branch.c:467
+#: builtin/branch.c:473
 #, c-format
 msgid "[ahead %d, behind %d]"
 msgstr "[före %d, bakom %d] "
 
-#: builtin/branch.c:490
+#: builtin/branch.c:496
 msgid " **** invalid ref ****"
 msgstr " **** ogiltig ref ****"
 
-#: builtin/branch.c:582
+#: builtin/branch.c:588
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(ingen gren, ombaserar %s)"
 
-#: builtin/branch.c:585
+#: builtin/branch.c:591
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(ingen gren, \"bisect\" startad på %s)"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:594
 #, c-format
 msgid "(detached from %s)"
 msgstr "(frånkopplad från %s)"
 
-#: builtin/branch.c:591
+#: builtin/branch.c:597
 msgid "(no branch)"
 msgstr "(ingen gren)"
 
-#: builtin/branch.c:637
+#: builtin/branch.c:643
 #, c-format
 msgid "object '%s' does not point to a commit"
 msgstr "objektet \"%s\" pekar på en incheckning"
 
-#: builtin/branch.c:669
+#: builtin/branch.c:675
 msgid "some refs could not be read"
 msgstr "vissa referenser kunde inte läsas"
 
-#: builtin/branch.c:682
+#: builtin/branch.c:688
 msgid "cannot rename the current branch while not on any."
 msgstr ""
 "kunde inte byta namn på aktuell gren när du inte befinner dig på någon."
 
-#: builtin/branch.c:692
+#: builtin/branch.c:698
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Felaktigt namn på gren: \"%s\""
 
-#: builtin/branch.c:707
+#: builtin/branch.c:713
 msgid "Branch rename failed"
 msgstr "Misslyckades byta namn på gren"
 
-#: builtin/branch.c:711
+#: builtin/branch.c:717
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Bytte bort namn på en felaktigt namngiven gren \"%s\""
 
-#: builtin/branch.c:715
+#: builtin/branch.c:721
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "Grenen namnbytt till %s, men HEAD har inte uppdaterats!"
 
-#: builtin/branch.c:722
+#: builtin/branch.c:728
 msgid "Branch is renamed, but update of config-file failed"
 msgstr "Grenen namnbytt, men misslyckades uppdatera konfigurationsfilen"
 
-#: builtin/branch.c:737
+#: builtin/branch.c:743
 #, c-format
 msgid "malformed object name %s"
 msgstr "felformat objektnamn %s"
 
-#: builtin/branch.c:761
+#: builtin/branch.c:767
 #, c-format
 msgid "could not write branch description template: %s"
 msgstr "kunde inte skriva grenbeskrivningsmall: %s"
 
-#: builtin/branch.c:791
+#: builtin/branch.c:797
 msgid "Generic options"
 msgstr "Allmänna flaggor"
 
-#: builtin/branch.c:793
+#: builtin/branch.c:799
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "visa hash och ärenderad, ange två gånger för uppströmsgren"
 
-#: builtin/branch.c:794
+#: builtin/branch.c:800
 msgid "suppress informational messages"
 msgstr "undertryck informationsmeddelanden"
 
-#: builtin/branch.c:795
+#: builtin/branch.c:801
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "ställ in spårningsläge (se git-pull(1))"
 
-#: builtin/branch.c:797
+#: builtin/branch.c:803
 msgid "change upstream info"
 msgstr "ändra uppströmsinformation"
 
-#: builtin/branch.c:801
+#: builtin/branch.c:807
 msgid "use colored output"
 msgstr "använd färgad utdata"
 
-#: builtin/branch.c:802
+#: builtin/branch.c:808
 msgid "act on remote-tracking branches"
 msgstr "arbeta på fjärrspårande grenar"
 
-#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832
-#: builtin/branch.c:838 builtin/commit.c:1433 builtin/commit.c:1434
-#: builtin/commit.c:1435 builtin/commit.c:1436 builtin/tag.c:468
+#: builtin/branch.c:811 builtin/branch.c:817 builtin/branch.c:838
+#: builtin/branch.c:844 builtin/commit.c:1460 builtin/commit.c:1461
+#: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468
 msgid "commit"
 msgstr "incheckning"
 
-#: builtin/branch.c:806 builtin/branch.c:812
+#: builtin/branch.c:812 builtin/branch.c:818
 msgid "print only branches that contain the commit"
 msgstr "visa endast grenar som innehåller incheckningen"
 
-#: builtin/branch.c:818
+#: builtin/branch.c:824
 msgid "Specific git-branch actions:"
 msgstr "Specifika git-branch-åtgärder:"
 
-#: builtin/branch.c:819
+#: builtin/branch.c:825
 msgid "list both remote-tracking and local branches"
 msgstr "visa både fjärrspårande och lokala grenar"
 
-#: builtin/branch.c:821
+#: builtin/branch.c:827
 msgid "delete fully merged branch"
 msgstr "ta bort helt sammanslagen gren"
 
-#: builtin/branch.c:822
+#: builtin/branch.c:828
 msgid "delete branch (even if not merged)"
 msgstr "ta bort gren (även om inte helt sammanslagen)"
 
-#: builtin/branch.c:823
+#: builtin/branch.c:829
 msgid "move/rename a branch and its reflog"
 msgstr "flytta/ta bort en gren och dess reflogg"
 
-#: builtin/branch.c:824
+#: builtin/branch.c:830
 msgid "move/rename a branch, even if target exists"
 msgstr "flytta/ta bort en gren, även om målet finns"
 
-#: builtin/branch.c:825
+#: builtin/branch.c:831
 msgid "list branch names"
 msgstr "lista namn på grenar"
 
-#: builtin/branch.c:826
+#: builtin/branch.c:832
 msgid "create the branch's reflog"
 msgstr "skapa grenens reflogg"
 
-#: builtin/branch.c:828
+#: builtin/branch.c:834
 msgid "edit the description for the branch"
 msgstr "redigera beskrivning för grenen"
 
-#: builtin/branch.c:829
+#: builtin/branch.c:835
 msgid "force creation (when already exists)"
 msgstr "tvinga skapande (när den redan finns)"
 
-#: builtin/branch.c:832
+#: builtin/branch.c:838
 msgid "print only not merged branches"
 msgstr "visa endast ej sammanslagna grenar"
 
-#: builtin/branch.c:838
+#: builtin/branch.c:844
 msgid "print only merged branches"
 msgstr "visa endast sammanslagna grenar"
 
-#: builtin/branch.c:842
+#: builtin/branch.c:848
 msgid "list branches in columns"
 msgstr "visa grenar i spalter"
 
-#: builtin/branch.c:855
+#: builtin/branch.c:861
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Misslyckades slå upp HEAD som giltig referens"
 
-#: builtin/branch.c:860 builtin/clone.c:630
+#: builtin/branch.c:866 builtin/clone.c:629
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD hittades inte under refs/heads!"
 
-#: builtin/branch.c:883
+#: builtin/branch.c:890
 msgid "--column and --verbose are incompatible"
 msgstr "--column och --verbose är inkompatibla"
 
-#: builtin/branch.c:889 builtin/branch.c:928
+#: builtin/branch.c:896 builtin/branch.c:935
 msgid "branch name required"
 msgstr "grennamn krävs"
 
-#: builtin/branch.c:904
+#: builtin/branch.c:911
 msgid "Cannot give description to detached HEAD"
 msgstr "Kan inte beskriva frånkopplad HEAD"
 
-#: builtin/branch.c:909
+#: builtin/branch.c:916
 msgid "cannot edit description of more than one branch"
 msgstr "kan inte redigera beskrivning för mer än en gren"
 
-#: builtin/branch.c:916
+#: builtin/branch.c:923
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Inga incheckningar på grenen \"%s\" ännu"
 
-#: builtin/branch.c:919
+#: builtin/branch.c:926
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Ingen gren vid namnet \"%s\"."
 
-#: builtin/branch.c:934
+#: builtin/branch.c:941
 msgid "too many branches for a rename operation"
 msgstr "för många grenar för namnbyte"
 
-#: builtin/branch.c:939
+#: builtin/branch.c:946
 msgid "too many branches to set new upstream"
 msgstr "för många grenar för att byta uppström"
 
-#: builtin/branch.c:943
+#: builtin/branch.c:950
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr ""
 "kunde inte sätta uppström för HEAD till %s när det inte pekar mot någon gren."
 
-#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990
+#: builtin/branch.c:953 builtin/branch.c:975 builtin/branch.c:997
 #, c-format
 msgid "no such branch '%s'"
 msgstr "okänd gren \"%s\""
 
-#: builtin/branch.c:950
+#: builtin/branch.c:957
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "grenen \"%s\" finns inte"
 
-#: builtin/branch.c:962
+#: builtin/branch.c:969
 msgid "too many branches to unset upstream"
 msgstr "för många grenar för att ta bort uppström"
 
-#: builtin/branch.c:966
+#: builtin/branch.c:973
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "kunde inte ta bort uppström för HEAD när det inte pekar mot någon gren."
 
-#: builtin/branch.c:972
+#: builtin/branch.c:979
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "Grenen \"%s\" har ingen uppströmsinformation"
 
-#: builtin/branch.c:987
+#: builtin/branch.c:994
 msgid "it does not make sense to create 'HEAD' manually"
 msgstr "kan inte skapa \"HEAD\" manuellt"
 
-#: builtin/branch.c:993
+#: builtin/branch.c:1000
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "flaggorna -a och -r på \"git branch\" kan inte anges tillsammans med ett "
 "grennamn"
 
-#: builtin/branch.c:996
+#: builtin/branch.c:1003
 #, c-format
 msgid ""
 "The --set-upstream flag is deprecated and will be removed. Consider using --"
@@ -2907,7 +3082,7 @@
 "Flaggan --set-upstream rekommenderas ej och kommer tas bort. Använd --track "
 "eller --set-upstream-to\n"
 
-#: builtin/branch.c:1013
+#: builtin/branch.c:1020
 #, c-format
 msgid ""
 "\n"
@@ -2918,12 +3093,12 @@
 "Om du vill göra så att \"%s\" spårar \"%s\" gör du så här:\n"
 "\n"
 
-#: builtin/branch.c:1014
+#: builtin/branch.c:1021
 #, c-format
 msgid "    git branch -d %s\n"
 msgstr "    git branch -d %s\n"
 
-#: builtin/branch.c:1015
+#: builtin/branch.c:1022
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
 msgstr "    git branch --set-upstream-to %s\n"
@@ -2941,43 +3116,43 @@
 msgid "Need a repository to unbundle."
 msgstr "Behöver ett arkiv för att packa upp ett paket (bundle)."
 
-#: builtin/cat-file.c:285
+#: builtin/cat-file.c:312
 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"
 msgstr "git cat-file (-t|-s|-e|-p|<typ>|--textconv) <objekt>"
 
-#: builtin/cat-file.c:286
+#: builtin/cat-file.c:313
 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>"
 msgstr "git cat-file (--batch|--batch-check) < <objektlista>"
 
-#: builtin/cat-file.c:323
+#: builtin/cat-file.c:350
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<typ> kan vara en av: blob, tree, commit, tag"
 
-#: builtin/cat-file.c:324
+#: builtin/cat-file.c:351
 msgid "show object type"
 msgstr "visa objekttyp"
 
-#: builtin/cat-file.c:325
+#: builtin/cat-file.c:352
 msgid "show object size"
 msgstr "visa objektstorlek"
 
-#: builtin/cat-file.c:327
+#: builtin/cat-file.c:354
 msgid "exit with zero when there's no error"
 msgstr "avsluta med noll när det inte uppstått något fel"
 
-#: builtin/cat-file.c:328
+#: builtin/cat-file.c:355
 msgid "pretty-print object's content"
 msgstr "visa objektets innehåll snyggt"
 
-#: builtin/cat-file.c:330
+#: builtin/cat-file.c:357
 msgid "for blob objects, run textconv on object's content"
 msgstr "för blob-objekt, kör textconv på objektets innehåll"
 
-#: builtin/cat-file.c:332
+#: builtin/cat-file.c:359
 msgid "show info and content of objects fed from the standard input"
 msgstr "visa information och innehåll för objekt som listas på standard in"
 
-#: builtin/cat-file.c:335
+#: builtin/cat-file.c:362
 msgid "show info about objects fed from the standard input"
 msgstr "visa information för objekt som listas på standard in"
 
@@ -3002,10 +3177,10 @@
 msgstr "läs filnamn från standard in"
 
 #: builtin/check-attr.c:23 builtin/check-ignore.c:24
-msgid "input paths are terminated by a null character"
-msgstr "sökvägar avdelas med null-tecken"
+msgid "terminate input and output records by a NUL character"
+msgstr "avsluta in- och utdataposter med NUL-tecken"
 
-#: builtin/check-ignore.c:18 builtin/checkout.c:1054 builtin/gc.c:177
+#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:259
 msgid "suppress progress reporting"
 msgstr "undertryck förloppsrapportering"
 
@@ -3013,27 +3188,31 @@
 msgid "show non-matching input paths"
 msgstr "visa indatasökvägar som inte träffas"
 
-#: builtin/check-ignore.c:143
+#: builtin/check-ignore.c:28
+msgid "ignore index when checking"
+msgstr "ignorera index vid kontroll"
+
+#: builtin/check-ignore.c:154
 msgid "cannot specify pathnames with --stdin"
 msgstr "kan inte ange sökvägsnamn med --stdin"
 
-#: builtin/check-ignore.c:146
+#: builtin/check-ignore.c:157
 msgid "-z only makes sense with --stdin"
 msgstr "-z kan endast användas tillsammans med --stdin"
 
-#: builtin/check-ignore.c:148
+#: builtin/check-ignore.c:159
 msgid "no path specified"
 msgstr "ingen sökväg angavs"
 
-#: builtin/check-ignore.c:152
+#: builtin/check-ignore.c:163
 msgid "--quiet is only valid with a single pathname"
 msgstr "--quiet kan endast användas med ett enkelt sökvägsnamn"
 
-#: builtin/check-ignore.c:154
+#: builtin/check-ignore.c:165
 msgid "cannot have both --quiet and --verbose"
 msgstr "kan inte använda både --quiet och --verbose"
 
-#: builtin/check-ignore.c:157
+#: builtin/check-ignore.c:168
 msgid "--non-matching is only valid with --verbose"
 msgstr "--non-matching är endast giltig med --verbose"
 
@@ -3106,106 +3285,106 @@
 msgid "git checkout [options] [<branch>] -- <file>..."
 msgstr "git checkout [flaggor] [<gren>] -- <fil>..."
 
-#: builtin/checkout.c:117 builtin/checkout.c:150
+#: 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:119 builtin/checkout.c:152
+#: 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:135
+#: 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:179
+#: 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:196
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "sökväg \"%s\": kan inte slå ihop"
 
-#: builtin/checkout.c:213
+#: 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:237 builtin/checkout.c:240 builtin/checkout.c:243
-#: builtin/checkout.c:246
+#: builtin/checkout.c:232 builtin/checkout.c:235 builtin/checkout.c:238
+#: builtin/checkout.c:241
 #, c-format
 msgid "'%s' cannot be used with updating paths"
 msgstr "\"%s\" kan inte användas vid uppdatering av sökvägar"
 
-#: builtin/checkout.c:249 builtin/checkout.c:252
+#: builtin/checkout.c:244 builtin/checkout.c:247
 #, c-format
 msgid "'%s' cannot be used with %s"
 msgstr "\"%s\" kan inte användas med %s"
 
-#: builtin/checkout.c:255
+#: builtin/checkout.c:250
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
 msgstr "Kan inte uppdatera sökvägar och växla till grenen \"%s\" samtidigt."
 
-#: builtin/checkout.c:266 builtin/checkout.c:458
+#: builtin/checkout.c:261 builtin/checkout.c:451
 msgid "corrupt index file"
 msgstr "indexfilen är trasig"
 
-#: builtin/checkout.c:329 builtin/checkout.c:336
+#: builtin/checkout.c:322 builtin/checkout.c:329
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "sökvägen \"%s\" har inte slagits ihop"
 
-#: builtin/checkout.c:480
+#: builtin/checkout.c:473
 msgid "you need to resolve your current index first"
 msgstr "du måste lösa ditt befintliga index först"
 
-#: builtin/checkout.c:601
+#: builtin/checkout.c:594
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "Kan inte skapa referenslog för \"%s\"\n"
 
-#: builtin/checkout.c:639
+#: builtin/checkout.c:632
 msgid "HEAD is now at"
 msgstr "HEAD är nu på"
 
-#: builtin/checkout.c:646
+#: builtin/checkout.c:639
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Återställ gren \"%s\"\n"
 
-#: builtin/checkout.c:649
+#: builtin/checkout.c:642
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Redan på \"%s\"\n"
 
-#: builtin/checkout.c:653
+#: builtin/checkout.c:646
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Växlade till och nollställde grenen \"%s\"\n"
 
-#: builtin/checkout.c:655 builtin/checkout.c:997
+#: builtin/checkout.c:648 builtin/checkout.c:1033
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Växlade till en ny gren \"%s\"\n"
 
-#: builtin/checkout.c:657
+#: builtin/checkout.c:650
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Växlade till grenen \"%s\"\n"
 
-#: builtin/checkout.c:713
+#: builtin/checkout.c:706
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... och %d till.\n"
 
 #. The singular version
-#: builtin/checkout.c:719
+#: builtin/checkout.c:712
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -3228,7 +3407,7 @@
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:737
+#: builtin/checkout.c:730
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -3243,136 +3422,140 @@
 " git branch nytt_grennamn %s\n"
 "\n"
 
-#: builtin/checkout.c:767
+#: builtin/checkout.c:760
 msgid "internal error in revision walk"
 msgstr "internt fel vid genomgång av revisioner (revision walk)"
 
-#: builtin/checkout.c:771
+#: builtin/checkout.c:764
 msgid "Previous HEAD position was"
 msgstr "Tidigare position för HEAD var"
 
-#: builtin/checkout.c:798 builtin/checkout.c:992
+#: builtin/checkout.c:791 builtin/checkout.c:1028
 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:928
+#: builtin/checkout.c:935
+#, c-format
+msgid "only one reference expected, %d given."
+msgstr "endast en referens förväntades, %d gavs."
+
+#: builtin/checkout.c:974
 #, c-format
 msgid "invalid reference: %s"
 msgstr "felaktig referens: %s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:967
+#: builtin/checkout.c:1003
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "referensen är inte ett träd: %s"
 
-#: builtin/checkout.c:1006
+#: builtin/checkout.c:1042
 msgid "paths cannot be used with switching branches"
 msgstr "sökvägar kan inte användas vid byte av gren"
 
-#: builtin/checkout.c:1009 builtin/checkout.c:1013
+#: builtin/checkout.c:1045 builtin/checkout.c:1049
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "\"%s\" kan inte användas vid byte av gren"
 
-#: builtin/checkout.c:1017 builtin/checkout.c:1020 builtin/checkout.c:1025
-#: builtin/checkout.c:1028
+#: builtin/checkout.c:1053 builtin/checkout.c:1056 builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "\"%s\" kan inte användas med \"%s\""
 
-#: builtin/checkout.c:1033
+#: builtin/checkout.c:1069
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "Kan inte växla gren till icke-incheckningen \"%s\""
 
-#: builtin/checkout.c:1055 builtin/checkout.c:1057 builtin/clone.c:89
+#: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88
 #: builtin/remote.c:169 builtin/remote.c:171
 msgid "branch"
 msgstr "gren"
 
-#: builtin/checkout.c:1056
+#: builtin/checkout.c:1092
 msgid "create and checkout a new branch"
 msgstr "skapa och checka ut en ny gren"
 
-#: builtin/checkout.c:1058
+#: builtin/checkout.c:1094
 msgid "create/reset and checkout a branch"
 msgstr "skapa/nollställ och checka ut en gren"
 
-#: builtin/checkout.c:1059
+#: builtin/checkout.c:1095
 msgid "create reflog for new branch"
 msgstr "skapa reflogg för ny gren"
 
-#: builtin/checkout.c:1060
+#: builtin/checkout.c:1096
 msgid "detach the HEAD at named commit"
 msgstr "koppla från HEAD vid namngiven incheckning"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1097
 msgid "set upstream info for new branch"
 msgstr "sätt uppströmsinformation för ny gren"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new branch"
 msgstr "ny gren"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new unparented branch"
 msgstr "ny gren utan förälder"
 
-#: builtin/checkout.c:1064
+#: builtin/checkout.c:1100
 msgid "checkout our version for unmerged files"
 msgstr "checka ut vår version för ej sammanslagna filer"
 
-#: builtin/checkout.c:1066
+#: builtin/checkout.c:1102
 msgid "checkout their version for unmerged files"
 msgstr "checka ut deras version för ej sammanslagna filer"
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1104
 msgid "force checkout (throw away local modifications)"
 msgstr "tvinga utcheckning (kasta bort lokala ändringar)"
 
-#: builtin/checkout.c:1069
+#: builtin/checkout.c:1105
 msgid "perform a 3-way merge with the new branch"
 msgstr "utför en 3-vägssammanslagning för den nya grenen"
 
-#: builtin/checkout.c:1070 builtin/merge.c:232
+#: builtin/checkout.c:1106 builtin/merge.c:232
 msgid "update ignored files (default)"
 msgstr "uppdatera ignorerade filer (standard)"
 
-#: builtin/checkout.c:1071 builtin/log.c:1208 parse-options.h:249
+#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:251
 msgid "style"
 msgstr "stil"
 
-#: builtin/checkout.c:1072
+#: builtin/checkout.c:1108
 msgid "conflict style (merge or diff3)"
 msgstr "konfliktstil (merge eller diff3)"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1111
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "begränsa inte sökvägar till endast glesa poster"
 
-#: builtin/checkout.c:1077
+#: builtin/checkout.c:1113
 msgid "second guess 'git checkout no-such-branch'"
 msgstr "förutspå \"git checkout gren-saknas\""
 
-#: builtin/checkout.c:1101
+#: builtin/checkout.c:1136
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b, -B och --orphan är ömsesidigt uteslutande"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1153
 msgid "--track needs a branch name"
 msgstr "--track behöver ett namn på en gren"
 
-#: builtin/checkout.c:1125
+#: builtin/checkout.c:1160
 msgid "Missing branch name; try -b"
 msgstr "Grennamn saknas; försök med -b"
 
-#: builtin/checkout.c:1160
+#: builtin/checkout.c:1197
 msgid "invalid path specification"
 msgstr "felaktig sökvägsangivelse"
 
-#: builtin/checkout.c:1167
+#: builtin/checkout.c:1204
 #, c-format
 msgid ""
 "Cannot update paths and switch to branch '%s' at the same time.\n"
@@ -3381,12 +3564,12 @@
 "Kan inte uppdatera sökvägar och växla till grenen \"%s\" samtidigt.\n"
 "Ville du checka ut \"%s\" som inte kan lösas som en utcheckning?"
 
-#: builtin/checkout.c:1172
+#: builtin/checkout.c:1209
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach tar inte en sökväg som argument \"%s\""
 
-#: builtin/checkout.c:1176
+#: builtin/checkout.c:1213
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -3394,39 +3577,39 @@
 "git checkout: --ours/--theirs, --force och --merge är inkompatibla när\n"
 "du checkar ut från indexet."
 
-#: builtin/clean.c:25
+#: builtin/clean.c:26
 msgid ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
 msgstr ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <mönster>] [-x | -X] [--] "
 "<sökvägar>..."
 
-#: builtin/clean.c:29
+#: builtin/clean.c:30
 #, c-format
 msgid "Removing %s\n"
 msgstr "Tar bort %s\n"
 
-#: builtin/clean.c:30
+#: builtin/clean.c:31
 #, c-format
 msgid "Would remove %s\n"
 msgstr "Skulle ta bort %s\n"
 
-#: builtin/clean.c:31
+#: builtin/clean.c:32
 #, c-format
 msgid "Skipping repository %s\n"
 msgstr "Hoppar över arkivet %s\n"
 
-#: builtin/clean.c:32
+#: builtin/clean.c:33
 #, c-format
 msgid "Would skip repository %s\n"
 msgstr "Skulle hoppa över arkivet %s\n"
 
-#: builtin/clean.c:33
+#: builtin/clean.c:34
 #, c-format
 msgid "failed to remove %s"
 msgstr "misslyckades ta bort %s"
 
-#: builtin/clean.c:293
+#: builtin/clean.c:294
 msgid ""
 "Prompt help:\n"
 "1          - select a numbered item\n"
@@ -3438,7 +3621,7 @@
 "foo        - markera post baserad på unikt prefix\n"
 "           - (tomt) markera ingenting"
 
-#: builtin/clean.c:297
+#: builtin/clean.c:298
 msgid ""
 "Prompt help:\n"
 "1          - select a single item\n"
@@ -3458,35 +3641,35 @@
 "*          - välj alla poster\n"
 "           - (tomt) avsluta markering"
 
-#: builtin/clean.c:515
+#: builtin/clean.c:516
 #, c-format
 msgid "Huh (%s)?"
 msgstr "Vadå (%s)?"
 
-#: builtin/clean.c:658
+#: builtin/clean.c:659
 #, c-format
 msgid "Input ignore patterns>> "
 msgstr "Ange ignoreringsmönster>>"
 
-#: builtin/clean.c:695
+#: builtin/clean.c:696
 #, c-format
 msgid "WARNING: Cannot find items matched by: %s"
 msgstr "VARNING: Hittar inte poster som motsvarar: %s"
 
-#: builtin/clean.c:716
+#: builtin/clean.c:717
 msgid "Select items to delete"
 msgstr "Välj poster att ta bort"
 
-#: builtin/clean.c:756
+#: builtin/clean.c:757
 #, c-format
 msgid "remove %s? "
 msgstr "ta bort %s?"
 
-#: builtin/clean.c:781
+#: builtin/clean.c:782
 msgid "Bye."
 msgstr "Hej då."
 
-#: builtin/clean.c:789
+#: builtin/clean.c:790
 msgid ""
 "clean               - start cleaning\n"
 "filter by pattern   - exclude items from deletion\n"
@@ -3504,21 +3687,21 @@
 "help                - denna skärm\n"
 "?                   - hjälp för kommandoval"
 
-#: builtin/clean.c:816
+#: builtin/clean.c:817
 msgid "*** Commands ***"
 msgstr "*** Kommandon ***"
 
-#: builtin/clean.c:817
+#: builtin/clean.c:818
 msgid "What now"
 msgstr "Vad nu"
 
-#: builtin/clean.c:825
+#: builtin/clean.c:826
 msgid "Would remove the following item:"
 msgid_plural "Would remove the following items:"
 msgstr[0] "Skulle ta bort följande post:"
 msgstr[1] "Skulle ta bort följande poster:"
 
-#: builtin/clean.c:842
+#: builtin/clean.c:843
 msgid "No more files to clean, exiting."
 msgstr "Inga fler filer att städa, avslutar."
 
@@ -3538,8 +3721,8 @@
 msgid "remove whole directories"
 msgstr "ta bort hela kataloger"
 
-#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:716
-#: builtin/ls-files.c:493 builtin/name-rev.c:315 builtin/show-ref.c:186
+#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718
+#: builtin/ls-files.c:483 builtin/name-rev.c:315 builtin/show-ref.c:185
 msgid "pattern"
 msgstr "mönster"
 
@@ -3579,8 +3762,8 @@
 msgid "git clone [options] [--] <repo> [<dir>]"
 msgstr "git clone [flaggor] [--] <arkiv> [<kat>]"
 
-#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:229
-#: builtin/push.c:462
+#: builtin/clone.c:64 builtin/fetch.c:96 builtin/merge.c:229
+#: builtin/push.c:474
 msgid "force progress reporting"
 msgstr "tvinga förloppsrapportering"
 
@@ -3592,123 +3775,123 @@
 msgid "create a bare repository"
 msgstr "skapa ett naket (\"bare\") arkiv"
 
-#: builtin/clone.c:72
+#: builtin/clone.c:71
 msgid "create a mirror repository (implies bare)"
 msgstr "skapa ett spegelarkiv (implicerar \"bare\")"
 
-#: builtin/clone.c:74
+#: builtin/clone.c:73
 msgid "to clone from a local repository"
 msgstr "för att klona från ett lokalt arkiv"
 
-#: builtin/clone.c:76
+#: builtin/clone.c:75
 msgid "don't use local hardlinks, always copy"
 msgstr "skapa inte lokala hårda länkar, kopiera alltid"
 
-#: builtin/clone.c:78
+#: builtin/clone.c:77
 msgid "setup as shared repository"
 msgstr "skapa som ett delat arkiv"
 
-#: builtin/clone.c:80 builtin/clone.c:82
+#: builtin/clone.c:79 builtin/clone.c:81
 msgid "initialize submodules in the clone"
 msgstr "initiera undermoduler i klonen"
 
-#: builtin/clone.c:83 builtin/init-db.c:485
+#: builtin/clone.c:82 builtin/init-db.c:485
 msgid "template-directory"
 msgstr "mallkatalog"
 
-#: builtin/clone.c:84 builtin/init-db.c:486
+#: builtin/clone.c:83 builtin/init-db.c:486
 msgid "directory from which templates will be used"
 msgstr "katalog att använda mallar från"
 
-#: builtin/clone.c:86
+#: builtin/clone.c:85
 msgid "reference repository"
 msgstr "referensarkiv"
 
-#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44
+#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44
 msgid "name"
 msgstr "namn"
 
-#: builtin/clone.c:88
+#: builtin/clone.c:87
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "använd <namn> istället för \"origin\" för att spåra uppströms"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:89
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "checka ut <gren> istället för fjärrens HEAD"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:91
 msgid "path to git-upload-pack on the remote"
 msgstr "sökväg till git-upload-pack på fjärren"
 
-#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:661
+#: builtin/clone.c:92 builtin/fetch.c:97 builtin/grep.c:663
 msgid "depth"
 msgstr "djup"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:93
 msgid "create a shallow clone of that depth"
 msgstr "skapa en grund klon på detta djup"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:95
 msgid "clone only one branch, HEAD or --branch"
 msgstr "klona endast en gren, HEAD eller --branch"
 
-#: builtin/clone.c:97 builtin/init-db.c:494
+#: builtin/clone.c:96 builtin/init-db.c:494
 msgid "gitdir"
 msgstr "gitkat"
 
-#: builtin/clone.c:98 builtin/init-db.c:495
+#: builtin/clone.c:97 builtin/init-db.c:495
 msgid "separate git dir from working tree"
 msgstr "separera gitkatalogen från arbetskatalogen"
 
-#: builtin/clone.c:99
+#: builtin/clone.c:98
 msgid "key=value"
 msgstr "nyckel=värde"
 
-#: builtin/clone.c:100
+#: builtin/clone.c:99
 msgid "set config inside the new repository"
 msgstr "ställ in konfiguration i det nya arkivet"
 
-#: builtin/clone.c:253
+#: builtin/clone.c:252
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "referensarkivet \"%s\" är inte ett lokalt arkiv."
 
-#: builtin/clone.c:316
+#: builtin/clone.c:315
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "misslyckades skapa katalogen \"%s\""
 
-#: builtin/clone.c:318 builtin/diff.c:77
+#: builtin/clone.c:317 builtin/diff.c:77
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "misslyckades ta status på \"%s\""
 
-#: builtin/clone.c:320
+#: builtin/clone.c:319
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s finns och är ingen katalog"
 
-#: builtin/clone.c:334
+#: builtin/clone.c:333
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "misslyckades ta status på %s\n"
 
-#: builtin/clone.c:356
+#: builtin/clone.c:355
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "misslyckades skapa länken \"%s\""
 
-#: builtin/clone.c:360
+#: builtin/clone.c:359
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "misslyckades kopiera filen till \"%s\""
 
-#: builtin/clone.c:383
+#: builtin/clone.c:382 builtin/clone.c:559
 #, c-format
 msgid "done.\n"
 msgstr "klart.\n"
 
-#: builtin/clone.c:396
+#: builtin/clone.c:395
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -3718,105 +3901,100 @@
 "Du kan inspektera det som checkades ut med \"git status\"\n"
 "och försöka checka ut igen med \"git checkout -f HEAD\"\n"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:474
 #, 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:555
+#: builtin/clone.c:554
 #, c-format
 msgid "Checking connectivity... "
 msgstr "Kontrollerar anslutning..."
 
-#: builtin/clone.c:558
+#: builtin/clone.c:557
 msgid "remote did not send all necessary objects"
 msgstr "fjärren sände inte alla nödvändiga objekt"
 
-#: builtin/clone.c:560
-#, c-format
-msgid "done\n"
-msgstr "klart\n"
-
-#: builtin/clone.c:621
+#: builtin/clone.c:620
 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:652
+#: builtin/clone.c:651
 msgid "unable to checkout working tree"
 msgstr "kunde inte checka ut arbetskatalogen"
 
-#: builtin/clone.c:760
+#: builtin/clone.c:759
 msgid "Too many arguments."
 msgstr "För många argument."
 
-#: builtin/clone.c:764
+#: builtin/clone.c:763
 msgid "You must specify a repository to clone."
 msgstr "Du måste ange ett arkiv att klona."
 
-#: builtin/clone.c:775
+#: builtin/clone.c:774
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "flaggorna --bare och --origin %s är inkompatibla."
 
-#: builtin/clone.c:778
+#: builtin/clone.c:777
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "flaggorna --bare och --separate-git-dir är inkompatibla."
 
-#: builtin/clone.c:791
+#: builtin/clone.c:790
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "arkivet \"%s\" finns inte"
 
-#: builtin/clone.c:796
+#: builtin/clone.c:795
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr "--depth ignoreras i lokala kloningar; använd file:// istället"
 
-#: builtin/clone.c:798
+#: builtin/clone.c:797
 msgid "--local is ignored"
 msgstr "--local ignoreras"
 
-#: builtin/clone.c:808
+#: builtin/clone.c:807
 #, 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:818
+#: builtin/clone.c:817
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "arbetsträdet \"%s\" finns redan."
 
-#: builtin/clone.c:831 builtin/clone.c:843
+#: builtin/clone.c:830 builtin/clone.c:842
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "kunde inte skapa inledande kataloger för \"%s\""
 
-#: builtin/clone.c:834
+#: builtin/clone.c:833
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "kunde inte skapa arbetskatalogen \"%s\""
 
-#: builtin/clone.c:853
+#: builtin/clone.c:852
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Klonar till ett naket arkiv \"%s\"...\n"
 
-#: builtin/clone.c:855
+#: builtin/clone.c:854
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Klonar till \"%s\"...\n"
 
-#: builtin/clone.c:890
+#: builtin/clone.c:888
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "Vet inte hur man klonar %s"
 
-#: builtin/clone.c:942
+#: builtin/clone.c:939 builtin/clone.c:947
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "Fjärrgrenen %s hittades inte i uppströmsarkivet %s"
 
-#: builtin/clone.c:949
+#: builtin/clone.c:950
 msgid "You appear to have cloned an empty repository."
 msgstr "Du verkar ha klonat ett tomt arkiv."
 
@@ -3852,15 +4030,15 @@
 msgid "--command must be the first argument"
 msgstr "--command måste vara första argument"
 
-#: builtin/commit.c:35
+#: builtin/commit.c:36
 msgid "git commit [options] [--] <pathspec>..."
 msgstr "git commit [flaggor] [--] <sökväg>..."
 
-#: builtin/commit.c:40
+#: builtin/commit.c:41
 msgid "git status [options] [--] <pathspec>..."
 msgstr "git status [flaggor] [--] <sökväg>..."
 
-#: builtin/commit.c:45
+#: builtin/commit.c:46
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3885,7 +4063,7 @@
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: builtin/commit.c:57
+#: builtin/commit.c:58
 msgid ""
 "You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
@@ -3895,7 +4073,7 @@
 "blir den tom. Du kan köra kommandot på nytt med --allow-empty, eller\n"
 "så kan du ta bort incheckningen helt med \"git reset HEAD^\".\n"
 
-#: builtin/commit.c:62
+#: builtin/commit.c:63
 msgid ""
 "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 "If you wish to commit it anyway, use:\n"
@@ -3909,11 +4087,11 @@
 "    git commit --allow-empty\n"
 "\n"
 
-#: builtin/commit.c:69
+#: builtin/commit.c:70
 msgid "Otherwise, please use 'git reset'\n"
 msgstr "Använd annars \"git reset\"\n"
 
-#: builtin/commit.c:72
+#: builtin/commit.c:73
 msgid ""
 "If you wish to skip this commit, use:\n"
 "\n"
@@ -3929,93 +4107,93 @@
 "\"git cherry-pick --continue\" kommer därefter att återuppta\n"
 "cherry-pick för återstående incheckningar.\n"
 
-#: builtin/commit.c:279
+#: builtin/commit.c:287
 msgid "failed to unpack HEAD tree object"
 msgstr "misslyckades packa upp HEAD:s trädobjekt"
 
-#: builtin/commit.c:321
+#: builtin/commit.c:329
 msgid "unable to create temporary index"
 msgstr "kunde inte skapa temporär indexfil"
 
-#: builtin/commit.c:327
+#: builtin/commit.c:335
 msgid "interactive add failed"
 msgstr "interaktiv tilläggning misslyckades"
 
-#: builtin/commit.c:360 builtin/commit.c:381 builtin/commit.c:431
+#: builtin/commit.c:368 builtin/commit.c:389 builtin/commit.c:439
 msgid "unable to write new_index file"
 msgstr "kunde inte skriva filen new_index"
 
-#: builtin/commit.c:412
+#: builtin/commit.c:420
 msgid "cannot do a partial commit during a merge."
 msgstr "kan inte utföra en delvis incheckning under en sammanslagning."
 
-#: builtin/commit.c:414
+#: builtin/commit.c:422
 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:424
+#: builtin/commit.c:432
 msgid "cannot read the index"
 msgstr "kan inte läsa indexet"
 
-#: builtin/commit.c:444
+#: builtin/commit.c:452
 msgid "unable to write temporary index file"
 msgstr "kunde inte skriva temporär indexfil"
 
-#: builtin/commit.c:535 builtin/commit.c:541
+#: builtin/commit.c:543 builtin/commit.c:549
 #, c-format
 msgid "invalid commit: %s"
 msgstr "felaktig incheckning: %s"
 
-#: builtin/commit.c:563
+#: builtin/commit.c:571
 msgid "malformed --author parameter"
 msgstr "felformad \"--author\"-flagga"
 
-#: builtin/commit.c:583
+#: builtin/commit.c:591
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "Felaktig indragningssträng: \"%s\""
 
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:982
+#: builtin/commit.c:630 builtin/commit.c:663 builtin/commit.c:1007
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "kunde inte slå upp incheckningen %s"
 
-#: builtin/commit.c:633 builtin/shortlog.c:271
+#: builtin/commit.c:642 builtin/shortlog.c:273
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(läser loggmeddelande från standard in)\n"
 
-#: builtin/commit.c:635
+#: builtin/commit.c:644
 msgid "could not read log from standard input"
 msgstr "kunde inte läsa logg från standard in"
 
-#: builtin/commit.c:639
+#: builtin/commit.c:648
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "kunde inte läsa loggfilen \"%s\""
 
-#: builtin/commit.c:645
+#: builtin/commit.c:654
 msgid "commit has empty message"
 msgstr "incheckningen har ett tomt meddelande"
 
-#: builtin/commit.c:661
+#: builtin/commit.c:670
 msgid "could not read MERGE_MSG"
 msgstr "kunde inte läsa MERGE_MSG"
 
-#: builtin/commit.c:665
+#: builtin/commit.c:674
 msgid "could not read SQUASH_MSG"
 msgstr "kunde inte läsa SQUASH_MSG"
 
-#: builtin/commit.c:669
+#: builtin/commit.c:678
 #, c-format
 msgid "could not read '%s'"
 msgstr "kunde inte läsa \"%s\""
 
-#: builtin/commit.c:730
+#: builtin/commit.c:749
 msgid "could not write commit template"
 msgstr "kunde inte skriva incheckningsmall"
 
-#: builtin/commit.c:741
+#: builtin/commit.c:760
 #, c-format
 msgid ""
 "\n"
@@ -4030,7 +4208,7 @@
 "\t%s\n"
 "och försöker igen.\n"
 
-#: builtin/commit.c:746
+#: builtin/commit.c:765
 #, c-format
 msgid ""
 "\n"
@@ -4045,7 +4223,7 @@
 "\t%s\n"
 "och försöker igen.\n"
 
-#: builtin/commit.c:758
+#: builtin/commit.c:777
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4055,7 +4233,7 @@
 "med \"%c\" kommer ignoreras, och ett tomt meddelande avbryter "
 "incheckningen.\n"
 
-#: builtin/commit.c:763
+#: builtin/commit.c:782
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4066,139 +4244,139 @@
 "med \"%c\" kommer behållas; du kan själv ta bort dem om du vill.\n"
 "Ett tomt meddelande avbryter incheckningen.\n"
 
-#: builtin/commit.c:776
+#: builtin/commit.c:795
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%sFörfattare: %s"
 
-#: builtin/commit.c:783
+#: builtin/commit.c:802
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%sIncheckare: %s"
 
-#: builtin/commit.c:803
+#: builtin/commit.c:822
 msgid "Cannot read index"
 msgstr "Kan inte läsa indexet"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:865
 msgid "Error building trees"
 msgstr "Fel vid byggande av träd"
 
-#: builtin/commit.c:860 builtin/tag.c:359
+#: builtin/commit.c:880 builtin/tag.c:359
 #, 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:957
+#: builtin/commit.c:982
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "Hittade ingen befintlig författare med \"%s\""
 
-#: builtin/commit.c:972 builtin/commit.c:1208
+#: builtin/commit.c:997 builtin/commit.c:1237
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Ogiltigt läge för ospårade filer: \"%s\""
 
-#: builtin/commit.c:1009
+#: builtin/commit.c:1034
 msgid "--long and -z are incompatible"
 msgstr "--long och -z är inkompatibla"
 
-#: builtin/commit.c:1039
+#: builtin/commit.c:1064
 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:1050
+#: builtin/commit.c:1075
 msgid "You have nothing to amend."
 msgstr "Du har inget att utöka."
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1078
 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:1055
+#: builtin/commit.c:1080
 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:1058
+#: builtin/commit.c:1083
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Flaggorna --squash och --fixup kan inte användas samtidigt"
 
-#: builtin/commit.c:1068
+#: builtin/commit.c:1093
 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:1070
+#: builtin/commit.c:1095
 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:1078
+#: builtin/commit.c:1103
 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:1095
+#: builtin/commit.c:1120
 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:1097
+#: builtin/commit.c:1122
 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:1099
+#: builtin/commit.c:1124
 msgid "Clever... amending the last one with dirty index."
 msgstr "Smart... utöka den senaste med smutsigt index."
 
-#: builtin/commit.c:1101
+#: builtin/commit.c:1126
 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:1111 builtin/tag.c:575
+#: builtin/commit.c:1136 builtin/tag.c:572
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Felaktigt städningsläge %s"
 
-#: builtin/commit.c:1116
+#: builtin/commit.c:1141
 msgid "Paths with -a does not make sense."
 msgstr "Kan inte ange sökvägar med -a."
 
-#: builtin/commit.c:1222 builtin/commit.c:1455
+#: builtin/commit.c:1251 builtin/commit.c:1482
 msgid "show status concisely"
 msgstr "visa koncis status"
 
-#: builtin/commit.c:1224 builtin/commit.c:1457
+#: builtin/commit.c:1253 builtin/commit.c:1484
 msgid "show branch information"
 msgstr "visa information om gren"
 
-#: builtin/commit.c:1226 builtin/commit.c:1459 builtin/push.c:452
+#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:460
 msgid "machine-readable output"
 msgstr "maskinläsbar utdata"
 
-#: builtin/commit.c:1229 builtin/commit.c:1461
+#: builtin/commit.c:1258 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "visa status i långt format (standard)"
 
-#: builtin/commit.c:1232 builtin/commit.c:1464
+#: builtin/commit.c:1261 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "terminera poster med NUL"
 
-#: builtin/commit.c:1234 builtin/commit.c:1467 builtin/fast-export.c:667
-#: builtin/fast-export.c:670 builtin/tag.c:459
+#: builtin/commit.c:1263 builtin/commit.c:1494 builtin/fast-export.c:674
+#: builtin/fast-export.c:677 builtin/tag.c:459
 msgid "mode"
 msgstr "läge"
 
-#: builtin/commit.c:1235 builtin/commit.c:1467
+#: builtin/commit.c:1264 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr "visa ospårade filer, valfria lägen: alla, normal, no. (Standard: all)"
 
-#: builtin/commit.c:1238
+#: builtin/commit.c:1267
 msgid "show ignored files"
 msgstr "visa ignorerade filer"
 
-#: builtin/commit.c:1239 parse-options.h:154
+#: builtin/commit.c:1268 parse-options.h:156
 msgid "when"
 msgstr "när"
 
-#: builtin/commit.c:1240
+#: builtin/commit.c:1269
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -4206,217 +4384,217 @@
 "ignorera ändringar i undermoduler, valfritt när: all, dirty, untracked. "
 "(Default: all)"
 
-#: builtin/commit.c:1242
+#: builtin/commit.c:1271
 msgid "list untracked files in columns"
 msgstr "visa ospårade filer i spalter"
 
-#: builtin/commit.c:1313
+#: builtin/commit.c:1340
 msgid "couldn't look up newly created commit"
 msgstr "kunde inte slå upp en precis skapad incheckning"
 
-#: builtin/commit.c:1315
+#: builtin/commit.c:1342
 msgid "could not parse newly created commit"
 msgstr "kunde inte tolka en precis skapad incheckning"
 
-#: builtin/commit.c:1356
+#: builtin/commit.c:1383
 msgid "detached HEAD"
 msgstr "frånkopplad HEAD"
 
-#: builtin/commit.c:1358
+#: builtin/commit.c:1385
 msgid " (root-commit)"
 msgstr " (rotincheckning)"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1452
 msgid "suppress summary after successful commit"
 msgstr "undertryck sammanfattning efter framgångsrik incheckning"
 
-#: builtin/commit.c:1426
+#: builtin/commit.c:1453
 msgid "show diff in commit message template"
 msgstr "visa diff i mallen för incheckningsmeddelandet"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1455
 msgid "Commit message options"
 msgstr "Alternativ för incheckningsmeddelande"
 
-#: builtin/commit.c:1429 builtin/tag.c:457
+#: builtin/commit.c:1456 builtin/tag.c:457
 msgid "read message from file"
 msgstr "läs meddelande från fil"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "author"
 msgstr "författare"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "override author for commit"
 msgstr "överstyr författare för incheckningen"
 
-#: builtin/commit.c:1431 builtin/gc.c:178
+#: builtin/commit.c:1458 builtin/gc.c:260
 msgid "date"
 msgstr "datum"
 
-#: builtin/commit.c:1431
+#: builtin/commit.c:1458
 msgid "override date for commit"
 msgstr "överstyr datum för inchecknignen"
 
-#: builtin/commit.c:1432 builtin/merge.c:223 builtin/notes.c:405
+#: builtin/commit.c:1459 builtin/merge.c:223 builtin/notes.c:405
 #: builtin/notes.c:562 builtin/tag.c:455
 msgid "message"
 msgstr "meddelande"
 
-#: builtin/commit.c:1432
+#: builtin/commit.c:1459
 msgid "commit message"
 msgstr "incheckningsmeddelande"
 
-#: builtin/commit.c:1433
+#: builtin/commit.c:1460
 msgid "reuse and edit message from specified commit"
 msgstr "återanvänd och redigera meddelande från angiven incheckning"
 
-#: builtin/commit.c:1434
+#: builtin/commit.c:1461
 msgid "reuse message from specified commit"
 msgstr "återanvänd meddelande från angiven incheckning"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1462
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 "använd autosquash-formaterat meddelande för att fixa angiven incheckning"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1463
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 "använd autosquash-formaterat meddelande för att slå ihop med angiven "
 "incheckning"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1464
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "jag är nu författare av incheckningen (används med -C/-c/--amend)"
 
-#: builtin/commit.c:1438 builtin/log.c:1160 builtin/revert.c:111
+#: builtin/commit.c:1465 builtin/log.c:1180 builtin/revert.c:86
 msgid "add Signed-off-by:"
 msgstr "lägg till Signed-off-by:"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1466
 msgid "use specified template file"
 msgstr "använd angiven mallfil"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1467
 msgid "force edit of commit"
 msgstr "tvinga redigering av incheckning"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1468
 msgid "default"
 msgstr "standard"
 
-#: builtin/commit.c:1441 builtin/tag.c:460
+#: builtin/commit.c:1468 builtin/tag.c:460
 msgid "how to strip spaces and #comments from message"
 msgstr "hur blanksteg och #kommentarer skall tas bort från meddelande"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1469
 msgid "include status in commit message template"
 msgstr "inkludera status i mallen för incheckningsmeddelandet"
 
-#: builtin/commit.c:1443 builtin/merge.c:230 builtin/tag.c:461
+#: builtin/commit.c:1470 builtin/merge.c:230 builtin/tag.c:461
 msgid "key id"
 msgstr "nyckel-id"
 
-#: builtin/commit.c:1444 builtin/merge.c:231
+#: builtin/commit.c:1471 builtin/merge.c:231
 msgid "GPG sign commit"
 msgstr "GPG-signera incheckning"
 
 #. end commit message options
-#: builtin/commit.c:1447
+#: builtin/commit.c:1474
 msgid "Commit contents options"
 msgstr "Alternativ för incheckningens innehåll"
 
-#: builtin/commit.c:1448
+#: builtin/commit.c:1475
 msgid "commit all changed files"
 msgstr "checka in alla ändrade filer"
 
-#: builtin/commit.c:1449
+#: builtin/commit.c:1476
 msgid "add specified files to index for commit"
 msgstr "lägg till angivna filer till indexet för incheckning"
 
-#: builtin/commit.c:1450
+#: builtin/commit.c:1477
 msgid "interactively add files"
 msgstr "lägg till filer interaktivt"
 
-#: builtin/commit.c:1451
+#: builtin/commit.c:1478
 msgid "interactively add changes"
 msgstr "lägg till ändringar interaktivt"
 
-#: builtin/commit.c:1452
+#: builtin/commit.c:1479
 msgid "commit only specified files"
 msgstr "checka endast in angivna filer"
 
-#: builtin/commit.c:1453
+#: builtin/commit.c:1480
 msgid "bypass pre-commit hook"
 msgstr "förbigå pre-commit-krok"
 
-#: builtin/commit.c:1454
+#: builtin/commit.c:1481
 msgid "show what would be committed"
 msgstr "visa vad som skulle checkas in"
 
-#: builtin/commit.c:1465
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "lägg till föregående incheckning"
 
-#: builtin/commit.c:1466
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "förbigå post-rewrite-krok"
 
-#: builtin/commit.c:1471
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "ok att registrera en tom ändring"
 
-#: builtin/commit.c:1474
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "ok att registrera en ändring med tomt meddelande"
 
-#: builtin/commit.c:1507
+#: builtin/commit.c:1529
 msgid "could not parse HEAD commit"
 msgstr "kunde inte tolka HEAD:s incheckning"
 
-#: builtin/commit.c:1545 builtin/merge.c:525
+#: builtin/commit.c:1567 builtin/merge.c:525
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "kunde inte öppna \"%s\" för läsning"
 
-#: builtin/commit.c:1552
+#: builtin/commit.c:1574
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Trasig MERGE_HEAD-fil (%s)"
 
-#: builtin/commit.c:1559
+#: builtin/commit.c:1581
 msgid "could not read MERGE_MODE"
 msgstr "kunde inte läsa MERGE_MODE"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1600
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "kunde inte läsa incheckningsmeddelande: %s"
 
-#: builtin/commit.c:1592
+#: builtin/commit.c:1614
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Avbryter incheckning; meddelandet inte redigerat.\n"
 
-#: builtin/commit.c:1597
+#: builtin/commit.c:1619
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Avbryter på grund av tomt incheckningsmeddelande.\n"
 
-#: builtin/commit.c:1612 builtin/merge.c:861 builtin/merge.c:886
+#: builtin/commit.c:1634 builtin/merge.c:861 builtin/merge.c:886
 msgid "failed to write commit object"
 msgstr "kunde inte skriva incheckningsobjekt"
 
-#: builtin/commit.c:1633
+#: builtin/commit.c:1655
 msgid "cannot lock HEAD ref"
 msgstr "kunde inte låsa HEAD-referens"
 
-#: builtin/commit.c:1637
+#: builtin/commit.c:1659
 msgid "cannot update HEAD ref"
 msgstr "kunde inte uppdatera HEAD-referens"
 
-#: builtin/commit.c:1648
+#: builtin/commit.c:1670
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -4427,127 +4605,131 @@
 "att kvoten inte har överskridits, och kör sedan\n"
 "\"git reset HEAD\" för att återställa."
 
-#: builtin/config.c:7
+#: builtin/config.c:8
 msgid "git config [options]"
 msgstr "git config [flaggor]"
 
-#: builtin/config.c:52
+#: builtin/config.c:54
 msgid "Config file location"
 msgstr "Konfigurationsfilens plats"
 
-#: builtin/config.c:53
+#: builtin/config.c:55
 msgid "use global config file"
 msgstr "använd global konfigurationsfil"
 
-#: builtin/config.c:54
+#: builtin/config.c:56
 msgid "use system config file"
 msgstr "använd systemets konfigurationsfil"
 
-#: builtin/config.c:55
+#: builtin/config.c:57
 msgid "use repository config file"
 msgstr "använd arkivets konfigurationsfil"
 
-#: builtin/config.c:56
+#: builtin/config.c:58
 msgid "use given config file"
 msgstr "använd angiven konfigurationsil"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "blob-id"
 msgstr "blob-id"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "read config from given blob object"
 msgstr "läs konfiguration från givet blob-objekt"
 
-#: builtin/config.c:58
+#: builtin/config.c:60
 msgid "Action"
 msgstr "Åtgärd"
 
-#: builtin/config.c:59
+#: builtin/config.c:61
 msgid "get value: name [value-regex]"
 msgstr "hämta värde: namn [värde-reguttr]"
 
-#: builtin/config.c:60
+#: builtin/config.c:62
 msgid "get all values: key [value-regex]"
 msgstr "hämta alla värden: nyckel [värde-reguttr]"
 
-#: builtin/config.c:61
+#: builtin/config.c:63
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "hämta värden för reguttr: namn-reguttr [värde-reguttr]"
 
-#: builtin/config.c:62
+#: builtin/config.c:64
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "hämta värde specifikt URL:en: sektion[.var] URL"
+
+#: builtin/config.c:65
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "ersätt alla motsvarande variabler: namn värde [värde-reguttr]"
 
-#: builtin/config.c:63
+#: builtin/config.c:66
 msgid "add a new variable: name value"
 msgstr "lägg till en ny variabel: namn värde"
 
-#: builtin/config.c:64
+#: builtin/config.c:67
 msgid "remove a variable: name [value-regex]"
 msgstr "ta bort en variabel: namn [värde-reguttr]"
 
-#: builtin/config.c:65
+#: builtin/config.c:68
 msgid "remove all matches: name [value-regex]"
 msgstr "ta bort alla träffar: namn [värde-reguttr]"
 
-#: builtin/config.c:66
+#: builtin/config.c:69
 msgid "rename section: old-name new-name"
 msgstr "byt namn på sektion: gammalt-namn nytt-namn"
 
-#: builtin/config.c:67
+#: builtin/config.c:70
 msgid "remove a section: name"
 msgstr "ta bort en sektion: namn"
 
-#: builtin/config.c:68
+#: builtin/config.c:71
 msgid "list all"
 msgstr "visa alla"
 
-#: builtin/config.c:69
+#: builtin/config.c:72
 msgid "open an editor"
 msgstr "öppna textredigeringsprogram"
 
-#: builtin/config.c:70 builtin/config.c:71
+#: builtin/config.c:73 builtin/config.c:74
 msgid "slot"
 msgstr "plats"
 
-#: builtin/config.c:70
+#: builtin/config.c:73
 msgid "find the color configured: [default]"
 msgstr "hitta den inställda färgen: [default]"
 
-#: builtin/config.c:71
+#: builtin/config.c:74
 msgid "find the color setting: [stdout-is-tty]"
 msgstr "hitta färginställningen: [stdout-is-tty]"
 
-#: builtin/config.c:72
+#: builtin/config.c:75
 msgid "Type"
 msgstr "Typ"
 
-#: builtin/config.c:73
+#: builtin/config.c:76
 msgid "value is \"true\" or \"false\""
 msgstr "värdet är \"true\" eller \"false\""
 
-#: builtin/config.c:74
+#: builtin/config.c:77
 msgid "value is decimal number"
 msgstr "värdet är ett decimalt tal"
 
-#: builtin/config.c:75
+#: builtin/config.c:78
 msgid "value is --bool or --int"
 msgstr "värdet är --bool eller --int"
 
-#: builtin/config.c:76
+#: builtin/config.c:79
 msgid "value is a path (file or directory name)"
 msgstr "värdet är en sökväg (fil- eller katalognamn)"
 
-#: builtin/config.c:77
+#: builtin/config.c:80
 msgid "Other"
 msgstr "Andra"
 
-#: builtin/config.c:78
+#: builtin/config.c:81
 msgid "terminate values with NUL byte"
 msgstr "terminera värden med NUL-byte"
 
-#: builtin/config.c:79
+#: builtin/config.c:82
 msgid "respect include directives on lookup"
 msgstr "respektera inkluderingsdirektiv vid uppslag"
 
@@ -4560,7 +4742,7 @@
 msgstr "skriv storlekar i människoläsbart format"
 
 #: builtin/describe.c:16
-msgid "git describe [options] <committish>*"
+msgid "git describe [options] <commit-ish>*"
 msgstr "git describe [flaggor] <incheckning-igt>*"
 
 #: builtin/describe.c:17
@@ -4696,8 +4878,8 @@
 msgstr "Inga namn hittades, kan inte beskriva något."
 
 #: builtin/describe.c:489
-msgid "--dirty is incompatible with committishes"
-msgstr "--dirty är inkompatibelt med \"committish\"-värden"
+msgid "--dirty is incompatible with commit-ishes"
+msgstr "--dirty är inkompatibelt med \"commit-ish\"-värden"
 
 #: builtin/diff.c:79
 #, c-format
@@ -4732,39 +4914,39 @@
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-flaggor]"
 
-#: builtin/fast-export.c:666
+#: builtin/fast-export.c:673
 msgid "show progress after <n> objects"
 msgstr "visa förlopp efter <n> objekt"
 
-#: builtin/fast-export.c:668
+#: builtin/fast-export.c:675
 msgid "select handling of signed tags"
 msgstr "välj hantering av signerade taggar"
 
-#: builtin/fast-export.c:671
+#: builtin/fast-export.c:678
 msgid "select handling of tags that tag filtered objects"
 msgstr "välj hantering av taggar som har taggfiltrerade objekt"
 
-#: builtin/fast-export.c:674
+#: builtin/fast-export.c:681
 msgid "Dump marks to this file"
 msgstr "Dump märken till filen"
 
-#: builtin/fast-export.c:676
+#: builtin/fast-export.c:683
 msgid "Import marks from this file"
 msgstr "Importera märken från filen"
 
-#: builtin/fast-export.c:678
+#: builtin/fast-export.c:685
 msgid "Fake a tagger when tags lack one"
 msgstr "Fejka taggare när taggen saknar en"
 
-#: builtin/fast-export.c:680
+#: builtin/fast-export.c:687
 msgid "Output full tree for each commit"
 msgstr "Skriv ut hela trädet för varje incheckning"
 
-#: builtin/fast-export.c:682
+#: builtin/fast-export.c:689
 msgid "Use the done feature to terminate the stream"
 msgstr "Använd done-funktionen för att avsluta strömmen"
 
-#: builtin/fast-export.c:683
+#: builtin/fast-export.c:690
 msgid "Skip output of blob data"
 msgstr "Hoppa över skrivning av blob-data"
 
@@ -4784,144 +4966,144 @@
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<flaggor>]"
 
-#: builtin/fetch.c:60
+#: builtin/fetch.c:74
 msgid "fetch from all remotes"
 msgstr "hämta från alla fjärrar"
 
-#: builtin/fetch.c:62
+#: builtin/fetch.c:76
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "lägg till i .git/FETCH_HEAD istället för att skriva över"
 
-#: builtin/fetch.c:64
+#: builtin/fetch.c:78
 msgid "path to upload pack on remote end"
 msgstr "sökväg till upload pack på fjärren"
 
-#: builtin/fetch.c:65
+#: builtin/fetch.c:79
 msgid "force overwrite of local branch"
 msgstr "tvinga överskrivning av lokal gren"
 
-#: builtin/fetch.c:67
+#: builtin/fetch.c:81
 msgid "fetch from multiple remotes"
 msgstr "hämta från flera fjärrar"
 
-#: builtin/fetch.c:69
+#: builtin/fetch.c:83
 msgid "fetch all tags and associated objects"
 msgstr "hämta alla taggar och associerade objekt"
 
-#: builtin/fetch.c:71
+#: builtin/fetch.c:85
 msgid "do not fetch all tags (--no-tags)"
 msgstr "hämta inte alla taggar (--no-tags)"
 
-#: builtin/fetch.c:73
+#: builtin/fetch.c:87
 msgid "prune remote-tracking branches no longer on remote"
 msgstr "rensa fjärrspårande grenar ej längre på fjärren"
 
-#: builtin/fetch.c:74
+#: builtin/fetch.c:88
 msgid "on-demand"
 msgstr "on-demand"
 
-#: builtin/fetch.c:75
+#: builtin/fetch.c:89
 msgid "control recursive fetching of submodules"
 msgstr "styr rekursiv hämtning av undermoduler"
 
-#: builtin/fetch.c:79
+#: builtin/fetch.c:93
 msgid "keep downloaded pack"
 msgstr "behåll hämtade paket"
 
-#: builtin/fetch.c:81
+#: builtin/fetch.c:95
 msgid "allow updating of HEAD ref"
 msgstr "tillåt uppdatering av HEAD-referens"
 
-#: builtin/fetch.c:84
+#: builtin/fetch.c:98
 msgid "deepen history of shallow clone"
 msgstr "fördjupa historik för grund klon"
 
-#: builtin/fetch.c:86
+#: builtin/fetch.c:100
 msgid "convert to a complete repository"
 msgstr "konvertera till komplett arkiv"
 
-#: builtin/fetch.c:88 builtin/log.c:1177
+#: builtin/fetch.c:102 builtin/log.c:1197
 msgid "dir"
 msgstr "kat"
 
-#: builtin/fetch.c:89
+#: builtin/fetch.c:103
 msgid "prepend this to submodule path output"
 msgstr "lägg till i början av undermodulens sökvägsutdata"
 
-#: builtin/fetch.c:92
+#: builtin/fetch.c:106
 msgid "default mode for recursion"
 msgstr "standardläge för rekursion"
 
-#: builtin/fetch.c:220
+#: builtin/fetch.c:236
 msgid "Couldn't find remote ref HEAD"
 msgstr "Kunde inte hitta fjärr-referensen HEAD"
 
-#: builtin/fetch.c:273
+#: builtin/fetch.c:290
 #, c-format
 msgid "object %s not found"
 msgstr "objektet %s hittades inte"
 
-#: builtin/fetch.c:278
+#: builtin/fetch.c:295
 msgid "[up to date]"
 msgstr "[àjour]"
 
-#: builtin/fetch.c:292
+#: builtin/fetch.c:309
 #, c-format
 msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
 msgstr "! %-*s %-*s -> %s  (kan inte hämta i aktuell gren)"
 
-#: builtin/fetch.c:293 builtin/fetch.c:379
+#: builtin/fetch.c:310 builtin/fetch.c:396
 msgid "[rejected]"
 msgstr "[refuserad]"
 
-#: builtin/fetch.c:304
+#: builtin/fetch.c:321
 msgid "[tag update]"
 msgstr "[uppdaterad tagg]"
 
-#: builtin/fetch.c:306 builtin/fetch.c:341 builtin/fetch.c:359
+#: builtin/fetch.c:323 builtin/fetch.c:358 builtin/fetch.c:376
 msgid "  (unable to update local ref)"
 msgstr "  (kunde inte uppdatera lokal ref)"
 
-#: builtin/fetch.c:324
+#: builtin/fetch.c:341
 msgid "[new tag]"
 msgstr "[ny tagg]"
 
-#: builtin/fetch.c:327
+#: builtin/fetch.c:344
 msgid "[new branch]"
 msgstr "[ny gren]"
 
-#: builtin/fetch.c:330
+#: builtin/fetch.c:347
 msgid "[new ref]"
 msgstr "[ny ref]"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "unable to update local ref"
 msgstr "kunde inte uppdatera lokal ref"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "forced update"
 msgstr "tvingad uppdatering"
 
-#: builtin/fetch.c:381
+#: builtin/fetch.c:398
 msgid "(non-fast-forward)"
 msgstr "(ej snabbspolad)"
 
-#: builtin/fetch.c:412 builtin/fetch.c:718
+#: builtin/fetch.c:429 builtin/fetch.c:735
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr "kan inte öppna %s: %s\n"
 
-#: builtin/fetch.c:421
+#: builtin/fetch.c:438
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s sände inte alla nödvändiga objekt\n"
 
-#: builtin/fetch.c:520
+#: builtin/fetch.c:537
 #, c-format
 msgid "From %.*s\n"
 msgstr "Från %.*s\n"
 
-#: builtin/fetch.c:531
+#: builtin/fetch.c:548
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -4930,55 +5112,55 @@
 "vissa lokala referenser kunde inte uppdateras; testa att köra\n"
 " \"git remote prune %s\" för att ta bort gamla grenar som står i konflikt"
 
-#: builtin/fetch.c:581
+#: builtin/fetch.c:598
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s kommer bli dinglande)"
 
-#: builtin/fetch.c:582
+#: builtin/fetch.c:599
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s har blivit dinglande)"
 
-#: builtin/fetch.c:589
+#: builtin/fetch.c:606
 msgid "[deleted]"
 msgstr "[borttagen]"
 
-#: builtin/fetch.c:590 builtin/remote.c:1055
+#: builtin/fetch.c:607 builtin/remote.c:1055
 msgid "(none)"
 msgstr "(ingen)"
 
-#: builtin/fetch.c:708
+#: builtin/fetch.c:725
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "Vägrar hämta till aktuell gren %s i ett icke-naket arkiv"
 
-#: builtin/fetch.c:742
-#, c-format
-msgid "Don't know how to fetch from %s"
-msgstr "Vet inte hur man hämtar från %s"
-
-#: builtin/fetch.c:823
+#: builtin/fetch.c:744
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "Flaggan \"%s\" och värdet \"%s\" är inte giltigt för %s"
 
-#: builtin/fetch.c:826
+#: builtin/fetch.c:747
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "Flaggan \"%s\" ignoreras för %s\n"
 
-#: builtin/fetch.c:928
+#: builtin/fetch.c:801
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr "Vet inte hur man hämtar från %s"
+
+#: builtin/fetch.c:976
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Hämtar %s\n"
 
-#: builtin/fetch.c:930 builtin/remote.c:100
+#: builtin/fetch.c:978 builtin/remote.c:100
 #, c-format
 msgid "Could not fetch %s"
 msgstr "Kunde inte hämta %s"
 
-#: builtin/fetch.c:949
+#: builtin/fetch.c:997
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -4986,32 +5168,32 @@
 "Inget fjärrarkiv angavs. Ange antingen en URL eller namnet på ett\n"
 "fjärrarkiv som nya incheckningar skall hämtas från."
 
-#: builtin/fetch.c:969
+#: builtin/fetch.c:1020
 msgid "You need to specify a tag name."
 msgstr "Du måste ange namnet på en tagg."
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1068
 msgid "--depth and --unshallow cannot be used together"
 msgstr "--depth och --unshallow kan inte användas samtidigt"
 
-#: builtin/fetch.c:1017
+#: builtin/fetch.c:1070
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "--unshallow kan inte användas på ett komplett arkiv"
 
-#: builtin/fetch.c:1036
+#: builtin/fetch.c:1089
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all tar inte namnet på ett arkiv som argument"
 
-#: builtin/fetch.c:1038
+#: builtin/fetch.c:1091
 msgid "fetch --all does not make sense with refspecs"
 msgstr "fetch --all kan inte anges med referensspecifikationer"
 
-#: builtin/fetch.c:1049
+#: builtin/fetch.c:1102
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "Fjärren eller fjärrgruppen finns inte: %s"
 
-#: builtin/fetch.c:1057
+#: builtin/fetch.c:1110
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "Kan inte hämta från grupp och ange referensspecifikationer"
 
@@ -5020,9 +5202,9 @@
 msgstr ""
 "git fmt-merge-msg [-m <meddelande>] [--log[=<n>]|--no-log] [--file <fil>]"
 
-#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:700
-#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:179
-#: builtin/tag.c:446 parse-options.h:133 parse-options.h:243
+#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:702
+#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:178
+#: builtin/tag.c:446 parse-options.h:135 parse-options.h:245
 msgid "n"
 msgstr "n"
 
@@ -5046,117 +5228,121 @@
 msgid "file to read from"
 msgstr "fil att läsa från"
 
-#: builtin/for-each-ref.c:979
+#: builtin/for-each-ref.c:995
 msgid "git for-each-ref [options] [<pattern>]"
 msgstr "git for-each-ref [flaggor] [<mönster>]"
 
-#: builtin/for-each-ref.c:994
+#: builtin/for-each-ref.c:1010
 msgid "quote placeholders suitably for shells"
 msgstr "citera platshållare passande för skal"
 
-#: builtin/for-each-ref.c:996
+#: builtin/for-each-ref.c:1012
 msgid "quote placeholders suitably for perl"
 msgstr "citera platshållare passande för perl"
 
-#: builtin/for-each-ref.c:998
+#: builtin/for-each-ref.c:1014
 msgid "quote placeholders suitably for python"
 msgstr "citera platshållare passande för python"
 
-#: builtin/for-each-ref.c:1000
+#: builtin/for-each-ref.c:1016
 msgid "quote placeholders suitably for tcl"
 msgstr "citera platshållare passande för tcl"
 
-#: builtin/for-each-ref.c:1003
+#: builtin/for-each-ref.c:1019
 msgid "show only <n> matched refs"
 msgstr "visa endast <n> träffade refs"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format"
 msgstr "format"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format to use for the output"
 msgstr "format att använda för utdata"
 
-#: builtin/for-each-ref.c:1005
+#: builtin/for-each-ref.c:1021
 msgid "key"
 msgstr "nyckel"
 
-#: builtin/for-each-ref.c:1006
+#: builtin/for-each-ref.c:1022
 msgid "field name to sort on"
 msgstr "fältnamn att sortera på"
 
-#: builtin/fsck.c:608
+#: builtin/fsck.c:607
 msgid "git fsck [options] [<object>...]"
 msgstr "git fsck [flaggor] [<objekt>...]"
 
-#: builtin/fsck.c:614
+#: builtin/fsck.c:613
 msgid "show unreachable objects"
 msgstr "visa onåbara objekt"
 
-#: builtin/fsck.c:615
+#: builtin/fsck.c:614
 msgid "show dangling objects"
 msgstr "visa dinglande objekt"
 
-#: builtin/fsck.c:616
+#: builtin/fsck.c:615
 msgid "report tags"
 msgstr "rapportera taggar"
 
-#: builtin/fsck.c:617
+#: builtin/fsck.c:616
 msgid "report root nodes"
 msgstr "rapportera rotnoder"
 
-#: builtin/fsck.c:618
+#: builtin/fsck.c:617
 msgid "make index objects head nodes"
 msgstr "gör indexojekt till huvudnoder"
 
-#: builtin/fsck.c:619
+#: builtin/fsck.c:618
 msgid "make reflogs head nodes (default)"
 msgstr "gör refloggar till huvudnoder (standard)"
 
-#: builtin/fsck.c:620
+#: builtin/fsck.c:619
 msgid "also consider packs and alternate objects"
 msgstr "ta även hänsyn till paket och alternativa objekt"
 
-#: builtin/fsck.c:621
+#: builtin/fsck.c:620
 msgid "enable more strict checking"
 msgstr "aktivera striktare kontroll"
 
-#: builtin/fsck.c:623
+#: builtin/fsck.c:622
 msgid "write dangling objects in .git/lost-found"
 msgstr "skriv dinglande objekt i .git/lost-found"
 
-#: builtin/fsck.c:624 builtin/prune.c:134
+#: builtin/fsck.c:623 builtin/prune.c:134
 msgid "show progress"
 msgstr "visa förlopp"
 
-#: builtin/gc.c:22
+#: builtin/gc.c:23
 msgid "git gc [options]"
 msgstr "git gc [flaggor]"
 
-#: builtin/gc.c:63
+#: builtin/gc.c:79
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "Felaktigt %s: \"%s\""
 
-#: builtin/gc.c:90
+#: builtin/gc.c:106
 #, c-format
 msgid "insanely long object directory %.*s"
 msgstr "tokigt lång objektkatalog %.*s"
 
-#: builtin/gc.c:179
+#: builtin/gc.c:261
 msgid "prune unreferenced objects"
 msgstr "rensa ej refererade objekt"
 
-#: builtin/gc.c:181
+#: builtin/gc.c:263
 msgid "be more thorough (increased runtime)"
 msgstr "var mer grundlig (ökar körtiden)"
 
-#: builtin/gc.c:182
+#: builtin/gc.c:264
 msgid "enable auto-gc mode"
 msgstr "aktivera auto-gc-läge"
 
-#: builtin/gc.c:222
+#: builtin/gc.c:265
+msgid "force running gc even if there may be another gc running"
+msgstr "tvinga gc-körning även om en annan gc kanske körs"
+
+#: builtin/gc.c:305
 #, c-format
 msgid ""
 "Auto packing the repository for optimum performance. You may also\n"
@@ -5165,43 +5351,52 @@
 "Packar arkivet automatiskt för optimal prestanda. Du kan även\n"
 "köra \"git gc\" manuellt. Se \"git help gc\" för mer information.\n"
 
-#: builtin/gc.c:249
+#. be quiet on --auto
+#: builtin/gc.c:315
+#, c-format
+msgid ""
+"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
+msgstr ""
+"gc körs redan på maskinen \"%s\" pid %<PRIuMAX> (använd --force om så inte "
+"är fallet)"
+
+#: builtin/gc.c:340
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "Det finns för många onåbara lösa objekt; kör \"git prune\" för att ta bort "
 "dem."
 
-#: builtin/grep.c:22
+#: builtin/grep.c:23
 msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [flaggor] [-e] <mönster> [<rev>...] [[--] <sökväg>...]"
 
-#: builtin/grep.c:217
+#: builtin/grep.c:218
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: misslyckades skapa tråd. %s"
 
-#: builtin/grep.c:364
+#: builtin/grep.c:365
 #, c-format
 msgid "Failed to chdir: %s"
 msgstr "Kunde inte byta katalog (chdir): %s"
 
-#: builtin/grep.c:442 builtin/grep.c:477
+#: builtin/grep.c:443 builtin/grep.c:478
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "kunde inte läsa träd (%s)"
 
-#: builtin/grep.c:492
+#: builtin/grep.c:493
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "Kunde inte \"grep\" från objekt av typen %s"
 
-#: builtin/grep.c:550
+#: builtin/grep.c:551
 #, c-format
 msgid "switch `%c' expects a numerical value"
 msgstr "flaggan \"%c\" antar ett numeriskt värde"
 
-#: builtin/grep.c:567
+#: builtin/grep.c:568
 #, c-format
 msgid "cannot open '%s'"
 msgstr "kan inte öppna \"%s\""
@@ -5243,158 +5438,162 @@
 msgstr "träffa inte mönster i binärfiler"
 
 #: builtin/grep.c:662
+msgid "process binary files with textconv filters"
+msgstr "hantera binärfiler med textconv-filter"
+
+#: builtin/grep.c:664
 msgid "descend at most <depth> levels"
 msgstr "gå som mest ned <djup> nivåer"
 
-#: builtin/grep.c:666
+#: builtin/grep.c:668
 msgid "use extended POSIX regular expressions"
 msgstr "använd utökade POSIX-reguljära uttryck"
 
-#: builtin/grep.c:669
+#: builtin/grep.c:671
 msgid "use basic POSIX regular expressions (default)"
 msgstr "använd grundläggande POSIX-reguljära uttryck (standard)"
 
-#: builtin/grep.c:672
+#: builtin/grep.c:674
 msgid "interpret patterns as fixed strings"
 msgstr "tolka mönster som fixerade strängar"
 
-#: builtin/grep.c:675
+#: builtin/grep.c:677
 msgid "use Perl-compatible regular expressions"
 msgstr "använd Perlkompatibla reguljära uttryck"
 
-#: builtin/grep.c:678
+#: builtin/grep.c:680
 msgid "show line numbers"
 msgstr "visa radnummer"
 
-#: builtin/grep.c:679
+#: builtin/grep.c:681
 msgid "don't show filenames"
 msgstr "visa inte filnamn"
 
-#: builtin/grep.c:680
+#: builtin/grep.c:682
 msgid "show filenames"
 msgstr "visa filnamn"
 
-#: builtin/grep.c:682
+#: builtin/grep.c:684
 msgid "show filenames relative to top directory"
 msgstr "visa filnamn relativa till toppkatalogen"
 
-#: builtin/grep.c:684
+#: builtin/grep.c:686
 msgid "show only filenames instead of matching lines"
 msgstr "visa endast filnamn istället för träffade rader"
 
-#: builtin/grep.c:686
+#: builtin/grep.c:688
 msgid "synonym for --files-with-matches"
 msgstr "synonym för --files-with-matches"
 
-#: builtin/grep.c:689
+#: builtin/grep.c:691
 msgid "show only the names of files without match"
 msgstr "visa endast namn på filer utan träffar"
 
-#: builtin/grep.c:691
+#: builtin/grep.c:693
 msgid "print NUL after filenames"
 msgstr "skriv NUL efter filnamn"
 
-#: builtin/grep.c:693
+#: builtin/grep.c:695
 msgid "show the number of matches instead of matching lines"
 msgstr "visa antal träffar istället för träffade rader"
 
-#: builtin/grep.c:694
+#: builtin/grep.c:696
 msgid "highlight matches"
 msgstr "ljusmarkera träffar"
 
-#: builtin/grep.c:696
+#: builtin/grep.c:698
 msgid "print empty line between matches from different files"
 msgstr "skriv tomma rader mellan träffar från olika filer"
 
-#: builtin/grep.c:698
+#: builtin/grep.c:700
 msgid "show filename only once above matches from same file"
 msgstr "visa filnamn endast en gång ovanför träffar från samma fil"
 
-#: builtin/grep.c:701
+#: builtin/grep.c:703
 msgid "show <n> context lines before and after matches"
 msgstr "visa <n> rader sammanhang före och efter träffar"
 
-#: builtin/grep.c:704
+#: builtin/grep.c:706
 msgid "show <n> context lines before matches"
 msgstr "visa <n> rader sammanhang före träffar"
 
-#: builtin/grep.c:706
+#: builtin/grep.c:708
 msgid "show <n> context lines after matches"
 msgstr "visa <n> rader sammanhang efter träffar"
 
-#: builtin/grep.c:707
+#: builtin/grep.c:709
 msgid "shortcut for -C NUM"
 msgstr "genväg för -C NUM"
 
-#: builtin/grep.c:710
+#: builtin/grep.c:712
 msgid "show a line with the function name before matches"
 msgstr "visa en rad med funktionsnamnet före träffen"
 
-#: builtin/grep.c:712
+#: builtin/grep.c:714
 msgid "show the surrounding function"
 msgstr "visa den omkringliggande funktionen"
 
-#: builtin/grep.c:715
+#: builtin/grep.c:717
 msgid "read patterns from file"
 msgstr "läs mönster från fil"
 
-#: builtin/grep.c:717
+#: builtin/grep.c:719
 msgid "match <pattern>"
 msgstr "träffa <mönster>"
 
-#: builtin/grep.c:719
+#: builtin/grep.c:721
 msgid "combine patterns specified with -e"
 msgstr "kombinera mönster som anges med -e"
 
-#: builtin/grep.c:731
+#: builtin/grep.c:733
 msgid "indicate hit with exit status without output"
 msgstr "ange träff med slutstatuskod utan utdata"
 
-#: builtin/grep.c:733
+#: builtin/grep.c:735
 msgid "show only matches from files that match all patterns"
 msgstr "visa endast träffar från filer som träffar alla mönster"
 
-#: builtin/grep.c:735
+#: builtin/grep.c:737
 msgid "show parse tree for grep expression"
 msgstr "visa analysträd för grep-uttryck"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "pager"
 msgstr "bläddrare"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "show matching files in the pager"
 msgstr "visa träffade filer i filbläddraren"
 
-#: builtin/grep.c:742
+#: builtin/grep.c:744
 msgid "allow calling of grep(1) (ignored by this build)"
 msgstr "tillåt anropa grep(1) (ignoreras av detta bygge)"
 
-#: builtin/grep.c:743 builtin/show-ref.c:188
+#: builtin/grep.c:745 builtin/show-ref.c:187
 msgid "show usage"
 msgstr "visa användning"
 
-#: builtin/grep.c:810
+#: builtin/grep.c:812
 msgid "no pattern given."
 msgstr "inget mönster angavs."
 
-#: builtin/grep.c:865
+#: builtin/grep.c:870
 msgid "--open-files-in-pager only works on the worktree"
 msgstr "--open-files-in-pager fungerar endast i arbetskatalogen"
 
-#: builtin/grep.c:888
+#: builtin/grep.c:893
 msgid "--cached or --untracked cannot be used with --no-index."
 msgstr "--cached och --untracked kan inte användas med --no-index."
 
-#: builtin/grep.c:893
+#: builtin/grep.c:898
 msgid "--no-index or --untracked cannot be used with revs."
 msgstr "--no-index och --untracked kan inte användas med revisioner."
 
-#: builtin/grep.c:896
+#: builtin/grep.c:901
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
 msgstr "--[no-]exclude-standard kan inte användas för spårat innehåll."
 
-#: builtin/grep.c:904
+#: builtin/grep.c:909
 msgid "both --cached and trees are given."
 msgstr "både --cached och träd angavs."
 
@@ -5649,8 +5848,8 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !"
 
-#: builtin/index-pack.c:669 builtin/pack-objects.c:170
-#: builtin/pack-objects.c:262
+#: builtin/index-pack.c:669 builtin/pack-objects.c:171
+#: builtin/pack-objects.c:263
 #, c-format
 msgid "unable to read %s"
 msgstr "kunde inte läsa %s"
@@ -5679,155 +5878,155 @@
 msgid "Not all child objects of %s are reachable"
 msgstr "Inte alla barnobjekt för %s kan nås"
 
-#: builtin/index-pack.c:838 builtin/index-pack.c:868
+#: builtin/index-pack.c:839 builtin/index-pack.c:869
 msgid "failed to apply delta"
 msgstr "misslyckades tillämpa delta"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Receiving objects"
 msgstr "Tar emot objekt"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Indexing objects"
 msgstr "Skapar index för objekt"
 
-#: builtin/index-pack.c:1035
+#: builtin/index-pack.c:1036
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "paketet är trasigt (SHA1 stämmer inte)"
 
-#: builtin/index-pack.c:1040
+#: builtin/index-pack.c:1041
 msgid "cannot fstat packfile"
 msgstr "kan inte utföra \"fstat\" på paketfil"
 
-#: builtin/index-pack.c:1043
+#: builtin/index-pack.c:1044
 msgid "pack has junk at the end"
 msgstr "paket har skräp i slutet"
 
-#: builtin/index-pack.c:1054
+#: builtin/index-pack.c:1055
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "förvirrad bortom vanvett i parse_pack_objects()"
 
-#: builtin/index-pack.c:1077
+#: builtin/index-pack.c:1078
 msgid "Resolving deltas"
 msgstr "Analyserar delta"
 
-#: builtin/index-pack.c:1087
+#: builtin/index-pack.c:1088
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "kunde inte skapa tråd: %s"
 
-#: builtin/index-pack.c:1129
+#: builtin/index-pack.c:1130
 msgid "confusion beyond insanity"
 msgstr "förvirrad bortom vanvett"
 
-#: builtin/index-pack.c:1137
+#: builtin/index-pack.c:1138
 #, c-format
 msgid "completed with %d local objects"
 msgstr "slutfördes med %d lokala objekt"
 
-#: builtin/index-pack.c:1147
+#: builtin/index-pack.c:1148
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "Oväntad svanschecksumma för %s (trasig disk?)"
 
-#: builtin/index-pack.c:1151
+#: builtin/index-pack.c:1152
 #, 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:1176
+#: builtin/index-pack.c:1177
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "kunde inte utföra \"deflate\" på tillagt objekt (%d)"
 
-#: builtin/index-pack.c:1255
+#: builtin/index-pack.c:1256
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "lokalt objekt %s är trasigt"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1280
 msgid "error while closing pack file"
 msgstr "fel vid stängning av paketfil"
 
-#: builtin/index-pack.c:1292
+#: builtin/index-pack.c:1293
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "kan inte ta skriva \"keep\"-fil \"%s\""
 
-#: builtin/index-pack.c:1300
+#: builtin/index-pack.c:1301
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr "akn inte stänga skriven \"keep\"-fil \"%s\""
 
-#: builtin/index-pack.c:1313
+#: builtin/index-pack.c:1314
 msgid "cannot store pack file"
 msgstr "kan inte spara paketfil"
 
-#: builtin/index-pack.c:1324
+#: builtin/index-pack.c:1325
 msgid "cannot store index file"
 msgstr "kan inte spara indexfil"
 
-#: builtin/index-pack.c:1357
+#: builtin/index-pack.c:1358
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "felaktig pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1363
+#: builtin/index-pack.c:1364
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "felaktigt antal trådar angivet (%d)"
 
-#: builtin/index-pack.c:1367 builtin/index-pack.c:1545
+#: builtin/index-pack.c:1368 builtin/index-pack.c:1546
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "trådstöd saknas, ignorerar %s"
 
-#: builtin/index-pack.c:1425
+#: builtin/index-pack.c:1426
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Kan inte öppna befintlig paketfil \"%s\""
 
-#: builtin/index-pack.c:1427
+#: builtin/index-pack.c:1428
 #, 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:1474
+#: builtin/index-pack.c:1475
 #, 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:1481
+#: builtin/index-pack.c:1482
 #, 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:1509
+#: builtin/index-pack.c:1510
 msgid "Cannot come back to cwd"
 msgstr "Kan inte gå tillbaka till arbetskatalogen (cwd)"
 
-#: builtin/index-pack.c:1557 builtin/index-pack.c:1560
-#: builtin/index-pack.c:1572 builtin/index-pack.c:1576
+#: builtin/index-pack.c:1558 builtin/index-pack.c:1561
+#: builtin/index-pack.c:1573 builtin/index-pack.c:1577
 #, c-format
 msgid "bad %s"
 msgstr "felaktig %s"
 
-#: builtin/index-pack.c:1590
+#: builtin/index-pack.c:1591
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin kan inte användas med --stdin"
 
-#: builtin/index-pack.c:1594 builtin/index-pack.c:1604
+#: builtin/index-pack.c:1595 builtin/index-pack.c:1605
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "paketfilnamnet \"%s\" slutar inte med \".pack\""
 
-#: builtin/index-pack.c:1613
+#: builtin/index-pack.c:1614
 msgid "--verify with no packfile name given"
 msgstr "--verify angavs utan paketfilnamn"
 
@@ -5916,11 +6115,6 @@
 msgid "unable to move %s to %s"
 msgstr "kan inte flytta %s till %s"
 
-#: builtin/init-db.c:363
-#, c-format
-msgid "Could not create git link %s"
-msgstr "Kunde inte skapa gitlänk %s"
-
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
 #. * existing" or "Initialized empty", the second " shared" or
@@ -5963,7 +6157,7 @@
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "ange att git-arkivet skall delas bland flera användare"
 
-#: builtin/init-db.c:493 builtin/prune-packed.c:75
+#: builtin/init-db.c:493 builtin/prune-packed.c:75 builtin/repack.c:155
 msgid "be quiet"
 msgstr "var tyst"
 
@@ -6003,381 +6197,381 @@
 msgid "   or: git show [options] <object>..."
 msgstr "     eller: git show [flaggor] <objekt>..."
 
-#: builtin/log.c:124
+#: builtin/log.c:125
 msgid "suppress diff output"
 msgstr "undertryck diff-utdata"
 
-#: builtin/log.c:125
+#: builtin/log.c:126
 msgid "show source"
 msgstr "visa källkod"
 
-#: builtin/log.c:126
+#: builtin/log.c:127
 msgid "Use mail map file"
 msgstr "Använd e-postmappningsfil"
 
-#: builtin/log.c:127
+#: builtin/log.c:128
 msgid "decorate options"
 msgstr "dekoreringsflaggor"
 
-#: builtin/log.c:230
+#: builtin/log.c:231
 #, c-format
 msgid "Final output: %d %s\n"
 msgstr "Slututdata: %d %s\n"
 
-#: builtin/log.c:453 builtin/log.c:545
+#: builtin/log.c:473 builtin/log.c:565
 #, c-format
 msgid "Could not read object %s"
 msgstr "Kunde inte läsa objektet %s"
 
-#: builtin/log.c:569
+#: builtin/log.c:589
 #, c-format
 msgid "Unknown type: %d"
 msgstr "Okänd typ: %d"
 
-#: builtin/log.c:669
+#: builtin/log.c:689
 msgid "format.headers without value"
 msgstr "format.headers utan värde"
 
-#: builtin/log.c:751
+#: builtin/log.c:771
 msgid "name of output directory is too long"
 msgstr "namnet på utdatakatalogen är för långt"
 
-#: builtin/log.c:767
+#: builtin/log.c:787
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "Kan inte öppna patchfilen %s"
 
-#: builtin/log.c:781
+#: builtin/log.c:801
 msgid "Need exactly one range."
 msgstr "Behöver precis ett intervall."
 
-#: builtin/log.c:789
+#: builtin/log.c:809
 msgid "Not a range."
 msgstr "Inte ett intervall."
 
-#: builtin/log.c:891
+#: builtin/log.c:911
 msgid "Cover letter needs email format"
 msgstr "Omslagsbrevet behöver e-postformat"
 
-#: builtin/log.c:967
+#: builtin/log.c:987
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "tokigt in-reply-to: %s"
 
-#: builtin/log.c:995
+#: builtin/log.c:1015
 msgid "git format-patch [options] [<since> | <revision range>]"
 msgstr "git format-patch [flaggor] [<sedan> | <revisionsintervall>]"
 
-#: builtin/log.c:1040
+#: builtin/log.c:1060
 msgid "Two output directories?"
 msgstr "Två utdatakataloger?"
 
-#: builtin/log.c:1155
+#: builtin/log.c:1175
 msgid "use [PATCH n/m] even with a single patch"
 msgstr "använd [PATCH n/m] även för en ensam patch"
 
-#: builtin/log.c:1158
+#: builtin/log.c:1178
 msgid "use [PATCH] even with multiple patches"
 msgstr "använd [PATCH] även för flera patchar"
 
-#: builtin/log.c:1162
+#: builtin/log.c:1182
 msgid "print patches to standard out"
 msgstr "skriv patcharna på stnadard ut"
 
-#: builtin/log.c:1164
+#: builtin/log.c:1184
 msgid "generate a cover letter"
 msgstr "generera ett följebrev"
 
-#: builtin/log.c:1166
+#: builtin/log.c:1186
 msgid "use simple number sequence for output file names"
 msgstr "använd enkel nummersekvens för utdatafilnamn"
 
-#: builtin/log.c:1167
+#: builtin/log.c:1187
 msgid "sfx"
 msgstr "sfx"
 
-#: builtin/log.c:1168
+#: builtin/log.c:1188
 msgid "use <sfx> instead of '.patch'"
 msgstr "använd <sfx> istället för \".patch\""
 
-#: builtin/log.c:1170
+#: builtin/log.c:1190
 msgid "start numbering patches at <n> instead of 1"
 msgstr "börja numrera patchar på <n> istället för 1"
 
-#: builtin/log.c:1172
+#: builtin/log.c:1192
 msgid "mark the series as Nth re-roll"
 msgstr "markera serien som N:te försök"
 
-#: builtin/log.c:1174
+#: builtin/log.c:1194
 msgid "Use [<prefix>] instead of [PATCH]"
 msgstr "Använd [<prefix>] istället för [PATCH]"
 
-#: builtin/log.c:1177
+#: builtin/log.c:1197
 msgid "store resulting files in <dir>"
 msgstr "spara filerna i <katalog>"
 
-#: builtin/log.c:1180
+#: builtin/log.c:1200
 msgid "don't strip/add [PATCH]"
 msgstr "ta inte bort eller lägg till [PATCH]"
 
-#: builtin/log.c:1183
+#: builtin/log.c:1203
 msgid "don't output binary diffs"
 msgstr "skriv inte binära diffar"
 
-#: builtin/log.c:1185
+#: builtin/log.c:1205
 msgid "don't include a patch matching a commit upstream"
 msgstr "ta inte med patchar som motsvarar en uppströmsincheckning"
 
-#: builtin/log.c:1187
+#: builtin/log.c:1207
 msgid "show patch format instead of default (patch + stat)"
 msgstr "visa patchformat istället för standard (patch + stat)"
 
-#: builtin/log.c:1189
+#: builtin/log.c:1209
 msgid "Messaging"
 msgstr "E-post"
 
-#: builtin/log.c:1190
+#: builtin/log.c:1210
 msgid "header"
 msgstr "huvud"
 
-#: builtin/log.c:1191
+#: builtin/log.c:1211
 msgid "add email header"
 msgstr "lägg till e-posthuvud"
 
-#: builtin/log.c:1192 builtin/log.c:1194
+#: builtin/log.c:1212 builtin/log.c:1214
 msgid "email"
 msgstr "epost"
 
-#: builtin/log.c:1192
+#: builtin/log.c:1212
 msgid "add To: header"
 msgstr "Lägg till mottagarhuvud (\"To:\")"
 
-#: builtin/log.c:1194
+#: builtin/log.c:1214
 msgid "add Cc: header"
 msgstr "Lägg till kopiehuvud (\"Cc:\")"
 
-#: builtin/log.c:1196
+#: builtin/log.c:1216
 msgid "ident"
 msgstr "ident"
 
-#: builtin/log.c:1197
+#: builtin/log.c:1217
 msgid "set From address to <ident> (or committer ident if absent)"
 msgstr "sätt Från-adress till <ident> (eller incheckare om ident saknas)"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1219
 msgid "message-id"
 msgstr "meddelande-id"
 
-#: builtin/log.c:1200
+#: builtin/log.c:1220
 msgid "make first mail a reply to <message-id>"
 msgstr "Gör det första brevet ett svar till <meddelande-id>"
 
-#: builtin/log.c:1201 builtin/log.c:1204
+#: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
 msgstr "gräns"
 
-#: builtin/log.c:1202
+#: builtin/log.c:1222
 msgid "attach the patch"
 msgstr "bifoga patchen"
 
-#: builtin/log.c:1205
+#: builtin/log.c:1225
 msgid "inline the patch"
 msgstr "gör patchen ett inline-objekt"
 
-#: builtin/log.c:1209
+#: builtin/log.c:1229
 msgid "enable message threading, styles: shallow, deep"
 msgstr "aktivera brevtrådning, typer: shallow, deep"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1231
 msgid "signature"
 msgstr "signatur"
 
-#: builtin/log.c:1212
+#: builtin/log.c:1232
 msgid "add a signature"
 msgstr "lägg till signatur"
 
-#: builtin/log.c:1214
+#: builtin/log.c:1233
 msgid "don't print the patch filenames"
 msgstr "visa inte filnamn för patchar"
 
-#: builtin/log.c:1288
+#: builtin/log.c:1307
 #, c-format
 msgid "invalid ident line: %s"
 msgstr "ogiltig ident-rad: %s"
 
-#: builtin/log.c:1303
+#: builtin/log.c:1322
 msgid "-n and -k are mutually exclusive."
 msgstr "-n och -k kan inte användas samtidigt."
 
-#: builtin/log.c:1305
+#: builtin/log.c:1324
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "--subject-prefix och -k kan inte användas samtidigt."
 
-#: builtin/log.c:1313
+#: builtin/log.c:1332
 msgid "--name-only does not make sense"
 msgstr "kan inte använda --name-only"
 
-#: builtin/log.c:1315
+#: builtin/log.c:1334
 msgid "--name-status does not make sense"
 msgstr "kan inte använda --name-status"
 
-#: builtin/log.c:1317
+#: builtin/log.c:1336
 msgid "--check does not make sense"
 msgstr "kan inte använda --check"
 
-#: builtin/log.c:1340
+#: builtin/log.c:1359
 msgid "standard output, or directory, which one?"
 msgstr "standard ut, eller katalog, vilken skall det vara?"
 
-#: builtin/log.c:1342
+#: builtin/log.c:1361
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "Kunde inte skapa katalogen \"%s\""
 
-#: builtin/log.c:1490
+#: builtin/log.c:1509
 msgid "Failed to create output files"
 msgstr "Misslyckades skapa utdatafiler"
 
-#: builtin/log.c:1539
+#: builtin/log.c:1558
 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
 msgstr "git cherry [-v] [<uppström> [<huvud> [<gräns>]]]"
 
-#: builtin/log.c:1594
+#: builtin/log.c:1613
 #, 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:1607 builtin/log.c:1609 builtin/log.c:1621
+#: builtin/log.c:1626 builtin/log.c:1628 builtin/log.c:1640
 #, c-format
 msgid "Unknown commit %s"
 msgstr "Okänd incheckning %s"
 
-#: builtin/ls-files.c:408
+#: builtin/ls-files.c:398
 msgid "git ls-files [options] [<file>...]"
 msgstr "git ls-files [flaggor] [<fil>...]"
 
-#: builtin/ls-files.c:465
+#: builtin/ls-files.c:455
 msgid "identify the file status with tags"
 msgstr "identifiera filstatus med taggar"
 
-#: builtin/ls-files.c:467
+#: builtin/ls-files.c:457
 msgid "use lowercase letters for 'assume unchanged' files"
 msgstr "använd små bokstäver för \"anta oförändrade\"-filer"
 
-#: builtin/ls-files.c:469
+#: builtin/ls-files.c:459
 msgid "show cached files in the output (default)"
 msgstr "visa cachade filer i utdata (standard)"
 
-#: builtin/ls-files.c:471
+#: builtin/ls-files.c:461
 msgid "show deleted files in the output"
 msgstr "visa borttagna filer i utdata"
 
-#: builtin/ls-files.c:473
+#: builtin/ls-files.c:463
 msgid "show modified files in the output"
 msgstr "visa modifierade filer i utdata"
 
-#: builtin/ls-files.c:475
+#: builtin/ls-files.c:465
 msgid "show other files in the output"
 msgstr "visa andra filer i utdata"
 
-#: builtin/ls-files.c:477
+#: builtin/ls-files.c:467
 msgid "show ignored files in the output"
 msgstr "visa ignorerade filer i utdata"
 
-#: builtin/ls-files.c:480
+#: builtin/ls-files.c:470
 msgid "show staged contents' object name in the output"
 msgstr "visa köat innehålls objektnamn i utdata"
 
-#: builtin/ls-files.c:482
+#: builtin/ls-files.c:472
 msgid "show files on the filesystem that need to be removed"
 msgstr "visa filer i filsystemet som behöver tas bort"
 
-#: builtin/ls-files.c:484
+#: builtin/ls-files.c:474
 msgid "show 'other' directories' name only"
 msgstr "visa endast namn för \"andra\" kataloger"
 
-#: builtin/ls-files.c:487
+#: builtin/ls-files.c:477
 msgid "don't show empty directories"
 msgstr "visa inte tomma kataloger"
 
-#: builtin/ls-files.c:490
+#: builtin/ls-files.c:480
 msgid "show unmerged files in the output"
 msgstr "visa ej sammanslagna filer i utdata"
 
-#: builtin/ls-files.c:492
+#: builtin/ls-files.c:482
 msgid "show resolve-undo information"
 msgstr "visa \"resolve-undo\"-information"
 
-#: builtin/ls-files.c:494
+#: builtin/ls-files.c:484
 msgid "skip files matching pattern"
 msgstr "hoppa över filer som motsvarar mönster"
 
-#: builtin/ls-files.c:497
+#: builtin/ls-files.c:487
 msgid "exclude patterns are read from <file>"
 msgstr "exkludera mönster som läses från <fil>"
 
-#: builtin/ls-files.c:500
+#: builtin/ls-files.c:490
 msgid "read additional per-directory exclude patterns in <file>"
 msgstr "läs ytterligare per-katalog-exkluderingsmönster från <fil>"
 
-#: builtin/ls-files.c:502
+#: builtin/ls-files.c:492
 msgid "add the standard git exclusions"
 msgstr "lägg till git:s standardexkluderingar"
 
-#: builtin/ls-files.c:505
+#: builtin/ls-files.c:495
 msgid "make the output relative to the project top directory"
 msgstr "gör utdata relativ till projektets toppkatalog"
 
-#: builtin/ls-files.c:508
+#: builtin/ls-files.c:498
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr "om en <fil> inte är indexet, betrakta det som ett fel"
 
-#: builtin/ls-files.c:509
+#: builtin/ls-files.c:499
 msgid "tree-ish"
 msgstr "träd-igt"
 
-#: builtin/ls-files.c:510
+#: builtin/ls-files.c:500
 msgid "pretend that paths removed since <tree-ish> are still present"
 msgstr "låtsas att sökvägar borttagna sedan <träd-igt> fortfarande finns"
 
-#: builtin/ls-files.c:512
+#: builtin/ls-files.c:502
 msgid "show debugging data"
 msgstr "visa felsökningsutdata"
 
-#: builtin/ls-tree.c:27
+#: builtin/ls-tree.c:28
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<flaggor>] <träd-igt> [<sökväg>...]"
 
-#: builtin/ls-tree.c:125
+#: builtin/ls-tree.c:126
 msgid "only show trees"
 msgstr "visa endast träd"
 
-#: builtin/ls-tree.c:127
+#: builtin/ls-tree.c:128
 msgid "recurse into subtrees"
 msgstr "rekursera ner i underträd"
 
-#: builtin/ls-tree.c:129
+#: builtin/ls-tree.c:130
 msgid "show trees when recursing"
 msgstr "visa träd medan rekursering"
 
-#: builtin/ls-tree.c:132
+#: builtin/ls-tree.c:133
 msgid "terminate entries with NUL byte"
 msgstr "terminera poster med NUL-byte"
 
-#: builtin/ls-tree.c:133
+#: builtin/ls-tree.c:134
 msgid "include object size"
 msgstr "inkludera objektstorlek"
 
-#: builtin/ls-tree.c:135 builtin/ls-tree.c:137
+#: builtin/ls-tree.c:136 builtin/ls-tree.c:138
 msgid "list only filenames"
 msgstr "visa endast filnamn"
 
-#: builtin/ls-tree.c:140
+#: builtin/ls-tree.c:141
 msgid "use full path names"
 msgstr "använd fullständiga sökvägsnamn"
 
-#: builtin/ls-tree.c:142
+#: builtin/ls-tree.c:143
 msgid "list entire tree; not just current directory (implies --full-name)"
 msgstr "visa hela trädet; inte bara aktuell katalog (implicerar --full-name)"
 
@@ -6453,7 +6647,7 @@
 msgid "Verify that the named commit has a valid GPG signature"
 msgstr "Bekräfta att den namngivna incheckningen har en giltig GPG-signatur"
 
-#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:114
+#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:89
 msgid "strategy"
 msgstr "strategi"
 
@@ -6822,76 +7016,86 @@
 msgid "allow creation of more than one tree"
 msgstr "tillåt skapa mer än ett träd"
 
-#: builtin/mv.c:14
+#: builtin/mv.c:15
 msgid "git mv [options] <source>... <destination>"
 msgstr "git mv [flaggor] <källa>... <mål>"
 
-#: builtin/mv.c:64
+#: builtin/mv.c:67
 msgid "force move/rename even if target exists"
 msgstr "tvinga flytta/ändra namn även om målet finns"
 
-#: builtin/mv.c:65
+#: builtin/mv.c:68
 msgid "skip move/rename errors"
 msgstr "hoppa över fel vid flytt/namnändring"
 
-#: builtin/mv.c:108
+#: builtin/mv.c:113
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
 msgstr "Kontrollerar namnbyte av \"%s\" till \"%s\"\n"
 
-#: builtin/mv.c:112
+#: builtin/mv.c:117
 msgid "bad source"
 msgstr "felaktig källa"
 
-#: builtin/mv.c:115
+#: builtin/mv.c:120
 msgid "can not move directory into itself"
 msgstr "kan inte flytta katalog till sig själv"
 
-#: builtin/mv.c:118
+#: builtin/mv.c:123
 msgid "cannot move directory over file"
 msgstr "kan inte flytta katalog över fil"
 
-#: builtin/mv.c:128
+#: builtin/mv.c:129
+#, c-format
+msgid "Huh? Directory %s is in index and no submodule?"
+msgstr "Vad? Katalogen %s är i indexet och inte en undermodul?"
+
+#: builtin/mv.c:131 builtin/rm.c:318
+msgid "Please, stage your changes to .gitmodules or stash them to proceed"
+msgstr ""
+"Köa dina ändringar i .gitmodules eller använd \"stash\" för att fortsätta"
+
+#: builtin/mv.c:147
 #, c-format
 msgid "Huh? %.*s is in index?"
 msgstr "Vad? %.*s är i indexet?"
 
-#: builtin/mv.c:140
+#: builtin/mv.c:159
 msgid "source directory is empty"
 msgstr "källkatalogen är tom"
 
-#: builtin/mv.c:171
+#: builtin/mv.c:191
 msgid "not under version control"
 msgstr "inte versionshanterad"
 
-#: builtin/mv.c:173
+#: builtin/mv.c:193
 msgid "destination exists"
 msgstr "destinationen finns"
 
-#: builtin/mv.c:181
+#: builtin/mv.c:201
 #, c-format
 msgid "overwriting '%s'"
 msgstr "skriver över \"%s\""
 
-#: builtin/mv.c:184
+#: builtin/mv.c:204
 msgid "Cannot overwrite"
 msgstr "Kan inte skriva över"
 
-#: builtin/mv.c:187
+#: builtin/mv.c:207
 msgid "multiple sources for the same target"
 msgstr "flera källor för samma mål"
 
-#: builtin/mv.c:202
+#: builtin/mv.c:222
 #, c-format
 msgid "%s, source=%s, destination=%s"
 msgstr "%s, källa=%s, mål=%s"
 
-#: builtin/mv.c:212
+#: builtin/mv.c:232
 #, c-format
 msgid "Renaming %s to %s\n"
 msgstr "Byter namn på %s till %s\n"
 
-#: builtin/mv.c:215 builtin/remote.c:731
+#: builtin/mv.c:235 builtin/remote.c:731 builtin/repack.c:330
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "misslyckades byta namn på \"%s\""
@@ -6929,8 +7133,8 @@
 msgstr "läs från standard in"
 
 #: builtin/name-rev.c:320
-msgid "allow to print `undefined` names"
-msgstr "tillåt att skriva \"odefinierade\" namn"
+msgid "allow to print `undefined` names (default)"
+msgstr "tillåt att skriva \"odefinierade\" namn (standard)"
 
 #: builtin/name-rev.c:326
 msgid "dereference tags in the input (internal use)"
@@ -7085,12 +7289,12 @@
 msgid "The note contents has been left in %s"
 msgstr "Anteckningens innehåll har lämnats kvar i %s"
 
-#: builtin/notes.c:248 builtin/tag.c:540
+#: builtin/notes.c:248 builtin/tag.c:537
 #, c-format
 msgid "cannot read '%s'"
 msgstr "kunde inte läsa \"%s\""
 
-#: builtin/notes.c:250 builtin/tag.c:543
+#: builtin/notes.c:250 builtin/tag.c:540
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "kunde inte öppna eller läsa \"%s\""
@@ -7098,7 +7302,7 @@
 #: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318
 #: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515
 #: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637
-#: builtin/notes.c:839 builtin/tag.c:556
+#: builtin/notes.c:839 builtin/tag.c:553
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "Kunde inte slå upp \"%s\" som en giltig referens."
@@ -7271,148 +7475,148 @@
 msgid "git pack-objects [options...] base-name [< ref-list | < object-list]"
 msgstr "git pack-objects [flaggor...] basnamn [< reflista | < objektlista]"
 
-#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#: builtin/pack-objects.c:184 builtin/pack-objects.c:187
 #, c-format
 msgid "deflate error (%d)"
 msgstr "fel i deflate (%d)"
 
-#: builtin/pack-objects.c:2397
+#: builtin/pack-objects.c:2398
 #, c-format
 msgid "unsupported index version %s"
 msgstr "indexversionen %s stöds ej"
 
-#: builtin/pack-objects.c:2401
+#: builtin/pack-objects.c:2402
 #, c-format
 msgid "bad index version '%s'"
 msgstr "felaktig indexversion \"%s\""
 
-#: builtin/pack-objects.c:2424
+#: builtin/pack-objects.c:2425
 #, c-format
 msgid "option %s does not accept negative form"
 msgstr "flaggan %s godtar inte negativ form"
 
-#: builtin/pack-objects.c:2428
+#: builtin/pack-objects.c:2429
 #, c-format
 msgid "unable to parse value '%s' for option %s"
 msgstr "kunde inte tolka värdet \"%s\" för flaggan %s"
 
-#: builtin/pack-objects.c:2447
+#: builtin/pack-objects.c:2448
 msgid "do not show progress meter"
 msgstr "visa inte förloppsindikator"
 
-#: builtin/pack-objects.c:2449
+#: builtin/pack-objects.c:2450
 msgid "show progress meter"
 msgstr "visa förloppsindikator"
 
-#: builtin/pack-objects.c:2451
+#: builtin/pack-objects.c:2452
 msgid "show progress meter during object writing phase"
 msgstr "visa förloppsindikator under objektskrivningsfasen"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:2455
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "som --all-progress när förloppsmätaren visas"
 
-#: builtin/pack-objects.c:2455
+#: builtin/pack-objects.c:2456
 msgid "version[,offset]"
 msgstr "version[,offset]"
 
-#: builtin/pack-objects.c:2456
+#: builtin/pack-objects.c:2457
 msgid "write the pack index file in the specified idx format version"
 msgstr "skriv paketindexfilen i angiven indexformatversion"
 
-#: builtin/pack-objects.c:2459
+#: builtin/pack-objects.c:2460
 msgid "maximum size of each output pack file"
 msgstr "maximal storlek på varje utdatapaketfil"
 
-#: builtin/pack-objects.c:2461
+#: builtin/pack-objects.c:2462
 msgid "ignore borrowed objects from alternate object store"
 msgstr "ignorera lånade objekt från alternativa objektlager"
 
-#: builtin/pack-objects.c:2463
+#: builtin/pack-objects.c:2464
 msgid "ignore packed objects"
 msgstr "ignorera packade objekt"
 
-#: builtin/pack-objects.c:2465
+#: builtin/pack-objects.c:2466
 msgid "limit pack window by objects"
 msgstr "begränsa paketfönster efter objekt"
 
-#: builtin/pack-objects.c:2467
+#: builtin/pack-objects.c:2468
 msgid "limit pack window by memory in addition to object limit"
 msgstr "begränsa paketfönster efter minne förutom objektgräns"
 
-#: builtin/pack-objects.c:2469
+#: builtin/pack-objects.c:2470
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr "maximal längd på deltakedja tillåten i slutligt paket"
 
-#: builtin/pack-objects.c:2471
+#: builtin/pack-objects.c:2472
 msgid "reuse existing deltas"
 msgstr "återanvänd befintliga delta"
 
-#: builtin/pack-objects.c:2473
+#: builtin/pack-objects.c:2474
 msgid "reuse existing objects"
 msgstr "återanvänd befintliga objekt"
 
-#: builtin/pack-objects.c:2475
+#: builtin/pack-objects.c:2476
 msgid "use OFS_DELTA objects"
 msgstr "använd OFS_DELTA-objekt"
 
-#: builtin/pack-objects.c:2477
+#: builtin/pack-objects.c:2478
 msgid "use threads when searching for best delta matches"
 msgstr "använd trådar vid sökning efter bästa deltaträffar"
 
-#: builtin/pack-objects.c:2479
+#: builtin/pack-objects.c:2480
 msgid "do not create an empty pack output"
 msgstr "försök inte skapa tom paketutdata"
 
-#: builtin/pack-objects.c:2481
+#: builtin/pack-objects.c:2482
 msgid "read revision arguments from standard input"
 msgstr "läs revisionsargument från standard in"
 
-#: builtin/pack-objects.c:2483
+#: builtin/pack-objects.c:2484
 msgid "limit the objects to those that are not yet packed"
 msgstr "begränsa objekt till de som ännu inte packats"
 
-#: builtin/pack-objects.c:2486
+#: builtin/pack-objects.c:2487
 msgid "include objects reachable from any reference"
 msgstr "inkludera objekt som kan nås från någon referens"
 
-#: builtin/pack-objects.c:2489
+#: builtin/pack-objects.c:2490
 msgid "include objects referred by reflog entries"
 msgstr "inkludera objekt som refereras från referensloggposter"
 
-#: builtin/pack-objects.c:2492
+#: builtin/pack-objects.c:2493
 msgid "output pack to stdout"
 msgstr "skriv paket på standard ut"
 
-#: builtin/pack-objects.c:2494
+#: builtin/pack-objects.c:2495
 msgid "include tag objects that refer to objects to be packed"
 msgstr "inkludera taggobjekt som refererar objekt som skall packas"
 
-#: builtin/pack-objects.c:2496
+#: builtin/pack-objects.c:2497
 msgid "keep unreachable objects"
 msgstr "behåll onåbara objekt"
 
-#: builtin/pack-objects.c:2497 parse-options.h:141
+#: builtin/pack-objects.c:2498 parse-options.h:143
 msgid "time"
 msgstr "tid"
 
-#: builtin/pack-objects.c:2498
+#: builtin/pack-objects.c:2499
 msgid "unpack unreachable objects newer than <time>"
 msgstr "packa upp onåbara objekt nyare än <tid>"
 
-#: builtin/pack-objects.c:2501
+#: builtin/pack-objects.c:2502
 msgid "create thin packs"
 msgstr "skapa tunna paket"
 
-#: builtin/pack-objects.c:2503
+#: builtin/pack-objects.c:2504
 msgid "ignore packs that have companion .keep file"
 msgstr "ignorera paket som har tillhörande .keep-fil"
 
-#: builtin/pack-objects.c:2505
+#: builtin/pack-objects.c:2506
 msgid "pack compression level"
 msgstr "komprimeringsgrad för paket"
 
-#: builtin/pack-objects.c:2507
+#: builtin/pack-objects.c:2508
 msgid "do not hide commits by grafts"
 msgstr "göm inte incheckningar med ympningar (\"grafts\")"
 
@@ -7452,15 +7656,15 @@
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<flaggor>] [<arkiv> [<refspec>...]]"
 
-#: builtin/push.c:45
+#: builtin/push.c:47
 msgid "tag shorthand without <tag>"
 msgstr "taggförkortning utan <tagg>"
 
-#: builtin/push.c:64
+#: builtin/push.c:66
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete godtar endast enkla målreferensnamn"
 
-#: builtin/push.c:99
+#: builtin/push.c:101
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -7469,7 +7673,7 @@
 "För att välja ett av alternativen permanent, se push.default i \"git help "
 "config\"."
 
-#: builtin/push.c:102
+#: builtin/push.c:104
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -7494,7 +7698,7 @@
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:117
+#: builtin/push.c:119
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -7509,7 +7713,7 @@
 "\n"
 "    git push %s HEAD:<namn-på-fjärrgren>\n"
 
-#: builtin/push.c:131
+#: builtin/push.c:133
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -7522,12 +7726,12 @@
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:139
+#: builtin/push.c:141
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "Den aktuella grenen %s har flera uppströmsgrenar, vägrar sända."
 
-#: builtin/push.c:142
+#: builtin/push.c:144
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -7538,7 +7742,7 @@
 "aktuella grenen \"%s\", utan att tala om för mig vad som\n"
 "skall sändas för att uppdatera fjärrgrenen."
 
-#: builtin/push.c:165
+#: builtin/push.c:167
 msgid ""
 "push.default is unset; its implicit value is changing in\n"
 "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -7572,14 +7776,14 @@
 "liknande läget \"current\" istället för \"simple\" om du ibland använder\n"
 "äldre versioner av Git.)"
 
-#: builtin/push.c:225
+#: builtin/push.c:227
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "Du angav inga referensspecifikationer att sända, och push.default är "
 "\"nothing\"."
 
-#: builtin/push.c:232
+#: builtin/push.c:234
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -7591,7 +7795,7 @@
 "\"git pull ....\") innan du sänder igen.\n"
 "Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
 
-#: builtin/push.c:238
+#: builtin/push.c:240
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. If you did not intend to push that branch, you may want to\n"
@@ -7605,7 +7809,7 @@
 "endast\n"
 "sända aktuell gren."
 
-#: builtin/push.c:244
+#: builtin/push.c:246
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. Check out this branch and integrate the remote changes\n"
@@ -7617,7 +7821,7 @@
 "\"git pull ...\") innan du sänder igen.\n"
 "Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
 
-#: builtin/push.c:250
+#: builtin/push.c:252
 msgid ""
 "Updates were rejected because the remote contains work that you do\n"
 "not have locally. This is usually caused by another repository pushing\n"
@@ -7631,11 +7835,11 @@
 "(t.ex. \"git pull ...\") innan du sänder igen.\n"
 "Se avsnittet \"Note about fast-forwards\" i \"git push --help\" för detaljer."
 
-#: builtin/push.c:257
+#: builtin/push.c:259
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr "Uppdateringarna avvisades eftersom taggen redan finns på fjärren."
 
-#: builtin/push.c:260
+#: builtin/push.c:262
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -7646,22 +7850,22 @@
 "pekar på något som inte är en incheckning, utan att använda flaggan\n"
 "\"--force\".\n"
 
-#: builtin/push.c:320
+#: builtin/push.c:328
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Sänder till %s\n"
 
-#: builtin/push.c:324
+#: builtin/push.c:332
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "misslyckades sända vissa referenser till \"%s\""
 
-#: builtin/push.c:357
+#: builtin/push.c:365
 #, c-format
 msgid "bad repository '%s'"
 msgstr "felaktigt arkiv \"%s\""
 
-#: builtin/push.c:358
+#: builtin/push.c:366
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -7682,87 +7886,95 @@
 "\n"
 "    git push <namn>\n"
 
-#: builtin/push.c:373
+#: builtin/push.c:381
 msgid "--all and --tags are incompatible"
 msgstr "--all och --tags är inkompatibla"
 
-#: builtin/push.c:374
+#: builtin/push.c:382
 msgid "--all can't be combined with refspecs"
 msgstr "--all kan inte kombineras med referensspecifikationer"
 
-#: builtin/push.c:379
+#: builtin/push.c:387
 msgid "--mirror and --tags are incompatible"
 msgstr "--mirror och --tags är inkompatibla"
 
-#: builtin/push.c:380
+#: builtin/push.c:388
 msgid "--mirror can't be combined with refspecs"
 msgstr "--mirror kan inte kombineras med referensspecifikationer"
 
-#: builtin/push.c:385
+#: builtin/push.c:393
 msgid "--all and --mirror are incompatible"
 msgstr "--all och --mirror är inkompatibla"
 
-#: builtin/push.c:445
+#: builtin/push.c:453
 msgid "repository"
 msgstr "arkiv"
 
-#: builtin/push.c:446
+#: builtin/push.c:454
 msgid "push all refs"
 msgstr "sänd alla referenser"
 
-#: builtin/push.c:447
+#: builtin/push.c:455
 msgid "mirror all refs"
 msgstr "spegla alla referenser"
 
-#: builtin/push.c:449
+#: builtin/push.c:457
 msgid "delete refs"
 msgstr "ta bort referenser"
 
-#: builtin/push.c:450
+#: builtin/push.c:458
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "sänd taggar (kan inte användas med --all eller --mirror)"
 
-#: builtin/push.c:453
+#: builtin/push.c:461
 msgid "force updates"
 msgstr "tvinga uppdateringar"
 
-#: builtin/push.c:454
+#: builtin/push.c:463
+msgid "refname>:<expect"
+msgstr "refnamn>:<förvänta"
+
+#: builtin/push.c:464
+msgid "require old value of ref to be at this value"
+msgstr "kräv att ref:s tidigare värde är detta"
+
+#: builtin/push.c:466
 msgid "check"
 msgstr "kontrollera"
 
-#: builtin/push.c:455
+#: builtin/push.c:467
 msgid "control recursive pushing of submodules"
 msgstr "styr rekursiv insändning av undermoduler"
 
-#: builtin/push.c:457
+#: builtin/push.c:469
 msgid "use thin pack"
 msgstr "använd tunna paket"
 
-#: builtin/push.c:458 builtin/push.c:459
+#: builtin/push.c:470 builtin/push.c:471
 msgid "receive pack program"
 msgstr "program för att ta emot paket"
 
-#: builtin/push.c:460
+#: builtin/push.c:472
 msgid "set upstream for git pull/status"
 msgstr "ställ in uppström för git pull/status"
 
-#: builtin/push.c:463
+#: builtin/push.c:475
 msgid "prune locally removed refs"
 msgstr "ta bort lokalt borttagna referenser"
 
-#: builtin/push.c:465
+#: builtin/push.c:477
 msgid "bypass pre-push hook"
 msgstr "förbigå pre-push-krok"
 
-#: builtin/push.c:466
+#: builtin/push.c:478
 msgid "push missing but relevant tags"
 msgstr "sänd in saknade men relevanta taggar"
 
-#: builtin/push.c:476
+#: builtin/push.c:488
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete är imkompatibel med --all, --mirror och --tags"
 
-#: builtin/push.c:478
+#: builtin/push.c:490
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete kan inte användas utan referenser"
 
@@ -7840,12 +8052,12 @@
 msgid "debug unpack-trees"
 msgstr "felsök unpack-trees"
 
-#: builtin/reflog.c:500
+#: builtin/reflog.c:499
 #, c-format
 msgid "%s' for '%s' is not a valid timestamp"
 msgstr "\"%s\" för \"%s\" är inte en giltig tidsstämpel"
 
-#: builtin/reflog.c:616 builtin/reflog.c:621
+#: builtin/reflog.c:615 builtin/reflog.c:620
 #, c-format
 msgid "'%s' is not a valid timestamp"
 msgstr "\"%s\" är inte en giltig tidsstämpel"
@@ -7870,9 +8082,9 @@
 msgid "git remote remove <name>"
 msgstr "git remote remove <namn>"
 
-#: builtin/remote.c:15 builtin/remote.c:42
-msgid "git remote set-head <name> (-a | -d | <branch>)"
-msgstr "git remote set-head <namn> (-a | -d | <gren>)"
+#: builtin/remote.c:15
+msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"
+msgstr "git remote set-head <namn> (-a | --auto | -d | --delete | <gren>)"
 
 #: builtin/remote.c:16
 msgid "git remote [-v | --verbose] show [-n] <name>"
@@ -7908,6 +8120,10 @@
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<flaggor>] <namn> <url>"
 
+#: builtin/remote.c:42
+msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
+msgstr "git remote set-head <namn> (-a | --auto | -d | --delete | <gren>)"
+
 #: builtin/remote.c:47
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <namn> <gren>..."
@@ -8344,6 +8560,67 @@
 msgid "be verbose; must be placed before a subcommand"
 msgstr "var pratsam; måste skrivas före ett underkommando"
 
+#: builtin/repack.c:15
+msgid "git repack [options]"
+msgstr "git repack [flaggor]"
+
+#: builtin/repack.c:143
+msgid "pack everything in a single pack"
+msgstr "packa allt i ett enda paket"
+
+#: builtin/repack.c:145
+msgid "same as -a, and turn unreachable objects loose"
+msgstr "samma som -a, och gör onåbara objekt lösa"
+
+#: builtin/repack.c:148
+msgid "remove redundant packs, and run git-prune-packed"
+msgstr "ta bort överflödiga paket, och kör git-prune-packed"
+
+#: builtin/repack.c:150
+msgid "pass --no-reuse-delta to git-pack-objects"
+msgstr "sänd --no-reuse-delta till git-pack-objects"
+
+#: builtin/repack.c:152
+msgid "pass --no-reuse-object to git-pack-objects"
+msgstr "sänd --no-reuse-object till git-pack-objects"
+
+#: builtin/repack.c:154
+msgid "do not run git-update-server-info"
+msgstr "kör inte git-update-server-info"
+
+#: builtin/repack.c:157
+msgid "pass --local to git-pack-objects"
+msgstr "sänd --local till git-pack-objects"
+
+#: builtin/repack.c:158
+msgid "approxidate"
+msgstr "cirkadatum"
+
+#: builtin/repack.c:159
+msgid "with -A, do not loosen objects older than this"
+msgstr "med -A, lös inte upp objekt äldre än detta"
+
+#: builtin/repack.c:161
+msgid "size of the window used for delta compression"
+msgstr "storlek på fönster använt för deltakomprimering"
+
+#: builtin/repack.c:163
+msgid "same as the above, but limit memory size instead of entries count"
+msgstr "samma som ovan, men begränsa minnesstorleken istället för postantal"
+
+#: builtin/repack.c:165
+msgid "limits the maximum delta depth"
+msgstr "begränsa maximalt deltadjup"
+
+#: builtin/repack.c:167
+msgid "maximum size of each packfile"
+msgstr "maximal storlek på varje paketfil"
+
+#: builtin/repack.c:345
+#, c-format
+msgid "removing '%s' failed"
+msgstr "misslyckades ta bort \"%s\""
+
 #: builtin/replace.c:17
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <objekt> <ersättning>"
@@ -8356,23 +8633,23 @@
 msgid "git replace -l [<pattern>]"
 msgstr "git replace -l [<mönster>]"
 
-#: builtin/replace.c:121
+#: builtin/replace.c:131
 msgid "list replace refs"
 msgstr "visa ersättningsreferenser"
 
-#: builtin/replace.c:122
+#: builtin/replace.c:132
 msgid "delete replace refs"
 msgstr "ta bort ersättningsreferenser"
 
-#: builtin/replace.c:123
+#: builtin/replace.c:133
 msgid "replace the ref if it exists"
 msgstr "ersätt referensen om den finns"
 
-#: builtin/rerere.c:11
+#: builtin/rerere.c:12
 msgid "git rerere [clear | forget path... | status | remaining | diff | gc]"
 msgstr "git rerere [clear | forget path... | status | remaining | diff | gc]"
 
-#: builtin/rerere.c:56
+#: builtin/rerere.c:57
 msgid "register clean resolutions in index"
 msgstr "registrera rena lösningar i indexet"
 
@@ -8433,70 +8710,70 @@
 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:251
+#: builtin/reset.c:262
 msgid "be quiet, only report errors"
 msgstr "var tyst, rapportera endast fel"
 
-#: builtin/reset.c:253
+#: builtin/reset.c:264
 msgid "reset HEAD and index"
 msgstr "återställ HEAD och index"
 
-#: builtin/reset.c:254
+#: builtin/reset.c:265
 msgid "reset only HEAD"
 msgstr "återställ endast HEAD"
 
-#: builtin/reset.c:256 builtin/reset.c:258
+#: builtin/reset.c:267 builtin/reset.c:269
 msgid "reset HEAD, index and working tree"
 msgstr "återställ HEAD, index och arbetskatalog"
 
-#: builtin/reset.c:260
+#: builtin/reset.c:271
 msgid "reset HEAD but keep local changes"
 msgstr "återställ HEAD men behåll lokala ändringar"
 
-#: builtin/reset.c:278
+#: builtin/reset.c:289
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
 msgstr "Kunde inte slå upp \"%s\" som en giltig revision."
 
-#: builtin/reset.c:281 builtin/reset.c:289
+#: builtin/reset.c:292 builtin/reset.c:300
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "Kan inte tolka objektet \"%s\""
 
-#: builtin/reset.c:286
+#: builtin/reset.c:297
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
 msgstr "Kunde inte slå upp \"%s\" som ett giltigt träd."
 
-#: builtin/reset.c:295
+#: builtin/reset.c:306
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch är inkompatibel med --{hard,mixed,soft}"
 
-#: builtin/reset.c:304
+#: builtin/reset.c:315
 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:306
+#: builtin/reset.c:317
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "Kan inte göra %s återställning med sökvägar."
 
-#: builtin/reset.c:316
+#: builtin/reset.c:327
 #, 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:336
+#: builtin/reset.c:344
+msgid "Unstaged changes after reset:"
+msgstr "Oköade ändringar efter återställning:"
+
+#: builtin/reset.c:350
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "Kunde inte återställa indexfilen till versionen \"%s\"."
 
-#: builtin/reset.c:342
-msgid "Unstaged changes after reset:"
-msgstr "Oköade ändringar efter återställning:"
-
-#: builtin/reset.c:347
+#: builtin/reset.c:355
 msgid "Could not write new index file."
 msgstr "Kunde inte skriva ny indexfil."
 
@@ -8543,84 +8820,84 @@
 msgid "git cherry-pick <subcommand>"
 msgstr "git cherry-pick <underkommando>"
 
-#: builtin/revert.c:71 builtin/revert.c:94
+#: builtin/revert.c:71
 #, c-format
 msgid "%s: %s cannot be used with %s"
 msgstr "%s: %s kan inte användas med %s"
 
-#: builtin/revert.c:105
+#: builtin/revert.c:80
 msgid "end revert or cherry-pick sequence"
 msgstr "avsluta revert- eller cherry-pick-sekvens"
 
-#: builtin/revert.c:106
+#: builtin/revert.c:81
 msgid "resume revert or cherry-pick sequence"
 msgstr "återuppta revert- eller cherry-pick-sekvens"
 
-#: builtin/revert.c:107
+#: builtin/revert.c:82
 msgid "cancel revert or cherry-pick sequence"
 msgstr "avbryt revert- eller cherry-pick-sekvens"
 
-#: builtin/revert.c:108
+#: builtin/revert.c:83
 msgid "don't automatically commit"
 msgstr "checka inte in automatiskt"
 
-#: builtin/revert.c:109
+#: builtin/revert.c:84
 msgid "edit the commit message"
 msgstr "redigera incheckningsmeddelandet"
 
-#: builtin/revert.c:112
+#: builtin/revert.c:87
 msgid "parent number"
 msgstr "nummer på förälder"
 
-#: builtin/revert.c:114
+#: builtin/revert.c:89
 msgid "merge strategy"
 msgstr "sammanslagninsstrategi"
 
-#: builtin/revert.c:115
+#: builtin/revert.c:90
 msgid "option"
 msgstr "alternativ"
 
-#: builtin/revert.c:116
+#: builtin/revert.c:91
 msgid "option for merge strategy"
 msgstr "alternativ för sammanslagningsstrategi"
 
-#: builtin/revert.c:127
+#: builtin/revert.c:102
 msgid "append commit name"
 msgstr "lägg till incheckningsnamn"
 
-#: builtin/revert.c:128
+#: builtin/revert.c:103
 msgid "allow fast-forward"
 msgstr "tillåt snabbspolning"
 
-#: builtin/revert.c:129
+#: builtin/revert.c:104
 msgid "preserve initially empty commits"
 msgstr "behåll incheckningar som börjar som tomma"
 
-#: builtin/revert.c:130
+#: builtin/revert.c:105
 msgid "allow commits with empty messages"
 msgstr "tillåt incheckningar med tomt meddelande"
 
-#: builtin/revert.c:131
+#: builtin/revert.c:106
 msgid "keep redundant, empty commits"
 msgstr "behåll redundanta, tomma incheckningar"
 
-#: builtin/revert.c:135
+#: builtin/revert.c:110
 msgid "program error"
 msgstr "programfel"
 
-#: builtin/revert.c:225
+#: builtin/revert.c:195
 msgid "revert failed"
 msgstr "\"revert\" misslyckades"
 
-#: builtin/revert.c:240
+#: builtin/revert.c:210
 msgid "cherry-pick failed"
 msgstr "\"cherry-pick\" misslyckades"
 
-#: builtin/rm.c:16
+#: builtin/rm.c:17
 msgid "git rm [options] [--] <file>..."
 msgstr "git rm [flaggor] [--] <fil>..."
 
-#: builtin/rm.c:64
+#: builtin/rm.c:65
 msgid ""
 "the following submodule (or one of its nested submodules)\n"
 "uses a .git directory:"
@@ -8634,7 +8911,7 @@
 "följande undermoduler (eller en av deras nästlade undermoduler)\n"
 "använder en .git-katalog:"
 
-#: builtin/rm.c:70
+#: builtin/rm.c:71
 msgid ""
 "\n"
 "(use 'rm -rf' if you really want to remove it including all of its history)"
@@ -8642,7 +8919,7 @@
 "\n"
 "(använd \"rm -rf\" om du verkligen vill ta bort den och all dess historik)"
 
-#: builtin/rm.c:230
+#: builtin/rm.c:231
 msgid ""
 "the following file has staged content different from both the\n"
 "file and the HEAD:"
@@ -8654,7 +8931,7 @@
 msgstr[1] ""
 "följande filer har köat innehåll som skiljer sig både från filen och HEAD:"
 
-#: builtin/rm.c:235
+#: builtin/rm.c:236
 msgid ""
 "\n"
 "(use -f to force removal)"
@@ -8662,13 +8939,13 @@
 "\n"
 "(använd -f för att tvinga borttagning)"
 
-#: builtin/rm.c:239
+#: builtin/rm.c:240
 msgid "the following file has changes staged in the index:"
 msgid_plural "the following files have changes staged in the index:"
 msgstr[0] "följande fil har ändringar köade i indexet:"
 msgstr[1] "följande filer har ändringar köade i indexet:"
 
-#: builtin/rm.c:243 builtin/rm.c:254
+#: builtin/rm.c:244 builtin/rm.c:255
 msgid ""
 "\n"
 "(use --cached to keep the file, or -f to force removal)"
@@ -8676,38 +8953,38 @@
 "\n"
 "(använd --cached för att behålla filen eller -f för att tvinga borttagning)"
 
-#: builtin/rm.c:251
+#: builtin/rm.c:252
 msgid "the following file has local modifications:"
 msgid_plural "the following files have local modifications:"
 msgstr[0] "följande fil har lokala ändringar:"
 msgstr[1] "följande filer har lokala ändringar:"
 
-#: builtin/rm.c:269
+#: builtin/rm.c:270
 msgid "do not list removed files"
 msgstr "lista inte borttagna filer"
 
-#: builtin/rm.c:270
+#: builtin/rm.c:271
 msgid "only remove from the index"
 msgstr "ta bara bort från indexet"
 
-#: builtin/rm.c:271
+#: builtin/rm.c:272
 msgid "override the up-to-date check"
 msgstr "överstyr àjour-testet"
 
-#: builtin/rm.c:272
+#: builtin/rm.c:273
 msgid "allow recursive removal"
 msgstr "tillåt rekursiv borttagning"
 
-#: builtin/rm.c:274
+#: builtin/rm.c:275
 msgid "exit with a zero status even if nothing matched"
 msgstr "avsluta med nollstatus även om inget träffades"
 
-#: builtin/rm.c:345
+#: builtin/rm.c:336
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "tar inte bort \"%s\" rekursivt utan -r"
 
-#: builtin/rm.c:384
+#: builtin/rm.c:375
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: kan inte ta bort %s"
@@ -8721,23 +8998,23 @@
 msgid "Missing author: %s"
 msgstr "Författare saknas: %s"
 
-#: builtin/shortlog.c:228
+#: builtin/shortlog.c:230
 msgid "sort output according to the number of commits per author"
 msgstr "sortera utdata enligt antal incheckningar per författare"
 
-#: builtin/shortlog.c:230
+#: builtin/shortlog.c:232
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "Undertryck beskrivningar, visa bara antal incheckningar"
 
-#: builtin/shortlog.c:232
+#: builtin/shortlog.c:234
 msgid "Show the email address of each author"
 msgstr "Visa e-postadress för varje författare"
 
-#: builtin/shortlog.c:233
+#: builtin/shortlog.c:235
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:234
+#: builtin/shortlog.c:236
 msgid "Linewrap output"
 msgstr "Radbryt utdata"
 
@@ -8845,23 +9122,23 @@
 msgid "stricter reference checking, requires exact ref path"
 msgstr "striktare referenskontroll, kräver exakt referenssökväg"
 
-#: builtin/show-ref.c:173 builtin/show-ref.c:176
+#: builtin/show-ref.c:173 builtin/show-ref.c:175
 msgid "show the HEAD reference, even if it would be filtered out"
 msgstr "visa HEAD-refrens, även när den skulle filtreras ut"
 
-#: builtin/show-ref.c:178
+#: builtin/show-ref.c:177
 msgid "dereference tags into object IDs"
 msgstr "avreferera taggar till objekt-id"
 
-#: builtin/show-ref.c:180
+#: builtin/show-ref.c:179
 msgid "only show SHA1 hash using <n> digits"
 msgstr "visa SHA1-hash endast med <n> siffror"
 
-#: builtin/show-ref.c:184
+#: builtin/show-ref.c:183
 msgid "do not print results to stdout (useful with --verify)"
 msgstr "visa inte resultat på standard ut (användbart med --verify)"
 
-#: builtin/show-ref.c:186
+#: builtin/show-ref.c:185
 msgid "show refs from stdin that aren't in local repository"
 msgstr "visa referenser från standard in som inte finns i lokalt arkiv"
 
@@ -8886,11 +9163,11 @@
 msgid "shorten ref output"
 msgstr "förkorta ref-utdata"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason"
 msgstr "skäl"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason of the update"
 msgstr "skäl till uppdateringen"
 
@@ -9055,183 +9332,195 @@
 msgid "print only tags of the object"
 msgstr "visa endast taggar för objektet"
 
-#: builtin/tag.c:504
+#: builtin/tag.c:501
 msgid "--column and -n are incompatible"
 msgstr "--column och -n är inkompatibla"
 
-#: builtin/tag.c:521
+#: builtin/tag.c:518
 msgid "-n option is only allowed with -l."
 msgstr "Flaggan -n är endast tillåten tillsammans med -l."
 
-#: builtin/tag.c:523
+#: builtin/tag.c:520
 msgid "--contains option is only allowed with -l."
 msgstr "Flaggan --contains är endast tillåten tillsammans med -l"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:522
 msgid "--points-at option is only allowed with -l."
 msgstr "Flaggan --points-at är endast tillåten tillsammans med -l."
 
-#: builtin/tag.c:533
+#: builtin/tag.c:530
 msgid "only one -F or -m option is allowed."
 msgstr "endast en av flaggorna -F eller -m tillåts."
 
-#: builtin/tag.c:553
+#: builtin/tag.c:550
 msgid "too many params"
 msgstr "för många parametrar"
 
-#: builtin/tag.c:559
+#: builtin/tag.c:556
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "\"%s\" är inte ett giltigt taggnamn."
 
-#: builtin/tag.c:564
+#: builtin/tag.c:561
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "taggen \"%s\" finns redan"
 
-#: builtin/tag.c:582
+#: builtin/tag.c:579
 #, c-format
 msgid "%s: cannot lock the ref"
 msgstr "%s: kan inte låsa referensen"
 
-#: builtin/tag.c:584
+#: builtin/tag.c:581
 #, c-format
 msgid "%s: cannot update the ref"
 msgstr "%s: kan inte uppdatera referensen"
 
-#: builtin/tag.c:586
+#: builtin/tag.c:583
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Uppdaterad tagg \"%s\" (var %s)\n"
 
-#: builtin/update-index.c:401
+#: builtin/update-index.c:402
 msgid "git update-index [options] [--] [<file>...]"
 msgstr "git update-index [flaggor] [--] [<fil>...]"
 
-#: builtin/update-index.c:718
+#: builtin/update-index.c:720
 msgid "continue refresh even when index needs update"
 msgstr "fortsätt uppdatera även när index inte är àjour"
 
-#: builtin/update-index.c:721
+#: builtin/update-index.c:723
 msgid "refresh: ignore submodules"
 msgstr "refresh: ignorera undermoduler"
 
-#: builtin/update-index.c:724
+#: builtin/update-index.c:726
 msgid "do not ignore new files"
 msgstr "ignorera inte nya filer"
 
-#: builtin/update-index.c:726
+#: builtin/update-index.c:728
 msgid "let files replace directories and vice-versa"
 msgstr "låt filer ersätta kataloger och omvänt"
 
-#: builtin/update-index.c:728
+#: builtin/update-index.c:730
 msgid "notice files missing from worktree"
 msgstr "lägg märke till filer som saknas i arbetskatalogen"
 
-#: builtin/update-index.c:730
+#: builtin/update-index.c:732
 msgid "refresh even if index contains unmerged entries"
 msgstr "uppdatera även om indexet innehåller ej sammanslagna poster"
 
-#: builtin/update-index.c:733
+#: builtin/update-index.c:735
 msgid "refresh stat information"
 msgstr "uppdatera statusinformation"
 
-#: builtin/update-index.c:737
+#: builtin/update-index.c:739
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "som --refresh, men ignorera assume-unchanged-inställning"
 
-#: builtin/update-index.c:741
+#: builtin/update-index.c:743
 msgid "<mode> <object> <path>"
 msgstr "<läge> <objekt> <sökväg>"
 
-#: builtin/update-index.c:742
+#: builtin/update-index.c:744
 msgid "add the specified entry to the index"
 msgstr "lägg till angiven post i indexet"
 
-#: builtin/update-index.c:746
+#: builtin/update-index.c:748
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/update-index.c:747
+#: builtin/update-index.c:749
 msgid "override the executable bit of the listed files"
 msgstr "överstyr exekveringsbiten för angivna filer"
 
-#: builtin/update-index.c:751
+#: builtin/update-index.c:753
 msgid "mark files as \"not changing\""
 msgstr "markera filer som \"ändras inte\""
 
-#: builtin/update-index.c:754
+#: builtin/update-index.c:756
 msgid "clear assumed-unchanged bit"
 msgstr "rensa \"assume-unchanged\"-biten"
 
-#: builtin/update-index.c:757
+#: builtin/update-index.c:759
 msgid "mark files as \"index-only\""
 msgstr "markera filer som \"endast index\""
 
-#: builtin/update-index.c:760
+#: builtin/update-index.c:762
 msgid "clear skip-worktree bit"
 msgstr "töm \"skip-worktree\"-biten"
 
-#: builtin/update-index.c:763
+#: builtin/update-index.c:765
 msgid "add to index only; do not add content to object database"
 msgstr "lägg endast till indexet; lägg inte till innehållet i objektdatabasen"
 
-#: builtin/update-index.c:765
+#: builtin/update-index.c:767
 msgid "remove named paths even if present in worktree"
 msgstr "ta bort namngivna sökvägar även om de finns i arbetskatalogen"
 
-#: builtin/update-index.c:767
+#: builtin/update-index.c:769
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "med --stdin: indatarader termineras med null-byte"
 
-#: builtin/update-index.c:769
+#: builtin/update-index.c:771
 msgid "read list of paths to be updated from standard input"
 msgstr "läs lista över sökvägar att uppdatera från standard in"
 
-#: builtin/update-index.c:773
+#: builtin/update-index.c:775
 msgid "add entries from standard input to the index"
 msgstr "lägg poster från från standard in till indexet"
 
-#: builtin/update-index.c:777
+#: builtin/update-index.c:779
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "återfyll etapp 2 och 3 från angivna sökvägar"
 
-#: builtin/update-index.c:781
+#: builtin/update-index.c:783
 msgid "only update entries that differ from HEAD"
 msgstr "uppdatera endast poster som skiljer sig från HEAD"
 
-#: builtin/update-index.c:785
+#: builtin/update-index.c:787
 msgid "ignore files missing from worktree"
 msgstr "ignorera filer som saknas i arbetskatalogen"
 
-#: builtin/update-index.c:788
+#: builtin/update-index.c:790
 msgid "report actions to standard output"
 msgstr "raportera åtgärder på standard ut"
 
-#: builtin/update-index.c:790
+#: builtin/update-index.c:792
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(för porslin) glöm sparade olösta konflikter"
 
-#: builtin/update-index.c:794
+#: builtin/update-index.c:796
 msgid "write index in this format"
 msgstr "skriv index i detta format"
 
-#: builtin/update-ref.c:7
+#: builtin/update-ref.c:9
 msgid "git update-ref [options] -d <refname> [<oldval>]"
 msgstr "git update-ref [flaggor] -d <refnamn> [<gammaltvärde>]"
 
-#: builtin/update-ref.c:8
+#: builtin/update-ref.c:10
 msgid "git update-ref [options]    <refname> <newval> [<oldval>]"
 msgstr "git update-ref [flaggor]    <refnamn> <gammaltvärde> [<nyttvärde>]"
 
-#: builtin/update-ref.c:19
+#: builtin/update-ref.c:11
+msgid "git update-ref [options] --stdin [-z]"
+msgstr "git update-ref [flaggor] --stdin [-z]"
+
+#: builtin/update-ref.c:255
 msgid "delete the reference"
 msgstr "ta bort referensen"
 
-#: builtin/update-ref.c:21
+#: builtin/update-ref.c:257
 msgid "update <refname> not the one it points to"
 msgstr "uppdatera <refnamn> inte det den pekar på"
 
+#: builtin/update-ref.c:258
+msgid "stdin has NUL-terminated arguments"
+msgstr "standard in har NUL-terminerade argument"
+
+#: builtin/update-ref.c:259
+msgid "read updates from stdin"
+msgstr "läs uppdateringar från standard in"
+
 #: builtin/update-server-info.c:6
 msgid "git update-server-info [--force]"
 msgstr "git update-server-info [--force]"
@@ -9286,23 +9575,23 @@
 "några konceptvägledningar. Se \"git help <kommando>\" eller \"git help\n"
 "<koncept>\" för att läsa mer om specifika underkommandon och koncept."
 
-#: parse-options.h:144
+#: parse-options.h:146
 msgid "expiry date"
 msgstr "giltig till"
 
-#: parse-options.h:159
+#: parse-options.h:161
 msgid "no-op (backward compatibility)"
 msgstr "ingen funktion (bakåtkompatibilitet)"
 
-#: parse-options.h:236
+#: parse-options.h:238
 msgid "be more verbose"
 msgstr "var mer pratsam"
 
-#: parse-options.h:238
+#: parse-options.h:240
 msgid "be more quiet"
 msgstr "var mer tyst"
 
-#: parse-options.h:244
+#: parse-options.h:246
 msgid "use <n> digits to display SHA-1s"
 msgstr "använd <n> siffror för att visa SHA-1:or"
 
@@ -9438,7 +9727,7 @@
 #: git-am.sh:163
 msgid "Falling back to patching base and 3-way merge..."
 msgstr ""
-"Faller tillbaka på att pacha grundversionen och trevägssammanslagning..."
+"Faller tillbaka på att patcha grundversionen och trevägssammanslagning..."
 
 #: git-am.sh:179
 msgid "Failed to merge in the changes."
@@ -9740,7 +10029,7 @@
 msgid "Pull is not possible because you have unmerged files."
 msgstr "Du kan inte göra en \"pull\" då du har ändringar som inte checkats in."
 
-#: git-pull.sh:203
+#: git-pull.sh:223
 msgid "updating an unborn branch with changes added to the index"
 msgstr "uppdaterar en ofödd gren med ändringar som lagts till i indexet"
 
@@ -9748,7 +10037,7 @@
 #. The working tree and the index file is still based on the
 #. $orig_head commit, but we are merging into $curr_head.
 #. First update the working tree to match $curr_head.
-#: git-pull.sh:235
+#: git-pull.sh:255
 #, sh-format
 msgid ""
 "Warning: fetch updated the current branch head.\n"
@@ -9759,11 +10048,11 @@
 "Varning: snabbspolar din arbetskatalog från\n"
 "Varning: incheckningen $orig_head."
 
-#: git-pull.sh:260
+#: git-pull.sh:280
 msgid "Cannot merge multiple branches into empty head"
 msgstr "Kan inte slå ihop flera grenar i ett tomt huvud."
 
-#: git-pull.sh:264
+#: git-pull.sh:284
 msgid "Cannot rebase onto multiple branches"
 msgstr "Kan inte utföra en \"rebase\" ovanpå flera grenar"
 
@@ -9797,31 +10086,31 @@
 "Dina ändringar är säkra i stashen.\n"
 "Du kan när som helst använda \"git stash pop\" eller \"git stash drop\".\n"
 
-#: git-rebase.sh:190
+#: git-rebase.sh:199
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Kroken pre-rebase vägrade ombaseringen."
 
-#: git-rebase.sh:195
+#: git-rebase.sh:204
 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:329
+#: git-rebase.sh:338
 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:334
+#: git-rebase.sh:343
 msgid "No rebase in progress?"
 msgstr "Ingen ombasering pågår?"
 
-#: git-rebase.sh:345
+#: git-rebase.sh:354
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "Åtgärden --edit-todo kan endast användas under interaktiv ombasering."
 
-#: git-rebase.sh:352
+#: git-rebase.sh:361
 msgid "Cannot read HEAD"
 msgstr "Kan inte läsa HEAD"
 
-#: git-rebase.sh:355
+#: git-rebase.sh:364
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -9829,12 +10118,12 @@
 "Du måste redigera alla sammanslagningskonflikter och\n"
 "därefter markera dem som lösta med git add"
 
-#: git-rebase.sh:373
+#: git-rebase.sh:382
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Kunde inte flytta tillbaka till $head_name"
 
-#: git-rebase.sh:392
+#: git-rebase.sh:401
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -9855,66 +10144,66 @@
 "och kör programmet igen. Jag avslutar ifall du fortfarande har\n"
 "något av värde där."
 
-#: git-rebase.sh:437
+#: git-rebase.sh:446
 #, sh-format
 msgid "invalid upstream $upstream_name"
 msgstr "ogiltig uppström $upstream_name"
 
-#: git-rebase.sh:461
+#: git-rebase.sh:470
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: mer än en sammanslagningsbas finns"
 
-#: git-rebase.sh:464 git-rebase.sh:468
+#: git-rebase.sh:473 git-rebase.sh:477
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: ingen sammanslagningsbas finns"
 
-#: git-rebase.sh:473
+#: git-rebase.sh:482
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "Peka på en giltig incheckning: $onto_name"
 
-#: git-rebase.sh:496
+#: git-rebase.sh:505
 #, sh-format
 msgid "fatal: no such branch: $branch_name"
 msgstr "ödesdigert: ingen sådan gren: $branch_name"
 
-#: git-rebase.sh:519
+#: git-rebase.sh:528
 msgid "Cannot autostash"
 msgstr "Kan inte utföra \"autostash\""
 
-#: git-rebase.sh:524
+#: git-rebase.sh:533
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "Skapade autostash: $stash_abbrev"
 
-#: git-rebase.sh:528
+#: git-rebase.sh:537
 msgid "Please commit or stash them."
 msgstr "Checka in eller använd \"stash\" på dem."
 
-#: git-rebase.sh:548
+#: git-rebase.sh:557
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "Aktuell gren $branch_name är à jour."
 
-#: git-rebase.sh:552
+#: git-rebase.sh:561
 #, 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:563
+#: git-rebase.sh:572
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Ändringar från $mb till $onto:"
 
 #. Detach HEAD and reset the tree
-#: git-rebase.sh:572
+#: git-rebase.sh:581
 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:582
+#: git-rebase.sh:591
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "Snabbspolade $branch_name till $onto_name."
@@ -9962,7 +10251,7 @@
 #. $ git stash save --blah-blah 2>&1 | head -n 2
 #. error: unknown option for 'stash save': --blah-blah
 #. To provide a message, use git stash save -- '--blah-blah'
-#: git-stash.sh:241
+#: git-stash.sh:237
 #, sh-format
 msgid ""
 "error: unknown option for 'stash save': $option\n"
@@ -9971,100 +10260,85 @@
 "fel: felaktig flagga för \"stash save\": $option\n"
 "     För att ange ett meddelande, använd git stash save -- \"$option\""
 
-#: git-stash.sh:262
+#: git-stash.sh:258
 msgid "No local changes to save"
 msgstr "Inga lokala ändringar att spara"
 
-#: git-stash.sh:268
-msgid ""
-"The following untracked files would NOT be saved but need to be removed by "
-"stash save:"
-msgstr ""
-"Följande ospårade ändringar skulle INTE sparas utan måste tas bort med "
-"\"stash save\":"
-
-#: git-stash.sh:270
-msgid ""
-"Aborting. Consider using either the --force or --include-untracked option."
-msgstr ""
-"Avbryter. Överväg att använda antingen flaggan --force eller --include-"
-"untracked."
-
-#: git-stash.sh:274
+#: git-stash.sh:262
 msgid "Cannot initialize stash"
 msgstr "Kan inte initiera \"stash\""
 
-#: git-stash.sh:278
+#: git-stash.sh:266
 msgid "Cannot save the current status"
 msgstr "Kan inte spara aktuell status"
 
-#: git-stash.sh:296
+#: git-stash.sh:284
 msgid "Cannot remove worktree changes"
 msgstr "Kan inte ta bort ändringar i arbetskatalogen"
 
-#: git-stash.sh:395
+#: git-stash.sh:383
 msgid "No stash found."
 msgstr "Ingen \"stash\" hittades."
 
-#: git-stash.sh:402
+#: git-stash.sh:390
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "För många revisioner angivna: $REV"
 
-#: git-stash.sh:408
+#: git-stash.sh:396
 #, sh-format
 msgid "$reference is not valid reference"
 msgstr "$reference är inte en giltig referens."
 
-#: git-stash.sh:436
+#: git-stash.sh:424
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "\"$args\" är inte en \"stash\"-liknande incheckning"
 
-#: git-stash.sh:447
+#: git-stash.sh:435
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "\"$args\" är inte en \"stash\"-referens"
 
-#: git-stash.sh:455
+#: git-stash.sh:443
 msgid "unable to refresh index"
 msgstr "kan inte uppdatera indexet"
 
-#: git-stash.sh:459
+#: git-stash.sh:447
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "Kan inte tillämpa en \"stash\" mitt i en sammanslagning"
 
-#: git-stash.sh:467
+#: git-stash.sh:455
 msgid "Conflicts in index. Try without --index."
 msgstr "Konflikter i indexet. Testa utan --index."
 
-#: git-stash.sh:469
+#: git-stash.sh:457
 msgid "Could not save index tree"
 msgstr "Kunde inte spara indexträd"
 
-#: git-stash.sh:503
+#: git-stash.sh:491
 msgid "Cannot unstage modified files"
 msgstr "Kan inte ta bort ändrade filer ur kön"
 
-#: git-stash.sh:518
+#: git-stash.sh:506
 msgid "Index was not unstashed."
 msgstr "Indexet har inte tagits ur kön."
 
-#: git-stash.sh:535
+#: git-stash.sh:523
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "Kastade ${REV} ($s)"
 
-#: git-stash.sh:536
+#: git-stash.sh:524
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: Kunde inte kasta \"stash\"-post"
 
-#: git-stash.sh:543
+#: git-stash.sh:531
 msgid "No branch name specified"
 msgstr "Inget grennamn angavs"
 
-#: git-stash.sh:615
+#: git-stash.sh:603
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(För att återställa dem, skriv \"git stash apply\")"
 
@@ -10333,50 +10607,61 @@
 msgstr "Flaggan --cached kan inte användas med flaggan --files"
 
 #. unexpected type
-#: git-submodule.sh:1066
+#: git-submodule.sh:1073
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "oväntat läge $mod_dst"
 
-#: git-submodule.sh:1086
+#: git-submodule.sh:1093
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  Varning: $display_name innehåller inte incheckningen $sha1_src"
 
-#: git-submodule.sh:1089
+#: git-submodule.sh:1096
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  Varning: $display_name innehåller inte incheckningen $sha1_dst"
 
-#: git-submodule.sh:1092
+#: git-submodule.sh:1099
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
 "  Varning: $display_name innehåller inte incheckningarna $sha1_src och "
 "$sha1_dst"
 
-#: git-submodule.sh:1117
+#: git-submodule.sh:1124
 msgid "blob"
 msgstr "blob"
 
-#: git-submodule.sh:1155
-msgid "Submodules changed but not updated:"
-msgstr "Undermoduler ändrade men inte uppdaterade:"
-
-#: git-submodule.sh:1157
-msgid "Submodule changes to be committed:"
-msgstr "Undermodulers ändringar att checka in:"
-
-#: git-submodule.sh:1242
+#: git-submodule.sh:1238
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "Misslyckades rekursera in i undermodulsökvägen \"$sm_path\""
 
-#: git-submodule.sh:1306
+#: git-submodule.sh:1302
 #, sh-format
 msgid "Synchronizing submodule url for '$displaypath'"
 msgstr "Synkroniserar undermodul-url för \"$displaypath\""
 
+#~ msgid "input paths are terminated by a null character"
+#~ msgstr "sökvägar avdelas med null-tecken"
+
+#~ msgid "done\n"
+#~ msgstr "klart\n"
+
+#~ msgid ""
+#~ "The following untracked files would NOT be saved but need to be removed "
+#~ "by stash save:"
+#~ msgstr ""
+#~ "Följande ospårade ändringar skulle INTE sparas utan måste tas bort med "
+#~ "\"stash save\":"
+
+#~ msgid ""
+#~ "Aborting. Consider using either the --force or --include-untracked option."
+#~ msgstr ""
+#~ "Avbryter. Överväg att använda antingen flaggan --force eller --include-"
+#~ "untracked."
+
 #~ msgid "  (fix conflicts and then run \"git am --resolved\")"
 #~ msgstr "  (rätta konflikter och kör sedan \"git am --resolved\")"
 
@@ -10498,9 +10783,6 @@
 #~ msgid "-B cannot be used with -b"
 #~ msgstr "-B kan inte användas med -b"
 
-#~ msgid "--patch is incompatible with all other options"
-#~ msgstr "--patch är inkompatibel med alla andra flaggor"
-
 #~ msgid "--detach cannot be used with -b/-B/--orphan"
 #~ msgstr "--detcah kan inte användas med -b/-B/--orphan"
 
diff --git a/po/vi.po b/po/vi.po
index dd2d2a7..05420eb 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -1,14 +1,15 @@
 # Vietnamese translation for GIT-CORE.
+# Bản dịch tiếng Việt dành cho GIT-CORE.
 # This file is distributed under the same license as the git-core package.
 # First translated by Trần Ngọc Quân <vnwildman@gmail.com>, 2012-2013.
 # Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2012.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git-v1.8.4-rc1-22-gb8ecf23\n"
+"Project-Id-Version: git-v1.8.5-rc0-24-g727b957\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2013-08-06 14:10+0800\n"
-"PO-Revision-Date: 2013-08-06 14:28+0700\n"
+"POT-Creation-Date: 2013-11-02 08:06+0800\n"
+"PO-Revision-Date: 2013-11-02 13:15+0700\n"
 "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
 "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
 "Language: vi\n"
@@ -24,7 +25,7 @@
 #: advice.c:57
 #, c-format
 msgid "hint: %.*s\n"
-msgstr "gợi ý: %.*s\n"
+msgstr "tìm thấy: %.*s\n"
 
 #.
 #. * Message used both when 'git commit' fails and when
@@ -61,71 +62,76 @@
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <kho> [--exec <lệnh>] --list"
 
-#: archive.c:323
+#: archive.c:242 builtin/add.c:240 builtin/add.c:556 builtin/rm.c:328
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr "đặc tả đường dẫn “%s” không khớp với bất kỳ tập tin nào"
+
+#: archive.c:327
 msgid "fmt"
 msgstr "fmt"
 
-#: archive.c:323
+#: archive.c:327
 msgid "archive format"
 msgstr "định dạng lưu trữ"
 
-#: archive.c:324 builtin/log.c:1173
+#: archive.c:328 builtin/log.c:1193
 msgid "prefix"
 msgstr "tiền tố"
 
-#: archive.c:325
+#: archive.c:329
 msgid "prepend prefix to each pathname in the archive"
 msgstr "nối thêm tiền tố vào từng đường dẫn tập tin trong kho lưu"
 
-#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2292
-#: builtin/blame.c:2293 builtin/config.c:56 builtin/fast-export.c:673
-#: builtin/fast-export.c:675 builtin/grep.c:714 builtin/hash-object.c:77
-#: builtin/ls-files.c:496 builtin/ls-files.c:499 builtin/notes.c:408
-#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:152
+#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2264
+#: builtin/blame.c:2265 builtin/config.c:58 builtin/fast-export.c:680
+#: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77
+#: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408
+#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154
 msgid "file"
 msgstr "tập-tin"
 
-#: archive.c:327 builtin/archive.c:89
+#: archive.c:331 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "ghi kho lưu vào tập tin này"
 
-#: archive.c:329
+#: archive.c:333
 msgid "read .gitattributes in working directory"
 msgstr "đọc .gitattributes trong thư mục làm việc"
 
-#: archive.c:330
+#: archive.c:334
 msgid "report archived files on stderr"
 msgstr "liệt kê các tập tin được lưu trữ vào stderr (đầu ra lỗi tiêu chuẩn)"
 
-#: archive.c:331
+#: archive.c:335
 msgid "store only"
 msgstr "chỉ lưu (không nén)"
 
-#: archive.c:332
+#: archive.c:336
 msgid "compress faster"
 msgstr "nén nhanh hơn"
 
-#: archive.c:340
+#: archive.c:344
 msgid "compress better"
 msgstr "nén nhỏ hơn"
 
-#: archive.c:343
+#: archive.c:347
 msgid "list supported archive formats"
 msgstr "liệt kê các kiểu nén được hỗ trợ"
 
-#: archive.c:345 builtin/archive.c:90 builtin/clone.c:85
+#: archive.c:349 builtin/archive.c:90 builtin/clone.c:84
 msgid "repo"
 msgstr "kho"
 
-#: archive.c:346 builtin/archive.c:91
+#: archive.c:350 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "nhận kho lưu từ kho chứa <kho> trên máy chủ"
 
-#: archive.c:347 builtin/archive.c:92 builtin/notes.c:487
+#: archive.c:351 builtin/archive.c:92 builtin/notes.c:487
 msgid "command"
 msgstr "lệnh"
 
-#: archive.c:348 builtin/archive.c:93
+#: archive.c:352 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "đường dẫn đến lệnh git-upload-pack trên máy chủ"
 
@@ -208,19 +214,19 @@
 msgid "Cannot force update the current branch."
 msgstr "Không thể ép buộc cập nhật nhánh hiện hành."
 
-#: branch.c:216
+#: branch.c:215
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
 "Không thể cài đặt thông tin theo vết; điểm bắt đầu “%s” không phải là một "
 "nhánh."
 
-#: branch.c:218
+#: branch.c:217
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
-msgstr "nhánh dòng ngược đã yêu cầu “%s” chưa sẵn có"
+msgstr "nhánh thượng nguồn đã yêu cầu “%s” chưa sẵn có"
 
-#: branch.c:220
+#: branch.c:219
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -232,34 +238,34 @@
 "\"git push -u\" to set the upstream config as you push."
 msgstr ""
 "\n"
-"Nếu bạn có ý định trên cơ sở công việc của bạn trên nhánh dòng ngược\n"
+"Nếu bạn có ý định cải tổ công việc của bạn trên nhánh thượng nguồn\n"
 "(upstream) cái mà đã sẵn có trên máy chủ, bạn cần chạy\n"
 "lệnh \"git fetch\" để lấy nó về.\n"
 "\n"
-"Nếu bạn có ý định push lênh một nhánh nội bộ mới cái mà\n"
+"Nếu bạn có ý định push lên một nhánh nội bộ mới cái mà\n"
 "sẽ theo dõi bản đối chiếu máy chủ của nó, bạn cần dùng lệnh\n"
-"\"git push -u\" để đặt cấu hình dòng ngược bạn muốn push."
+"\"git push -u\" để đặt cấu hình thượng nguồn bạn muốn push."
 
-#: branch.c:265
+#: branch.c:264
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Không phải tên đối tượng hợp lệ: “%s”."
 
-#: branch.c:285
+#: branch.c:284
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Tên đối tượng chưa rõ ràng: “%s”."
 
-#: branch.c:290
+#: branch.c:289
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Nhánh không hợp lệ: “%s”."
 
-#: branch.c:296
+#: branch.c:295
 msgid "Failed to lock ref for update"
 msgstr "Gặp lỗi khi khóa tham chiếu (ref) để cập nhật"
 
-#: branch.c:314
+#: branch.c:313
 msgid "Failed to write ref"
 msgstr "Gặp lỗi khi ghi tham chiếu (ref)"
 
@@ -273,7 +279,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:697
+#: bundle.c:89 builtin/commit.c:706
 #, c-format
 msgid "could not open '%s'"
 msgstr "không thể mở “%s”"
@@ -282,9 +288,9 @@
 msgid "Repository lacks these prerequisite commits:"
 msgstr "Kho chứa thiếu những lần chuyển giao (commit) cần trước hết này:"
 
-#: bundle.c:164 sequencer.c:661 sequencer.c:1111 builtin/log.c:331
-#: builtin/log.c:801 builtin/log.c:1399 builtin/log.c:1625 builtin/merge.c:364
-#: builtin/shortlog.c:156
+#: bundle.c:164 sequencer.c:662 sequencer.c:1112 builtin/log.c:332
+#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:364
+#: builtin/shortlog.c:158
 msgid "revision walk setup failed"
 msgstr "cài đặt việc di chuyển qua các điểm xét duyệt gặp lỗi"
 
@@ -310,7 +316,7 @@
 msgid "rev-list died"
 msgstr "rev-list đã chết"
 
-#: bundle.c:300 builtin/log.c:1310 builtin/shortlog.c:259
+#: bundle.c:300 builtin/log.c:1329 builtin/shortlog.c:261
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "đối số không được thừa nhận: %s"
@@ -460,7 +466,7 @@
 "Tìm thấy các lỗi trong biến cấu hình “diff.dirstat”:\n"
 "%s"
 
-#: diff.c:3487
+#: diff.c:3490
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -469,7 +475,7 @@
 "Gặp lỗi khi phân tích đối số tùy chọn --dirstat/-X:\n"
 "%s"
 
-#: diff.c:3501
+#: diff.c:3504
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Gặp lỗi khi phân tích đối số tùy chọn --submodule: “%s”"
@@ -496,17 +502,17 @@
 msgid "failed writing detached signature to '%s': %s"
 msgstr "gặp lỗi khi ghi chữ ký đính kèm vào “%s”: %s"
 
-#: grep.c:1623
+#: grep.c:1695
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "“%s”: không thể đọc %s"
 
-#: grep.c:1640
+#: grep.c:1712
 #, c-format
 msgid "'%s': %s"
 msgstr "“%s”: %s"
 
-#: grep.c:1651
+#: grep.c:1723
 #, c-format
 msgid "'%s': short read %s"
 msgstr "“%s”: đọc ngắn %s"
@@ -577,10 +583,10 @@
 
 #: merge.c:56
 msgid "failed to read the cache"
-msgstr "gặp lỗi khi đọc bộ nhớ tạm"
+msgstr "gặp lỗi khi đọc bộ nhớ đệm"
 
-#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566
-#: builtin/clone.c:656
+#: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559
+#: builtin/clone.c:655
 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"
 
@@ -629,7 +635,7 @@
 msgid "blob expected for %s '%s'"
 msgstr "đối tượng blob được mong đợi cho %s “%s”"
 
-#: merge-recursive.c:774 builtin/clone.c:312
+#: merge-recursive.c:774 builtin/clone.c:311
 #, c-format
 msgid "failed to open '%s'"
 msgstr "gặp lỗi khi mở “%s”"
@@ -637,7 +643,7 @@
 #: merge-recursive.c:782
 #, 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”"
+msgstr "gặp lỗi khi tạo liên kết mềm (symlink) “%s”"
 
 #: merge-recursive.c:785
 #, c-format
@@ -764,7 +770,7 @@
 msgid "Auto-merging %s"
 msgstr "Tự-động-hòa-trộn %s"
 
-#: merge-recursive.c:1634 git-submodule.sh:1118
+#: merge-recursive.c:1634 git-submodule.sh:1125
 msgid "submodule"
 msgstr "mô-đun-con"
 
@@ -863,58 +869,125 @@
 msgid "Bad %s value: '%s'"
 msgstr "Giá trị %s sai: “%s”"
 
-#: object.c:204
+#: object.c:202
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "không thể phân tích đối tượng: “%s”"
 
-#: parse-options.c:489
+#: parse-options.c:537
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:507
+#: parse-options.c:555
 #, c-format
 msgid "usage: %s"
 msgstr "cách dùng: %s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:511
+#: parse-options.c:559
 #, c-format
 msgid "   or: %s"
 msgstr "     hoặc: %s"
 
-#: parse-options.c:514
+#: parse-options.c:562
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:548
+#: parse-options.c:596
 msgid "-NUM"
 msgstr "-SỐ"
 
-#: pathspec.c:83
-#, c-format
-msgid "Path '%s' is in submodule '%.*s'"
-msgstr "Đường dẫn “%s” thì ở trong mô-đun-con “%.*s”"
+#: pathspec.c:118
+msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
+msgstr ""
+"các cài đặt đặc tả đường dẫn “glob” và “noglob” toàn cục là xung khắc nhau"
 
-#: pathspec.c:99
-#, c-format
-msgid "'%s' is beyond a symbolic link"
-msgstr "“%s” nằm ngoài một liên kết tượng trưng"
+#: pathspec.c:128
+msgid ""
+"global 'literal' pathspec setting is incompatible with all other global "
+"pathspec settings"
+msgstr ""
+"cài đặt đặc tả đường dẫn “literal” toàn cục là xung khắc với các cài đặt đặc "
+"tả đường dẫn toàn cục khác"
 
-#: remote.c:1788
+#: pathspec.c:158
+msgid "invalid parameter for pathspec magic 'prefix'"
+msgstr "tham số không hợp lệ cho “tiền tố” màu nhiệm đặc tả đường đẫn"
+
+#: pathspec.c:164
+#, c-format
+msgid "Invalid pathspec magic '%.*s' in '%s'"
+msgstr "Số màu nhiệm đặc tả đường dẫn không hợp lệ “%.*s” trong “%s”"
+
+#: pathspec.c:168
+#, c-format
+msgid "Missing ')' at the end of pathspec magic in '%s'"
+msgstr "Thiếu “)” tại cuối của số màu nhiệm đặc tả đường dẫn trong “%s”"
+
+#: pathspec.c:186
+#, c-format
+msgid "Unimplemented pathspec magic '%c' in '%s'"
+msgstr "Chưa viết mã cho số màu nhiệm đặc tả đường dẫn “%c” trong “%s”"
+
+#: pathspec.c:211
+#, c-format
+msgid "%s: 'literal' and 'glob' are incompatible"
+msgstr "%s: “literal” và “glob” xung khắc nhau"
+
+#: pathspec.c:222
+#, c-format
+msgid "%s: '%s' is outside repository"
+msgstr "%s: “%s” ngoài một kho chứa"
+
+#: pathspec.c:278
+#, c-format
+msgid "Pathspec '%s' is in submodule '%.*s'"
+msgstr "Đặc tả đường dẫn “%s” thì ở trong mô-đun-con “%.*s”"
+
+#.
+#. * We may want to substitute "this command" with a command
+#. * name. E.g. when add--interactive dies when running
+#. * "checkout -p"
+#.
+#: pathspec.c:340
+#, c-format
+msgid "%s: pathspec magic not supported by this command: %s"
+msgstr "%s: số mầu nhiệm đặc tả đường dẫn chưa được hỗ trợ bởi lệnh này: %s"
+
+#: pathspec.c:415
+#, c-format
+msgid "pathspec '%s' is beyond a symbolic link"
+msgstr "đặc tả đường dẫn “%s” vượt ra ngoài liên kết mềm"
+
+#: remote.c:1833
+#, c-format
+msgid "Your branch is based on '%s', but the upstream is gone.\n"
+msgstr ""
+"Nhánh của bạn dựa trên cơ sở là “%s”, nhưng trên thượng nguồn không còn.\n"
+
+#: remote.c:1837
+msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
+msgstr "   (dùng \" git branch --unset-upstream\" để sửa)\n"
+
+#: remote.c:1840
+#, c-format
+msgid "Your branch is up-to-date with '%s'.\n"
+msgstr "Nhánh của bạn đã cập nhật với “%s”.\n"
+
+#: remote.c:1844
 #, 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:1794
+#: remote.c:1850
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (dùng \"git push\" để xuất bản các lần chuyển giao nội bộ của bạn)\n"
 
-#: remote.c:1797
+#: remote.c:1853
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -926,11 +999,11 @@
 "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:1805
+#: remote.c:1861
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (dùng \"git pull\" để cập nhật nhánh nội bộ của bạn)\n"
 
-#: remote.c:1808
+#: remote.c:1864
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -946,7 +1019,7 @@
 "Your branch and “%s” have diverged,\n"
 "and have %d and %d different commit each, respectively.\n"
 
-#: remote.c:1818
+#: remote.c:1874
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr ""
 "  (dùng \"git pull\" để hòa trộn nhánh trên máy chủ vào trong nhánh của "
@@ -991,7 +1064,7 @@
 "với lệnh “git add <đường_dẫn>” hoặc “git rm <đường_dẫn>”\n"
 "và chuyển giao (commit) kết quả bằng lệnh “git commit”"
 
-#: sequencer.c:245 sequencer.c:869 sequencer.c:952
+#: sequencer.c:245 sequencer.c:870 sequencer.c:953
 #, c-format
 msgid "Could not write to %s"
 msgstr "Không thể ghi vào %s"
@@ -1014,46 +1087,46 @@
 msgstr "Chuyển giao (commit) các thay đổi của bạn hay stash chúng để xử lý."
 
 #. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:324
+#: sequencer.c:325
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: Không thể ghi tập tin lưu bảng mục lục mới"
 
-#: sequencer.c:355
+#: sequencer.c:356
 msgid "Could not resolve HEAD commit\n"
 msgstr "Không thể phân giải commit (lần chuyển giao) HEAD\n"
 
-#: sequencer.c:377
+#: sequencer.c:378
 msgid "Unable to update cache tree\n"
 msgstr "Không thể cập nhật cây bộ nhớ đệm\n"
 
-#: sequencer.c:422
+#: sequencer.c:423
 #, c-format
 msgid "Could not parse commit %s\n"
 msgstr "Không thể phân tích commit (lần chuyển giao) %s\n"
 
-#: sequencer.c:427
+#: sequencer.c:428
 #, c-format
 msgid "Could not parse parent commit %s\n"
 msgstr "Không thể phân tích commit (lần chuyển giao) cha mẹ %s\n"
 
-#: sequencer.c:493
+#: sequencer.c:494
 msgid "Your index file is unmerged."
 msgstr "Tập tin lưu mục lục của bạn không được hòa trộn."
 
-#: sequencer.c:512
+#: sequencer.c:513
 #, c-format
 msgid "Commit %s is a merge but no -m option was given."
 msgstr ""
 "Lần chuyển giao (commit) %s là một lần hòa trộn nhưng không đưa ra tùy chọn -"
 "m."
 
-#: sequencer.c:520
+#: sequencer.c:521
 #, c-format
 msgid "Commit %s does not have parent %d"
 msgstr "Lần chuyển giao (commit) %s không có cha mẹ %d"
 
-#: sequencer.c:524
+#: sequencer.c:525
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
 msgstr ""
@@ -1062,153 +1135,153 @@
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
-#: sequencer.c:537
+#: sequencer.c:538
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: không thể phân tích lần chuyển giao mẹ của %s"
 
-#: sequencer.c:541
+#: sequencer.c:542
 #, c-format
 msgid "Cannot get commit message for %s"
 msgstr "Không thể lấy thông điệp lần chuyển giao (commit) cho %s"
 
-#: sequencer.c:627
+#: sequencer.c:628
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "không thể revert %s... %s"
 
-#: sequencer.c:628
+#: sequencer.c:629
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "không thể apply (áp dụng miếng vá) %s... %s"
 
-#: sequencer.c:664
+#: sequencer.c:665
 msgid "empty commit set passed"
 msgstr "lần chuyển giao (commit) trống rỗng đặt là hợp quy cách"
 
-#: sequencer.c:672
+#: sequencer.c:673
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: gặp lỗi đọc bảng mục lục"
 
-#: sequencer.c:677
+#: sequencer.c:678
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s: gặp lỗi khi làm tươi mới bảng mục lục"
 
-#: sequencer.c:735
+#: sequencer.c:736
 #, c-format
 msgid "Cannot %s during a %s"
 msgstr "Không thể %s trong khi %s"
 
-#: sequencer.c:757
+#: sequencer.c:758
 #, c-format
 msgid "Could not parse line %d."
 msgstr "Không phân tích được dòng %d."
 
-#: sequencer.c:762
+#: sequencer.c:763
 msgid "No commits parsed."
 msgstr "Không có lần chuyển giao (commit) nào được phân tích."
 
-#: sequencer.c:775
+#: sequencer.c:776
 #, c-format
 msgid "Could not open %s"
 msgstr "Không thể mở %s"
 
-#: sequencer.c:779
+#: sequencer.c:780
 #, c-format
 msgid "Could not read %s."
 msgstr "Không thể đọc %s."
 
-#: sequencer.c:786
+#: sequencer.c:787
 #, c-format
 msgid "Unusable instruction sheet: %s"
 msgstr "Bảng chỉ thị không thể dùng được: %s"
 
-#: sequencer.c:814
+#: sequencer.c:815
 #, c-format
 msgid "Invalid key: %s"
 msgstr "Khóa không đúng: %s"
 
-#: sequencer.c:817
+#: sequencer.c:818
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Giá trị không hợp lệ %s: %s"
 
-#: sequencer.c:829
+#: sequencer.c:830
 #, c-format
 msgid "Malformed options sheet: %s"
 msgstr "Bảng tùy chọn dị hình: %s"
 
-#: sequencer.c:850
+#: sequencer.c:851
 msgid "a cherry-pick or revert is already in progress"
 msgstr "một thao tác cherry-pick hoặc revert đang được thực hiện"
 
-#: sequencer.c:851
+#: sequencer.c:852
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "hãy thử \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:855
+#: sequencer.c:856
 #, c-format
 msgid "Could not create sequencer directory %s"
 msgstr "Không thể tạo thư mục xếp dãy %s"
 
-#: sequencer.c:871 sequencer.c:956
+#: sequencer.c:872 sequencer.c:957
 #, c-format
 msgid "Error wrapping up %s."
 msgstr "Lỗi bao bọc %s."
 
-#: sequencer.c:890 sequencer.c:1024
+#: sequencer.c:891 sequencer.c:1025
 msgid "no cherry-pick or revert in progress"
 msgstr "không cherry-pick hay revert trong tiến trình"
 
-#: sequencer.c:892
+#: sequencer.c:893
 msgid "cannot resolve HEAD"
 msgstr "không thể phân giải HEAD"
 
-#: sequencer.c:894
+#: sequencer.c:895
 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:916 builtin/apply.c:4061
+#: sequencer.c:917 builtin/apply.c:4061
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "không thể mở %s: %s"
 
-#: sequencer.c:919
+#: sequencer.c:920
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "không thể đọc %s: %s"
 
-#: sequencer.c:920
+#: sequencer.c:921
 msgid "unexpected end of file"
 msgstr "kết thúc tập tin đột xuất"
 
-#: sequencer.c:926
+#: sequencer.c:927
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "tập tin HEAD “pre-cherry-pick” đã lưu “%s” bị hỏng"
 
-#: sequencer.c:949
+#: sequencer.c:950
 #, c-format
 msgid "Could not format %s."
 msgstr "Không thể định dạng %s."
 
-#: sequencer.c:1092
+#: sequencer.c:1093
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: không thể cherry-pick một %s"
 
-#: sequencer.c:1095
+#: sequencer.c:1096
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: điểm xét duyệt sai"
 
-#: sequencer.c:1129
+#: sequencer.c:1130
 msgid "Can't revert as initial commit"
 msgstr "Không thể revert một lần chuyển giao (commit) khởi tạo"
 
-#: sequencer.c:1130
+#: sequencer.c:1131
 msgid "Can't cherry-pick into empty head"
 msgstr "Không thể cherry-pick vào một đầu (head) trống rỗng"
 
@@ -1236,265 +1309,359 @@
 "này\n"
 "bằng cách chạy lệnh \"git config advice.objectNameWarning false\""
 
-#: sha1_name.c:1097
+#: sha1_name.c:1112
 msgid "HEAD does not point to a branch"
 msgstr "HEAD không chỉ đến một nhánh nào cả"
 
-#: sha1_name.c:1100
+#: sha1_name.c:1115
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "Không có nhánh nào như thế: “%s”"
 
-#: sha1_name.c:1102
+#: sha1_name.c:1117
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "Không có thượng nguồn (upstream) được cấu hình cho nhánh “%s”"
 
-#: sha1_name.c:1106
+#: sha1_name.c:1121
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr ""
 "Nhánh thượng nguồn (upstream) “%s” không được lưu lại như là một nhánh "
 "“remote-tracking”"
 
-#: wrapper.c:408
+#: submodule.c:64 submodule.c:98
+msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
+msgstr ""
+"Không thể thay đổi .gitmodules chưa hòa trộn, hãy giải quyết xung đột trộn "
+"trước"
+
+#: submodule.c:68 submodule.c:102
+#, c-format
+msgid "Could not find section in .gitmodules where path=%s"
+msgstr "Không thể tìm thấy phần trong .gitmodules nơi mà đường_dẫn=%s"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:76
+#, c-format
+msgid "Could not update .gitmodules entry %s"
+msgstr "Không thể cập nhật mục .gitmodules %s"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:109
+#, c-format
+msgid "Could not remove .gitmodules entry for %s"
+msgstr "Không thể gỡ bỏ mục .gitmodules dành cho %s"
+
+#: submodule.c:127
+msgid "could not find .gitmodules in index"
+msgstr "không tìm thấy .gitmodules trong bảng mục lục"
+
+#: submodule.c:133
+msgid "reading updated .gitmodules failed"
+msgstr "gặp lỗi khi đọc cập nhật .gitmodules"
+
+#: submodule.c:135
+msgid "unable to stat updated .gitmodules"
+msgstr "không thể lấy thống kê .gitmodules đã cập nhật"
+
+#: submodule.c:139
+msgid "unable to remove .gitmodules from index"
+msgstr "không thể gỡ bỏ .gitmodules từ mục lục"
+
+#: submodule.c:141
+msgid "adding updated .gitmodules failed"
+msgstr "gặp lỗi khi thêm .gitmodules đã cập nhật"
+
+#: submodule.c:143
+msgid "staging updated .gitmodules failed"
+msgstr "gặp lỗi khi tổ chức .gitmodules đã cập nhật"
+
+#: submodule.c:1144 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”"
+
+#: submodule.c:1155
+#, c-format
+msgid "Could not set core.worktree in %s"
+msgstr "Không thể đặt cây thư mục làm việc “core.worktree” trong “%s”."
+
+#: urlmatch.c:120
+msgid "invalid URL scheme name or missing '://' suffix"
+msgstr "tên lược đồ URL không hợp lệ hay thiếu hậu tố “://”"
+
+#: urlmatch.c:144 urlmatch.c:297 urlmatch.c:356
+#, c-format
+msgid "invalid %XX escape sequence"
+msgstr "thoát chuỗi %XX không hợp lệ"
+
+#: urlmatch.c:172
+msgid "missing host and scheme is not 'file:'"
+msgstr "thiếu máy chủ và lược đồ thì không phải là giao thức “file:”"
+
+#: urlmatch.c:189
+msgid "a 'file:' URL may not have a port number"
+msgstr "URL kiểu “file:” không được chứa cổng"
+
+#: urlmatch.c:199
+msgid "invalid characters in host name"
+msgstr "có các ký tự không hợp lệ trong tên máy"
+
+#: urlmatch.c:244 urlmatch.c:255
+msgid "invalid port number"
+msgstr "tên cổng không hợp lệ"
+
+#: urlmatch.c:322
+msgid "invalid '..' path segment"
+msgstr "đoạn đường dẫn “..” không hợp lệ"
+
+#: wrapper.c:422
 #, c-format
 msgid "unable to access '%s': %s"
 msgstr "không thể truy cập “%s”: %s"
 
-#: wrapper.c:429
+#: wrapper.c:443
 #, c-format
 msgid "unable to access '%s'"
 msgstr "không thể truy cập “%s”"
 
-#: wrapper.c:440
+#: wrapper.c:454
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
 msgstr "không tìm thấy người dùng hiện tại trong tập tin passwd: %s"
 
-#: wrapper.c:441
+#: wrapper.c:455
 msgid "no such user"
 msgstr "không có người dùng như vậy"
 
-#: wt-status.c:141
+#: wt-status.c:146
 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:173 wt-status.c:200
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (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:175 wt-status.c:202
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (dùng \"git rm --cached <tập-tin>...\" để bỏ trạng thái (stage))"
 
-#: wt-status.c:174
+#: wt-status.c:179
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (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:181 wt-status.c:185
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 "  (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:183
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (dùng \"git rm <tập-tin>...\" để đánh dấu là cần giải quyết)"
 
-#: wt-status.c:189
+#: wt-status.c:194
 msgid "Changes to be committed:"
 msgstr "Những thay đổi sẽ được chuyển giao:"
 
-#: wt-status.c:207
+#: wt-status.c:212
 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:216
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 "  (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:218
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 "  (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:219
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (dùng \"git checkout -- <tập-tin>...\" để bỏ thay đổi trong thư mục làm "
 "việc)"
 
-#: wt-status.c:216
+#: wt-status.c:221
 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:228
+#: wt-status.c:233
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 "  (dùng \"git %s <tập-tin>...\" để thêm vào những gì cần chuyển giao "
 "(commit))"
 
-#: wt-status.c:245
+#: wt-status.c:250
 msgid "bug"
 msgstr "lỗi"
 
-#: wt-status.c:250
+#: wt-status.c:255
 msgid "both deleted:"
 msgstr "bị xóa bởi cả hai:"
 
-#: wt-status.c:251
+#: wt-status.c:256
 msgid "added by us:"
 msgstr "được thêm vào bởi chúng ta:"
 
-#: wt-status.c:252
+#: wt-status.c:257
 msgid "deleted by them:"
 msgstr "bị xóa đi bởi họ:"
 
-#: wt-status.c:253
+#: wt-status.c:258
 msgid "added by them:"
 msgstr "được thêm vào bởi họ:"
 
-#: wt-status.c:254
+#: wt-status.c:259
 msgid "deleted by us:"
 msgstr "bị xóa bởi chúng ta:"
 
-#: wt-status.c:255
+#: wt-status.c:260
 msgid "both added:"
 msgstr "được thêm vào bởi cả hai:"
 
-#: wt-status.c:256
+#: wt-status.c:261
 msgid "both modified:"
 msgstr "bị sửa bởi cả hai:"
 
-#: wt-status.c:286
+#: wt-status.c:291
 msgid "new commits, "
 msgstr "lần chuyển giao (commit) mới, "
 
-#: wt-status.c:288
+#: wt-status.c:293
 msgid "modified content, "
 msgstr "nội dung bị sửa đổi, "
 
-#: wt-status.c:290
+#: wt-status.c:295
 msgid "untracked content, "
 msgstr "nội dung chưa được theo dõi, "
 
-#: wt-status.c:307
+#: wt-status.c:312
 #, c-format
 msgid "new file:   %s"
 msgstr "tập tin mới:   %s"
 
-#: wt-status.c:310
+#: wt-status.c:315
 #, c-format
 msgid "copied:     %s -> %s"
-msgstr "đã sao chép:     %s -> %s"
+msgstr "đã sao chép:   %s -> %s"
 
-#: wt-status.c:313
+#: wt-status.c:318
 #, c-format
 msgid "deleted:    %s"
-msgstr "đã xóa:    %s"
+msgstr "đã xóa:        %s"
 
-#: wt-status.c:316
+#: wt-status.c:321
 #, c-format
 msgid "modified:   %s"
-msgstr "đã sửa đổi:   %s"
+msgstr "đã sửa đổi:    %s"
 
-#: wt-status.c:319
+#: wt-status.c:324
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "đã đổi tên:    %s -> %s"
 
-#: wt-status.c:322
+#: wt-status.c:327
 #, c-format
 msgid "typechange: %s"
-msgstr "đổi-kiểu: %s"
+msgstr "đổi-kiểu:      %s"
 
-#: wt-status.c:325
+#: wt-status.c:330
 #, c-format
 msgid "unknown:    %s"
 msgstr "không hiểu:    %s"
 
-#: wt-status.c:328
+#: wt-status.c:333
 #, c-format
 msgid "unmerged:   %s"
-msgstr "chưa hòa trộn:   %s"
+msgstr "chưa hòa trộn: %s"
 
-#: wt-status.c:331
+#: wt-status.c:336
 #, 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:803
+#: wt-status.c:703
+msgid "Submodules changed but not updated:"
+msgstr "Những mô-đun-con đã bị thay đổi nhưng chưa được cập nhật:"
+
+#: wt-status.c:705
+msgid "Submodule changes to be committed:"
+msgstr "Những mô-đun-con thay đổi đã được chuyển giao (commit):"
+
+#: wt-status.c:848
 msgid "You have unmerged paths."
 msgstr "Bạn có những đường dẫn chưa được hòa trộn."
 
-#: wt-status.c:806
+#: wt-status.c:851
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (sửa các xung đột sau đó chạy \"git commit\")"
 
-#: wt-status.c:809
+#: wt-status.c:854
 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:812
+#: wt-status.c:857
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (dùng \"git commit\" để hoàn tất việc hòa trộn)"
 
-#: wt-status.c:822
+#: wt-status.c:867
 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:825
+#: wt-status.c:870
 msgid "The current patch is empty."
 msgstr "Miếng vá hiện tại bị trống rỗng."
 
-#: wt-status.c:829
+#: wt-status.c:874
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git am --continue\")"
 
-#: wt-status.c:831
+#: wt-status.c:876
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (dùng \"git am --skip\" để bỏ qua miếng vá này)"
 
-#: wt-status.c:833
+#: wt-status.c:878
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (dùng \"git am --abort\" để phục hồi lại nhánh nguyên thủy)"
 
-#: wt-status.c:893 wt-status.c:910
+#: wt-status.c:938 wt-status.c:955
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "Bạn hiện nay đang thực hiện việc rebase nhánh “%s” trên “%s”."
 
-#: wt-status.c:898 wt-status.c:915
+#: wt-status.c:943 wt-status.c:960
 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:901
+#: wt-status.c:946
 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:903
+#: wt-status.c:948
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (dùng \"git rebase --skip\" để bỏ qua lần vá này)"
 
-#: wt-status.c:905
+#: wt-status.c:950
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (dùng \"git rebase --abort\" để check-out nhánh nguyên thủy)"
 
-#: wt-status.c:918
+#: wt-status.c:963
 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:922
+#: wt-status.c:967
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
@@ -1502,126 +1669,127 @@
 "Bạn hiện nay đang thực hiện việc chia tách một lần chuyển giao (commit) "
 "trong khi đang rebase nhánh “%s” trên “%s”."
 
-#: wt-status.c:927
+#: wt-status.c:972
 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:930
+#: wt-status.c:975
 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:934
+#: wt-status.c:979
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 "Bạn hiện nay đang thực hiện việc sửa chữa một lần chuyển giao (commit) trong "
 "khi đang rebase nhánh “%s” trên “%s”."
 
-#: wt-status.c:939
+#: wt-status.c:984
 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:942
+#: wt-status.c:987
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 "  (dùng \"git commit --amend\" để tu bổ lần chuyển giao (commit) hiện tại)"
 
-#: wt-status.c:944
+#: wt-status.c:989
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 "  (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:954
-msgid "You are currently cherry-picking."
-msgstr "Bạn hiện nay đang thực hiện việc cherry-pick."
+#: wt-status.c:999
+#, c-format
+msgid "You are currently cherry-picking commit %s."
+msgstr "Bạn hiện nay đang thực hiện việc cherry-pick lần chuyển giao %s."
 
-#: wt-status.c:958
+#: wt-status.c:1004
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr ""
 "  (sửa các xung đột và sau đó chạy lệnh \"git cherry-pick --continue\")"
 
-#: wt-status.c:961
+#: wt-status.c:1007
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 "  (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git cherry-pick --"
 "continue\")"
 
-#: wt-status.c:963
+#: wt-status.c:1009
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr "  (dùng \"git cherry-pick --abort\" để hủy bỏ thao tác cherry-pick)"
 
-#: wt-status.c:972
+#: wt-status.c:1018
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "Bạn hiện nay đang thực hiện thao tác revert lần chuyển giao “%s”."
 
-#: wt-status.c:977
+#: wt-status.c:1023
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git revert --continue\")"
 
-#: wt-status.c:980
+#: wt-status.c:1026
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr ""
 "  (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git revert --continue\")"
 
-#: wt-status.c:982
+#: wt-status.c:1028
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (dùng \"git revert --abort\" để hủy bỏ thao tác revert)"
 
-#: wt-status.c:993
+#: wt-status.c:1039
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr ""
 "Bạn hiện nay đang thực hiện thao tác di chuyển nửa bước (bisect), bắt đầu từ "
 "nhánh “%s”."
 
-#: wt-status.c:997
+#: wt-status.c:1043
 msgid "You are currently bisecting."
-msgstr "Bạn hiện tại đang thực hiện việc bisect (chia đôi)."
+msgstr "Bạn hiện tại đang thực hiện việc bisect (di chuyển nửa bước)."
 
-#: wt-status.c:1000
+#: wt-status.c:1046
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (dùng \"git bisect reset\" để quay trở lại nhánh nguyên thủy)"
 
-#: wt-status.c:1173
+#: wt-status.c:1221
 msgid "On branch "
 msgstr "Trên nhánh "
 
-#: wt-status.c:1180
+#: wt-status.c:1228
 msgid "rebase in progress; onto "
-msgstr "rebase đang được thực hiện: lên trên"
+msgstr "rebase đang được thực hiện: lên trên "
 
-#: wt-status.c:1187
+#: wt-status.c:1235
 msgid "HEAD detached at "
-msgstr "HEAD được tách rời tại"
+msgstr "HEAD được tách rời tại "
 
-#: wt-status.c:1189
+#: wt-status.c:1237
 msgid "HEAD detached from "
 msgstr "HEAD được tách rời từ"
 
-#: wt-status.c:1192
+#: wt-status.c:1240
 msgid "Not currently on any branch."
 msgstr "Hiện tại chẳng ở nhánh nào cả."
 
-#: wt-status.c:1209
+#: wt-status.c:1257
 msgid "Initial commit"
 msgstr "Lần chuyển giao (commit) khởi đầu"
 
-#: wt-status.c:1223
+#: wt-status.c:1271
 msgid "Untracked files"
 msgstr "Những tập tin chưa được theo dõi"
 
-#: wt-status.c:1225
+#: wt-status.c:1273
 msgid "Ignored files"
 msgstr "Những tập tin bị lờ đi"
 
-#: wt-status.c:1229
+#: wt-status.c:1277
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -1633,32 +1801,32 @@
 "có lẽ làm nó nhanh hơn, nhưng bạn phải cẩn thận đừng quên mình phải\n"
 "tự thêm các tập tin mới (xem “git help status”.."
 
-#: wt-status.c:1235
+#: wt-status.c:1283
 #, 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:1237
+#: wt-status.c:1285
 msgid " (use -u option to show untracked files)"
 msgstr " (dùng tùy chọn -u để hiển thị các tập tin chưa được theo dõi)"
 
-#: wt-status.c:1243
+#: wt-status.c:1291
 msgid "No changes"
 msgstr "Không có thay đổi nào"
 
-#: wt-status.c:1248
+#: wt-status.c:1296
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 "không có thay đổi nào được thêm vào commit (dùng \"git add\" và/hoặc \"git "
 "commit -a\")\n"
 
-#: wt-status.c:1251
+#: wt-status.c:1299
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "không có thay đổi nào được thêm vào lần chuyển giao (commit)\n"
 
-#: wt-status.c:1254
+#: wt-status.c:1302
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -1667,58 +1835,62 @@
 "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 (dùng \"git add\" để đưa vào theo dõi)\n"
 
-#: wt-status.c:1257
+#: wt-status.c:1305
 #, c-format
 msgid "nothing added to commit but untracked files present\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\n"
 
-#: wt-status.c:1260
+#: wt-status.c:1308
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 " không có gì để commit (tạo/sao-chép các tập tin và dùng \"git add\" để theo "
 "dõi dấu vết)\n"
 
-#: wt-status.c:1263 wt-status.c:1268
+#: wt-status.c:1311 wt-status.c:1316
 #, c-format
 msgid "nothing to commit\n"
 msgstr "không có gì để chuyển giao (commit)\n"
 
-#: wt-status.c:1266
+#: wt-status.c:1314
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
 "không có gì để chuyển giao (commit) (dùng -u để bỏ các tập tin cần theo dấu "
 "vết)\n"
 
-#: wt-status.c:1270
+#: wt-status.c:1318
 #, c-format
 msgid "nothing to commit, working directory clean\n"
 msgstr "không có gì để chuyển giao (commit), thư mục làm việc sạch sẽ\n"
 
-#: wt-status.c:1378
+#: wt-status.c:1427
 msgid "HEAD (no branch)"
 msgstr "HEAD (không nhánh)"
 
-#: wt-status.c:1384
+#: wt-status.c:1433
 msgid "Initial commit on "
 msgstr "Lần chuyển giao (commit) khởi tạo trên "
 
-#: wt-status.c:1399
+#: wt-status.c:1463
+msgid "gone"
+msgstr "đã ra đi"
+
+#: wt-status.c:1465
 msgid "behind "
 msgstr "đằng sau "
 
-#: wt-status.c:1402 wt-status.c:1405
+#: wt-status.c:1468 wt-status.c:1471
 msgid "ahead "
 msgstr "phía trước "
 
-#: wt-status.c:1407
+#: wt-status.c:1473
 msgid ", behind "
 msgstr ", đằng sau "
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:351
+#: compat/precompose_utf8.c:55 builtin/clone.c:350
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "bỏ liên kết (unlink) %s không thành công"
@@ -1806,7 +1978,7 @@
 msgid "unexpected diff status %c"
 msgstr "trạng thái lệnh diff không như mong đợi %c"
 
-#: builtin/add.c:149 builtin/commit.c:252
+#: builtin/add.c:149 builtin/commit.c:260
 msgid "updating files failed"
 msgstr "Cập nhật tập tin gặp lỗi"
 
@@ -1815,147 +1987,142 @@
 msgid "remove '%s'\n"
 msgstr "gỡ bỏ “%s”\n"
 
-#: builtin/add.c:253
+#: builtin/add.c:237
 msgid "Unstaged changes after refreshing the index:"
 msgstr ""
 "Các thay đổi không được lưu trạng thái sau khi làm tươi mới lại bảng mục lục:"
 
-#: builtin/add.c:256 builtin/add.c:573 builtin/rm.c:337
-#, c-format
-msgid "pathspec '%s' did not match any files"
-msgstr "pathspec “%s” không khớp với bất kỳ tập tin nào"
-
-#: builtin/add.c:339
+#: builtin/add.c:299
 msgid "Could not read the index"
 msgstr "Không thể đọc bảng mục lục"
 
-#: builtin/add.c:350
+#: builtin/add.c:310
 #, c-format
 msgid "Could not open '%s' for writing."
 msgstr "Không thể mở “%s” để ghi."
 
-#: builtin/add.c:354
+#: builtin/add.c:314
 msgid "Could not write patch"
 msgstr "Không thể ghi ra miếng vá"
 
-#: builtin/add.c:359
+#: builtin/add.c:319
 #, c-format
 msgid "Could not stat '%s'"
 msgstr "không thể lấy trạng thái về “%s”"
 
-#: builtin/add.c:361
+#: builtin/add.c:321
 msgid "Empty patch. Aborted."
 msgstr "Miếng vá trống rỗng. Đã bỏ qua."
 
-#: builtin/add.c:367
+#: builtin/add.c:327
 #, c-format
 msgid "Could not apply '%s'"
 msgstr "Không thể apply (áp dụng miếng vá) “%s”"
 
-#: builtin/add.c:377
+#: builtin/add.c:337
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
 "Các đường dẫn theo sau đây sẽ bị lờ đi bởi một trong các tập tin .gitignore "
 "của bạn:\n"
 
-#: builtin/add.c:394 builtin/clean.c:875 builtin/fetch.c:78 builtin/mv.c:63
-#: builtin/prune-packed.c:73 builtin/push.c:451 builtin/remote.c:1253
-#: builtin/rm.c:268
+#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:92 builtin/mv.c:66
+#: builtin/prune-packed.c:73 builtin/push.c:459 builtin/remote.c:1253
+#: builtin/rm.c:269
 msgid "dry run"
 msgstr "chạy thử"
 
-#: builtin/add.c:395 builtin/apply.c:4410 builtin/check-ignore.c:19
-#: builtin/commit.c:1220 builtin/count-objects.c:95 builtin/fsck.c:613
-#: builtin/log.c:1573 builtin/mv.c:62 builtin/read-tree.c:113
+#: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19
+#: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612
+#: builtin/log.c:1592 builtin/mv.c:65 builtin/read-tree.c:113
 msgid "be verbose"
 msgstr "chi tiết"
 
-#: builtin/add.c:397
+#: builtin/add.c:357
 msgid "interactive picking"
 msgstr "sửa bằng cách tương tác"
 
-#: builtin/add.c:398 builtin/checkout.c:1073 builtin/reset.c:261
+#: builtin/add.c:358 builtin/checkout.c:1109 builtin/reset.c:272
 msgid "select hunks interactively"
 msgstr "chọn “hunks” một cách tương tác"
 
-#: builtin/add.c:399
+#: builtin/add.c:359
 msgid "edit current diff and apply"
 msgstr "sửa diff hiện nay và áp dụng nó"
 
-#: builtin/add.c:400
+#: builtin/add.c:360
 msgid "allow adding otherwise ignored files"
 msgstr "cho phép thêm các tập tin bị bỏ qua khác"
 
-#: builtin/add.c:401
+#: builtin/add.c:361
 msgid "update tracked files"
 msgstr "cập nhật các tập tin được theo vết"
 
-#: builtin/add.c:402
+#: builtin/add.c:362
 msgid "record only the fact that the path will be added later"
 msgstr "chỉ ghi lại sự việc mà đường dẫn sẽ được thêm vào sau"
 
-#: builtin/add.c:403
+#: builtin/add.c:363
 msgid "add changes from all tracked and untracked files"
 msgstr ""
 "thêm các thay đổi từ tất cả các tập tin có cũng như không được theo dõi dấu "
 "vết"
 
 #. takes no arguments
-#: builtin/add.c:406
+#: builtin/add.c:366
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr ""
 "lờ đi các đường dẫn bị gỡ bỏ trong cây thư mục làm việc (giống với --no-all)"
 
-#: builtin/add.c:408
+#: builtin/add.c:368
 msgid "don't add, only refresh the index"
 msgstr "không thêm, chỉ làm tươi mới bảng mục lục"
 
-#: builtin/add.c:409
+#: builtin/add.c:369
 msgid "just skip files which cannot be added because of errors"
 msgstr "chie bỏ qua những tập tin mà nó không thể được thêm vào bởi vì gặp lỗi"
 
-#: builtin/add.c:410
+#: builtin/add.c:370
 msgid "check if - even missing - files are ignored in dry run"
 msgstr ""
 "kiểm tra xem - thậm chí thiếu - tập tin bị bỏ qua trong quá trình chạy thử"
 
-#: builtin/add.c:432
+#: builtin/add.c:392
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Sử dụng tùy chọn -f nếu bạn thực sự muốn thêm chúng vào.\n"
 
-#: builtin/add.c:433
+#: builtin/add.c:393
 msgid "no files added"
 msgstr "chưa có tập tin nào được thêm vào"
 
-#: builtin/add.c:439
+#: builtin/add.c:399
 msgid "adding files failed"
 msgstr "thêm tập tin gặp lỗi"
 
-#: builtin/add.c:478
+#: builtin/add.c:438
 msgid "-A and -u are mutually incompatible"
 msgstr "-A và -u xung khắc nhau"
 
-#: builtin/add.c:496
+#: builtin/add.c:456
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "Tùy chọn --ignore-missing chỉ có thể được dùng cùng với --dry-run"
 
-#: builtin/add.c:526
+#: builtin/add.c:486
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Không có gì được chỉ ra, không có gì được thêm vào.\n"
 
-#: builtin/add.c:527
+#: builtin/add.c:487
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Có lẽ bạn muốn là “git add .” phải không?\n"
 
-#: builtin/add.c:533 builtin/check-ignore.c:161 builtin/clean.c:919
-#: builtin/commit.c:312 builtin/mv.c:82 builtin/rm.c:297
+#: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919
+#: builtin/commit.c:320 builtin/mv.c:86 builtin/reset.c:224 builtin/rm.c:299
 msgid "index file corrupt"
 msgstr "tập tin ghi bảng mục lục bị hỏng"
 
-#: builtin/add.c:605 builtin/apply.c:4506 builtin/mv.c:229 builtin/rm.c:432
+#: builtin/add.c:589 builtin/apply.c:4506 builtin/mv.c:259 builtin/rm.c:432
 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"
 
@@ -2211,7 +2378,7 @@
 msgid "Checking patch %s..."
 msgstr "Đang kiểm tra miếng vá %s..."
 
-#: builtin/apply.c:3680 builtin/checkout.c:216 builtin/reset.c:127
+#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:127
 #, 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”"
@@ -2239,7 +2406,7 @@
 #: builtin/apply.c:3863 builtin/apply.c:3971
 #, c-format
 msgid "unable to add cache entry for %s"
-msgstr "không thể thêm mục nhớ tạm cho %s"
+msgstr "không thể thêm mục nhớ đệm cho %s"
 
 #: builtin/apply.c:3896
 #, c-format
@@ -2271,7 +2438,7 @@
 #: builtin/apply.c:4053
 #, 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"
+msgstr "đang cắt ngắn tên tập tin .rej thành %.*s.rej"
 
 #: builtin/apply.c:4074
 #, c-format
@@ -2291,8 +2458,8 @@
 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:4357 builtin/apply.c:4360 builtin/clone.c:91
-#: builtin/fetch.c:63
+#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90
+#: builtin/fetch.c:77
 msgid "path"
 msgstr "đường-dẫn"
 
@@ -2356,7 +2523,7 @@
 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:4389 builtin/checkout-index.c:197 builtin/ls-files.c:462
+#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:452
 msgid "paths are separated with NUL character"
 msgstr "các đường dẫn bị ngăn cách bởi ký tự NULL"
 
@@ -2455,7 +2622,7 @@
 
 #: builtin/archive.c:58
 msgid "git archive: expected ACK/NAK, got EOF"
-msgstr "git archive: mong đợi ACK/NAK, nhận EOF"
+msgstr "git archive: cần ACK/NAK, nhưng lại nhận được EOF"
 
 #: builtin/archive.c:61
 #, c-format
@@ -2473,7 +2640,7 @@
 
 #: builtin/archive.c:68
 msgid "git archive: expected a flush"
-msgstr "git archive: đã mong chờ một flush"
+msgstr "git archive: cần một flush (đẩy dữ liệu lên đĩa)"
 
 #: builtin/bisect--helper.c:7
 msgid "git bisect--helper --next-all [--no-checkout]"
@@ -2489,105 +2656,105 @@
 "cập nhật BISECT_HEAD thay vì lấy ra (checking out) lần chuyển giao (commit) "
 "hiện hành"
 
-#: builtin/blame.c:26
+#: builtin/blame.c:27
 msgid "git blame [options] [rev-opts] [rev] [--] file"
 msgstr "git blame [các-tùy-chọn] [rev-opts] [rev] [--] tập-tin"
 
-#: builtin/blame.c:31
+#: builtin/blame.c:32
 msgid "[rev-opts] are documented in git-rev-list(1)"
 msgstr "[rev-opts] được mô tả trong git-rev-list(1)"
 
-#: builtin/blame.c:2276
+#: builtin/blame.c:2248
 msgid "Show blame entries as we find them, incrementally"
 msgstr "Hiển thị các mục “blame” như là chúng ta thấy chúng, tăng dần"
 
-#: builtin/blame.c:2277
+#: builtin/blame.c:2249
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr ""
 "Hiển thị SHA-1 trắng cho những lần chuyển giao biên giới (Mặc định: off)"
 
-#: builtin/blame.c:2278
+#: builtin/blame.c:2250
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "Không coi các lần chuyển giao gốc là giới hạn (Mặc định: off)"
 
-#: builtin/blame.c:2279
+#: builtin/blame.c:2251
 msgid "Show work cost statistics"
 msgstr "Hiển thị thống kê công sức làm việc"
 
-#: builtin/blame.c:2280
+#: builtin/blame.c:2252
 msgid "Show output score for blame entries"
 msgstr "Hiển thị kết xuất điểm số có các mục tin “blame”"
 
-#: builtin/blame.c:2281
+#: builtin/blame.c:2253
 msgid "Show original filename (Default: auto)"
 msgstr "Hiển thị tên tập tin gốc (Mặc định: auto)"
 
-#: builtin/blame.c:2282
+#: builtin/blame.c:2254
 msgid "Show original linenumber (Default: off)"
 msgstr "Hiển thị số dòng gốc (Mặc định: off)"
 
-#: builtin/blame.c:2283
+#: builtin/blame.c:2255
 msgid "Show in a format designed for machine consumption"
 msgstr "Hiển thị ở định dạng đã thiết kế cho sự tiêu dùng bằng máy"
 
-#: builtin/blame.c:2284
+#: builtin/blame.c:2256
 msgid "Show porcelain format with per-line commit information"
 msgstr "Hiển thị định dạng “porcelain” với thông tin chuyển giao mỗi dòng"
 
-#: builtin/blame.c:2285
+#: builtin/blame.c:2257
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "Dùng cùng chế độ xuất ra vóigit-annotate (Mặc định: off)"
 
-#: builtin/blame.c:2286
+#: builtin/blame.c:2258
 msgid "Show raw timestamp (Default: off)"
 msgstr "Hiển thị dấu vết thời gian dạng thô (Mặc định: off)"
 
-#: builtin/blame.c:2287
+#: builtin/blame.c:2259
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Hiển thị SHA1 của lần chuyển giao (commit) dạng dài (Mặc định: off)"
 
-#: builtin/blame.c:2288
+#: builtin/blame.c:2260
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Không hiển thị tên tác giả và dấu vết thời gian (Mặc định: off)"
 
-#: builtin/blame.c:2289
+#: builtin/blame.c:2261
 msgid "Show author email instead of name (Default: off)"
 msgstr "Hiển thị thư điện tử của tác giả thay vì tên (Mặc định: off)"
 
-#: builtin/blame.c:2290
+#: builtin/blame.c:2262
 msgid "Ignore whitespace differences"
 msgstr "Bỏ qua các khác biệt do khoảng trắng gây ra"
 
-#: builtin/blame.c:2291
+#: builtin/blame.c:2263
 msgid "Spend extra cycles to find better match"
 msgstr "Tiêu thụ thêm năng tài nguyên máy móc để tìm kiếm tốt hơn nữa"
 
-#: builtin/blame.c:2292
+#: builtin/blame.c:2264
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr ""
 "Sử dụng điểm xét duyệt (revision) từ <tập tin> thay vì gọi “git-rev-list”"
 
-#: builtin/blame.c:2293
+#: builtin/blame.c:2265
 msgid "Use <file>'s contents as the final image"
 msgstr "Sử dụng nội dung của <tập tin> như là ảnh cuối cùng"
 
-#: builtin/blame.c:2294 builtin/blame.c:2295
+#: builtin/blame.c:2266 builtin/blame.c:2267
 msgid "score"
 msgstr "điểm số"
 
-#: builtin/blame.c:2294
+#: builtin/blame.c:2266
 msgid "Find line copies within and across files"
 msgstr "Tìm các bản sao chép dòng trong và ngang qua tập tin"
 
-#: builtin/blame.c:2295
+#: builtin/blame.c:2267
 msgid "Find line movements within and across files"
 msgstr "Tìm các di chuyển dòng trong và ngang qua tập tin"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "Process only line range n,m, counting from 1"
 msgstr "Xử lý chỉ dòng vùng n,m, tính từ 1"
 
@@ -2674,7 +2841,7 @@
 #: builtin/branch.c:256
 #, c-format
 msgid "Error deleting branch '%s'"
-msgstr "Lỗi khi xoá bỏ nhánh “%s”"
+msgstr "Gặp lỗi khi xoá bỏ nhánh “%s”"
 
 #: builtin/branch.c:263
 #, c-format
@@ -2693,279 +2860,289 @@
 
 #: builtin/branch.c:453
 #, c-format
+msgid "[%s: gone]"
+msgstr "[%s: đã ra đi]"
+
+#: builtin/branch.c:456
+#, c-format
+msgid "[%s]"
+msgstr "[%s]"
+
+#: builtin/branch.c:459
+#, c-format
 msgid "[%s: behind %d]"
 msgstr "[%s: đằng sau %d]"
 
-#: builtin/branch.c:455
+#: builtin/branch.c:461
 #, c-format
 msgid "[behind %d]"
 msgstr "[đằng sau %d]"
 
-#: builtin/branch.c:459
+#: builtin/branch.c:465
 #, c-format
 msgid "[%s: ahead %d]"
 msgstr "[%s: phía trước %d]"
 
-#: builtin/branch.c:461
+#: builtin/branch.c:467
 #, c-format
 msgid "[ahead %d]"
 msgstr "[phía trước %d]"
 
-#: builtin/branch.c:464
+#: builtin/branch.c:470
 #, c-format
 msgid "[%s: ahead %d, behind %d]"
 msgstr "[%s: trước %d, sau %d]"
 
-#: builtin/branch.c:467
+#: builtin/branch.c:473
 #, c-format
 msgid "[ahead %d, behind %d]"
 msgstr "[trước %d, sau %d]"
 
-#: builtin/branch.c:490
+#: builtin/branch.c:496
 msgid " **** invalid ref ****"
 msgstr " **** tham chiếu sai ****"
 
-#: builtin/branch.c:582
+#: builtin/branch.c:588
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(không nhánh, đang rebase %s)"
 
-#: builtin/branch.c:585
+#: builtin/branch.c:591
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(không nhánh, bisect được bắt đầu tại %s)"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:594
 #, c-format
 msgid "(detached from %s)"
 msgstr "(được tách rời từ %s)"
 
-#: builtin/branch.c:591
+#: builtin/branch.c:597
 msgid "(no branch)"
 msgstr "(không nhánh)"
 
-#: builtin/branch.c:637
+#: builtin/branch.c:643
 #, c-format
 msgid "object '%s' does not point to a commit"
 msgstr "đối tượng “%s” không chỉ đến một lần chuyển giao (commit) nào cả"
 
-#: builtin/branch.c:669
+#: builtin/branch.c:675
 msgid "some refs could not be read"
 msgstr "một số tham chiếu đã không thể đọc được"
 
-#: builtin/branch.c:682
+#: builtin/branch.c:688
 msgid "cannot rename the current branch while not on any."
 msgstr "không thể đổi tên nhánh hiện hành trong khi nó chẳng ở đâu cả."
 
-#: builtin/branch.c:692
+#: builtin/branch.c:698
 #, c-format
 msgid "Invalid branch name: '%s'"
-msgstr "Sai tên nhánh: “%s”"
+msgstr "Tên nhánh không hợp lệ: “%s”"
 
-#: builtin/branch.c:707
+#: builtin/branch.c:713
 msgid "Branch rename failed"
-msgstr "Đổi tên nhánh gặp lỗi"
+msgstr "Gặp lỗi khi đổi tên nhánh"
 
-#: builtin/branch.c:711
+#: builtin/branch.c:717
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Đã đổi tên nhánh khuyết danh “%s” đi"
 
-#: builtin/branch.c:715
+#: builtin/branch.c:721
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "Nhánh bị đổi tên thành %s, nhưng HEAD lại không được cập nhật!"
 
-#: builtin/branch.c:722
+#: builtin/branch.c:728
 msgid "Branch is renamed, but update of config-file failed"
 msgstr "Nhánh bị đổi tên, nhưng cập nhật tập tin cấu hình gặp lỗi"
 
-#: builtin/branch.c:737
+#: builtin/branch.c:743
 #, c-format
 msgid "malformed object name %s"
 msgstr "tên đối tượng dị hình %s"
 
-#: builtin/branch.c:761
+#: builtin/branch.c:767
 #, c-format
 msgid "could not write branch description template: %s"
 msgstr "không thể ghi vào mẫu mô tả nhánh: %s"
 
-#: builtin/branch.c:791
+#: builtin/branch.c:797
 msgid "Generic options"
 msgstr "Tùy chọn chung"
 
-#: builtin/branch.c:793
+#: builtin/branch.c:799
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "hiển thị mã băm và chủ đề, đưa ra hai lần cho nhánh thượng nguồn"
 
-#: builtin/branch.c:794
+#: builtin/branch.c:800
 msgid "suppress informational messages"
 msgstr "Thu hồi các thông điệp thông tin"
 
-#: builtin/branch.c:795
+#: builtin/branch.c:801
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "cài đặt chế độ theo vết (xem git-pull(1))"
 
-#: builtin/branch.c:797
+#: builtin/branch.c:803
 msgid "change upstream info"
 msgstr "thay đổi thông tin thượng nguồn (upstream)"
 
-#: builtin/branch.c:801
+#: builtin/branch.c:807
 msgid "use colored output"
 msgstr "sử dụng kết xuất có tô màu"
 
-#: builtin/branch.c:802
+#: builtin/branch.c:808
 msgid "act on remote-tracking branches"
 msgstr "thao tác trên nhánh “remote-tracking”"
 
-#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832
-#: builtin/branch.c:838 builtin/commit.c:1433 builtin/commit.c:1434
-#: builtin/commit.c:1435 builtin/commit.c:1436 builtin/tag.c:468
+#: builtin/branch.c:811 builtin/branch.c:817 builtin/branch.c:838
+#: builtin/branch.c:844 builtin/commit.c:1460 builtin/commit.c:1461
+#: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468
 msgid "commit"
 msgstr "commit"
 
-#: builtin/branch.c:806 builtin/branch.c:812
+#: builtin/branch.c:812 builtin/branch.c:818
 msgid "print only branches that contain the commit"
 msgstr "chỉ hiển thị những nhánh mà nó chứa lần chuyển giao"
 
-#: builtin/branch.c:818
+#: builtin/branch.c:824
 msgid "Specific git-branch actions:"
 msgstr "Hành động git-branch:"
 
-#: builtin/branch.c:819
+#: builtin/branch.c:825
 msgid "list both remote-tracking and local branches"
 msgstr "liệt kê cả nhánh “remote-tracking” và nội bộ"
 
-#: builtin/branch.c:821
+#: builtin/branch.c:827
 msgid "delete fully merged branch"
 msgstr "xóa một cách đầy đủ nhánh đã hòa trộn"
 
-#: builtin/branch.c:822
+#: builtin/branch.c:828
 msgid "delete branch (even if not merged)"
 msgstr "xoá nhánh (cho dù là chưa được hòa trộn)"
 
-#: builtin/branch.c:823
+#: builtin/branch.c:829
 msgid "move/rename a branch and its reflog"
 msgstr "di chuyển hay đổi tên một nhánh và reflog của nó"
 
-#: builtin/branch.c:824
+#: builtin/branch.c:830
 msgid "move/rename a branch, even if target exists"
 msgstr "di chuyển hoặc đổi tên một nhánh, thậm chí cả khi đích đã có sẵn"
 
-#: builtin/branch.c:825
+#: builtin/branch.c:831
 msgid "list branch names"
 msgstr "liệt kê các tên nhánh"
 
-#: builtin/branch.c:826
+#: builtin/branch.c:832
 msgid "create the branch's reflog"
 msgstr "tạo reflog của nhánh"
 
-#: builtin/branch.c:828
+#: builtin/branch.c:834
 msgid "edit the description for the branch"
 msgstr "sửa mô tả cho nhánh"
 
-#: builtin/branch.c:829
+#: builtin/branch.c:835
 msgid "force creation (when already exists)"
 msgstr "ép buộc tạo (khi đã sẵn tồn tại rồi)"
 
-#: builtin/branch.c:832
+#: builtin/branch.c:838
 msgid "print only not merged branches"
 msgstr "chỉ hiển thị các nhánh chưa được hòa trộn"
 
-#: builtin/branch.c:838
+#: builtin/branch.c:844
 msgid "print only merged branches"
 msgstr "chỉ hiển thị các nhánh được hòa trộn"
 
-#: builtin/branch.c:842
+#: builtin/branch.c:848
 msgid "list branches in columns"
 msgstr "liệt kê các nhánh trong các cột"
 
-#: builtin/branch.c:855
+#: builtin/branch.c:861
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Gặp lỗi khi phân giải HEAD như là một tham chiếu (ref) hợp lệ."
 
-#: builtin/branch.c:860 builtin/clone.c:630
+#: builtin/branch.c:866 builtin/clone.c:629
 msgid "HEAD not found below refs/heads!"
 msgstr "không tìm thấy HEAD ở dưới refs/heads!"
 
-#: builtin/branch.c:883
+#: builtin/branch.c:890
 msgid "--column and --verbose are incompatible"
 msgstr "--column và --verbose xung khắc nhau"
 
-#: builtin/branch.c:889 builtin/branch.c:928
+#: builtin/branch.c:896 builtin/branch.c:935
 msgid "branch name required"
 msgstr "cần tên nhánh"
 
-#: builtin/branch.c:904
+#: builtin/branch.c:911
 msgid "Cannot give description to detached HEAD"
 msgstr "Không thể đưa ra mô tả HEAD đã tách rời"
 
-#: builtin/branch.c:909
+#: builtin/branch.c:916
 msgid "cannot edit description of more than one branch"
 msgstr "không thể sửa mô tả cho nhiều hơn một nhánh"
 
-#: builtin/branch.c:916
+#: builtin/branch.c:923
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Vẫn chưa chuyển giao trên nhánh “%s”."
 
-#: builtin/branch.c:919
+#: builtin/branch.c:926
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Không có nhánh nào có tên “%s”."
 
-#: builtin/branch.c:934
+#: builtin/branch.c:941
 msgid "too many branches for a rename operation"
 msgstr "quá nhiều nhánh dành cho thao tác đổi tên"
 
-#: builtin/branch.c:939
+#: builtin/branch.c:946
 msgid "too many branches to set new upstream"
-msgstr "quá nhiều nhánh được đặt cho dòng ngược (upstream) mới"
+msgstr "quá nhiều nhánh được đặt cho thượng nguồn (upstream) mới"
 
-#: builtin/branch.c:943
+#: builtin/branch.c:950
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr ""
-"không thể đặt dòng ngược (upstream) của HEAD thành %s khi mà nó chẳng chỉ "
+"không thể đặt thượng nguồn (upstream) của HEAD thành %s khi mà nó chẳng chỉ "
 "đến nhánh nào cả."
 
-#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990
+#: builtin/branch.c:953 builtin/branch.c:975 builtin/branch.c:997
 #, c-format
 msgid "no such branch '%s'"
 msgstr "không có nhánh nào như thế “%s”"
 
-#: builtin/branch.c:950
+#: builtin/branch.c:957
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "nhánh “%s” chưa sẵn có"
 
-#: builtin/branch.c:962
+#: builtin/branch.c:969
 msgid "too many branches to unset upstream"
 msgstr "quá nhiều nhánh để bỏ đặt ngược dòng (upstream)"
 
-#: builtin/branch.c:966
+#: builtin/branch.c:973
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "không thể bỏ đặt ngược dòng (upstream) của HEAD không chỉ đến một nhánh nào "
 "cả."
 
-#: builtin/branch.c:972
+#: builtin/branch.c:979
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "Nhánh “%s” không có thông tin thượng nguồn (upstream)"
 
-#: builtin/branch.c:987
+#: builtin/branch.c:994
 msgid "it does not make sense to create 'HEAD' manually"
 msgstr "không hợp lý khi tạo “HEAD” thủ công "
 
-#: builtin/branch.c:993
+#: builtin/branch.c:1000
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "hai tùy chọn -a và -r áp dụng cho lệnh “git branch” không hợp lý đối với tên "
 "nhánh"
 
-#: builtin/branch.c:996
+#: builtin/branch.c:1003
 #, c-format
 msgid ""
 "The --set-upstream flag is deprecated and will be removed. Consider using --"
@@ -2974,7 +3151,7 @@
 "Cờ --set-upstream bị phản đối và sẽ bị xóa bỏ. Nên dùng --track hoặc --set-"
 "upstream-to\n"
 
-#: builtin/branch.c:1013
+#: builtin/branch.c:1020
 #, c-format
 msgid ""
 "\n"
@@ -2985,12 +3162,12 @@
 "Nếu bạn muốn “%s” theo dõi “%s”, thực hiện lệnh sau:\n"
 "\n"
 
-#: builtin/branch.c:1014
+#: builtin/branch.c:1021
 #, c-format
 msgid "    git branch -d %s\n"
 msgstr "    git branch -d %s\n"
 
-#: builtin/branch.c:1015
+#: builtin/branch.c:1022
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
 msgstr "    git branch --set-upstream-to %s\n"
@@ -3008,44 +3185,44 @@
 msgid "Need a repository to unbundle."
 msgstr "Cần một kho chứa để mà bung một bundle."
 
-#: builtin/cat-file.c:285
+#: builtin/cat-file.c:312
 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"
 msgstr "git cat-file (-t|-s|-e|-p|<kiểu>|--textconv) <đối tượng>"
 
-#: builtin/cat-file.c:286
+#: builtin/cat-file.c:313
 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>"
 msgstr "git cat-file (--batch|--batch-check) < <danh-sách-đối-tượng>"
 
-#: builtin/cat-file.c:323
+#: builtin/cat-file.c:350
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<kiểu> là một trong số: blob, tree, commit, tag"
 
-#: builtin/cat-file.c:324
+#: builtin/cat-file.c:351
 msgid "show object type"
 msgstr "hiển thị kiểu đối tượng"
 
-#: builtin/cat-file.c:325
+#: builtin/cat-file.c:352
 msgid "show object size"
 msgstr "hiển thị kích thước đối tượng"
 
-#: builtin/cat-file.c:327
+#: builtin/cat-file.c:354
 msgid "exit with zero when there's no error"
 msgstr "thoát với 0 khi không có lỗi"
 
-#: builtin/cat-file.c:328
+#: builtin/cat-file.c:355
 msgid "pretty-print object's content"
 msgstr "in nội dung đối tượng dạng dễ đọc"
 
-#: builtin/cat-file.c:330
+#: builtin/cat-file.c:357
 msgid "for blob objects, run textconv on object's content"
 msgstr "với đối tượng blob, chạy lệnh textconv trên nội dung của đối tượng"
 
-#: builtin/cat-file.c:332
+#: builtin/cat-file.c:359
 msgid "show info and content of objects fed from the standard input"
 msgstr ""
 "hiển thị thông tin và nội dung của các đối tượng lấy từ đầu vào tiêu chuẩn"
 
-#: builtin/cat-file.c:335
+#: builtin/cat-file.c:362
 msgid "show info about objects fed from the standard input"
 msgstr "hiển thị các thông tin về đối tượng fed  từ đầu vào tiêu chuẩn"
 
@@ -3071,10 +3248,10 @@
 msgstr "đọc tên tập tin từ đầu vào tiêu chuẩn"
 
 #: builtin/check-attr.c:23 builtin/check-ignore.c:24
-msgid "input paths are terminated by a null character"
-msgstr "các đường dẫn được  ngăn cách bởi ký tự null"
+msgid "terminate input and output records by a NUL character"
+msgstr "chấm dứt các bản ghi vào và ra bằng ký tự NULL"
 
-#: builtin/check-ignore.c:18 builtin/checkout.c:1054 builtin/gc.c:177
+#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:259
 msgid "suppress progress reporting"
 msgstr "chặn các báo cáo tiến trình hoạt động"
 
@@ -3082,27 +3259,31 @@
 msgid "show non-matching input paths"
 msgstr "hiển thị những đường dẫn đầu vào không khớp với mẫu"
 
-#: builtin/check-ignore.c:143
+#: builtin/check-ignore.c:28
+msgid "ignore index when checking"
+msgstr "bỏ qua mục lục khi kiểm tra"
+
+#: builtin/check-ignore.c:154
 msgid "cannot specify pathnames with --stdin"
 msgstr "không thể chỉ định các tên đường dẫn với --stdin"
 
-#: builtin/check-ignore.c:146
+#: builtin/check-ignore.c:157
 msgid "-z only makes sense with --stdin"
 msgstr "-z chỉ hợp lý với --stdin"
 
-#: builtin/check-ignore.c:148
+#: builtin/check-ignore.c:159
 msgid "no path specified"
-msgstr "chưa ghi rõ đường dẫn"
+msgstr "chưa chỉ ra đường dẫn"
 
-#: builtin/check-ignore.c:152
+#: builtin/check-ignore.c:163
 msgid "--quiet is only valid with a single pathname"
 msgstr "--quiet chỉ hợp lệ với tên đường dẫn đơn"
 
-#: builtin/check-ignore.c:154
+#: builtin/check-ignore.c:165
 msgid "cannot have both --quiet and --verbose"
 msgstr "không thể dùng cả hai tùy chọn --quiet và --verbose"
 
-#: builtin/check-ignore.c:157
+#: builtin/check-ignore.c:168
 msgid "--non-matching is only valid with --verbose"
 msgstr "tùy-chọn --non-matching chỉ hợp lệ khi dùng với --verbose"
 
@@ -3176,107 +3357,107 @@
 msgid "git checkout [options] [<branch>] -- <file>..."
 msgstr "git checkout [các-tùy-chọn] [<nhánh>] -- <tập-tin>..."
 
-#: builtin/checkout.c:117 builtin/checkout.c:150
+#: 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:119 builtin/checkout.c:152
+#: 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:135
+#: 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:179
+#: 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:196
+#: 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:213
+#: 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:237 builtin/checkout.c:240 builtin/checkout.c:243
-#: builtin/checkout.c:246
+#: builtin/checkout.c:232 builtin/checkout.c:235 builtin/checkout.c:238
+#: builtin/checkout.c:241
 #, c-format
 msgid "'%s' cannot be used with updating paths"
 msgstr "“%s” không thể được sử dụng với các đường dẫn cập nhật"
 
-#: builtin/checkout.c:249 builtin/checkout.c:252
+#: builtin/checkout.c:244 builtin/checkout.c:247
 #, c-format
 msgid "'%s' cannot be used with %s"
-msgstr "“%s” không thể được sử dụng với %s"
+msgstr "“%s” không thể được dùng cùng với %s"
 
-#: builtin/checkout.c:255
+#: builtin/checkout.c:250
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
 msgstr ""
 "Không thể cập nhật các đường dẫn và chuyển đến nhánh “%s” cùng một lúc."
 
-#: builtin/checkout.c:266 builtin/checkout.c:458
+#: builtin/checkout.c:261 builtin/checkout.c:451
 msgid "corrupt index file"
 msgstr "tập tin ghi bảng mục lục bị hỏng"
 
-#: builtin/checkout.c:329 builtin/checkout.c:336
+#: builtin/checkout.c:322 builtin/checkout.c:329
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "đường dẫn “%s” không được hòa trộn"
 
-#: builtin/checkout.c:480
+#: builtin/checkout.c:473
 msgid "you need to resolve your current index first"
 msgstr "bạn cần phải phân giải bảng mục lục hiện tại của bạn trước đã"
 
-#: builtin/checkout.c:601
+#: builtin/checkout.c:594
 #, 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:639
+#: builtin/checkout.c:632
 msgid "HEAD is now at"
 msgstr "HEAD hiện giờ tại"
 
-#: builtin/checkout.c:646
+#: builtin/checkout.c:639
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Đặt lại nhánh “%s”\n"
 
-#: builtin/checkout.c:649
+#: builtin/checkout.c:642
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Đã sẵn sàng trên “%s”\n"
 
-#: builtin/checkout.c:653
+#: builtin/checkout.c:646
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Đã chuyển tới và reset nhánh “%s”\n"
 
-#: builtin/checkout.c:655 builtin/checkout.c:997
+#: builtin/checkout.c:648 builtin/checkout.c:1033
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Đã chuyển đến nhánh mới “%s”\n"
 
-#: builtin/checkout.c:657
+#: builtin/checkout.c:650
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Đã chuyển đến nhánh “%s”\n"
 
-#: builtin/checkout.c:713
+#: builtin/checkout.c:706
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... và nhiều hơn %d.\n"
 
 #. The singular version
-#: builtin/checkout.c:719
+#: builtin/checkout.c:712
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -3301,7 +3482,7 @@
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:737
+#: builtin/checkout.c:730
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -3317,138 +3498,142 @@
 " git branch tên_nhánh_mới %s\n"
 "\n"
 
-#: builtin/checkout.c:767
+#: builtin/checkout.c:760
 msgid "internal error in revision walk"
 msgstr "lỗi nội bộ trong khi di chuyển qua các điểm xét duyệt"
 
-#: builtin/checkout.c:771
+#: builtin/checkout.c:764
 msgid "Previous HEAD position was"
 msgstr "Vị trí kế trước của HEAD là"
 
-#: builtin/checkout.c:798 builtin/checkout.c:992
+#: builtin/checkout.c:791 builtin/checkout.c:1028
 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:928
+#: builtin/checkout.c:935
+#, c-format
+msgid "only one reference expected, %d given."
+msgstr "chỉ cần một tham chiếu, nhưng lại đưa ra %d."
+
+#: builtin/checkout.c:974
 #, c-format
 msgid "invalid reference: %s"
 msgstr "tham chiếu sai: %s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:967
+#: builtin/checkout.c:1003
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "tham chiếu không phải là một cây (tree):%s"
 
-#: builtin/checkout.c:1006
+#: builtin/checkout.c:1042
 msgid "paths cannot be used with switching branches"
 msgstr "các đường dẫn không thể dùng cùng với các nhánh chuyển"
 
-#: builtin/checkout.c:1009 builtin/checkout.c:1013
+#: builtin/checkout.c:1045 builtin/checkout.c:1049
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "“%s” không thể được sử dụng với các nhánh chuyển"
 
-#: builtin/checkout.c:1017 builtin/checkout.c:1020 builtin/checkout.c:1025
-#: builtin/checkout.c:1028
+#: builtin/checkout.c:1053 builtin/checkout.c:1056 builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "“%s” không thể được sử dụng với “%s”"
 
-#: builtin/checkout.c:1033
+#: builtin/checkout.c:1069
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "Không thể chuyển nhánh đến một non-commit “%s”"
 
-#: builtin/checkout.c:1055 builtin/checkout.c:1057 builtin/clone.c:89
+#: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88
 #: builtin/remote.c:169 builtin/remote.c:171
 msgid "branch"
 msgstr "nhánh"
 
-#: builtin/checkout.c:1056
+#: builtin/checkout.c:1092
 msgid "create and checkout a new branch"
 msgstr "tạo và checkout một nhánh mới"
 
-#: builtin/checkout.c:1058
+#: builtin/checkout.c:1094
 msgid "create/reset and checkout a branch"
 msgstr "create/reset và checkout một nhánh"
 
-#: builtin/checkout.c:1059
+#: builtin/checkout.c:1095
 msgid "create reflog for new branch"
 msgstr "tạo reflog cho nhánh mới"
 
-#: builtin/checkout.c:1060
+#: builtin/checkout.c:1096
 msgid "detach the HEAD at named commit"
 msgstr "rời bỏ HEAD tại lần chuyển giao danh nghĩa"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1097
 msgid "set upstream info for new branch"
 msgstr "đặt thông tin thượng nguồn (upstream) cho nhánh mới"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new branch"
 msgstr "nhánh mới"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new unparented branch"
 msgstr "nhánh mồ côi mới"
 
-#: builtin/checkout.c:1064
+#: builtin/checkout.c:1100
 msgid "checkout our version for unmerged files"
 msgstr ""
 "lấy ra (checkout) phiên bản của chúng ta cho các tập tin chưa được hòa trộn"
 
-#: builtin/checkout.c:1066
+#: builtin/checkout.c:1102
 msgid "checkout their version for unmerged files"
 msgstr ""
 "lấy ra (checkout) phiên bản của chúng họ cho các tập tin chưa được hòa trộn"
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1104
 msgid "force checkout (throw away local modifications)"
 msgstr "ép buộc lấy ra (checkout) (bỏ đi những thay đổi nội bộ)"
 
-#: builtin/checkout.c:1069
+#: builtin/checkout.c:1105
 msgid "perform a 3-way merge with the new branch"
 msgstr "thực hiện hòa trộn kiểu 3-way với nhánh mới"
 
-#: builtin/checkout.c:1070 builtin/merge.c:232
+#: builtin/checkout.c:1106 builtin/merge.c:232
 msgid "update ignored files (default)"
 msgstr "cập nhật các tập tin bị bỏ qua (mặc định)"
 
-#: builtin/checkout.c:1071 builtin/log.c:1208 parse-options.h:249
+#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:251
 msgid "style"
 msgstr "kiểu"
 
-#: builtin/checkout.c:1072
+#: builtin/checkout.c:1108
 msgid "conflict style (merge or diff3)"
 msgstr "xung đột kiểu (hòa trộn hay diff3)"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1111
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "không giới hạn pathspecs chỉ thành các mục thưa thớt"
 
-#: builtin/checkout.c:1077
+#: builtin/checkout.c:1113
 msgid "second guess 'git checkout no-such-branch'"
 msgstr "gợi ý thứ hai “git checkout không-nhánh-nào-như-vậy”"
 
-#: builtin/checkout.c:1101
+#: builtin/checkout.c:1136
 msgid "-b, -B and --orphan are mutually exclusive"
-msgstr "Tùy chọn -b|-B và --orphan loại từ lẫn nhau"
+msgstr "Tùy chọn -b, -B và --orphan loại từ lẫn nhau"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1153
 msgid "--track needs a branch name"
 msgstr "--track cần tên một nhánh"
 
-#: builtin/checkout.c:1125
+#: builtin/checkout.c:1160
 msgid "Missing branch name; try -b"
 msgstr "Thiếu tên nhánh; hãy thử -b"
 
-#: builtin/checkout.c:1160
+#: builtin/checkout.c:1197
 msgid "invalid path specification"
 msgstr "đường dẫn đã cho không hợp lệ"
 
-#: builtin/checkout.c:1167
+#: builtin/checkout.c:1204
 #, c-format
 msgid ""
 "Cannot update paths and switch to branch '%s' at the same time.\n"
@@ -3458,12 +3643,12 @@
 "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:1172
+#: builtin/checkout.c:1209
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach không nhận một đối số đường dẫn “%s”"
 
-#: builtin/checkout.c:1176
+#: builtin/checkout.c:1213
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -3471,38 +3656,38 @@
 "git checkout: --ours/--theirs, --force và --merge là xung khắc với nhau khi\n"
 "checkout bảng mục lục (index)."
 
-#: builtin/clean.c:25
+#: builtin/clean.c:26
 msgid ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
 msgstr ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <mẫu>] [-x | -X] [--] <đường-dẫn>..."
 
-#: builtin/clean.c:29
+#: builtin/clean.c:30
 #, c-format
 msgid "Removing %s\n"
 msgstr "Đang gỡ bỏ %s\n"
 
-#: builtin/clean.c:30
+#: builtin/clean.c:31
 #, c-format
 msgid "Would remove %s\n"
 msgstr "Có thể gỡ bỏ %s\n"
 
-#: builtin/clean.c:31
+#: builtin/clean.c:32
 #, c-format
 msgid "Skipping repository %s\n"
 msgstr "Đang bỏ qua kho chứa %s\n"
 
-#: builtin/clean.c:32
+#: builtin/clean.c:33
 #, c-format
 msgid "Would skip repository %s\n"
 msgstr "Nên bỏ qua kho chứa %s\n"
 
-#: builtin/clean.c:33
+#: builtin/clean.c:34
 #, c-format
 msgid "failed to remove %s"
 msgstr "gặp lỗi khi gỡ bỏ %s"
 
-#: builtin/clean.c:293
+#: builtin/clean.c:294
 msgid ""
 "Prompt help:\n"
 "1          - select a numbered item\n"
@@ -3514,7 +3699,7 @@
 "foo        - chọn mục trên cơ sở tiền tố duy nhất\n"
 "           - (trống rỗng) không chọn gì cả"
 
-#: builtin/clean.c:297
+#: builtin/clean.c:298
 msgid ""
 "Prompt help:\n"
 "1          - select a single item\n"
@@ -3534,35 +3719,35 @@
 "*          - chọn tất\n"
 "           - (trống rỗng) kết thúc việc chọn"
 
-#: builtin/clean.c:515
+#: builtin/clean.c:516
 #, c-format
 msgid "Huh (%s)?"
 msgstr "Hả (%s)?"
 
-#: builtin/clean.c:658
+#: builtin/clean.c:659
 #, c-format
 msgid "Input ignore patterns>> "
 msgstr "Mẫu để lọc các tập tin cần lờ đi đầu vào>>"
 
-#: builtin/clean.c:695
+#: builtin/clean.c:696
 #, c-format
 msgid "WARNING: Cannot find items matched by: %s"
 msgstr "CẢNH BÁO: Không tìm thấy các mục được khớp bởi: %s"
 
-#: builtin/clean.c:716
+#: builtin/clean.c:717
 msgid "Select items to delete"
 msgstr "Chọn mục muốn xóa"
 
-#: builtin/clean.c:756
+#: builtin/clean.c:757
 #, c-format
 msgid "remove %s? "
 msgstr "gỡ bỏ “%s”?"
 
-#: builtin/clean.c:781
+#: builtin/clean.c:782
 msgid "Bye."
 msgstr "Tạm biệt."
 
-#: builtin/clean.c:789
+#: builtin/clean.c:790
 msgid ""
 "clean               - start cleaning\n"
 "filter by pattern   - exclude items from deletion\n"
@@ -3580,21 +3765,21 @@
 "help                - hiển thị chính trợ giúp này\n"
 "?                   - trợ giúp dành cho chọn bằng cách nhắc"
 
-#: builtin/clean.c:816
+#: builtin/clean.c:817
 msgid "*** Commands ***"
 msgstr "*** Lệnh ***"
 
-#: builtin/clean.c:817
+#: builtin/clean.c:818
 msgid "What now"
 msgstr "Giờ thì sao"
 
-#: builtin/clean.c:825
+#: builtin/clean.c:826
 msgid "Would remove the following item:"
 msgid_plural "Would remove the following items:"
 msgstr[0] "Có muốn gỡ bỏ mục sau đây không:"
 msgstr[1] "Có muốn gỡ bỏ các mục sau đây không:"
 
-#: builtin/clean.c:842
+#: builtin/clean.c:843
 msgid "No more files to clean, exiting."
 msgstr "Không còn tập-tin nào để dọn dẹp, đang thoát ra."
 
@@ -3614,8 +3799,8 @@
 msgid "remove whole directories"
 msgstr "gỡ bỏ toàn bộ thư mục"
 
-#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:716
-#: builtin/ls-files.c:493 builtin/name-rev.c:315 builtin/show-ref.c:186
+#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718
+#: builtin/ls-files.c:483 builtin/name-rev.c:315 builtin/show-ref.c:185
 msgid "pattern"
 msgstr "mẫu"
 
@@ -3655,8 +3840,8 @@
 msgid "git clone [options] [--] <repo> [<dir>]"
 msgstr "git clone [các-tùy-chọn] [--] <kho> [<t.mục>]"
 
-#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:229
-#: builtin/push.c:462
+#: builtin/clone.c:64 builtin/fetch.c:96 builtin/merge.c:229
+#: builtin/push.c:474
 msgid "force progress reporting"
 msgstr "ép buộc báo cáo tiến trình"
 
@@ -3666,125 +3851,125 @@
 
 #: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488
 msgid "create a bare repository"
-msgstr "tạo kho chứa bare"
+msgstr "tạo kho thuần (bare)"
 
-#: builtin/clone.c:72
+#: builtin/clone.c:71
 msgid "create a mirror repository (implies bare)"
 msgstr "tạo kho bản sao (mirror) (ngụ ý là bare)"
 
-#: builtin/clone.c:74
+#: builtin/clone.c:73
 msgid "to clone from a local repository"
 msgstr "để nhân bản từ kho nội bộ"
 
-#: builtin/clone.c:76
+#: builtin/clone.c:75
 msgid "don't use local hardlinks, always copy"
 msgstr "không sử dụng liên kết cứng nội bộ, luôn sao chép"
 
-#: builtin/clone.c:78
+#: builtin/clone.c:77
 msgid "setup as shared repository"
 msgstr "cài đặt đây là kho chia sẻ"
 
-#: builtin/clone.c:80 builtin/clone.c:82
+#: builtin/clone.c:79 builtin/clone.c:81
 msgid "initialize submodules in the clone"
 msgstr "khởi tạo mô-đun-con trong bản sao"
 
-#: builtin/clone.c:83 builtin/init-db.c:485
+#: builtin/clone.c:82 builtin/init-db.c:485
 msgid "template-directory"
 msgstr "thư-mục-tạm"
 
-#: builtin/clone.c:84 builtin/init-db.c:486
+#: builtin/clone.c:83 builtin/init-db.c:486
 msgid "directory from which templates will be used"
 msgstr "thư mục mà tại đó các mẫu sẽ được dùng"
 
-#: builtin/clone.c:86
+#: builtin/clone.c:85
 msgid "reference repository"
 msgstr "kho tham chiếu"
 
-#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44
+#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44
 msgid "name"
 msgstr "tên"
 
-#: builtin/clone.c:88
+#: builtin/clone.c:87
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "dùng <tên> thay vì “origin” để theo dõi thượng nguồn (uptream)"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:89
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "lấy ra nhánh (checkout <nhánh>) thay vì HEAD của máy chủ"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:91
 msgid "path to git-upload-pack on the remote"
 msgstr "đường dẫn đến git-upload-pack trên máy chủ"
 
-#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:661
+#: builtin/clone.c:92 builtin/fetch.c:97 builtin/grep.c:663
 msgid "depth"
 msgstr "độ sâu"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:93
 msgid "create a shallow clone of that depth"
 msgstr "tạo bản sao không đầy đủ cho mức sâu đã cho"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:95
 msgid "clone only one branch, HEAD or --branch"
 msgstr "nhân bản (clone) chỉ một nhánh, HEAD hoặc --branch"
 
-#: builtin/clone.c:97 builtin/init-db.c:494
+#: builtin/clone.c:96 builtin/init-db.c:494
 msgid "gitdir"
 msgstr "gitdir"
 
-#: builtin/clone.c:98 builtin/init-db.c:495
+#: builtin/clone.c:97 builtin/init-db.c:495
 msgid "separate git dir from working tree"
 msgstr "không dùng chung thư mục dành riêng cho git và thư mục làm việc"
 
-#: builtin/clone.c:99
+#: builtin/clone.c:98
 msgid "key=value"
 msgstr "khóa=giá trị"
 
-#: builtin/clone.c:100
+#: builtin/clone.c:99
 msgid "set config inside the new repository"
 msgstr "đặt cấu hình bên trong một kho chứa mới"
 
-#: builtin/clone.c:253
+#: builtin/clone.c:252
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "kho tham chiếu “%s” không phải là một kho nội bộ."
 
-#: builtin/clone.c:316
+#: builtin/clone.c:315
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "tạo thư mục \"%s\" gặp lỗi"
 
-#: builtin/clone.c:318 builtin/diff.c:77
+#: builtin/clone.c:317 builtin/diff.c:77
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "gặp lỗi stat (lấy trạng thái về) “%s”"
 
-#: builtin/clone.c:320
+#: builtin/clone.c:319
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s tồn tại nhưng không phải là một thư mục"
 
-#: builtin/clone.c:334
+#: builtin/clone.c:333
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "lỗi stat (lấy trạng thái về) %s\n"
 
-#: builtin/clone.c:356
+#: builtin/clone.c:355
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "gặp lỗi khi tạo được liên kết mềm %s"
 
-#: builtin/clone.c:360
+#: builtin/clone.c:359
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "gặp lỗi khi chép tập tin tới “%s”"
 
-#: builtin/clone.c:383
+#: builtin/clone.c:382 builtin/clone.c:559
 #, c-format
 msgid "done.\n"
 msgstr "hoàn tất.\n"
 
-#: builtin/clone.c:396
+#: builtin/clone.c:395
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -3794,104 +3979,99 @@
 "Bạn kiểm tra kỹ xem cái gì được lấy ra bằng lệnh “git status”\n"
 "và thử checkout với lệnh “git checkout -f HEAD”\n"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:474
 #, 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:555
+#: builtin/clone.c:554
 #, c-format
 msgid "Checking connectivity... "
 msgstr "Đang kiểm tra kết nối..."
 
-#: builtin/clone.c:558
+#: builtin/clone.c:557
 msgid "remote did not send all necessary objects"
 msgstr "máy chủ đã không gửi tất cả các đối tượng cần thiết"
 
-#: builtin/clone.c:560
-#, c-format
-msgid "done\n"
-msgstr "xong.\n"
-
-#: builtin/clone.c:621
+#: builtin/clone.c:620
 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:652
+#: builtin/clone.c:651
 msgid "unable to checkout working tree"
 msgstr "không thể lấy ra (checkout) cây làm việc"
 
-#: builtin/clone.c:760
+#: builtin/clone.c:759
 msgid "Too many arguments."
 msgstr "Có quá nhiều đối số."
 
-#: builtin/clone.c:764
+#: builtin/clone.c:763
 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:775
+#: builtin/clone.c:774
 #, 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:778
+#: builtin/clone.c:777
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "tùy chọn --bare và --separate-git-dir xung khắc nhau."
 
-#: builtin/clone.c:791
+#: builtin/clone.c:790
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "kho chứa “%s” chưa tồn tại"
 
-#: builtin/clone.c:796
+#: builtin/clone.c:795
 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:798
+#: builtin/clone.c:797
 msgid "--local is ignored"
 msgstr "--local bị lờ đi"
 
-#: builtin/clone.c:808
+#: builtin/clone.c:807
 #, 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:818
+#: builtin/clone.c:817
 #, 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:831 builtin/clone.c:843
+#: builtin/clone.c:830 builtin/clone.c:842
 #, 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:834
+#: builtin/clone.c:833
 #, 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:853
+#: builtin/clone.c:852
 #, 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:855
+#: builtin/clone.c:854
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Đang nhân bản thành “%s”...\n"
 
-#: builtin/clone.c:890
+#: builtin/clone.c:888
 #, 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:942
+#: builtin/clone.c:939 builtin/clone.c:947
 #, 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 thượng nguồn (upstream) %s"
 
-#: builtin/clone.c:949
+#: builtin/clone.c:950
 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."
 
@@ -3913,11 +4093,11 @@
 
 #: builtin/column.c:30
 msgid "Padding space on left border"
-msgstr "Chèn thêm khoảng trống vào bờ bên trái"
+msgstr "Chèn thêm khoảng trống vào bên trái"
 
 #: builtin/column.c:31
 msgid "Padding space on right border"
-msgstr "Chèn thêm khoảng trắng vào tiếp giáp bên phải"
+msgstr "Chèn thêm khoảng trắng vào bên phải"
 
 #: builtin/column.c:32
 msgid "Padding space between columns"
@@ -3927,15 +4107,15 @@
 msgid "--command must be the first argument"
 msgstr "--command phải là đối số đầu tiên"
 
-#: builtin/commit.c:35
+#: builtin/commit.c:36
 msgid "git commit [options] [--] <pathspec>..."
 msgstr "git commit [các-tùy-chọn] [--] <pathspec>..."
 
-#: builtin/commit.c:40
+#: builtin/commit.c:41
 msgid "git status [options] [--] <pathspec>..."
 msgstr "git status [các-tùy-chọn] [--] <pathspec>..."
 
-#: builtin/commit.c:45
+#: builtin/commit.c:46
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3959,11 +4139,11 @@
 "    git config --global user.email you@example.com\n"
 "\n"
 "Sau khi thực hiện xong, bạn có thể sửa chữa định danh được sử dụng cho lần "
-"chuyển giao (commit) này với lệnh:\n"
+"chuyển giao này với lệnh:\n"
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: builtin/commit.c:57
+#: builtin/commit.c:58
 msgid ""
 "You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
@@ -3976,7 +4156,7 @@
 "hoặc là bạn gỡ bỏ các lần chuyển giao một cách hoàn toàn bằng lệnh:\n"
 "\"git reset HEAD^\".\n"
 
-#: builtin/commit.c:62
+#: builtin/commit.c:63
 msgid ""
 "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 "If you wish to commit it anyway, use:\n"
@@ -3991,11 +4171,11 @@
 "    git commit --allow-empty\n"
 "\n"
 
-#: builtin/commit.c:69
+#: builtin/commit.c:70
 msgid "Otherwise, please use 'git reset'\n"
 msgstr "Nếu không được thì dùng lệnh \"git reset\"\n"
 
-#: builtin/commit.c:72
+#: builtin/commit.c:73
 msgid ""
 "If you wish to skip this commit, use:\n"
 "\n"
@@ -4011,97 +4191,97 @@
 "Thế thì \"git cherry-pick --continue\" sẽ phục hồi lại việc cherry-pick\n"
 "những lần chuyển giao còn lại.\n"
 
-#: builtin/commit.c:279
+#: builtin/commit.c:287
 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:321
+#: builtin/commit.c:329
 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:327
+#: builtin/commit.c:335
 msgid "interactive add failed"
 msgstr "việc thêm tương tác gặp lỗi"
 
-#: builtin/commit.c:360 builtin/commit.c:381 builtin/commit.c:431
+#: builtin/commit.c:368 builtin/commit.c:389 builtin/commit.c:439
 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:412
+#: builtin/commit.c:420
 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:414
+#: builtin/commit.c:422
 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:424
+#: builtin/commit.c:432
 msgid "cannot read the index"
 msgstr "không đọc được bảng mục lục"
 
-#: builtin/commit.c:444
+#: builtin/commit.c:452
 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:535 builtin/commit.c:541
+#: builtin/commit.c:543 builtin/commit.c:549
 #, c-format
 msgid "invalid commit: %s"
 msgstr "lần chuyển giao (commit) không hợp lệ: %s"
 
-#: builtin/commit.c:563
+#: builtin/commit.c:571
 msgid "malformed --author parameter"
 msgstr "đối số --author bị dị hình"
 
-#: builtin/commit.c:583
+#: builtin/commit.c:591
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "Chuỗi thụt lề đầu dòng dị hình: “%s”"
 
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:982
+#: builtin/commit.c:630 builtin/commit.c:663 builtin/commit.c:1007
 #, 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:633 builtin/shortlog.c:271
+#: builtin/commit.c:642 builtin/shortlog.c:273
 #, 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:635
+#: builtin/commit.c:644
 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:639
+#: builtin/commit.c:648
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "không đọc được tệp nhật ký “%s”"
 
-#: builtin/commit.c:645
+#: builtin/commit.c:654
 msgid "commit has empty message"
 msgstr "lần chuyển giao (commit) có ghi chú trống rỗng"
 
-#: builtin/commit.c:661
+#: builtin/commit.c:670
 msgid "could not read MERGE_MSG"
 msgstr "không thể đọc MERGE_MSG"
 
-#: builtin/commit.c:665
+#: builtin/commit.c:674
 msgid "could not read SQUASH_MSG"
 msgstr "không thể đọc SQUASH_MSG"
 
-#: builtin/commit.c:669
+#: builtin/commit.c:678
 #, c-format
 msgid "could not read '%s'"
 msgstr "Không thể đọc “%s”."
 
-#: builtin/commit.c:730
+#: builtin/commit.c:749
 msgid "could not write commit template"
 msgstr "không thể ghi mẫu commit"
 
-#: builtin/commit.c:741
+#: builtin/commit.c:760
 #, c-format
 msgid ""
 "\n"
@@ -4116,7 +4296,7 @@
 "\t%s\n"
 "và thử lại.\n"
 
-#: builtin/commit.c:746
+#: builtin/commit.c:765
 #, c-format
 msgid ""
 "\n"
@@ -4131,7 +4311,7 @@
 "\t%s\n"
 "và thử lại.\n"
 
-#: builtin/commit.c:758
+#: builtin/commit.c:777
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4142,7 +4322,7 @@
 "bắt đầu bằng “%c” sẽ được bỏ qua, nếu phần chú thích rỗng sẽ hủy bỏ lần "
 "chuyển giao (commit).\n"
 
-#: builtin/commit.c:763
+#: builtin/commit.c:782
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4154,148 +4334,148 @@
 "bắt đầu bằng “%c” sẽ được bỏ qua; bạn có thể xóa chúng đi nếu muốn thế.\n"
 "Phần chú thích này nếu trống rỗng sẽ hủy bỏ lần chuyển giao (commit).\n"
 
-#: builtin/commit.c:776
+#: builtin/commit.c:795
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%sTác giả:    %s"
 
-#: builtin/commit.c:783
+#: builtin/commit.c:802
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%sNgười chuyển giao (commit): %s"
 
-#: builtin/commit.c:803
+#: builtin/commit.c:822
 msgid "Cannot read index"
 msgstr "không đọc được bảng mục lục"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:865
 msgid "Error building trees"
 msgstr "Gặp lỗi khi xây dựng cây"
 
-#: builtin/commit.c:860 builtin/tag.c:359
+#: builtin/commit.c:880 builtin/tag.c:359
 #, 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"
+msgstr "Xin hãy cung cấp lời chú giải hoặc là dùng tùy chọn -m hoặc là -F.\n"
 
-#: builtin/commit.c:957
+#: builtin/commit.c:982
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "Không tìm thấy tác giả có sẵn với “%s”"
 
-#: builtin/commit.c:972 builtin/commit.c:1208
+#: builtin/commit.c:997 builtin/commit.c:1237
 #, 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:1009
+#: builtin/commit.c:1034
 msgid "--long and -z are incompatible"
 msgstr "hai tùy chọn -long và -z không tương thích với nhau"
 
-#: builtin/commit.c:1039
+#: builtin/commit.c:1064
 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:1050
+#: builtin/commit.c:1075
 msgid "You have nothing to amend."
 msgstr "Không có gì để amend (tu bổ) cả."
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1078
 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:1055
+#: builtin/commit.c:1080
 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:1058
+#: builtin/commit.c:1083
 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:1068
+#: builtin/commit.c:1093
 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:1070
+#: builtin/commit.c:1095
 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:1078
+#: builtin/commit.c:1103
 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:1095
+#: builtin/commit.c:1120
 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:1097
+#: builtin/commit.c:1122
 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:1099
+#: builtin/commit.c:1124
 msgid "Clever... amending the last one with dirty index."
-msgstr "Giỏi...  tu bổ cái cuối với bảng mục lục phi nghĩa."
+msgstr "Giỏi...  tu bổ cái cuối với bảng mục lục bẩn."
 
-#: builtin/commit.c:1101
+#: builtin/commit.c:1126
 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:1111 builtin/tag.c:575
+#: builtin/commit.c:1136 builtin/tag.c:572
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Chế độ dọn dẹp không hợp lệ %s"
 
-#: builtin/commit.c:1116
+#: builtin/commit.c:1141
 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:1222 builtin/commit.c:1455
+#: builtin/commit.c:1251 builtin/commit.c:1482
 msgid "show status concisely"
 msgstr "hiển thị trạng thái ở dạng súc tích"
 
-#: builtin/commit.c:1224 builtin/commit.c:1457
+#: builtin/commit.c:1253 builtin/commit.c:1484
 msgid "show branch information"
 msgstr "hiển thị thông tin nhánh"
 
-#: builtin/commit.c:1226 builtin/commit.c:1459 builtin/push.c:452
+#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:460
 msgid "machine-readable output"
 msgstr "kết xuất dạng máy-có-thể-đọc"
 
-#: builtin/commit.c:1229 builtin/commit.c:1461
+#: builtin/commit.c:1258 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "hiển thị trạng thái ở định dạng dài (mặc định)"
 
-#: builtin/commit.c:1232 builtin/commit.c:1464
+#: builtin/commit.c:1261 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "chấm dứt các mục bằng NUL"
 
-#: builtin/commit.c:1234 builtin/commit.c:1467 builtin/fast-export.c:667
-#: builtin/fast-export.c:670 builtin/tag.c:459
+#: builtin/commit.c:1263 builtin/commit.c:1494 builtin/fast-export.c:674
+#: builtin/fast-export.c:677 builtin/tag.c:459
 msgid "mode"
 msgstr "chế độ"
 
-#: builtin/commit.c:1235 builtin/commit.c:1467
+#: builtin/commit.c:1264 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 "hiển thị các tập tin chưa được theo dõi  dấu vết, các chế độ tùy chọn:  all, "
 "normal, no. (Mặc định: all)"
 
-#: builtin/commit.c:1238
+#: builtin/commit.c:1267
 msgid "show ignored files"
 msgstr "hiển thị các tập tin ẩn"
 
-#: builtin/commit.c:1239 parse-options.h:154
+#: builtin/commit.c:1268 parse-options.h:156
 msgid "when"
 msgstr "khi"
 
-#: builtin/commit.c:1240
+#: builtin/commit.c:1269
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -4303,223 +4483,223 @@
 "bỏ qua các thay đổi trong mô-đun-con, tùy chọn khi: all, dirty, untracked. "
 "(Mặc định: all)"
 
-#: builtin/commit.c:1242
+#: builtin/commit.c:1271
 msgid "list untracked files in columns"
 msgstr "hiển thị danh sách các tập-tin chưa được theo dõi trong các cột"
 
-#: builtin/commit.c:1313
+#: builtin/commit.c:1340
 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:1315
+#: builtin/commit.c:1342
 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:1356
+#: builtin/commit.c:1383
 msgid "detached HEAD"
 msgstr "đã rời khỏi HEAD"
 
-#: builtin/commit.c:1358
+#: builtin/commit.c:1385
 msgid " (root-commit)"
 msgstr " (root-commit)"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1452
 msgid "suppress summary after successful commit"
 msgstr "không hiển thị tổng kết sau khi chuyển giao thành công"
 
-#: builtin/commit.c:1426
+#: builtin/commit.c:1453
 msgid "show diff in commit message template"
 msgstr "hiển thị sự khác biệt trong mẫu tin nhắn chuyển giao"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1455
 msgid "Commit message options"
 msgstr "Các tùy chọn ghi chú commit"
 
-#: builtin/commit.c:1429 builtin/tag.c:457
+#: builtin/commit.c:1456 builtin/tag.c:457
 msgid "read message from file"
 msgstr "đọc chú thích từ tập tin"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "author"
 msgstr "tác giả"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "override author for commit"
 msgstr "ghi đè tác giả cho commit"
 
-#: builtin/commit.c:1431 builtin/gc.c:178
+#: builtin/commit.c:1458 builtin/gc.c:260
 msgid "date"
 msgstr "ngày tháng"
 
-#: builtin/commit.c:1431
+#: builtin/commit.c:1458
 msgid "override date for commit"
 msgstr "ghi đè ngày tháng cho commit"
 
-#: builtin/commit.c:1432 builtin/merge.c:223 builtin/notes.c:405
+#: builtin/commit.c:1459 builtin/merge.c:223 builtin/notes.c:405
 #: builtin/notes.c:562 builtin/tag.c:455
 msgid "message"
 msgstr "thông điệp"
 
-#: builtin/commit.c:1432
+#: builtin/commit.c:1459
 msgid "commit message"
 msgstr "chú thích của lần commit"
 
-#: builtin/commit.c:1433
+#: builtin/commit.c:1460
 msgid "reuse and edit message from specified commit"
 msgstr ""
 "dùng lại các ghi chú từ lần chuyển giao (commit) đã cho nhưng có cho sửa chữa"
 
-#: builtin/commit.c:1434
+#: builtin/commit.c:1461
 msgid "reuse message from specified commit"
 msgstr "dùng lại các ghi chú từ lần chuyển giao (commit) đã cho"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1462
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 "dùng ghi chú có định dạng autosquash để sửa chữa lần chuyển giao đã chỉ ra"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1463
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 "dùng lời nhắn có định dạng tự động nén để nén lại các lần chuyển giao đã chỉ "
 "ra"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1464
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr ""
 "lần chuyển giao nhận tôi là tác giả (được dùng với tùy chọn -C/-c/--amend)"
 
-#: builtin/commit.c:1438 builtin/log.c:1160 builtin/revert.c:111
+#: builtin/commit.c:1465 builtin/log.c:1180 builtin/revert.c:86
 msgid "add Signed-off-by:"
 msgstr "thêm dòng Signed-off-by:"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1466
 msgid "use specified template file"
 msgstr "sử dụng tập tin mẫu đã cho"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1467
 msgid "force edit of commit"
 msgstr "ép buộc sửa lần commit"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1468
 msgid "default"
 msgstr "mặc định"
 
-#: builtin/commit.c:1441 builtin/tag.c:460
+#: builtin/commit.c:1468 builtin/tag.c:460
 msgid "how to strip spaces and #comments from message"
 msgstr "làm thế nào để cắt bỏ khoảng trắng và #ghichú từ mẩu tin nhắn"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1469
 msgid "include status in commit message template"
 msgstr "bao gồm các trạng thái ghi mẫu ghi chú chuyển giao (commit)"
 
-#: builtin/commit.c:1443 builtin/merge.c:230 builtin/tag.c:461
+#: builtin/commit.c:1470 builtin/merge.c:230 builtin/tag.c:461
 msgid "key id"
 msgstr "id khóa"
 
-#: builtin/commit.c:1444 builtin/merge.c:231
+#: builtin/commit.c:1471 builtin/merge.c:231
 msgid "GPG sign commit"
 msgstr "ký lần commit dùng GPG"
 
 #. end commit message options
-#: builtin/commit.c:1447
+#: builtin/commit.c:1474
 msgid "Commit contents options"
 msgstr "Các tùy nội dung ghi chú commit"
 
-#: builtin/commit.c:1448
+#: builtin/commit.c:1475
 msgid "commit all changed files"
 msgstr "chuyển giao tất cả các tập tin có thay đổi"
 
-#: builtin/commit.c:1449
+#: builtin/commit.c:1476
 msgid "add specified files to index for commit"
 msgstr "thêm các tập tin đã chỉ ra vào bảng mục lục để chuyển giao (commit)"
 
-#: builtin/commit.c:1450
+#: builtin/commit.c:1477
 msgid "interactively add files"
 msgstr "thêm các tập-tin bằng tương tác"
 
-#: builtin/commit.c:1451
+#: builtin/commit.c:1478
 msgid "interactively add changes"
 msgstr "thêm các thay đổi bằng tương tác"
 
-#: builtin/commit.c:1452
+#: builtin/commit.c:1479
 msgid "commit only specified files"
 msgstr "chỉ chuyển giao các tập tin đã chỉ ra"
 
-#: builtin/commit.c:1453
+#: builtin/commit.c:1480
 msgid "bypass pre-commit hook"
 msgstr "vòng qua móc (hook) pre-commit"
 
-#: builtin/commit.c:1454
+#: builtin/commit.c:1481
 msgid "show what would be committed"
 msgstr "hiển thị xem cái gì có thể được chuyển giao"
 
-#: builtin/commit.c:1465
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "tu bổ (amend) lần commit trước"
 
-#: builtin/commit.c:1466
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "vòng qua móc (hook) post-rewrite"
 
-#: builtin/commit.c:1471
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "ok để ghi lại một thay đổi trống rỗng"
 
-#: builtin/commit.c:1474
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "ok để ghi các thay đổi với lời nhắn trống rỗng"
 
-#: builtin/commit.c:1507
+#: builtin/commit.c:1529
 msgid "could not parse HEAD commit"
 msgstr "không thể phân tích commit (lần chuyển giao) HEAD"
 
-#: builtin/commit.c:1545 builtin/merge.c:525
+#: builtin/commit.c:1567 builtin/merge.c:525
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "không thể mở “%s” để đọc"
 
-#: builtin/commit.c:1552
+#: builtin/commit.c:1574
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Tập tin MERGE_HEAD sai hỏng (%s)"
 
-#: builtin/commit.c:1559
+#: builtin/commit.c:1581
 msgid "could not read MERGE_MODE"
 msgstr "không thể đọc MERGE_MODE"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1600
 #, 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:1592
+#: builtin/commit.c:1614
 #, 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:1597
+#: builtin/commit.c:1619
 #, 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:1612 builtin/merge.c:861 builtin/merge.c:886
+#: builtin/commit.c:1634 builtin/merge.c:861 builtin/merge.c:886
 msgid "failed to write commit object"
 msgstr "gặp lỗi khi ghi đối tượng chuyển giao (commit)"
 
-#: builtin/commit.c:1633
+#: builtin/commit.c:1655
 msgid "cannot lock HEAD ref"
 msgstr "không thể khóa HEAD ref (tham chiếu)"
 
-#: builtin/commit.c:1637
+#: builtin/commit.c:1659
 msgid "cannot update HEAD ref"
 msgstr "không thể cập nhật ref (tham chiếu) HEAD"
 
-#: builtin/commit.c:1648
+#: builtin/commit.c:1670
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -4530,127 +4710,131 @@
 "hay quota (hạn nghạch đĩa cứng) bị vượt quá, và sau đó \"git reset HEAD\" để "
 "khắc phục."
 
-#: builtin/config.c:7
+#: builtin/config.c:8
 msgid "git config [options]"
 msgstr "git config [các-tùy-chọn]"
 
-#: builtin/config.c:52
+#: builtin/config.c:54
 msgid "Config file location"
 msgstr "Vị trí tập tin cấu hình"
 
-#: builtin/config.c:53
+#: builtin/config.c:55
 msgid "use global config file"
 msgstr "đặt tập tin cấu hình cần toàn cục"
 
-#: builtin/config.c:54
+#: builtin/config.c:56
 msgid "use system config file"
 msgstr "sử dụng tập tin cấu hình hệ thống"
 
-#: builtin/config.c:55
+#: builtin/config.c:57
 msgid "use repository config file"
 msgstr "dùng tập tin cấu hình của kho"
 
-#: builtin/config.c:56
+#: builtin/config.c:58
 msgid "use given config file"
 msgstr "sử dụng tập tin cấu hình đã cho"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "blob-id"
 msgstr "blob-id"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "read config from given blob object"
 msgstr "đọc cấu hình từ đối tượng blob đã cho"
 
-#: builtin/config.c:58
+#: builtin/config.c:60
 msgid "Action"
 msgstr "Hành động"
 
-#: builtin/config.c:59
+#: builtin/config.c:61
 msgid "get value: name [value-regex]"
 msgstr "lấy giá-trị: tên [value-regex]"
 
-#: builtin/config.c:60
+#: builtin/config.c:62
 msgid "get all values: key [value-regex]"
 msgstr "lấy tất cả giá-trị: khóa [value-regex]"
 
-#: builtin/config.c:61
+#: builtin/config.c:63
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "lấy giá trị cho regexp: name-regex [value-regex]"
 
-#: builtin/config.c:62
+#: builtin/config.c:64
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "lấy đặc tả giá trị cho URL: phần[.biến] URL"
+
+#: builtin/config.c:65
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "thay thế tất cả các biến khớp mẫu: tên giá-trị [value_regex]"
 
-#: builtin/config.c:63
+#: builtin/config.c:66
 msgid "add a new variable: name value"
 msgstr "thêm biến mới: tên giá-trị"
 
-#: builtin/config.c:64
+#: builtin/config.c:67
 msgid "remove a variable: name [value-regex]"
 msgstr "gỡ bỏ biến: tên [value-regex]"
 
-#: builtin/config.c:65
+#: builtin/config.c:68
 msgid "remove all matches: name [value-regex]"
 msgstr "gỡ bỏ mọi cái khớp: tên [value-regex]"
 
-#: builtin/config.c:66
+#: builtin/config.c:69
 msgid "rename section: old-name new-name"
 msgstr "đổi tên chương: tên-cũ tên-mới"
 
-#: builtin/config.c:67
+#: builtin/config.c:70
 msgid "remove a section: name"
 msgstr "gỡ bỏ chương: tên"
 
-#: builtin/config.c:68
+#: builtin/config.c:71
 msgid "list all"
 msgstr "liệt kê tất"
 
-#: builtin/config.c:69
+#: builtin/config.c:72
 msgid "open an editor"
 msgstr "mở một trình biên soạn"
 
-#: builtin/config.c:70 builtin/config.c:71
+#: builtin/config.c:73 builtin/config.c:74
 msgid "slot"
 msgstr "khe"
 
-#: builtin/config.c:70
+#: builtin/config.c:73
 msgid "find the color configured: [default]"
 msgstr "tìm cấu hình màu sắc: [mặc định]"
 
-#: builtin/config.c:71
+#: builtin/config.c:74
 msgid "find the color setting: [stdout-is-tty]"
 msgstr "tìm các cài đặt về màu sắc: [stdout-là-tty]"
 
-#: builtin/config.c:72
+#: builtin/config.c:75
 msgid "Type"
 msgstr "Kiểu"
 
-#: builtin/config.c:73
+#: builtin/config.c:76
 msgid "value is \"true\" or \"false\""
 msgstr "giá trị là \"true\" hoặc \"false\""
 
-#: builtin/config.c:74
+#: builtin/config.c:77
 msgid "value is decimal number"
 msgstr "giá trị ở dạng số thập phân"
 
-#: builtin/config.c:75
+#: builtin/config.c:78
 msgid "value is --bool or --int"
 msgstr "giá trị là --bool hoặc --int"
 
-#: builtin/config.c:76
+#: builtin/config.c:79
 msgid "value is a path (file or directory name)"
 msgstr "giá trị là đường dẫn (tên tập tin hay thư mục)"
 
-#: builtin/config.c:77
+#: builtin/config.c:80
 msgid "Other"
 msgstr "Khác"
 
-#: builtin/config.c:78
+#: builtin/config.c:81
 msgid "terminate values with NUL byte"
 msgstr "chấm dứt giá trị với byte NUL"
 
-#: builtin/config.c:79
+#: builtin/config.c:82
 msgid "respect include directives on lookup"
 msgstr "tôn trọng kể cà các hướng trong tìm kiếm"
 
@@ -4663,8 +4847,8 @@
 msgstr "hiển thị kích cỡ theo định dạng dành cho người đọc"
 
 #: builtin/describe.c:16
-msgid "git describe [options] <committish>*"
-msgstr "git describe [các-tùy-chọn] <committish>*"
+msgid "git describe [options] <commit-ish>*"
+msgstr "git describe [các-tùy-chọn] <commit-ish>*"
 
 #: builtin/describe.c:17
 msgid "git describe [options] --dirty"
@@ -4799,18 +4983,18 @@
 msgstr "Không tìm thấy các tên, không thể mô tả gì cả."
 
 #: builtin/describe.c:489
-msgid "--dirty is incompatible with committishes"
-msgstr "--dirty là xung khắc với các tùy chọn dành cho chuyển giao (commit)"
+msgid "--dirty is incompatible with commit-ishes"
+msgstr "--dirty là xung khắc với các tùy chọn commit-ish"
 
 #: builtin/diff.c:79
 #, c-format
 msgid "'%s': not a regular file or symlink"
-msgstr "“%s”: không phải tập tin bình thường hay liên kết tượng trưng"
+msgstr "“%s”: không phải tập tin bình thường hay liên kết mềm"
 
 #: builtin/diff.c:230
 #, c-format
 msgid "invalid option: %s"
-msgstr "tùy chọn sai: %s"
+msgstr "tùy chọn không hợp lệ: %s"
 
 #: builtin/diff.c:307
 msgid "Not a git repository"
@@ -4835,39 +5019,39 @@
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-opts]"
 
-#: builtin/fast-export.c:666
+#: builtin/fast-export.c:673
 msgid "show progress after <n> objects"
 msgstr "hiển thị tiến triển sau <n> đối tượng"
 
-#: builtin/fast-export.c:668
+#: builtin/fast-export.c:675
 msgid "select handling of signed tags"
 msgstr "chọn điều khiển của thẻ đã ký"
 
-#: builtin/fast-export.c:671
+#: builtin/fast-export.c:678
 msgid "select handling of tags that tag filtered objects"
 msgstr "chọn sự xử lý của các thẻ, cái mà đánh thẻ các đối tượng được lọc ra"
 
-#: builtin/fast-export.c:674
+#: builtin/fast-export.c:681
 msgid "Dump marks to this file"
 msgstr "Đổ các đánh dấu này vào tập-tin"
 
-#: builtin/fast-export.c:676
+#: builtin/fast-export.c:683
 msgid "Import marks from this file"
 msgstr "nhập vào đánh dấu từ tập tin này"
 
-#: builtin/fast-export.c:678
+#: builtin/fast-export.c:685
 msgid "Fake a tagger when tags lack one"
 msgstr "Làm giả một cái thẻ khi thẻ bị thiếu một cái"
 
-#: builtin/fast-export.c:680
+#: builtin/fast-export.c:687
 msgid "Output full tree for each commit"
 msgstr "Xuất ra toàn bộ cây cho mỗi lần chuyển giao"
 
-#: builtin/fast-export.c:682
+#: builtin/fast-export.c:689
 msgid "Use the done feature to terminate the stream"
 msgstr "Sử dụng tính năng done để chấm dứt luồng dữ liệu"
 
-#: builtin/fast-export.c:683
+#: builtin/fast-export.c:690
 msgid "Skip output of blob data"
 msgstr "Bỏ qua kết xuất của dữ liệu blob"
 
@@ -4887,146 +5071,146 @@
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<các-tùy-chọn>]"
 
-#: builtin/fetch.c:60
+#: builtin/fetch.c:74
 msgid "fetch from all remotes"
 msgstr "lấy về từ tất cả các máy chủ"
 
-#: builtin/fetch.c:62
+#: builtin/fetch.c:76
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "nối thêm vào .git/FETCH_HEAD thay vì ghi đè lên nó"
 
-#: builtin/fetch.c:64
+#: builtin/fetch.c:78
 msgid "path to upload pack on remote end"
 msgstr "đường dẫn đến gói (pack) tải lên trên máy chủ cuối"
 
-#: builtin/fetch.c:65
+#: builtin/fetch.c:79
 msgid "force overwrite of local branch"
 msgstr "ép buộc ghi đè lên nhánh nội bộ"
 
-#: builtin/fetch.c:67
+#: builtin/fetch.c:81
 msgid "fetch from multiple remotes"
 msgstr "lấy từ nhiều máy chủ cùng lúc"
 
-#: builtin/fetch.c:69
+#: builtin/fetch.c:83
 msgid "fetch all tags and associated objects"
 msgstr "lấy tất cả các thẻ cùng với các đối tượng liên quan đến nó"
 
-#: builtin/fetch.c:71
+#: builtin/fetch.c:85
 msgid "do not fetch all tags (--no-tags)"
 msgstr "không lấy tất cả các thẻ (--no-tags)"
 
-#: builtin/fetch.c:73
+#: builtin/fetch.c:87
 msgid "prune remote-tracking branches no longer on remote"
 msgstr ""
 "cắt cụt (prune) các nhánh “remote-tracking” không còn tồn tại trên máy chủ "
 "nữa"
 
-#: builtin/fetch.c:74
+#: builtin/fetch.c:88
 msgid "on-demand"
 msgstr "khi-cần"
 
-#: builtin/fetch.c:75
+#: builtin/fetch.c:89
 msgid "control recursive fetching of submodules"
 msgstr "điều khiển việc lấy về đệ quy trong các mô-đun-con"
 
-#: builtin/fetch.c:79
+#: builtin/fetch.c:93
 msgid "keep downloaded pack"
 msgstr "giữ các gói đã tải về"
 
-#: builtin/fetch.c:81
+#: builtin/fetch.c:95
 msgid "allow updating of HEAD ref"
 msgstr "cho phép cập nhật th.chiếu HEAD"
 
-#: builtin/fetch.c:84
+#: builtin/fetch.c:98
 msgid "deepen history of shallow clone"
 msgstr "làm sâu hơn lịch sử của bản sao"
 
-#: builtin/fetch.c:86
+#: builtin/fetch.c:100
 msgid "convert to a complete repository"
 msgstr "chuyển đổi hoàn toàn sang kho git"
 
-#: builtin/fetch.c:88 builtin/log.c:1177
+#: builtin/fetch.c:102 builtin/log.c:1197
 msgid "dir"
 msgstr "tmục"
 
-#: builtin/fetch.c:89
+#: builtin/fetch.c:103
 msgid "prepend this to submodule path output"
 msgstr "soạn sẵn cái này cho kết xuất đường dẫn mô-đun-con"
 
-#: builtin/fetch.c:92
+#: builtin/fetch.c:106
 msgid "default mode for recursion"
 msgstr "chế độ mặc định cho đệ qui"
 
-#: builtin/fetch.c:220
+#: builtin/fetch.c:236
 msgid "Couldn't find remote ref HEAD"
 msgstr "Không thể tìm thấy máy chủ cho tham chiếu HEAD"
 
-#: builtin/fetch.c:273
+#: builtin/fetch.c:290
 #, c-format
 msgid "object %s not found"
 msgstr "Không tìm thấy đối tượng %s"
 
-#: builtin/fetch.c:278
+#: builtin/fetch.c:295
 msgid "[up to date]"
 msgstr "[đã cập nhật]"
 
-#: builtin/fetch.c:292
+#: builtin/fetch.c:309
 #, c-format
 msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
 msgstr "! %-*s %-*s -> %s  (không thể fetch (lấy) về nhánh hiện hành)"
 
-#: builtin/fetch.c:293 builtin/fetch.c:379
+#: builtin/fetch.c:310 builtin/fetch.c:396
 msgid "[rejected]"
 msgstr "[Bị từ chối]"
 
-#: builtin/fetch.c:304
+#: builtin/fetch.c:321
 msgid "[tag update]"
 msgstr "[cập nhật thẻ]"
 
-#: builtin/fetch.c:306 builtin/fetch.c:341 builtin/fetch.c:359
+#: builtin/fetch.c:323 builtin/fetch.c:358 builtin/fetch.c:376
 msgid "  (unable to update local ref)"
 msgstr "  (không thể cập nhật tham chiếu (ref) nội bộ)"
 
-#: builtin/fetch.c:324
+#: builtin/fetch.c:341
 msgid "[new tag]"
 msgstr "[thẻ mới]"
 
-#: builtin/fetch.c:327
+#: builtin/fetch.c:344
 msgid "[new branch]"
 msgstr "[nhánh mới]"
 
-#: builtin/fetch.c:330
+#: builtin/fetch.c:347
 msgid "[new ref]"
 msgstr "[ref (tham chiếu) mới]"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "unable to update local ref"
 msgstr "không thể cập nhật tham chiếu (ref) nội bộ"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "forced update"
 msgstr "cưỡng bức cập nhật"
 
-#: builtin/fetch.c:381
+#: builtin/fetch.c:398
 msgid "(non-fast-forward)"
 msgstr "(non-fast-forward)"
 
-#: builtin/fetch.c:412 builtin/fetch.c:718
+#: builtin/fetch.c:429 builtin/fetch.c:735
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr "không thể mở %s: %s\n"
 
-#: builtin/fetch.c:421
+#: builtin/fetch.c:438
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s đã không gửi tất cả các đối tượng cần thiết\n"
 
-#: builtin/fetch.c:520
+#: builtin/fetch.c:537
 #, c-format
 msgid "From %.*s\n"
 msgstr "Từ %.*s\n"
 
-#: builtin/fetch.c:531
+#: builtin/fetch.c:548
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -5035,57 +5219,57 @@
 "một số tham chiếu (refs) nội bộ không thể được cập nhật; hãy thử chạy\n"
 " “git remote prune %s” để bỏ đi những nhánh cũ, hay bị xung đột"
 
-#: builtin/fetch.c:581
+#: builtin/fetch.c:598
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s sẽ trở thành không đầu (không được quản lý))"
 
-#: builtin/fetch.c:582
+#: builtin/fetch.c:599
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s đã trở thành không đầu (không được quản lý))"
 
-#: builtin/fetch.c:589
+#: builtin/fetch.c:606
 msgid "[deleted]"
 msgstr "[đã xóa]"
 
-#: builtin/fetch.c:590 builtin/remote.c:1055
+#: builtin/fetch.c:607 builtin/remote.c:1055
 msgid "(none)"
 msgstr "(không)"
 
-#: builtin/fetch.c:708
+#: builtin/fetch.c:725
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr ""
 "Từ chối việc lấy (fetch) vào trong nhánh hiện tại %s của một kho chứa không "
 "phải kho trần (bare)"
 
-#: builtin/fetch.c:742
-#, c-format
-msgid "Don't know how to fetch from %s"
-msgstr "Không biết làm cách nào để lấy về từ %s"
-
-#: builtin/fetch.c:823
+#: builtin/fetch.c:744
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "Tùy chọn \"%s\" có giá trị \"%s\" là không hợp lệ cho %s"
 
-#: builtin/fetch.c:826
+#: builtin/fetch.c:747
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "Tùy chọn \"%s\" bị bỏ qua với %s\n"
 
-#: builtin/fetch.c:928
+#: builtin/fetch.c:801
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr "Không biết làm cách nào để lấy về từ %s"
+
+#: builtin/fetch.c:976
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Đang lấy về %s\n"
 
-#: builtin/fetch.c:930 builtin/remote.c:100
+#: builtin/fetch.c:978 builtin/remote.c:100
 #, c-format
 msgid "Could not fetch %s"
 msgstr "không thể lấy về %s"
 
-#: builtin/fetch.c:949
+#: builtin/fetch.c:997
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -5093,32 +5277,32 @@
 "Chưa chỉ ra kho chứa máy chủ.  Xin hãy chỉ định hoặc là URL hoặc\n"
 "tên máy chủ từ cái mà những điểm xét duyệt mới có thể được fetch (lấy về)."
 
-#: builtin/fetch.c:969
+#: builtin/fetch.c:1020
 msgid "You need to specify a tag name."
 msgstr "Bạn phải định rõ tên thẻ."
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1068
 msgid "--depth and --unshallow cannot be used together"
 msgstr "tùy chọn --depth và --unshallow không thể sử dụng cùng với nhau"
 
-#: builtin/fetch.c:1017
+#: builtin/fetch.c:1070
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "--unshallow trên kho hoàn chỉnh là không hợp lý"
 
-#: builtin/fetch.c:1036
+#: builtin/fetch.c:1089
 msgid "fetch --all does not take a repository argument"
 msgstr "lệnh lấy về \"fetch --all\" không lấy đối số kho chứa"
 
-#: builtin/fetch.c:1038
+#: builtin/fetch.c:1091
 msgid "fetch --all does not make sense with refspecs"
 msgstr "lệnh lấy về \"fetch --all\" không hợp lý với refspecs"
 
-#: builtin/fetch.c:1049
+#: builtin/fetch.c:1102
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "không có nhóm máy chủ hay máy chủ như thế: %s"
 
-#: builtin/fetch.c:1057
+#: builtin/fetch.c:1110
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "Việc lấy về cả một nhóm và chỉ định refspecs không hợp lý"
 
@@ -5127,9 +5311,9 @@
 msgstr ""
 "git fmt-merge-msg [-m <thông điệp>] [--log[=<n>]|--no-log] [--file <tập-tin>]"
 
-#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:700
-#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:179
-#: builtin/tag.c:446 parse-options.h:133 parse-options.h:243
+#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:702
+#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:178
+#: builtin/tag.c:446 parse-options.h:135 parse-options.h:245
 msgid "n"
 msgstr "n"
 
@@ -5153,117 +5337,121 @@
 msgid "file to read from"
 msgstr "tập tin để đọc dữ liệu từ đó"
 
-#: builtin/for-each-ref.c:979
+#: builtin/for-each-ref.c:995
 msgid "git for-each-ref [options] [<pattern>]"
 msgstr "git for-each-ref [các-tùy-chọn] [<mẫu>]"
 
-#: builtin/for-each-ref.c:994
+#: builtin/for-each-ref.c:1010
 msgid "quote placeholders suitably for shells"
 msgstr "trích dẫn để phù hợp cho hệ vỏ (shell)"
 
-#: builtin/for-each-ref.c:996
+#: builtin/for-each-ref.c:1012
 msgid "quote placeholders suitably for perl"
 msgstr "trích dẫn để phù hợp cho perl"
 
-#: builtin/for-each-ref.c:998
+#: builtin/for-each-ref.c:1014
 msgid "quote placeholders suitably for python"
 msgstr "trích dẫn để phù hợp cho python"
 
-#: builtin/for-each-ref.c:1000
+#: builtin/for-each-ref.c:1016
 msgid "quote placeholders suitably for tcl"
 msgstr "trích dẫn để phù hợp cho tcl"
 
-#: builtin/for-each-ref.c:1003
+#: builtin/for-each-ref.c:1019
 msgid "show only <n> matched refs"
 msgstr "hiển thị chỉ <n> tham chiếu khớp"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format"
 msgstr "định dạng"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format to use for the output"
 msgstr "định dạng sẽ dùng cho đầu ra"
 
-#: builtin/for-each-ref.c:1005
+#: builtin/for-each-ref.c:1021
 msgid "key"
 msgstr "khóa"
 
-#: builtin/for-each-ref.c:1006
+#: builtin/for-each-ref.c:1022
 msgid "field name to sort on"
 msgstr "tên trường cần sắp xếp"
 
-#: builtin/fsck.c:608
+#: builtin/fsck.c:607
 msgid "git fsck [options] [<object>...]"
 msgstr "git fsck [các-tùy-chọn] [<đối-tượng>...]"
 
-#: builtin/fsck.c:614
+#: builtin/fsck.c:613
 msgid "show unreachable objects"
 msgstr "hiển thị các đối tượng không thể đọc được"
 
-#: builtin/fsck.c:615
+#: builtin/fsck.c:614
 msgid "show dangling objects"
 msgstr "hiển thị các đối tượng không được quản lý"
 
-#: builtin/fsck.c:616
+#: builtin/fsck.c:615
 msgid "report tags"
 msgstr "báo cáo các thẻ"
 
-#: builtin/fsck.c:617
+#: builtin/fsck.c:616
 msgid "report root nodes"
 msgstr "báo cáo node gốc"
 
-#: builtin/fsck.c:618
+#: builtin/fsck.c:617
 msgid "make index objects head nodes"
 msgstr "tạo “ index objects head nodes”"
 
-#: builtin/fsck.c:619
+#: builtin/fsck.c:618
 msgid "make reflogs head nodes (default)"
 msgstr "tạo  reflogs head nodes (mặc định)"
 
-#: builtin/fsck.c:620
+#: builtin/fsck.c:619
 msgid "also consider packs and alternate objects"
 msgstr "cũng cân nhắc đến các đối tượng gói và thay thế"
 
-#: builtin/fsck.c:621
+#: builtin/fsck.c:620
 msgid "enable more strict checking"
 msgstr "cho phép kiểm tra hạn chế hơn"
 
-#: builtin/fsck.c:623
+#: builtin/fsck.c:622
 msgid "write dangling objects in .git/lost-found"
 msgstr "ghi các đối tượng không được quản lý trong .git/lost-found"
 
-#: builtin/fsck.c:624 builtin/prune.c:134
+#: builtin/fsck.c:623 builtin/prune.c:134
 msgid "show progress"
 msgstr "hiển thị quá trình"
 
-#: builtin/gc.c:22
+#: builtin/gc.c:23
 msgid "git gc [options]"
 msgstr "git gc [các-tùy-chọn]"
 
-#: builtin/gc.c:63
+#: builtin/gc.c:79
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "%s không hợp lệ: “%s”"
 
-#: builtin/gc.c:90
+#: builtin/gc.c:106
 #, c-format
 msgid "insanely long object directory %.*s"
 msgstr "thư mục đối tượng dài một cách điên rồ  %.*s"
 
-#: builtin/gc.c:179
+#: builtin/gc.c:261
 msgid "prune unreferenced objects"
 msgstr "xóa bỏ các đối tượng không được tham chiếu"
 
-#: builtin/gc.c:181
+#: builtin/gc.c:263
 msgid "be more thorough (increased runtime)"
 msgstr "cẩn thận hơn nữa (tăng thời gian chạy)"
 
-#: builtin/gc.c:182
+#: builtin/gc.c:264
 msgid "enable auto-gc mode"
 msgstr "bật chế độ auto-gc"
 
-#: builtin/gc.c:222
+#: builtin/gc.c:265
+msgid "force running gc even if there may be another gc running"
+msgstr "buộc gc chạy ngay cả khi có tiến trình gc khác đang chạy"
+
+#: builtin/gc.c:305
 #, c-format
 msgid ""
 "Auto packing the repository for optimum performance. You may also\n"
@@ -5273,43 +5461,52 @@
 "chạy lệnh \"git gc\" một cách thủ công. Hãy xem \"git help gc\" để biết thêm "
 "chi tiết.\n"
 
-#: builtin/gc.c:249
+#. be quiet on --auto
+#: builtin/gc.c:315
+#, c-format
+msgid ""
+"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
+msgstr ""
+"gc đang được thực hiện trên máy “%s” pid %<PRIuMAX> (dùng --force nếu không "
+"phải thế)"
+
+#: builtin/gc.c:340
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "Có quá nhiều đối tượng tự do không được dùng đến; hãy chạy lệnh “git prune” "
 "để xóa bỏ chúng đi."
 
-#: builtin/grep.c:22
+#: builtin/grep.c:23
 msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [các-tùy-chọn] [-e] <mẫu> [<rev>...] [[--] <đường-dẫn>...]"
 
-#: builtin/grep.c:217
+#: builtin/grep.c:218
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: gặp lỗi tạo tuyến (thread): %s"
 
-#: builtin/grep.c:364
+#: builtin/grep.c:365
 #, c-format
 msgid "Failed to chdir: %s"
 msgstr "Gặp lỗi với lệnh chdir: %s"
 
-#: builtin/grep.c:442 builtin/grep.c:477
+#: builtin/grep.c:443 builtin/grep.c:478
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "không thể đọc cây (%s)"
 
-#: builtin/grep.c:492
+#: builtin/grep.c:493
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "không thể thực hiện lệnh grep (lọc tìm) từ đối tượng thuộc kiểu %s"
 
-#: builtin/grep.c:550
+#: builtin/grep.c:551
 #, c-format
 msgid "switch `%c' expects a numerical value"
 msgstr "chuyển đến “%c” cần một giá trị bằng số"
 
-#: builtin/grep.c:567
+#: builtin/grep.c:568
 #, c-format
 msgid "cannot open '%s'"
 msgstr "không mở được “%s”"
@@ -5351,161 +5548,165 @@
 msgstr "không khớp mẫu trong các tập tin nhị phân"
 
 #: builtin/grep.c:662
+msgid "process binary files with textconv filters"
+msgstr "xử lý tập tin nhị phân với các bộ lọc `textconv`"
+
+#: builtin/grep.c:664
 msgid "descend at most <depth> levels"
 msgstr "giảm xuống ít nhất mức <sâu>"
 
-#: builtin/grep.c:666
+#: builtin/grep.c:668
 msgid "use extended POSIX regular expressions"
 msgstr "dùng biểu thức chính qui POSIX có mở rộng"
 
-#: builtin/grep.c:669
+#: builtin/grep.c:671
 msgid "use basic POSIX regular expressions (default)"
 msgstr "sử dụng biểu thức chính quy kiểu POSIX (mặc định)"
 
-#: builtin/grep.c:672
+#: builtin/grep.c:674
 msgid "interpret patterns as fixed strings"
 msgstr "diễn dịch các mẫu như là chuỗi cố định"
 
-#: builtin/grep.c:675
+#: builtin/grep.c:677
 msgid "use Perl-compatible regular expressions"
 msgstr "sử dụng biểu thức chính quy tương thích Perl"
 
-#: builtin/grep.c:678
+#: builtin/grep.c:680
 msgid "show line numbers"
 msgstr "hiển thị số của dòng"
 
-#: builtin/grep.c:679
+#: builtin/grep.c:681
 msgid "don't show filenames"
 msgstr "không hiển thị tên tập tin"
 
-#: builtin/grep.c:680
+#: builtin/grep.c:682
 msgid "show filenames"
 msgstr "hiển thị các tên tập tin"
 
-#: builtin/grep.c:682
+#: builtin/grep.c:684
 msgid "show filenames relative to top directory"
 msgstr "hiển thị tên tập tin tương đối với thư mục đỉnh (top)"
 
-#: builtin/grep.c:684
+#: builtin/grep.c:686
 msgid "show only filenames instead of matching lines"
 msgstr "chỉ hiển thị tên tập tin thay vì những dòng khớp với mẫu"
 
-#: builtin/grep.c:686
+#: builtin/grep.c:688
 msgid "synonym for --files-with-matches"
 msgstr "đồng nghĩa với --files-with-matches"
 
-#: builtin/grep.c:689
+#: builtin/grep.c:691
 msgid "show only the names of files without match"
 msgstr "chỉ hiển thị tên cho những tập tin không khớp với mẫu"
 
-#: builtin/grep.c:691
+#: builtin/grep.c:693
 msgid "print NUL after filenames"
 msgstr "thêm NUL vào sau tên tập tin"
 
-#: builtin/grep.c:693
+#: builtin/grep.c:695
 msgid "show the number of matches instead of matching lines"
 msgstr "hiển thị số lượng khớp thay vì những dòng khớp với mẫu"
 
-#: builtin/grep.c:694
+#: builtin/grep.c:696
 msgid "highlight matches"
 msgstr "tô sáng cái khớp"
 
-#: builtin/grep.c:696
+#: builtin/grep.c:698
 msgid "print empty line between matches from different files"
 msgstr "hiển thị dòng trống giữa các lần khớp từ các tập tin khác biệt"
 
-#: builtin/grep.c:698
+#: builtin/grep.c:700
 msgid "show filename only once above matches from same file"
 msgstr ""
 "hiển thị tên tập tin một lần phía trên các lần khớp từ cùng một tập tin"
 
-#: builtin/grep.c:701
+#: builtin/grep.c:703
 msgid "show <n> context lines before and after matches"
 msgstr "hiển thị <n> dòng nội dung phía trước và sau các lần khớp"
 
-#: builtin/grep.c:704
+#: builtin/grep.c:706
 msgid "show <n> context lines before matches"
 msgstr "hiển thị <n> dòng nội dung trước khớp"
 
-#: builtin/grep.c:706
+#: builtin/grep.c:708
 msgid "show <n> context lines after matches"
 msgstr "hiển thị <n> dòng nội dung sau khớp"
 
-#: builtin/grep.c:707
+#: builtin/grep.c:709
 msgid "shortcut for -C NUM"
 msgstr "Dạng tắt cho -C SỐ"
 
-#: builtin/grep.c:710
+#: builtin/grep.c:712
 msgid "show a line with the function name before matches"
 msgstr "hiển thị dòng vói tên hàm trước các lần khớp"
 
-#: builtin/grep.c:712
+#: builtin/grep.c:714
 msgid "show the surrounding function"
 msgstr "hiển thị hàm bao quanh"
 
-#: builtin/grep.c:715
+#: builtin/grep.c:717
 msgid "read patterns from file"
 msgstr "đọc mẫu từ tập-tin"
 
-#: builtin/grep.c:717
+#: builtin/grep.c:719
 msgid "match <pattern>"
 msgstr "match <mẫu>"
 
-#: builtin/grep.c:719
+#: builtin/grep.c:721
 msgid "combine patterns specified with -e"
 msgstr "tổ hợp mẫu được chỉ ra với tùy chọn -e"
 
-#: builtin/grep.c:731
+#: builtin/grep.c:733
 msgid "indicate hit with exit status without output"
 msgstr "đưa ra gợi ý với trạng thái thoát mà không có kết xuất"
 
-#: builtin/grep.c:733
+#: builtin/grep.c:735
 msgid "show only matches from files that match all patterns"
 msgstr "chỉ hiển thị những cái khớp từ tập tin mà nó khớp toàn bộ các mẫu"
 
-#: builtin/grep.c:735
+#: builtin/grep.c:737
 msgid "show parse tree for grep expression"
 msgstr "hiển thị cây phân tích cú pháp cho biểu thức “grep” (tìm kiếm)"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "pager"
 msgstr "trang giấy"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "show matching files in the pager"
 msgstr "hiển thị các tập tin khớp trong trang giấy"
 
-#: builtin/grep.c:742
+#: builtin/grep.c:744
 msgid "allow calling of grep(1) (ignored by this build)"
 msgstr "cho phép gọi grep(1) (bị bỏ qua bởi lần dịch này)"
 
-#: builtin/grep.c:743 builtin/show-ref.c:188
+#: builtin/grep.c:745 builtin/show-ref.c:187
 msgid "show usage"
 msgstr "hiển thị cách dùng"
 
-#: builtin/grep.c:810
+#: builtin/grep.c:812
 msgid "no pattern given."
 msgstr "chưa chỉ ra mẫu."
 
-#: builtin/grep.c:865
+#: builtin/grep.c:870
 msgid "--open-files-in-pager only works on the worktree"
 msgstr "--open-files-in-pager chỉ làm việc trên cây-làm-việc"
 
-#: builtin/grep.c:888
+#: builtin/grep.c:893
 msgid "--cached or --untracked cannot be used with --no-index."
 msgstr "--cached hay --untracked không được sử dụng với --no-index."
 
-#: builtin/grep.c:893
+#: builtin/grep.c:898
 msgid "--no-index or --untracked cannot be used with revs."
 msgstr ""
 "--no-index hay --untracked không được sử dụng cùng với các tùy chọn liên "
 "quan đến revs."
 
-#: builtin/grep.c:896
+#: builtin/grep.c:901
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
 msgstr "--[no-]exclude-standard không thể sử dụng cho nội dung lưu dấu vết."
 
-#: builtin/grep.c:904
+#: builtin/grep.c:909
 msgid "both --cached and trees are given."
 msgstr "cả hai --cached và các cây phải được chỉ ra."
 
@@ -5658,7 +5859,7 @@
 #: builtin/help.c:460 builtin/help.c:476
 #, c-format
 msgid "usage: %s%s"
-msgstr "cách sử dụng: %s%s"
+msgstr "cách dùng: %s%s"
 
 #: builtin/help.c:492
 #, c-format
@@ -5760,8 +5961,8 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SỰ VA CHẠM SHA1 ĐÃ XẢY RA VỚI %s!"
 
-#: builtin/index-pack.c:669 builtin/pack-objects.c:170
-#: builtin/pack-objects.c:262
+#: builtin/index-pack.c:669 builtin/pack-objects.c:171
+#: builtin/pack-objects.c:263
 #, c-format
 msgid "unable to read %s"
 msgstr "không thể đọc %s"
@@ -5790,155 +5991,155 @@
 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:838 builtin/index-pack.c:868
+#: builtin/index-pack.c:839 builtin/index-pack.c:869
 msgid "failed to apply delta"
 msgstr "gặp lỗi khi áp dụng delta"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Receiving objects"
 msgstr "Đang nhận về các đối tượng"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Indexing objects"
 msgstr "Các đối tượng bảng mục lục"
 
-#: builtin/index-pack.c:1035
+#: builtin/index-pack.c:1036
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "pack bị sai hỏng (SHA1 không khớp)"
 
-#: builtin/index-pack.c:1040
+#: builtin/index-pack.c:1041
 msgid "cannot fstat packfile"
 msgstr "không thể fstat packfile"
 
-#: builtin/index-pack.c:1043
+#: builtin/index-pack.c:1044
 msgid "pack has junk at the end"
 msgstr "pack có phần thừa ở cuối"
 
-#: builtin/index-pack.c:1054
+#: builtin/index-pack.c:1055
 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:1077
+#: builtin/index-pack.c:1078
 msgid "Resolving deltas"
 msgstr "Đang phân giải các delta"
 
-#: builtin/index-pack.c:1087
+#: builtin/index-pack.c:1088
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "không thể tạo tuyến: %s"
 
-#: builtin/index-pack.c:1129
+#: builtin/index-pack.c:1130
 msgid "confusion beyond insanity"
 msgstr "lộn xộn hơn cả điên rồ"
 
-#: builtin/index-pack.c:1137
+#: builtin/index-pack.c:1138
 #, c-format
 msgid "completed with %d local objects"
 msgstr "đầy đủ với %d đối tượng nội bộ"
 
-#: builtin/index-pack.c:1147
+#: builtin/index-pack.c:1148
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "Tổng kiểm tra tail không như mong đợi cho %s (đĩa hỏng?)"
 
-#: builtin/index-pack.c:1151
+#: builtin/index-pack.c:1152
 #, 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:1176
+#: builtin/index-pack.c:1177
 #, c-format
 msgid "unable to deflate appended object (%d)"
-msgstr "không thể xả đối tượng nối thêm (%d)"
+msgstr "không thể xả nén đối tượng nối thêm (%d)"
 
-#: builtin/index-pack.c:1255
+#: builtin/index-pack.c:1256
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "đối tượng nội bộ %s bị hỏng"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1280
 msgid "error while closing pack file"
-msgstr "gặp lỗi trong khi đóng tập tin pack"
+msgstr "gặp lỗi trong khi đóng tập tin gói (pack)"
 
-#: builtin/index-pack.c:1292
+#: builtin/index-pack.c:1293
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "không thể ghi tập tin giữ lại “%s”"
 
-#: builtin/index-pack.c:1300
+#: builtin/index-pack.c:1301
 #, 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:1313
+#: builtin/index-pack.c:1314
 msgid "cannot store pack file"
 msgstr "không thể lưu tập tin pack"
 
-#: builtin/index-pack.c:1324
+#: builtin/index-pack.c:1325
 msgid "cannot store index file"
 msgstr "không thể lưu trữ tập tin ghi mục lục"
 
-#: builtin/index-pack.c:1357
+#: builtin/index-pack.c:1358
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "sai pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1363
+#: builtin/index-pack.c:1364
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "số tuyến chỉ ra không hợp lệ (%d)"
 
-#: builtin/index-pack.c:1367 builtin/index-pack.c:1545
+#: builtin/index-pack.c:1368 builtin/index-pack.c:1546
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "không hỗ trợ đa tuyến, bỏ qua %s"
 
-#: builtin/index-pack.c:1425
+#: builtin/index-pack.c:1426
 #, 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:1427
+#: builtin/index-pack.c:1428
 #, 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:1474
+#: builtin/index-pack.c:1475
 #, 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:1481
+#: builtin/index-pack.c:1482
 #, 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:1509
+#: builtin/index-pack.c:1510
 msgid "Cannot come back to cwd"
 msgstr "Không thể quay lại cwd"
 
-#: builtin/index-pack.c:1557 builtin/index-pack.c:1560
-#: builtin/index-pack.c:1572 builtin/index-pack.c:1576
+#: builtin/index-pack.c:1558 builtin/index-pack.c:1561
+#: builtin/index-pack.c:1573 builtin/index-pack.c:1577
 #, c-format
 msgid "bad %s"
 msgstr "%s sai"
 
-#: builtin/index-pack.c:1590
+#: builtin/index-pack.c:1591
 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:1594 builtin/index-pack.c:1604
+#: builtin/index-pack.c:1595 builtin/index-pack.c:1605
 #, 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:1613
+#: builtin/index-pack.c:1614
 msgid "--verify with no packfile name given"
 msgstr "dùng tùy chọn --verify mà không đưa ra tên packfile"
 
@@ -6027,11 +6228,6 @@
 msgid "unable to move %s to %s"
 msgstr "không di chuyển được %s vào %s"
 
-#: 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”"
-
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
 #. * existing" or "Initialized empty", the second " shared" or
@@ -6060,8 +6256,8 @@
 
 #: builtin/init-db.c:467
 msgid ""
-"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared"
-"[=<permissions>]] [directory]"
+"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--"
+"shared[=<permissions>]] [directory]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<thư-mục-tạm>] [--shared[=<các-"
 "quyền>]] [thư-mục]"
@@ -6074,7 +6270,7 @@
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "chỉ ra cái mà kho git được chia sẻ giữa nhiều người dùng"
 
-#: builtin/init-db.c:493 builtin/prune-packed.c:75
+#: builtin/init-db.c:493 builtin/prune-packed.c:75 builtin/repack.c:155
 msgid "be quiet"
 msgstr "im lặng"
 
@@ -6114,247 +6310,247 @@
 msgid "   or: git show [options] <object>..."
 msgstr "  hay: git show [các-tùy-chọn] <đối-tượng>..."
 
-#: builtin/log.c:124
+#: builtin/log.c:125
 msgid "suppress diff output"
 msgstr "chặn mọi kết xuất từ diff"
 
-#: builtin/log.c:125
+#: builtin/log.c:126
 msgid "show source"
 msgstr "hiển thị mã nguồn"
 
-#: builtin/log.c:126
+#: builtin/log.c:127
 msgid "Use mail map file"
 msgstr "Sử dụng tập tin ánh xạ thư"
 
-#: builtin/log.c:127
+#: builtin/log.c:128
 msgid "decorate options"
 msgstr "các tùy chọn trang trí"
 
-#: builtin/log.c:230
+#: builtin/log.c:231
 #, c-format
 msgid "Final output: %d %s\n"
 msgstr "Kết xuất cuối cùng: %d %s\n"
 
-#: builtin/log.c:453 builtin/log.c:545
+#: builtin/log.c:473 builtin/log.c:565
 #, c-format
 msgid "Could not read object %s"
 msgstr "Không thể đọc đối tượng %s"
 
-#: builtin/log.c:569
+#: builtin/log.c:589
 #, c-format
 msgid "Unknown type: %d"
 msgstr "Không nhận ra kiểu: %d"
 
-#: builtin/log.c:669
+#: builtin/log.c:689
 msgid "format.headers without value"
 msgstr "format.headers không có giá trị cụ thể"
 
-#: builtin/log.c:751
+#: builtin/log.c:771
 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:767
+#: builtin/log.c:787
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "Không thể mở tập tin miếng vá: %s"
 
-#: builtin/log.c:781
+#: builtin/log.c:801
 msgid "Need exactly one range."
 msgstr "Cần chính xác một vùng."
 
-#: builtin/log.c:789
+#: builtin/log.c:809
 msgid "Not a range."
 msgstr "Không phải là một vùng."
 
-#: builtin/log.c:891
+#: builtin/log.c:911
 msgid "Cover letter needs email format"
 msgstr "”Cover letter” cần cho định dạng thư"
 
-#: builtin/log.c:967
+#: builtin/log.c:987
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "in-reply-to điên rồ: %s"
 
-#: builtin/log.c:995
+#: builtin/log.c:1015
 msgid "git format-patch [options] [<since> | <revision range>]"
 msgstr "git format-patch [các-tùy-chọn] [<kể-từ> | <vùng-xem-xét>]"
 
-#: builtin/log.c:1040
+#: builtin/log.c:1060
 msgid "Two output directories?"
 msgstr "Hai thư mục kết xuất?"
 
-#: builtin/log.c:1155
+#: builtin/log.c:1175
 msgid "use [PATCH n/m] even with a single patch"
 msgstr "dùng [PATCH n/m] ngay cả với miếng vá đơn"
 
-#: builtin/log.c:1158
+#: builtin/log.c:1178
 msgid "use [PATCH] even with multiple patches"
 msgstr "dùng [VÁ] ngay cả với các miếng vá phức tạp"
 
-#: builtin/log.c:1162
+#: builtin/log.c:1182
 msgid "print patches to standard out"
 msgstr "hiển thị miếng vá ra đầu ra chuẩn"
 
-#: builtin/log.c:1164
+#: builtin/log.c:1184
 msgid "generate a cover letter"
 msgstr "tạo bì thư"
 
-#: builtin/log.c:1166
+#: builtin/log.c:1186
 msgid "use simple number sequence for output file names"
 msgstr "sử dụng chỗi dãy số dạng đơn giản cho tên tập-tin xuất ra"
 
-#: builtin/log.c:1167
+#: builtin/log.c:1187
 msgid "sfx"
 msgstr "sfx"
 
-#: builtin/log.c:1168
+#: builtin/log.c:1188
 msgid "use <sfx> instead of '.patch'"
 msgstr "sử dụng <sfx> thay cho “.patch”"
 
-#: builtin/log.c:1170
+#: builtin/log.c:1190
 msgid "start numbering patches at <n> instead of 1"
 msgstr "bắt đầu đánh số miếng vá từ <n> thay vì 1"
 
-#: builtin/log.c:1172
+#: builtin/log.c:1192
 msgid "mark the series as Nth re-roll"
 msgstr "đánh dấu chuỗi nối tiếp dạng thứ-N re-roll"
 
-#: builtin/log.c:1174
+#: builtin/log.c:1194
 msgid "Use [<prefix>] instead of [PATCH]"
 msgstr "Dùng [<tiền-tố>] thay cho [VÁ]"
 
-#: builtin/log.c:1177
+#: builtin/log.c:1197
 msgid "store resulting files in <dir>"
 msgstr "lưu các tập tin kết quả trong <t.mục>"
 
-#: builtin/log.c:1180
+#: builtin/log.c:1200
 msgid "don't strip/add [PATCH]"
 msgstr "không strip/add [VÁ]"
 
-#: builtin/log.c:1183
+#: builtin/log.c:1203
 msgid "don't output binary diffs"
 msgstr "không kết xuất diff (những khác biệt) nhị phân"
 
-#: builtin/log.c:1185
+#: builtin/log.c:1205
 msgid "don't include a patch matching a commit upstream"
 msgstr "không bao gồm miếng vá khớp với một lần chuyển giao thượng nguồn"
 
-#: builtin/log.c:1187
+#: builtin/log.c:1207
 msgid "show patch format instead of default (patch + stat)"
 msgstr "hiển thị định dạng miếng vá thay vì mặc định (miếng vá + thống kê)"
 
-#: builtin/log.c:1189
+#: builtin/log.c:1209
 msgid "Messaging"
 msgstr "Lời nhắn"
 
-#: builtin/log.c:1190
+#: builtin/log.c:1210
 msgid "header"
 msgstr "đầu đề thư"
 
-#: builtin/log.c:1191
+#: builtin/log.c:1211
 msgid "add email header"
 msgstr "thêm đầu đề thư"
 
-#: builtin/log.c:1192 builtin/log.c:1194
+#: builtin/log.c:1212 builtin/log.c:1214
 msgid "email"
 msgstr "thư điện tử"
 
-#: builtin/log.c:1192
+#: builtin/log.c:1212
 msgid "add To: header"
 msgstr "thêm To: đầu đề thư"
 
-#: builtin/log.c:1194
+#: builtin/log.c:1214
 msgid "add Cc: header"
 msgstr "thêm Cc: đầu đề thư"
 
-#: builtin/log.c:1196
+#: builtin/log.c:1216
 msgid "ident"
 msgstr "thụt lề"
 
-#: builtin/log.c:1197
+#: builtin/log.c:1217
 msgid "set From address to <ident> (or committer ident if absent)"
 msgstr ""
-"đặt `Địa chỉ gửi' thành <thụ lề> (hoặc thụt lề người commit nếu bỏ quên)"
+"đặt “Địa chỉ gửi” thành <thụ lề> (hoặc thụt lề người commit nếu bỏ quên)"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1219
 msgid "message-id"
 msgstr "message-id"
 
-#: builtin/log.c:1200
+#: builtin/log.c:1220
 msgid "make first mail a reply to <message-id>"
 msgstr "dùng thư đầu tiên để trả lời <message-id>"
 
-#: builtin/log.c:1201 builtin/log.c:1204
+#: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
 msgstr "ranh giới"
 
-#: builtin/log.c:1202
+#: builtin/log.c:1222
 msgid "attach the patch"
 msgstr "đính kèm miếng vá"
 
-#: builtin/log.c:1205
+#: builtin/log.c:1225
 msgid "inline the patch"
 msgstr "dùng miếng vá làm nội dung"
 
-#: builtin/log.c:1209
+#: builtin/log.c:1229
 msgid "enable message threading, styles: shallow, deep"
 msgstr "cho phép luồng lời nhắn, kiểu: “shallow”, “deep”"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1231
 msgid "signature"
 msgstr "chữ ký"
 
-#: builtin/log.c:1212
+#: builtin/log.c:1232
 msgid "add a signature"
 msgstr "thêm chữ ký"
 
-#: builtin/log.c:1214
+#: builtin/log.c:1233
 msgid "don't print the patch filenames"
 msgstr "không hiển thị các tên tập tin của miếng vá"
 
-#: builtin/log.c:1288
+#: builtin/log.c:1307
 #, c-format
 msgid "invalid ident line: %s"
 msgstr "dòng thụt lề không hợp lệ: %s"
 
-#: builtin/log.c:1303
+#: builtin/log.c:1322
 msgid "-n and -k are mutually exclusive."
 msgstr "-n và  -k loại từ lẫn nhau."
 
-#: builtin/log.c:1305
+#: builtin/log.c:1324
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "--subject-prefix và -k xung khắc nhau."
 
-#: builtin/log.c:1313
+#: builtin/log.c:1332
 msgid "--name-only does not make sense"
 msgstr "--name-only không hợp lý"
 
-#: builtin/log.c:1315
+#: builtin/log.c:1334
 msgid "--name-status does not make sense"
 msgstr "--name-status không hợp lý"
 
-#: builtin/log.c:1317
+#: builtin/log.c:1336
 msgid "--check does not make sense"
 msgstr "--check không hợp lý"
 
-#: builtin/log.c:1340
+#: builtin/log.c:1359
 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:1342
+#: builtin/log.c:1361
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "Không thể tạo thư mục “%s”"
 
-#: builtin/log.c:1490
+#: builtin/log.c:1509
 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:1539
+#: builtin/log.c:1558
 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
 msgstr "git cherry [-v] [<thượng-nguồn> [<head> [<giới-hạn>]]]"
 
-#: builtin/log.c:1594
+#: builtin/log.c:1613
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
@@ -6362,139 +6558,139 @@
 "Không tìm thấy nhánh mạng bị theo vết, hãy chỉ định <thượng-nguồn> một cách "
 "thủ công.\n"
 
-#: builtin/log.c:1607 builtin/log.c:1609 builtin/log.c:1621
+#: builtin/log.c:1626 builtin/log.c:1628 builtin/log.c:1640
 #, c-format
 msgid "Unknown commit %s"
 msgstr "Không hiểu lần chuyển giao (commit) %s"
 
-#: builtin/ls-files.c:408
+#: builtin/ls-files.c:398
 msgid "git ls-files [options] [<file>...]"
 msgstr "git ls-files [các-tùy-chọn] [<tập-tin>...]"
 
-#: builtin/ls-files.c:465
+#: builtin/ls-files.c:455
 msgid "identify the file status with tags"
 msgstr "nhận dạng các trạng thái tập tin với thẻ"
 
-#: builtin/ls-files.c:467
+#: builtin/ls-files.c:457
 msgid "use lowercase letters for 'assume unchanged' files"
 msgstr ""
 "dùng chữ cái viết thường cho các tập tin “assume unchanged” (giả định không "
 "thay đổi)"
 
-#: builtin/ls-files.c:469
+#: builtin/ls-files.c:459
 msgid "show cached files in the output (default)"
 msgstr "hiển thị các tập tin được nhớ tạm vào đầu ra (mặc định)"
 
-#: builtin/ls-files.c:471
+#: builtin/ls-files.c:461
 msgid "show deleted files in the output"
 msgstr "hiển thị các tập tin đã xóa trong kết xuất"
 
-#: builtin/ls-files.c:473
+#: builtin/ls-files.c:463
 msgid "show modified files in the output"
 msgstr "hiển thị các tập tin đã bị sửa đổi ra kết xuất"
 
-#: builtin/ls-files.c:475
+#: builtin/ls-files.c:465
 msgid "show other files in the output"
 msgstr "hiển thị các tập tin khác trong kết xuất"
 
-#: builtin/ls-files.c:477
+#: builtin/ls-files.c:467
 msgid "show ignored files in the output"
 msgstr "hiển thị các tập tin bị bỏ qua trong kết xuất"
 
-#: builtin/ls-files.c:480
+#: builtin/ls-files.c:470
 msgid "show staged contents' object name in the output"
 msgstr "hiển thị tên đối tượng của nội dung được lưu trạng thái ở kết xuất"
 
-#: builtin/ls-files.c:482
+#: builtin/ls-files.c:472
 msgid "show files on the filesystem that need to be removed"
 msgstr "hiển thị các tập tin trên hệ thống tập tin mà nó cần được gỡ bỏ"
 
-#: builtin/ls-files.c:484
+#: builtin/ls-files.c:474
 msgid "show 'other' directories' name only"
 msgstr "chỉ hiển thị tên của các thư mục “khác”"
 
-#: builtin/ls-files.c:487
+#: builtin/ls-files.c:477
 msgid "don't show empty directories"
 msgstr "không hiển thị thư mục rỗng"
 
-#: builtin/ls-files.c:490
+#: builtin/ls-files.c:480
 msgid "show unmerged files in the output"
 msgstr "hiển thị các tập tin chưa hòa trộn trong kết xuất"
 
-#: builtin/ls-files.c:492
+#: builtin/ls-files.c:482
 msgid "show resolve-undo information"
 msgstr "hiển thị thông tin resolve-undo"
 
-#: builtin/ls-files.c:494
+#: builtin/ls-files.c:484
 msgid "skip files matching pattern"
 msgstr "bỏ qua những tập tin khớp với một mẫu"
 
-#: builtin/ls-files.c:497
+#: builtin/ls-files.c:487
 msgid "exclude patterns are read from <file>"
 msgstr "mẫu loại trừ được đọc từ <tập tin>"
 
-#: builtin/ls-files.c:500
+#: builtin/ls-files.c:490
 msgid "read additional per-directory exclude patterns in <file>"
 msgstr "đọc thêm các mẫu ngoại trừ mỗi thư mục trong <tập tin>"
 
-#: builtin/ls-files.c:502
+#: builtin/ls-files.c:492
 msgid "add the standard git exclusions"
 msgstr "thêm loại trừ tiêu chuẩn kiểu git"
 
-#: builtin/ls-files.c:505
+#: builtin/ls-files.c:495
 msgid "make the output relative to the project top directory"
 msgstr "làm cho kết xuất liên quan đến thư mục ở mức cao nhất (gốc) của dự án"
 
-#: builtin/ls-files.c:508
+#: builtin/ls-files.c:498
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr "nếu <tập tin> bất kỳ không ở trong bảng mục lục, xử lý nó như một lỗi"
 
-#: builtin/ls-files.c:509
+#: builtin/ls-files.c:499
 msgid "tree-ish"
 msgstr "tree-ish"
 
-#: builtin/ls-files.c:510
+#: builtin/ls-files.c:500
 msgid "pretend that paths removed since <tree-ish> are still present"
 msgstr ""
 "giả định rằng các đường dẫn đã bị gỡ bỏ kể từ <tree-ish> nay vẫn hiện diện"
 
-#: builtin/ls-files.c:512
+#: builtin/ls-files.c:502
 msgid "show debugging data"
 msgstr "hiển thị dữ liệu gỡ lỗi"
 
-#: builtin/ls-tree.c:27
+#: builtin/ls-tree.c:28
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<các-tùy-chọn>] <tree-ish> [<đường-dẫn>...]"
 
-#: builtin/ls-tree.c:125
+#: builtin/ls-tree.c:126
 msgid "only show trees"
 msgstr "chỉ hiển thị các tree"
 
-#: builtin/ls-tree.c:127
+#: builtin/ls-tree.c:128
 msgid "recurse into subtrees"
 msgstr "đệ quy vào các thư mục con"
 
-#: builtin/ls-tree.c:129
+#: builtin/ls-tree.c:130
 msgid "show trees when recursing"
 msgstr "hiển thị cây khi đệ quy"
 
-#: builtin/ls-tree.c:132
+#: builtin/ls-tree.c:133
 msgid "terminate entries with NUL byte"
 msgstr "chấm dứt mục tin với byte NUL"
 
-#: builtin/ls-tree.c:133
+#: builtin/ls-tree.c:134
 msgid "include object size"
 msgstr "gồm cả kích thước đối tượng"
 
-#: builtin/ls-tree.c:135 builtin/ls-tree.c:137
+#: builtin/ls-tree.c:136 builtin/ls-tree.c:138
 msgid "list only filenames"
 msgstr "chỉ liệt kê tên tập tin"
 
-#: builtin/ls-tree.c:140
+#: builtin/ls-tree.c:141
 msgid "use full path names"
 msgstr "dùng tên đường dẫn đầy đủ"
 
-#: builtin/ls-tree.c:142
+#: builtin/ls-tree.c:143
 msgid "list entire tree; not just current directory (implies --full-name)"
 msgstr "liệt kê cây mục tin; không chỉ thư mục hiện hành (ngụ ý --full-name)"
 
@@ -6569,7 +6765,7 @@
 msgid "Verify that the named commit has a valid GPG signature"
 msgstr "Thẩm tra xem lần chuyển giao có tên đó có chữ ký GPG hợp lệ hay không"
 
-#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:114
+#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:89
 msgid "strategy"
 msgstr "chiến lược"
 
@@ -6950,76 +7146,87 @@
 msgid "allow creation of more than one tree"
 msgstr "cho phép tạo nhiều hơn một cây"
 
-#: builtin/mv.c:14
+#: builtin/mv.c:15
 msgid "git mv [options] <source>... <destination>"
 msgstr "git mv [các-tùy-chọn] <nguồn>... <đích>"
 
-#: builtin/mv.c:64
+#: builtin/mv.c:67
 msgid "force move/rename even if target exists"
 msgstr "ép buộc di chuyển hay đổi tên thậm chí cả khi đích đã tồn tại"
 
-#: builtin/mv.c:65
+#: builtin/mv.c:68
 msgid "skip move/rename errors"
 msgstr "bỏ qua các lỗi liên quan đến di chuyển, đổi tên"
 
-#: builtin/mv.c:108
+#: builtin/mv.c:113
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
 msgstr "Đang kiểm tra việc đổi tên của “%s” thành “%s”\n"
 
-#: builtin/mv.c:112
+#: builtin/mv.c:117
 msgid "bad source"
 msgstr "nguồn sai"
 
-#: builtin/mv.c:115
+#: builtin/mv.c:120
 msgid "can not move directory into itself"
 msgstr "không thể di chuyển một thư mục vào trong chính nó được"
 
-#: builtin/mv.c:118
+#: builtin/mv.c:123
 msgid "cannot move directory over file"
 msgstr "không di chuyển được thư mục thông qua tập tin"
 
-#: builtin/mv.c:128
+#: builtin/mv.c:129
+#, c-format
+msgid "Huh? Directory %s is in index and no submodule?"
+msgstr "Hả? Thư mục “%s” trong chỉ mục và không mô-đun con?"
+
+#: builtin/mv.c:131 builtin/rm.c:318
+msgid "Please, stage your changes to .gitmodules or stash them to proceed"
+msgstr ""
+"Hãy lưu các thay đổi của bạn vào “.gitmodules” hay ghi vào vùng nhớ tạm "
+"(stash) chúng để xử lý"
+
+#: builtin/mv.c:147
 #, c-format
 msgid "Huh? %.*s is in index?"
 msgstr "Hả? %.*s trong bảng mục lục à?"
 
-#: builtin/mv.c:140
+#: builtin/mv.c:159
 msgid "source directory is empty"
 msgstr "thư mục nguồn là trống rỗng"
 
-#: builtin/mv.c:171
+#: builtin/mv.c:191
 msgid "not under version control"
 msgstr "không nằm dưới sự quản lý mã nguồn"
 
-#: builtin/mv.c:173
+#: builtin/mv.c:193
 msgid "destination exists"
 msgstr "đích đã tồn tại sẵn rồi"
 
-#: builtin/mv.c:181
+#: builtin/mv.c:201
 #, c-format
 msgid "overwriting '%s'"
 msgstr "đang ghi đè lên “%s”"
 
-#: builtin/mv.c:184
+#: builtin/mv.c:204
 msgid "Cannot overwrite"
 msgstr "Không thể ghi đè"
 
-#: builtin/mv.c:187
+#: builtin/mv.c:207
 msgid "multiple sources for the same target"
 msgstr "Nhiều nguồn cho cùng một đích"
 
-#: builtin/mv.c:202
+#: builtin/mv.c:222
 #, c-format
 msgid "%s, source=%s, destination=%s"
 msgstr "%s, nguồn=%s, đích=%s"
 
-#: builtin/mv.c:212
+#: builtin/mv.c:232
 #, c-format
 msgid "Renaming %s to %s\n"
 msgstr "Đổi tên %s thành %s\n"
 
-#: builtin/mv.c:215 builtin/remote.c:731
+#: builtin/mv.c:235 builtin/remote.c:731 builtin/repack.c:330
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "đổi tên %s gặp lỗi"
@@ -7058,8 +7265,8 @@
 msgstr "đọc từ đầu vào tiêu chuẩn"
 
 #: builtin/name-rev.c:320
-msgid "allow to print `undefined` names"
-msgstr "cho phép hiển thị các tên “chưa định nghĩa“"
+msgid "allow to print `undefined` names (default)"
+msgstr "cho phép in các tên “chưa định nghĩa” (mặc định)"
 
 #: builtin/name-rev.c:326
 msgid "dereference tags in the input (internal use)"
@@ -7213,12 +7420,12 @@
 msgid "The note contents has been left in %s"
 msgstr "Nội dung ghi chú còn lại %s"
 
-#: builtin/notes.c:248 builtin/tag.c:540
+#: builtin/notes.c:248 builtin/tag.c:537
 #, c-format
 msgid "cannot read '%s'"
 msgstr "không thể đọc “%s”"
 
-#: builtin/notes.c:250 builtin/tag.c:543
+#: builtin/notes.c:250 builtin/tag.c:540
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "không thể mở hay đọc “%s”"
@@ -7226,7 +7433,7 @@
 #: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318
 #: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515
 #: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637
-#: builtin/notes.c:839 builtin/tag.c:556
+#: builtin/notes.c:839 builtin/tag.c:553
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "Gặp lỗi khi phân giải “%s” như là một tham chiếu (ref) hợp lệ."
@@ -7239,7 +7446,7 @@
 #: builtin/notes.c:312
 #, c-format
 msgid "Malformed input line: '%s'."
-msgstr "Dòng nhập vào dị hình: “%s”."
+msgstr "Dòng đầu vào dị hình: “%s”."
 
 #: builtin/notes.c:327
 #, c-format
@@ -7403,149 +7610,149 @@
 "git pack-objects [các-tùy-chọn...] base-name [< danh-sách-ref | < danh-sách-"
 "đối-tượng]"
 
-#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#: builtin/pack-objects.c:184 builtin/pack-objects.c:187
 #, c-format
 msgid "deflate error (%d)"
 msgstr "lỗi giải nén (%d)"
 
-#: builtin/pack-objects.c:2397
+#: builtin/pack-objects.c:2398
 #, c-format
 msgid "unsupported index version %s"
 msgstr "phiên bản mục lục không được hỗ trợ %s"
 
-#: builtin/pack-objects.c:2401
+#: builtin/pack-objects.c:2402
 #, c-format
 msgid "bad index version '%s'"
 msgstr "phiên bản mục lục sai “%s”"
 
-#: builtin/pack-objects.c:2424
+#: builtin/pack-objects.c:2425
 #, c-format
 msgid "option %s does not accept negative form"
 msgstr "tùy chọn %s không chấp nhận dạng thức âm"
 
-#: builtin/pack-objects.c:2428
+#: builtin/pack-objects.c:2429
 #, c-format
 msgid "unable to parse value '%s' for option %s"
 msgstr "không thể phân tích giá trị “%s” cho tùy chọn %s"
 
-#: builtin/pack-objects.c:2447
+#: builtin/pack-objects.c:2448
 msgid "do not show progress meter"
 msgstr "không hiển thị bộ đo tiến trình"
 
-#: builtin/pack-objects.c:2449
+#: builtin/pack-objects.c:2450
 msgid "show progress meter"
 msgstr "hiển thị bộ đo tiến trình"
 
-#: builtin/pack-objects.c:2451
+#: builtin/pack-objects.c:2452
 msgid "show progress meter during object writing phase"
 msgstr "hiển thị bộ đo tiến triển trong suốt pha ghi đối tượng"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:2455
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "tương tự --all-progress khi bộ đo tiến trình được xuất hiện"
 
-#: builtin/pack-objects.c:2455
+#: builtin/pack-objects.c:2456
 msgid "version[,offset]"
 msgstr "phiên bản[,offset]"
 
-#: builtin/pack-objects.c:2456
+#: builtin/pack-objects.c:2457
 msgid "write the pack index file in the specified idx format version"
 msgstr "ghi tập tin bảng mục lục gói (pack) ở phiên bản định dạng idx đã cho"
 
-#: builtin/pack-objects.c:2459
+#: builtin/pack-objects.c:2460
 msgid "maximum size of each output pack file"
 msgstr "kcíh thước tối đa cho tập tin gói được tạo"
 
-#: builtin/pack-objects.c:2461
+#: builtin/pack-objects.c:2462
 msgid "ignore borrowed objects from alternate object store"
 msgstr "bỏ qua các đối tượng vay mượn từ kho đối tượng thay thế"
 
-#: builtin/pack-objects.c:2463
+#: builtin/pack-objects.c:2464
 msgid "ignore packed objects"
 msgstr "bỏ qua các đối tượng đóng gói"
 
-#: builtin/pack-objects.c:2465
+#: builtin/pack-objects.c:2466
 msgid "limit pack window by objects"
 msgstr "giới hạn cửa sổ đóng gói theo đối tượng"
 
-#: builtin/pack-objects.c:2467
+#: builtin/pack-objects.c:2468
 msgid "limit pack window by memory in addition to object limit"
 msgstr "giới hạn cửa sổ đóng gói theo bộ nhớ cộng thêm với giới hạn đối tượng"
 
-#: builtin/pack-objects.c:2469
+#: builtin/pack-objects.c:2470
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr "độ dài tối đa của chuỗi móc xích “delta” được phép trong gói kết quả"
 
-#: builtin/pack-objects.c:2471
+#: builtin/pack-objects.c:2472
 msgid "reuse existing deltas"
 msgstr "dùng lại các delta sẵn có"
 
-#: builtin/pack-objects.c:2473
+#: builtin/pack-objects.c:2474
 msgid "reuse existing objects"
 msgstr "dùng lại các đối tượng sẵn có"
 
-#: builtin/pack-objects.c:2475
+#: builtin/pack-objects.c:2476
 msgid "use OFS_DELTA objects"
 msgstr "dùng các đối tượng OFS_DELTA"
 
-#: builtin/pack-objects.c:2477
+#: builtin/pack-objects.c:2478
 msgid "use threads when searching for best delta matches"
 msgstr "sử dụng các tuyến trình khi tìm kiếm cho các mẫu khớp delta tốt nhất"
 
-#: builtin/pack-objects.c:2479
+#: builtin/pack-objects.c:2480
 msgid "do not create an empty pack output"
 msgstr "không thể tạo kết xuất gói (pack) trống rỗng"
 
-#: builtin/pack-objects.c:2481
+#: builtin/pack-objects.c:2482
 msgid "read revision arguments from standard input"
 msgstr " đọc tham số “revision” từ thiết bị nhập chuẩn"
 
-#: builtin/pack-objects.c:2483
+#: builtin/pack-objects.c:2484
 msgid "limit the objects to those that are not yet packed"
 msgstr "giới hạn các đối tượng thành những cái mà chúng vẫn chưa được đóng gói"
 
-#: builtin/pack-objects.c:2486
+#: builtin/pack-objects.c:2487
 msgid "include objects reachable from any reference"
 msgstr "bao gồm các đối tượng có thể đọc được từ bất kỳ tham chiếu nào"
 
-#: builtin/pack-objects.c:2489
+#: builtin/pack-objects.c:2490
 msgid "include objects referred by reflog entries"
 msgstr "bao gồm các đối tượng được tham chiếu bởi các mục reflog"
 
-#: builtin/pack-objects.c:2492
+#: builtin/pack-objects.c:2493
 msgid "output pack to stdout"
 msgstr "xuất gói ra đầu ra tiêu chuẩn"
 
-#: builtin/pack-objects.c:2494
+#: builtin/pack-objects.c:2495
 msgid "include tag objects that refer to objects to be packed"
 msgstr "bao gồm các đối tượng tham chiếu đến các đối tượng được đóng gói"
 
-#: builtin/pack-objects.c:2496
+#: builtin/pack-objects.c:2497
 msgid "keep unreachable objects"
 msgstr "giữ lại các đối tượng không thể đọc được"
 
-#: builtin/pack-objects.c:2497 parse-options.h:141
+#: builtin/pack-objects.c:2498 parse-options.h:143
 msgid "time"
 msgstr "thời-gian"
 
-#: builtin/pack-objects.c:2498
+#: builtin/pack-objects.c:2499
 msgid "unpack unreachable objects newer than <time>"
 msgstr ""
 "xả nén (gỡ khỏi gói) các đối tượng không thể đọc được mới hơn <thời-gian>"
 
-#: builtin/pack-objects.c:2501
+#: builtin/pack-objects.c:2502
 msgid "create thin packs"
 msgstr "tạo gói nhẹ"
 
-#: builtin/pack-objects.c:2503
+#: builtin/pack-objects.c:2504
 msgid "ignore packs that have companion .keep file"
 msgstr "bỏ qua các gói mà nó có tập tin .keep đi kèm"
 
-#: builtin/pack-objects.c:2505
+#: builtin/pack-objects.c:2506
 msgid "pack compression level"
 msgstr "mức nén gói"
 
-#: builtin/pack-objects.c:2507
+#: builtin/pack-objects.c:2508
 msgid "do not hide commits by grafts"
 msgstr "không ẩn các lần chuyển giao bởi “grafts”"
 
@@ -7585,15 +7792,15 @@
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<các-tùy-chọn>] [<kho-chứa> [<refspec>...]]"
 
-#: builtin/push.c:45
+#: builtin/push.c:47
 msgid "tag shorthand without <tag>"
 msgstr "dùng tốc ký tag không có <thẻ>"
 
-#: builtin/push.c:64
+#: builtin/push.c:66
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete chỉ chấp nhận các tên tham chiếu (ref) dạng thường"
 
-#: builtin/push.c:99
+#: builtin/push.c:101
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -7602,7 +7809,7 @@
 "Để chọn mỗi tùy chọn một cách cố định, xem push.default trong “git help "
 "config”."
 
-#: builtin/push.c:102
+#: builtin/push.c:104
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -7627,7 +7834,7 @@
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:117
+#: builtin/push.c:119
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -7642,7 +7849,7 @@
 "\n"
 "    git push %s HEAD:<tên-của-nhánh-máy-chủ>\n"
 
-#: builtin/push.c:131
+#: builtin/push.c:133
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -7656,12 +7863,12 @@
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:139
+#: builtin/push.c:141
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "Nhánh hiện tại %s có đa nhánh thượng nguồn (upstream), từ chối push."
 
-#: builtin/push.c:142
+#: builtin/push.c:144
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -7673,7 +7880,7 @@
 "nhánh hiện tại “%s” của bạn, mà không báo cho tôi biết là cái gì được push\n"
 "để cập nhật nhánh máy chủ nào."
 
-#: builtin/push.c:165
+#: builtin/push.c:167
 msgid ""
 "push.default is unset; its implicit value is changing in\n"
 "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -7706,14 +7913,14 @@
 "tự\n"
 "“current” thay vì “simple” nếu bạn thỉnh thoảng phải sử dụng bản Git cũ)"
 
-#: builtin/push.c:225
+#: builtin/push.c:227
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "Bạn đã không chỉ ra một refspecs nào để push, và push.default là \"không là "
 "gì cả\"."
 
-#: builtin/push.c:232
+#: builtin/push.c:234
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -7727,7 +7934,7 @@
 "Xem “Note about fast-forwards” từ lệnh “git push --help” để có thông tin chi "
 "tiết."
 
-#: builtin/push.c:238
+#: builtin/push.c:240
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. If you did not intend to push that branch, you may want to\n"
@@ -7742,7 +7949,7 @@
 "thành “simple”, “current” hoặc “upstream” để chỉ push nhánh hiện hành mà "
 "thôi."
 
-#: builtin/push.c:244
+#: builtin/push.c:246
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. Check out this branch and integrate the remote changes\n"
@@ -7756,7 +7963,7 @@
 "Xem “Note about fast-forwards” từ lệnh “git push --help” để có thông tin chi "
 "tiết."
 
-#: builtin/push.c:250
+#: builtin/push.c:252
 msgid ""
 "Updates were rejected because the remote contains work that you do\n"
 "not have locally. This is usually caused by another repository pushing\n"
@@ -7771,11 +7978,11 @@
 "Xem “Note about fast-forwards” từ lệnh “git push --help” để có thông tin chi "
 "tiết."
 
-#: builtin/push.c:257
+#: builtin/push.c:259
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr "Việc cập nhật bị từ chối bởi vì thẻ đã sẵn có từ trước trên máy chủ."
 
-#: builtin/push.c:260
+#: builtin/push.c:262
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -7787,22 +7994,22 @@
 "tượng\n"
 "không phải chuyển giao, mà không sử dụng tùy chọn “--force”.\n"
 
-#: builtin/push.c:320
+#: builtin/push.c:328
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Đang push (đẩy) lên %s\n"
 
-#: builtin/push.c:324
+#: builtin/push.c:332
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "gặp lỗi khi push (đẩy lên) một số tham chiếu (ref) đến “%s”"
 
-#: builtin/push.c:357
+#: builtin/push.c:365
 #, c-format
 msgid "bad repository '%s'"
 msgstr "repository (kho) sai “%s”"
 
-#: builtin/push.c:358
+#: builtin/push.c:366
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -7823,88 +8030,96 @@
 "\n"
 "    git push <tên>\n"
 
-#: builtin/push.c:373
+#: builtin/push.c:381
 msgid "--all and --tags are incompatible"
 msgstr "--all và --tags xung khắc nhau"
 
-#: builtin/push.c:374
+#: builtin/push.c:382
 msgid "--all can't be combined with refspecs"
-msgstr "--all không thể được tổ hợp cùng với refspecs"
+msgstr "--all không thể được tổ hợp cùng với đặc tả đường dẫn"
 
-#: builtin/push.c:379
+#: builtin/push.c:387
 msgid "--mirror and --tags are incompatible"
 msgstr "--mirror và --tags xung khắc nhau"
 
-#: builtin/push.c:380
+#: builtin/push.c:388
 msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror không thể được tổ hợp cùng với refspecs"
+msgstr "--mirror không thể được tổ hợp cùng với đặc tả đường dẫn"
 
-#: builtin/push.c:385
+#: builtin/push.c:393
 msgid "--all and --mirror are incompatible"
 msgstr "--all và --mirror xung khắc nhau"
 
-#: builtin/push.c:445
+#: builtin/push.c:453
 msgid "repository"
 msgstr "kho"
 
-#: builtin/push.c:446
+#: builtin/push.c:454
 msgid "push all refs"
 msgstr "push tất cả refs"
 
-#: builtin/push.c:447
+#: builtin/push.c:455
 msgid "mirror all refs"
-msgstr "mirror tất cả refs"
+msgstr "mirror tất cả các tham chiếu"
 
-#: builtin/push.c:449
+#: builtin/push.c:457
 msgid "delete refs"
 msgstr "xóa refs"
 
-#: builtin/push.c:450
+#: builtin/push.c:458
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr ""
 "các thẻ push (không thể sử dụng cùng với các tùy chọn --all hay --mirror)"
 
-#: builtin/push.c:453
+#: builtin/push.c:461
 msgid "force updates"
 msgstr "ép buộc cập nhật"
 
-#: builtin/push.c:454
+#: builtin/push.c:463
+msgid "refname>:<expect"
+msgstr "tên-tham-chiếu>:<cần"
+
+#: builtin/push.c:464
+msgid "require old value of ref to be at this value"
+msgstr "yêu cầu giá-trị cũ của tham chiếu thì là giá-trị này"
+
+#: builtin/push.c:466
 msgid "check"
 msgstr "kiểm tra"
 
-#: builtin/push.c:455
+#: builtin/push.c:467
 msgid "control recursive pushing of submodules"
 msgstr "điều khiển việc đẩy lên (push) đệ qui của mô-đun-con"
 
-#: builtin/push.c:457
+#: builtin/push.c:469
 msgid "use thin pack"
 msgstr "tạo gói nhẹ"
 
-#: builtin/push.c:458 builtin/push.c:459
+#: builtin/push.c:470 builtin/push.c:471
 msgid "receive pack program"
 msgstr "nhận về chương trình pack"
 
-#: builtin/push.c:460
+#: builtin/push.c:472
 msgid "set upstream for git pull/status"
 msgstr "đặt thượng nguồn (upstream) cho git pull/status"
 
-#: builtin/push.c:463
+#: builtin/push.c:475
 msgid "prune locally removed refs"
 msgstr "prune (cắt cụt) những tham chiếu (refs) bị gỡ bỏ"
 
-#: builtin/push.c:465
+#: builtin/push.c:477
 msgid "bypass pre-push hook"
 msgstr "vòng qua “pre-push hook”"
 
-#: builtin/push.c:466
+#: builtin/push.c:478
 msgid "push missing but relevant tags"
 msgstr "push bị trượt nhưng các thẻ thích hợp"
 
-#: builtin/push.c:476
+#: builtin/push.c:488
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete là xung khắc với các tùy chọn --all, --mirror và --tags"
 
-#: builtin/push.c:478
+#: builtin/push.c:490
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete không hợp lý nếu không có bất kỳ tham chiếu (refs) nào"
 
@@ -7982,14 +8197,14 @@
 
 #: builtin/read-tree.c:138
 msgid "debug unpack-trees"
-msgstr "gỡ lỗi unpack-trees"
+msgstr "gỡ lỗi “unpack-trees”"
 
-#: builtin/reflog.c:500
+#: builtin/reflog.c:499
 #, c-format
 msgid "%s' for '%s' is not a valid timestamp"
-msgstr "%s' cho '%s' không phải là dấu thời gian hợp lệ"
+msgstr "giá trị %s dành cho “%s” không phải là dấu thời gian hợp lệ"
 
-#: builtin/reflog.c:616 builtin/reflog.c:621
+#: builtin/reflog.c:615 builtin/reflog.c:620
 #, c-format
 msgid "'%s' is not a valid timestamp"
 msgstr "“%s” không phải là dấu thời gian hợp lệ"
@@ -8014,9 +8229,9 @@
 msgid "git remote remove <name>"
 msgstr "git remote remove <tên>"
 
-#: builtin/remote.c:15 builtin/remote.c:42
-msgid "git remote set-head <name> (-a | -d | <branch>)"
-msgstr "git remote set-head <tên> (-a | -d | <nhánh>)"
+#: builtin/remote.c:15
+msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"
+msgstr "git remote set-head <tên> (-a | --auto | -d | --delete | <nhánh>)"
 
 #: builtin/remote.c:16
 msgid "git remote [-v | --verbose] show [-n] <name>"
@@ -8052,6 +8267,10 @@
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<các-tùy-chọn>] <tên> <url>"
 
+#: builtin/remote.c:42
+msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
+msgstr "git remote set-head <tên> (-a | --auto | -d | --delete | <nhánh>)"
+
 #: builtin/remote.c:47
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <tên> <nhánh>..."
@@ -8150,7 +8369,7 @@
 #: builtin/remote.c:339
 #, c-format
 msgid "Could not get fetch map for refspec %s"
-msgstr "Không thể lấy ánh xạ (map) fetch cho refspec %s"
+msgstr "Không thể lấy ánh xạ (map) fetch cho đặc tả tham chiếu %s"
 
 #: builtin/remote.c:440 builtin/remote.c:448
 msgid "(matching)"
@@ -8242,7 +8461,7 @@
 
 #: builtin/remote.c:948
 msgid " stale (use 'git remote prune' to remove)"
-msgstr " cũ (dùng “git remote prune” để gỡ bỏ)"
+msgstr " cũ rích (dùng “git remote prune” để gỡ bỏ)"
 
 #: builtin/remote.c:950
 msgid " ???"
@@ -8490,6 +8709,67 @@
 msgid "be verbose; must be placed before a subcommand"
 msgstr "chi tiết; phải được đặt trước một lệnh-con"
 
+#: builtin/repack.c:15
+msgid "git repack [options]"
+msgstr "git repack [các-tùy-chọn]"
+
+#: builtin/repack.c:143
+msgid "pack everything in a single pack"
+msgstr "đóng gói mọi thứ trong một gói đơn"
+
+#: builtin/repack.c:145
+msgid "same as -a, and turn unreachable objects loose"
+msgstr "giống với -a, và chỉnh sửa các đối tượng không đọc được thiếu sót"
+
+#: builtin/repack.c:148
+msgid "remove redundant packs, and run git-prune-packed"
+msgstr "xóa bỏ các gói dư thừa, và chạy git-prune-packed"
+
+#: builtin/repack.c:150
+msgid "pass --no-reuse-delta to git-pack-objects"
+msgstr "chuyển --no-reuse-delta cho git-pack-objects"
+
+#: builtin/repack.c:152
+msgid "pass --no-reuse-object to git-pack-objects"
+msgstr "chuyển --no-reuse-object cho git-pack-objects"
+
+#: builtin/repack.c:154
+msgid "do not run git-update-server-info"
+msgstr "không chạy git-update-server-info"
+
+#: builtin/repack.c:157
+msgid "pass --local to git-pack-objects"
+msgstr "chuyển --local cho git-pack-objects"
+
+#: builtin/repack.c:158
+msgid "approxidate"
+msgstr "ngày ước tính"
+
+#: builtin/repack.c:159
+msgid "with -A, do not loosen objects older than this"
+msgstr "với -A, các đối tượng cũ hơn khoảng thời gian này thì không bị mất"
+
+#: builtin/repack.c:161
+msgid "size of the window used for delta compression"
+msgstr "kích thước cửa sổ được dùng cho nén “delta”"
+
+#: builtin/repack.c:163
+msgid "same as the above, but limit memory size instead of entries count"
+msgstr "giống như trên, nhưng giới hạn kích thước bộ nhớ hay vì số lượng"
+
+#: builtin/repack.c:165
+msgid "limits the maximum delta depth"
+msgstr "giới hạn độ sâu tối đa của “delta”"
+
+#: builtin/repack.c:167
+msgid "maximum size of each packfile"
+msgstr "kcíh thước tối đa cho từng tập tin gói"
+
+#: builtin/repack.c:345
+#, c-format
+msgid "removing '%s' failed"
+msgstr "gặp lỗi khi xóa bỏ “%s”"
+
 #: builtin/replace.c:17
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <đối-tượng> <thay-thế>"
@@ -8502,23 +8782,23 @@
 msgid "git replace -l [<pattern>]"
 msgstr "git replace -l [<mẫu>]"
 
-#: builtin/replace.c:121
+#: builtin/replace.c:131
 msgid "list replace refs"
 msgstr "liệt kê các refs thay thế"
 
-#: builtin/replace.c:122
+#: builtin/replace.c:132
 msgid "delete replace refs"
 msgstr "xóa tham chiếu (refs) thay thế"
 
-#: builtin/replace.c:123
+#: builtin/replace.c:133
 msgid "replace the ref if it exists"
 msgstr "thay thế tham chiếu (ref) nếu nó đã sẵn có"
 
-#: builtin/rerere.c:11
+#: builtin/rerere.c:12
 msgid "git rerere [clear | forget path... | status | remaining | diff | gc]"
 msgstr "git rerere [clear | forget path... | status | remaining | diff | gc]"
 
-#: builtin/rerere.c:56
+#: builtin/rerere.c:57
 msgid "register clean resolutions in index"
 msgstr "sổ ghi dọn sạch các phân giải trong bản mục lục"
 
@@ -8579,71 +8859,71 @@
 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:251
+#: builtin/reset.c:262
 msgid "be quiet, only report errors"
 msgstr "làm việc ở chế độ im lặng, chỉ hiển thị khi có lỗi"
 
-#: builtin/reset.c:253
+#: builtin/reset.c:264
 msgid "reset HEAD and index"
 msgstr "đặt lại (reset) HEAD và bảng mục lục"
 
-#: builtin/reset.c:254
+#: builtin/reset.c:265
 msgid "reset only HEAD"
 msgstr "chỉ đặt lại (reset) HEAD"
 
-#: builtin/reset.c:256 builtin/reset.c:258
+#: builtin/reset.c:267 builtin/reset.c:269
 msgid "reset HEAD, index and working tree"
 msgstr "đặt lại HEAD, bảng mục lục và cây làm việc"
 
-#: builtin/reset.c:260
+#: builtin/reset.c:271
 msgid "reset HEAD but keep local changes"
 msgstr "đặt lại HEAD nhưng giữ lại các thay đổi nội bộ"
 
-#: builtin/reset.c:278
+#: builtin/reset.c:289
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
 msgstr "Gặp lỗi khi phân giải “%s” như là điểm xét duyệt hợp lệ."
 
-#: builtin/reset.c:281 builtin/reset.c:289
+#: builtin/reset.c:292 builtin/reset.c:300
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "không thể phân tích đối tượng “%s”."
 
-#: builtin/reset.c:286
+#: builtin/reset.c:297
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
 msgstr "Gặp lỗi khi phân giải “%s” như là một cây (tree) hợp lệ."
 
-#: builtin/reset.c:295
+#: builtin/reset.c:306
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch xung khắc với --{hard,mixed,soft}"
 
-#: builtin/reset.c:304
+#: builtin/reset.c:315
 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:306
+#: builtin/reset.c:317
 #, 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:316
+#: builtin/reset.c:327
 #, 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:336
+#: builtin/reset.c:344
+msgid "Unstaged changes after reset:"
+msgstr "Những thay đổi bị bỏ trạng thái (stage) sau khi reset:"
+
+#: builtin/reset.c:350
 #, 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 duyệt “%s”."
 
-#: builtin/reset.c:342
-msgid "Unstaged changes after reset:"
-msgstr "Những thay đổi bị bỏ trạng thái (stage) sau khi reset:"
-
-#: builtin/reset.c:347
+#: builtin/reset.c:355
 msgid "Could not write new index file."
 msgstr "Không thể ghi tập tin lưu bảng mục lục mới."
 
@@ -8689,84 +8969,84 @@
 msgid "git cherry-pick <subcommand>"
 msgstr "git cherry-pick <lệnh-con>"
 
-#: builtin/revert.c:71 builtin/revert.c:94
+#: builtin/revert.c:71
 #, c-format
 msgid "%s: %s cannot be used with %s"
 msgstr "%s: %s không thể được sử dụng với %s"
 
-#: builtin/revert.c:105
+#: builtin/revert.c:80
 msgid "end revert or cherry-pick sequence"
 msgstr "kết thúc cherry-pick hay revert liên tiếp nhau"
 
-#: builtin/revert.c:106
+#: builtin/revert.c:81
 msgid "resume revert or cherry-pick sequence"
 msgstr "phục hồi lại cherry-pick hay revert liên tiếp nhau"
 
-#: builtin/revert.c:107
+#: builtin/revert.c:82
 msgid "cancel revert or cherry-pick sequence"
 msgstr "không cherry-pick hay revert liên tiếp nhau"
 
-#: builtin/revert.c:108
+#: builtin/revert.c:83
 msgid "don't automatically commit"
 msgstr "không commit một cách tự động."
 
-#: builtin/revert.c:109
+#: builtin/revert.c:84
 msgid "edit the commit message"
 msgstr "sửa lại chú thích cho commit"
 
-#: builtin/revert.c:112
+#: builtin/revert.c:87
 msgid "parent number"
 msgstr "số của cha mẹ"
 
-#: builtin/revert.c:114
+#: builtin/revert.c:89
 msgid "merge strategy"
 msgstr "chiến lược hòa trộn"
 
-#: builtin/revert.c:115
+#: builtin/revert.c:90
 msgid "option"
 msgstr "tùy chọn"
 
-#: builtin/revert.c:116
+#: builtin/revert.c:91
 msgid "option for merge strategy"
 msgstr "tùy chọn cho chiến lược hòa trộn"
 
-#: builtin/revert.c:127
+#: builtin/revert.c:102
 msgid "append commit name"
 msgstr "nối thêm tên lần chuyển giao (commit)"
 
-#: builtin/revert.c:128
+#: builtin/revert.c:103
 msgid "allow fast-forward"
 msgstr "cho phép fast-forward"
 
-#: builtin/revert.c:129
+#: builtin/revert.c:104
 msgid "preserve initially empty commits"
 msgstr "cấm khởi tạo lần chuyển giao trống rỗng"
 
-#: builtin/revert.c:130
+#: builtin/revert.c:105
 msgid "allow commits with empty messages"
 msgstr "chấp nhận chuyển giao (commit) mà không ghi chú gì"
 
-#: builtin/revert.c:131
+#: builtin/revert.c:106
 msgid "keep redundant, empty commits"
 msgstr "giữ lại các lần chuyển giao dư thừa, rỗng"
 
-#: builtin/revert.c:135
+#: builtin/revert.c:110
 msgid "program error"
 msgstr "lỗi chương trình"
 
-#: builtin/revert.c:225
+#: builtin/revert.c:195
 msgid "revert failed"
 msgstr "revert gặp lỗi"
 
-#: builtin/revert.c:240
+#: builtin/revert.c:210
 msgid "cherry-pick failed"
 msgstr "cherry-pick gặp lỗi"
 
-#: builtin/rm.c:16
+#: builtin/rm.c:17
 msgid "git rm [options] [--] <file>..."
 msgstr "git rm [các-tùy-chọn] [--] <tập-tin>..."
 
-#: builtin/rm.c:64
+#: builtin/rm.c:65
 msgid ""
 "the following submodule (or one of its nested submodules)\n"
 "uses a .git directory:"
@@ -8780,7 +9060,7 @@
 "các mô-đun-con sau đây (hay một trong số mô-đun-con bên trong của nó)\n"
 "dùng một thư mục .git:"
 
-#: builtin/rm.c:70
+#: builtin/rm.c:71
 msgid ""
 "\n"
 "(use 'rm -rf' if you really want to remove it including all of its history)"
@@ -8789,7 +9069,7 @@
 "(dùng /\"rm -rf/\" nếu bạn thực sự muốn gỡ bỏ nó cùng với tất cả lịch sử của "
 "chúng)"
 
-#: builtin/rm.c:230
+#: builtin/rm.c:231
 msgid ""
 "the following file has staged content different from both the\n"
 "file and the HEAD:"
@@ -8803,7 +9083,7 @@
 "các tập tin sau đây có trạng thái khác biệt nội dung từ cả tập tin\n"
 "và cả HEAD:"
 
-#: builtin/rm.c:235
+#: builtin/rm.c:236
 msgid ""
 "\n"
 "(use -f to force removal)"
@@ -8811,13 +9091,13 @@
 "\n"
 "(dùng -f để buộc gỡ bỏ)"
 
-#: builtin/rm.c:239
+#: builtin/rm.c:240
 msgid "the following file has changes staged in the index:"
 msgid_plural "the following files have changes staged in the index:"
 msgstr[0] "tập tin sau đây có thay đổi trạng thái trong bảng mục lục:"
 msgstr[1] "các tập tin sau đây có thay đổi trạng thái trong bảng mục lục:"
 
-#: builtin/rm.c:243 builtin/rm.c:254
+#: builtin/rm.c:244 builtin/rm.c:255
 msgid ""
 "\n"
 "(use --cached to keep the file, or -f to force removal)"
@@ -8825,38 +9105,38 @@
 "\n"
 "(dùng tùy chọn --cached để giữ tập tin, hoặc -f để ép buộc gỡ bỏ)"
 
-#: builtin/rm.c:251
+#: builtin/rm.c:252
 msgid "the following file has local modifications:"
 msgid_plural "the following files have local modifications:"
 msgstr[0] "tập tin sau đây có những thay đổi nội bộ:"
 msgstr[1] "những tập tin sau đây có những thay đổi nội bộ:"
 
-#: builtin/rm.c:269
+#: builtin/rm.c:270
 msgid "do not list removed files"
 msgstr "không liệt kê các tập tin đã gỡ bỏ"
 
-#: builtin/rm.c:270
+#: builtin/rm.c:271
 msgid "only remove from the index"
 msgstr "chỉ gỡ bỏ từ mục lục"
 
-#: builtin/rm.c:271
+#: builtin/rm.c:272
 msgid "override the up-to-date check"
 msgstr "ghi đè lên kiểm tra cập nhật"
 
-#: builtin/rm.c:272
+#: builtin/rm.c:273
 msgid "allow recursive removal"
 msgstr "cho phép gỡ bỏ đệ qui"
 
-#: builtin/rm.c:274
+#: builtin/rm.c:275
 msgid "exit with a zero status even if nothing matched"
 msgstr "thoát ra với trạng thái khác không thậm chí nếu không có gì khớp"
 
-#: builtin/rm.c:345
+#: builtin/rm.c:336
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "không thể gỡ bỏ “%s” một cách đệ qui mà không có tùy chọn -r"
 
-#: builtin/rm.c:384
+#: builtin/rm.c:375
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: không thể gỡ bỏ %s"
@@ -8870,23 +9150,23 @@
 msgid "Missing author: %s"
 msgstr "Thiếu tên tác giả: %s"
 
-#: builtin/shortlog.c:228
+#: builtin/shortlog.c:230
 msgid "sort output according to the number of commits per author"
 msgstr "sắp xếp kết xuất tuân theo số lượng chuyển giao trên mỗi tác giả"
 
-#: builtin/shortlog.c:230
+#: builtin/shortlog.c:232
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "Chặn mọi mô tả lần chuyển giao, chỉ đưa ra số lượng lần chuyển giao"
 
-#: builtin/shortlog.c:232
+#: builtin/shortlog.c:234
 msgid "Show the email address of each author"
 msgstr "Hiển thị thư điện tử cho từng tác giả"
 
-#: builtin/shortlog.c:233
+#: builtin/shortlog.c:235
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:234
+#: builtin/shortlog.c:236
 msgid "Linewrap output"
 msgstr "Ngắt dòng khi quá dài"
 
@@ -8972,11 +9252,11 @@
 
 #: builtin/show-ref.c:10
 msgid ""
-"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash"
-"[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] "
+"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--"
+"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] "
 msgstr ""
-"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash"
-"[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [mẫu*] "
+"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--"
+"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [mẫu*] "
 
 #: builtin/show-ref.c:11
 msgid "git show-ref --exclude-existing[=pattern] < ref-list"
@@ -8996,24 +9276,24 @@
 "việc kiểm tra tham chiếu chính xác, đòi hỏi chính xác đường dẫn tham chiếu "
 "(ref)"
 
-#: builtin/show-ref.c:173 builtin/show-ref.c:176
+#: builtin/show-ref.c:173 builtin/show-ref.c:175
 msgid "show the HEAD reference, even if it would be filtered out"
 msgstr "hiển thị tham chiếu HEAD, ngay cả khi nó đã được lọc ra"
 
-#: builtin/show-ref.c:178
+#: builtin/show-ref.c:177
 msgid "dereference tags into object IDs"
 msgstr "bãi bỏ tham chiếu các thẻ thành ra các ID đối tượng"
 
-#: builtin/show-ref.c:180
+#: builtin/show-ref.c:179
 msgid "only show SHA1 hash using <n> digits"
 msgstr "chỉ hiển thị mã băm SHA1 sử dụng <n> chữ số"
 
-#: builtin/show-ref.c:184
+#: builtin/show-ref.c:183
 msgid "do not print results to stdout (useful with --verify)"
 msgstr ""
 "không hiển thị kết quả ra đầu ra chuẩn (stdout) (chỉ hữu dụng với --verify)"
 
-#: builtin/show-ref.c:186
+#: builtin/show-ref.c:185
 msgid "show refs from stdin that aren't in local repository"
 msgstr ""
 "hiển thị các tham chiếu (refs) từ đầu vào tiêu chuẩn (stdin) cái mà không ở "
@@ -9040,11 +9320,11 @@
 msgid "shorten ref output"
 msgstr "làm ngắn kết xuất ref (tham chiếu)"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason"
 msgstr "lý do"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason of the update"
 msgstr "lý do cập nhật"
 
@@ -9209,187 +9489,199 @@
 msgid "print only tags of the object"
 msgstr "chỉ hiển thị các thẻ của đối tượng"
 
-#: builtin/tag.c:504
+#: builtin/tag.c:501
 msgid "--column and -n are incompatible"
 msgstr "--column và -n xung khắc nhau"
 
-#: builtin/tag.c:521
+#: builtin/tag.c:518
 msgid "-n option is only allowed with -l."
 msgstr "tùy chọn -n chỉ cho phép dùng với -l."
 
-#: builtin/tag.c:523
+#: builtin/tag.c:520
 msgid "--contains option is only allowed with -l."
 msgstr "tùy chọn --contains chỉ cho phép dùng với -l."
 
-#: builtin/tag.c:525
+#: builtin/tag.c:522
 msgid "--points-at option is only allowed with -l."
 msgstr "tùy chọn --points-at chỉ cho phép dùng với -l."
 
-#: builtin/tag.c:533
+#: builtin/tag.c:530
 msgid "only one -F or -m option is allowed."
 msgstr "chỉ có một tùy chọn -F hoặc -m là được phép."
 
-#: builtin/tag.c:553
+#: builtin/tag.c:550
 msgid "too many params"
 msgstr "quá nhiều đối số"
 
-#: builtin/tag.c:559
+#: builtin/tag.c:556
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "“%s” không phải thẻ hợp lệ."
 
-#: builtin/tag.c:564
+#: builtin/tag.c:561
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "Thẻ “%s” đã tồn tại rồi"
 
-#: builtin/tag.c:582
+#: builtin/tag.c:579
 #, c-format
 msgid "%s: cannot lock the ref"
 msgstr "%s: không thể khóa ref (tham chiếu)"
 
-#: builtin/tag.c:584
+#: builtin/tag.c:581
 #, c-format
 msgid "%s: cannot update the ref"
 msgstr "%s: không thể cập nhật ref (tham chiếu)"
 
-#: builtin/tag.c:586
+#: builtin/tag.c:583
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Đã cập nhật thẻ “%s” (trước là %s)\n"
 
-#: builtin/update-index.c:401
+#: builtin/update-index.c:402
 msgid "git update-index [options] [--] [<file>...]"
 msgstr "git update-index [các-tùy-chọn] [<tập-tin>...]"
 
-#: builtin/update-index.c:718
+#: builtin/update-index.c:720
 msgid "continue refresh even when index needs update"
 msgstr "tiếp tục làm mới ngay cả khi bảng mục lục cần được cập nhật"
 
-#: builtin/update-index.c:721
+#: builtin/update-index.c:723
 msgid "refresh: ignore submodules"
 msgstr "refresh: lờ đi mô-đun-con"
 
-#: builtin/update-index.c:724
+#: builtin/update-index.c:726
 msgid "do not ignore new files"
 msgstr "không bỏ qua các tập tin mới tạo"
 
-#: builtin/update-index.c:726
+#: builtin/update-index.c:728
 msgid "let files replace directories and vice-versa"
 msgstr "để các tập tin thay thế các thư mục và “vice-versa”"
 
-#: builtin/update-index.c:728
+#: builtin/update-index.c:730
 msgid "notice files missing from worktree"
 msgstr "thông báo các tập-tin thiếu trong thư-mục làm việc"
 
-#: builtin/update-index.c:730
+#: builtin/update-index.c:732
 msgid "refresh even if index contains unmerged entries"
 msgstr ""
 "làm tươi mới thậm chí khi bảng mục lục chứa các mục tin chưa được hòa trộn"
 
-#: builtin/update-index.c:733
+#: builtin/update-index.c:735
 msgid "refresh stat information"
 msgstr "lấy lại thông tin thống kê"
 
-#: builtin/update-index.c:737
+#: builtin/update-index.c:739
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "giống --refresh, nhưng bỏ qua các cài đặt “assume-unchanged”"
 
-#: builtin/update-index.c:741
+#: builtin/update-index.c:743
 msgid "<mode> <object> <path>"
 msgstr "<mode> <đối tượng> <đường dẫn>"
 
-#: builtin/update-index.c:742
+#: builtin/update-index.c:744
 msgid "add the specified entry to the index"
 msgstr "thêm các tập tin đã chỉ ra vào bảng mục lục"
 
-#: builtin/update-index.c:746
+#: builtin/update-index.c:748
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/update-index.c:747
+#: builtin/update-index.c:749
 msgid "override the executable bit of the listed files"
 msgstr "ghi đè lên bít thi hành của các tập tin được liệt kê"
 
-#: builtin/update-index.c:751
+#: builtin/update-index.c:753
 msgid "mark files as \"not changing\""
 msgstr "Đánh dấu các tập tin là \"không thay đổi\""
 
-#: builtin/update-index.c:754
+#: builtin/update-index.c:756
 msgid "clear assumed-unchanged bit"
 msgstr "xóa bít  assumed-unchanged"
 
-#: builtin/update-index.c:757
+#: builtin/update-index.c:759
 msgid "mark files as \"index-only\""
 msgstr "đánh dấu các tập tin là “chỉ-đọc”"
 
-#: builtin/update-index.c:760
+#: builtin/update-index.c:762
 msgid "clear skip-worktree bit"
 msgstr "xóa bít skip-worktree"
 
-#: builtin/update-index.c:763
+#: builtin/update-index.c:765
 msgid "add to index only; do not add content to object database"
 msgstr ""
 "chỉ thêm vào bảng mục lục; không thêm nội dung vào cơ sở dữ liệu đối tượng"
 
-#: builtin/update-index.c:765
+#: builtin/update-index.c:767
 msgid "remove named paths even if present in worktree"
 msgstr ""
 "gỡ bỏ các đường dẫn được đặt tên thậm chí cả khi nó hiện diện trong thư mục "
 "làm việc"
 
-#: builtin/update-index.c:767
+#: builtin/update-index.c:769
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "với tùy chọn --stdin: các dòng đầu vào được chấm dứt bởi ký tự null"
 
-#: builtin/update-index.c:769
+#: builtin/update-index.c:771
 msgid "read list of paths to be updated from standard input"
 msgstr "đọc danh sách đường dẫn cần cập nhật từ đầu vào tiêu chuẩn"
 
-#: builtin/update-index.c:773
+#: builtin/update-index.c:775
 msgid "add entries from standard input to the index"
 msgstr "không thể đọc các mục từ đầu vào tiêu chuẩn vào bảng mục lục"
 
-#: builtin/update-index.c:777
+#: builtin/update-index.c:779
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "phục hồi các trạng thái #2 và #3 cho các đường dẫn được liệt kê"
 
-#: builtin/update-index.c:781
+#: builtin/update-index.c:783
 msgid "only update entries that differ from HEAD"
 msgstr "chỉ cập nhật các mục tin mà nó khác biệt so với HEAD"
 
-#: builtin/update-index.c:785
+#: builtin/update-index.c:787
 msgid "ignore files missing from worktree"
 msgstr "bỏ qua các tập-tin thiếu trong thư-mục làm việc"
 
-#: builtin/update-index.c:788
+#: builtin/update-index.c:790
 msgid "report actions to standard output"
 msgstr "báo cáo các thao tác ra thiết bị xuất chuẩn"
 
-#: builtin/update-index.c:790
+#: builtin/update-index.c:792
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(cho “porcelains”) quên các xung đột chưa được giải quyết đã ghi"
 
-#: builtin/update-index.c:794
+#: builtin/update-index.c:796
 msgid "write index in this format"
 msgstr "ghi mục lục ở định dạng này"
 
-#: builtin/update-ref.c:7
+#: builtin/update-ref.c:9
 msgid "git update-ref [options] -d <refname> [<oldval>]"
 msgstr "git update-ref [các-tùy-chọn] -d <refname> [<biến-cũ>]"
 
-#: builtin/update-ref.c:8
+#: builtin/update-ref.c:10
 msgid "git update-ref [options]    <refname> <newval> [<oldval>]"
 msgstr "git update-ref [các-tùy-chọn]    <refname> <biến-mới> [<biến-cũ>]"
 
-#: builtin/update-ref.c:19
+#: builtin/update-ref.c:11
+msgid "git update-ref [options] --stdin [-z]"
+msgstr "git update-ref [các-tùy-chọn] --stdin [-z]"
+
+#: builtin/update-ref.c:255
 msgid "delete the reference"
 msgstr "xóa tham chiếu"
 
-#: builtin/update-ref.c:21
+#: builtin/update-ref.c:257
 msgid "update <refname> not the one it points to"
 msgstr "cập nhật <tên-tham-chiếu> không phải cái nó chỉ tới"
 
+#: builtin/update-ref.c:258
+msgid "stdin has NUL-terminated arguments"
+msgstr "đầu vào tiêu chuẩn có các đối số được chấm dứt bởi NUL"
+
+#: builtin/update-ref.c:259
+msgid "read updates from stdin"
+msgstr "đọc cập nhật từ đầu vào tiêu chuẩn"
+
 #: builtin/update-server-info.c:6
 msgid "git update-server-info [--force]"
 msgstr "git update-server-info [--force]"
@@ -9444,23 +9736,23 @@
 "hướng dẫn về khái niệm. Xem “git help <lệnh>” hay “git help <khái-niệm>”\n"
 "để xem các đặc tả cho lệnh hay khái niệm cụ thể."
 
-#: parse-options.h:144
+#: parse-options.h:146
 msgid "expiry date"
 msgstr "ngày hết hạn"
 
-#: parse-options.h:159
+#: parse-options.h:161
 msgid "no-op (backward compatibility)"
 msgstr "no-op (tương thích ngược)"
 
-#: parse-options.h:236
+#: parse-options.h:238
 msgid "be more verbose"
 msgstr "chi tiết hơn nữa"
 
-#: parse-options.h:238
+#: parse-options.h:240
 msgid "be more quiet"
 msgstr "im lặng hơn nữa"
 
-#: parse-options.h:244
+#: parse-options.h:246
 msgid "use <n> digits to display SHA-1s"
 msgstr "sử dụng <n> chữ số để hiển thị SHA-1s"
 
@@ -9669,7 +9961,7 @@
 
 #: git-am.sh:725
 msgid "Patch does not have a valid e-mail address."
-msgstr "Miếng vá không có địa chỉ e-mail hợp lệ."
+msgstr "Miếng vá không có địa chỉ thư điện tử hợp lệ."
 
 #: git-am.sh:772
 msgid "cannot be interactive without stdin connected to a terminal."
@@ -9686,8 +9978,8 @@
 #: git-am.sh:783
 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] "
+"Áp dụng? đồng ý [y]/khô[n]g/chỉnh sửa [e]/hiển thị miếng [v]á/đồng ý tất cả "
+"[a] "
 
 #: git-am.sh:819
 #, sh-format
@@ -9720,7 +10012,7 @@
 #: git-am.sh:874
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
-msgstr "Vá gặp lỗi tại $msgnum $FIRSTLINE"
+msgstr "Gặp lỗi khi vá tại $msgnum $FIRSTLINE"
 
 #: git-am.sh:877
 #, sh-format
@@ -9910,7 +10202,7 @@
 msgstr ""
 "Full là không thể thực hiện bởi vì bạn có những tập tin chưa được hòa trộn."
 
-#: git-pull.sh:203
+#: git-pull.sh:223
 msgid "updating an unborn branch with changes added to the index"
 msgstr ""
 "đang cập nhật một nhánh chưa được sinh ra với các thay đổi được thêm vào "
@@ -9920,7 +10212,7 @@
 #. The working tree and the index file is still based on the
 #. $orig_head commit, but we are merging into $curr_head.
 #. First update the working tree to match $curr_head.
-#: git-pull.sh:235
+#: git-pull.sh:255
 #, sh-format
 msgid ""
 "Warning: fetch updated the current branch head.\n"
@@ -9931,11 +10223,11 @@
 "Cảnh báo: đang fast-forward cây làm việc của bạn từ\n"
 "Cảnh báo: commit $orig_head."
 
-#: git-pull.sh:260
+#: git-pull.sh:280
 msgid "Cannot merge multiple branches into empty head"
 msgstr "Không thể hòa trộn nhiều nhánh và trong một head trống rỗng"
 
-#: git-pull.sh:264
+#: git-pull.sh:284
 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"
 
@@ -9972,35 +10264,35 @@
 "Bạn có thể chạy lệnh \"git stash pop\" hay \"git stash drop\" bất kỳ lúc "
 "nào.\n"
 
-#: git-rebase.sh:190
+#: git-rebase.sh:199
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Móc (hook) pre-rebase từ chối rebase."
 
-#: git-rebase.sh:195
+#: git-rebase.sh:204
 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:329
+#: git-rebase.sh:338
 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:334
+#: git-rebase.sh:343
 msgid "No rebase in progress?"
 msgstr "Không có tiến trình rebase nào phải không?"
 
-#: git-rebase.sh:345
+#: git-rebase.sh:354
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 "Hành động “--edit-todo” chỉ có thể dùng trong quá trình “rebase” (sửa lịch "
 "sử) tương tác."
 
-#: git-rebase.sh:352
+#: git-rebase.sh:361
 msgid "Cannot read HEAD"
 msgstr "Không thể đọc HEAD"
 
-#: git-rebase.sh:355
+#: git-rebase.sh:364
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -10008,12 +10300,12 @@
 "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:373
+#: git-rebase.sh:382
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Không thể quay trở lại $head_name"
 
-#: git-rebase.sh:392
+#: git-rebase.sh:401
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -10036,66 +10328,66 @@
 "\n"
 "TÔI: là lệnh bạn vừa gọi!"
 
-#: git-rebase.sh:437
+#: git-rebase.sh:446
 #, sh-format
 msgid "invalid upstream $upstream_name"
 msgstr "thượng nguồn không hợp lệ $upstream_name"
 
-#: git-rebase.sh:461
+#: git-rebase.sh:470
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: ở đây có nhiều hơn một nền móng hòa trộn"
 
-#: git-rebase.sh:464 git-rebase.sh:468
+#: git-rebase.sh:473 git-rebase.sh:477
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: ở đây không có nền móng hòa trộn nào"
 
-#: git-rebase.sh:473
+#: git-rebase.sh:482
 #, 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:496
+#: git-rebase.sh:505
 #, 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:519
+#: git-rebase.sh:528
 msgid "Cannot autostash"
 msgstr "Không thể autostash"
 
-#: git-rebase.sh:524
+#: git-rebase.sh:533
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "Đã tạo autostash: $stash_abbrev"
 
-#: git-rebase.sh:528
+#: git-rebase.sh:537
 msgid "Please commit or stash them."
 msgstr "Xin hãy commit hoặc tạm cất (stash) chúng."
 
-#: git-rebase.sh:548
+#: git-rebase.sh:557
 #, 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:552
+#: git-rebase.sh:561
 #, 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:563
+#: git-rebase.sh:572
 #, 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:572
+#: git-rebase.sh:581
 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:582
+#: git-rebase.sh:591
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "Fast-forward $branch_name thành $onto_name."
@@ -10144,7 +10436,7 @@
 #. $ git stash save --blah-blah 2>&1 | head -n 2
 #. error: unknown option for 'stash save': --blah-blah
 #. To provide a message, use git stash save -- '--blah-blah'
-#: git-stash.sh:241
+#: git-stash.sh:237
 #, sh-format
 msgid ""
 "error: unknown option for 'stash save': $option\n"
@@ -10154,99 +10446,85 @@
 "     Để dùng thông điệp có chứa -- ở đầu, sử dụng git stash save -- \"$option"
 "\""
 
-#: git-stash.sh:262
+#: git-stash.sh:258
 msgid "No local changes to save"
 msgstr "Không có thay đổi nội bộ nào được ghi lại"
 
-#: git-stash.sh:268
-msgid ""
-"The following untracked files would NOT be saved but need to be removed by "
-"stash save:"
-msgstr ""
-"Các tập tin chưa được theo dõi sau đây KHÔNG được ghi lại nhưng cần được gỡ "
-"bỏ bởi việc ghi lại stash:"
-
-#: git-stash.sh:270
-msgid ""
-"Aborting. Consider using either the --force or --include-untracked option."
-msgstr ""
-"Bãi bỏ. Cân nhắc dùng một trong hai tùy chọn --force và --include-untracked."
-
-#: git-stash.sh:274
+#: git-stash.sh:262
 msgid "Cannot initialize stash"
 msgstr "Không thể khởi tạo stash"
 
-#: git-stash.sh:278
+#: git-stash.sh:266
 msgid "Cannot save the current status"
 msgstr "Không thể ghi lại trạng thái hiện hành"
 
-#: git-stash.sh:296
+#: git-stash.sh:284
 msgid "Cannot remove worktree changes"
 msgstr "Không thể gỡ bỏ các thay đổi cây-làm-việc"
 
-#: git-stash.sh:395
+#: git-stash.sh:383
 msgid "No stash found."
 msgstr "Không tìm thấy stash nào."
 
-#: git-stash.sh:402
+#: git-stash.sh:390
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "Chỉ ra quá nhiều điểm xét duyệt: $REV"
 
-#: git-stash.sh:408
+#: git-stash.sh:396
 #, sh-format
 msgid "$reference is not valid reference"
 msgstr "$reference không phải là tham chiếu hợp lệ"
 
-#: git-stash.sh:436
+#: git-stash.sh:424
 #, sh-format
 msgid "'$args' is not a stash-like commit"
-msgstr "”$args” không phải là lần chuyển giao (commit) giống-stash"
+msgstr "”$args” không phải là lần chuyển giao (commit) kiểu-stash"
 
-#: git-stash.sh:447
+#: git-stash.sh:435
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "”$args” không phải tham chiếu đến stash"
 
-#: git-stash.sh:455
+#: git-stash.sh:443
 msgid "unable to refresh index"
 msgstr "không thể làm tươi mới bảng mục lục"
 
-#: git-stash.sh:459
+#: git-stash.sh:447
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "Không thể áp dụng một stash ở giữa của quá trình hòa trộn"
 
-#: git-stash.sh:467
+#: git-stash.sh:455
 msgid "Conflicts in index. Try without --index."
 msgstr "Xung đột trong bảng mục lục. Hãy thử mà không dùng tùy chọn --index."
 
-#: git-stash.sh:469
+#: git-stash.sh:457
 msgid "Could not save index tree"
 msgstr "Không thể ghi lại cây chỉ mục"
 
-#: git-stash.sh:503
+#: git-stash.sh:491
 msgid "Cannot unstage modified files"
 msgstr "Không thể bỏ trạng thía của các tập tin đã được sửa chữa"
 
-#: git-stash.sh:518
+#: git-stash.sh:506
 msgid "Index was not unstashed."
 msgstr "Bảng mục lục đã không được bỏ stash."
 
-#: git-stash.sh:535
+#: git-stash.sh:523
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "Đã xóa ${REV} ($s)"
 
-#: git-stash.sh:536
+#: git-stash.sh:524
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: Không thể xóa bỏ mục stash"
 
-#: git-stash.sh:543
+#: git-stash.sh:531
 msgid "No branch name specified"
 msgstr "Chưa chỉ ra tên của nhánh"
 
-#: git-stash.sh:615
+#: git-stash.sh:603
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(Để phục hồi lại chúng hãy gõ \"git stash apply\")"
 
@@ -10424,7 +10702,7 @@
 #: git-submodule.sh:683
 #, sh-format
 msgid "Cleared directory '$displaypath'"
-msgstr "Đã tạo thư mục '$displaypath'"
+msgstr "Đã tạo thư mục “$displaypath”"
 
 #: git-submodule.sh:684
 #, sh-format
@@ -10521,52 +10799,63 @@
 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:1066
+#: git-submodule.sh:1073
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "chế độ không như mong chờ $mod_dst"
 
-#: git-submodule.sh:1086
+#: git-submodule.sh:1093
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr ""
 "  Cảnh báo: $display_name không chứa lần chuyển giao (commit) $sha1_src"
 
-#: git-submodule.sh:1089
+#: git-submodule.sh:1096
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr ""
 "  Cảnh báo: $display_name không chứa lần chuyển giao (commit) $sha1_dst"
 
-#: git-submodule.sh:1092
+#: git-submodule.sh:1099
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
 "  Cảnh báo: $display_name không chứa những lần chuyển giao (commit) "
 "$sha1_src và $sha1_dst"
 
-#: git-submodule.sh:1117
+#: git-submodule.sh:1124
 msgid "blob"
 msgstr "blob"
 
-#: git-submodule.sh:1155
-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:1157
-msgid "Submodule changes to be committed:"
-msgstr "Những mô-đun-con thay đổi đã được chuyển giao (commit):"
-
-#: git-submodule.sh:1242
+#: git-submodule.sh:1238
 #, 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:1306
+#: git-submodule.sh:1302
 #, sh-format
 msgid "Synchronizing submodule url for '$displaypath'"
 msgstr "Url Mô-đun-con đồng bộ hóa cho “$displaypath”"
 
+#~ msgid "done\n"
+#~ msgstr "xong\n"
+
+#~ msgid "input paths are terminated by a null character"
+#~ msgstr "các đường dẫn được  ngăn cách bởi ký tự null"
+
+#~ msgid ""
+#~ "The following untracked files would NOT be saved but need to be removed "
+#~ "by stash save:"
+#~ msgstr ""
+#~ "Các tập tin chưa được theo dõi sau đây KHÔNG được ghi lại nhưng cần được "
+#~ "gỡ bỏ bởi việc ghi lại stash:"
+
+#~ msgid ""
+#~ "Aborting. Consider using either the --force or --include-untracked option."
+#~ msgstr ""
+#~ "Bãi bỏ. Cân nhắc dùng một trong hai tùy chọn --force và --include-"
+#~ "untracked."
+
 #~ 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\")"
 
@@ -10688,9 +10977,6 @@
 #~ msgid "-B cannot be used with -b"
 #~ msgstr "tùy chọn -B không thể dùng -b"
 
-#~ 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"
-
 #~ msgid "--detach cannot be used with -b/-B/--orphan"
 #~ msgstr "--detach không thể được sử dụng với tùy chọn -b/-B/--orphan"
 
diff --git a/po/zh_CN.po b/po/zh_CN.po
index b7b46f1..b701086 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -12,8 +12,8 @@
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2013-08-06 14:10+0800\n"
-"PO-Revision-Date: 2013-08-06 14:45+0800\n"
+"POT-Creation-Date: 2013-11-02 08:06+0800\n"
+"PO-Revision-Date: 2013-11-02 08:14+0800\n"
 "Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n"
 "Language-Team: GitHub <https://github.com/gotgit/git/>\n"
 "Language: zh_CN\n"
@@ -60,71 +60,76 @@
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <版本库> [--exec <命令>] --list"
 
-#: archive.c:323
+#: archive.c:242 builtin/add.c:240 builtin/add.c:556 builtin/rm.c:328
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr "路径规则 '%s' 未匹配任何文件"
+
+#: archive.c:327
 msgid "fmt"
 msgstr "格式"
 
-#: archive.c:323
+#: archive.c:327
 msgid "archive format"
 msgstr "归档格式"
 
-#: archive.c:324 builtin/log.c:1173
+#: archive.c:328 builtin/log.c:1193
 msgid "prefix"
 msgstr "前缀"
 
-#: archive.c:325
+#: archive.c:329
 msgid "prepend prefix to each pathname in the archive"
 msgstr "为归档中每个路径名加上前缀"
 
-#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2292
-#: builtin/blame.c:2293 builtin/config.c:56 builtin/fast-export.c:673
-#: builtin/fast-export.c:675 builtin/grep.c:714 builtin/hash-object.c:77
-#: builtin/ls-files.c:496 builtin/ls-files.c:499 builtin/notes.c:408
-#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:152
+#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2264
+#: builtin/blame.c:2265 builtin/config.c:58 builtin/fast-export.c:680
+#: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77
+#: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408
+#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154
 msgid "file"
 msgstr "文件"
 
-#: archive.c:327 builtin/archive.c:89
+#: archive.c:331 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "归档写入此文件"
 
-#: archive.c:329
+#: archive.c:333
 msgid "read .gitattributes in working directory"
 msgstr "读取工作区中的 .gitattributes"
 
-#: archive.c:330
+#: archive.c:334
 msgid "report archived files on stderr"
 msgstr "在标准错误上报告归档文件"
 
-#: archive.c:331
+#: archive.c:335
 msgid "store only"
 msgstr "只存储"
 
-#: archive.c:332
+#: archive.c:336
 msgid "compress faster"
 msgstr "压缩速度更快"
 
-#: archive.c:340
+#: archive.c:344
 msgid "compress better"
 msgstr "压缩效果更好"
 
-#: archive.c:343
+#: archive.c:347
 msgid "list supported archive formats"
 msgstr "列出支持的归档格式"
 
-#: archive.c:345 builtin/archive.c:90 builtin/clone.c:85
+#: archive.c:349 builtin/archive.c:90 builtin/clone.c:84
 msgid "repo"
 msgstr "版本库"
 
-#: archive.c:346 builtin/archive.c:91
+#: archive.c:350 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "从远程版本库(<版本库>)提取归档文件"
 
-#: archive.c:347 builtin/archive.c:92 builtin/notes.c:487
+#: archive.c:351 builtin/archive.c:92 builtin/notes.c:487
 msgid "command"
 msgstr "命令"
 
-#: archive.c:348 builtin/archive.c:93
+#: archive.c:352 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "远程 git-upload-archive 命令的路径"
 
@@ -205,17 +210,17 @@
 msgid "Cannot force update the current branch."
 msgstr "无法强制更新当前分支。"
 
-#: branch.c:216
+#: branch.c:215
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr "无法设置跟踪信息;起始点 '%s' 不是一个分支。"
 
-#: branch.c:218
+#: branch.c:217
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "请求的上游分支 '%s' 不存在"
 
-#: branch.c:220
+#: branch.c:219
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -233,26 +238,26 @@
 "如果您正计划推送一个能与对应远程分支建立跟踪的新的本地分支,\n"
 "您可能需要使用 \"git push -u\" 推送分支并配置和上游的关联。"
 
-#: branch.c:265
+#: branch.c:264
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "不是一个有效的对象名:'%s'。"
 
-#: branch.c:285
+#: branch.c:284
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "歧义的对象名:'%s'。"
 
-#: branch.c:290
+#: branch.c:289
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "无效的分支点:'%s'。"
 
-#: branch.c:296
+#: branch.c:295
 msgid "Failed to lock ref for update"
 msgstr "无法为更新锁定引用"
 
-#: branch.c:314
+#: branch.c:313
 msgid "Failed to write ref"
 msgstr "不能写引用"
 
@@ -266,7 +271,7 @@
 msgid "unrecognized header: %s%s (%d)"
 msgstr "未能识别的包头:%s%s (%d)"
 
-#: bundle.c:89 builtin/commit.c:697
+#: bundle.c:89 builtin/commit.c:706
 #, c-format
 msgid "could not open '%s'"
 msgstr "不能打开 '%s'"
@@ -275,9 +280,9 @@
 msgid "Repository lacks these prerequisite commits:"
 msgstr "版本库缺少这些必备的提交:"
 
-#: bundle.c:164 sequencer.c:661 sequencer.c:1111 builtin/log.c:331
-#: builtin/log.c:801 builtin/log.c:1399 builtin/log.c:1625 builtin/merge.c:364
-#: builtin/shortlog.c:156
+#: bundle.c:164 sequencer.c:662 sequencer.c:1112 builtin/log.c:332
+#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:364
+#: builtin/shortlog.c:158
 msgid "revision walk setup failed"
 msgstr "版本遍历设置失败"
 
@@ -303,7 +308,7 @@
 msgid "rev-list died"
 msgstr "rev-list 终止"
 
-#: bundle.c:300 builtin/log.c:1310 builtin/shortlog.c:259
+#: bundle.c:300 builtin/log.c:1329 builtin/shortlog.c:261
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "未能识别的参数:%s"
@@ -455,7 +460,7 @@
 "发现配置变量 'diff.dirstat' 中的错误:\n"
 "%s"
 
-#: diff.c:3487
+#: diff.c:3490
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -464,7 +469,7 @@
 "无法解析 --dirstat/-X 选项的参数:\n"
 "%s"
 
-#: diff.c:3501
+#: diff.c:3504
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "无法解析 --submodule 选项的参数:'%s'"
@@ -491,17 +496,17 @@
 msgid "failed writing detached signature to '%s': %s"
 msgstr "无法将分离式签名写入 '%s':%s"
 
-#: grep.c:1623
+#: grep.c:1695
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "'%s':无法读取 %s"
 
-#: grep.c:1640
+#: grep.c:1712
 #, c-format
 msgid "'%s': %s"
 msgstr "'%s':%s"
 
-#: grep.c:1651
+#: grep.c:1723
 #, c-format
 msgid "'%s': short read %s"
 msgstr "'%s':读取不完整 %s"
@@ -574,8 +579,8 @@
 msgid "failed to read the cache"
 msgstr "无法读取缓存"
 
-#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566
-#: builtin/clone.c:656
+#: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559
+#: builtin/clone.c:655
 msgid "unable to write new index file"
 msgstr "无法写新的索引文件"
 
@@ -624,7 +629,7 @@
 msgid "blob expected for %s '%s'"
 msgstr "%s '%s' 应为数据(blob)对象"
 
-#: merge-recursive.c:774 builtin/clone.c:312
+#: merge-recursive.c:774 builtin/clone.c:311
 #, c-format
 msgid "failed to open '%s'"
 msgstr "无法打开 '%s'"
@@ -759,7 +764,7 @@
 msgid "Auto-merging %s"
 msgstr "自动合并 %s"
 
-#: merge-recursive.c:1634 git-submodule.sh:1118
+#: merge-recursive.c:1634 git-submodule.sh:1125
 msgid "submodule"
 msgstr "子模组"
 
@@ -854,59 +859,122 @@
 msgid "Bad %s value: '%s'"
 msgstr "坏的 %s 值:'%s'"
 
-#: object.c:204
+#: object.c:202
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "不能解析对象:%s"
 
-#: parse-options.c:489
+#: parse-options.c:537
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:507
+#: parse-options.c:555
 #, c-format
 msgid "usage: %s"
 msgstr "用法:%s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:511
+#: parse-options.c:559
 #, c-format
 msgid "   or: %s"
 msgstr "  或:%s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: parse-options.c:514
+#: parse-options.c:562
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:548
+#: parse-options.c:596
 msgid "-NUM"
 msgstr "-数字"
 
-#: pathspec.c:83
-#, c-format
-msgid "Path '%s' is in submodule '%.*s'"
-msgstr "路径 '%s' 属于模组 '%.*s'"
+#: pathspec.c:118
+msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
+msgstr "全局的 'glob' 和 'noglob' 路径规则设置不兼容"
 
-#: pathspec.c:99
-#, c-format
-msgid "'%s' is beyond a symbolic link"
-msgstr "'%s' 位于符号链接中"
+#: pathspec.c:128
+msgid ""
+"global 'literal' pathspec setting is incompatible with all other global "
+"pathspec settings"
+msgstr "全局的 'literal' 路径规则设置和其它的全局路径规则设置不兼容"
 
-#: remote.c:1788
+#: pathspec.c:158
+msgid "invalid parameter for pathspec magic 'prefix'"
+msgstr "路径规则包含无效的神奇前缀"
+
+#: pathspec.c:164
+#, c-format
+msgid "Invalid pathspec magic '%.*s' in '%s'"
+msgstr "在路径规则 '%3$s' 中无效的神奇前缀 '%2$.*1$s'"
+
+#: pathspec.c:168
+#, c-format
+msgid "Missing ')' at the end of pathspec magic in '%s'"
+msgstr "路径规则 '%s' 的神奇前缀结尾少了一个 ')'"
+
+#: pathspec.c:186
+#, c-format
+msgid "Unimplemented pathspec magic '%c' in '%s'"
+msgstr "路径规则 '%2$s' 中包含未实现的神奇前缀 '%1$c'"
+
+#: pathspec.c:211
+#, c-format
+msgid "%s: 'literal' and 'glob' are incompatible"
+msgstr "%s:'literal' 和 'glob' 不兼容"
+
+#: pathspec.c:222
+#, c-format
+msgid "%s: '%s' is outside repository"
+msgstr "%s:'%s' 在版本库之外"
+
+#: pathspec.c:278
+#, c-format
+msgid "Pathspec '%s' is in submodule '%.*s'"
+msgstr "路径规则 '%s' 在子模组 '%.*s' 中"
+
+#.
+#. * We may want to substitute "this command" with a command
+#. * name. E.g. when add--interactive dies when running
+#. * "checkout -p"
+#.
+#: pathspec.c:340
+#, c-format
+msgid "%s: pathspec magic not supported by this command: %s"
+msgstr "%s:路径规则神奇前缀不被此命令支持:%s"
+
+#: pathspec.c:415
+#, c-format
+msgid "pathspec '%s' is beyond a symbolic link"
+msgstr "路径规则 '%s' 位于符号链接中"
+
+#: remote.c:1833
+#, c-format
+msgid "Your branch is based on '%s', but the upstream is gone.\n"
+msgstr "您的分支基于 '%s',但此上游分支已经不存在。\n"
+
+#: remote.c:1837
+msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
+msgstr "  (使用 \"git branch --unset-upstream\" 来修复)\n"
+
+#: remote.c:1840
+#, c-format
+msgid "Your branch is up-to-date with '%s'.\n"
+msgstr "您的分支与上游分支 '%s' 一致。\n"
+
+#: remote.c:1844
 #, 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:1794
+#: remote.c:1850
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (使用 \"git push\" 来发布您的本地提交)\n"
 
-#: remote.c:1797
+#: remote.c:1853
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -915,11 +983,11 @@
 msgstr[1] "您的分支落后 '%s' 共 %d 个提交,并且可以快进。\n"
 
 #  译者:注意保持前导空格
-#: remote.c:1805
+#: remote.c:1861
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (使用 \"git pull\" 来更新您的本地分支)\n"
 
-#: remote.c:1808
+#: remote.c:1864
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -935,7 +1003,7 @@
 "并且分别有 %d 和 %d 处不同的提交。\n"
 
 #  译者:注意保持前导空格
-#: remote.c:1818
+#: remote.c:1874
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (使用 \"git pull\" 来合并远程分支)\n"
 
@@ -977,7 +1045,7 @@
 "冲突解决完毕后,用 'git add <paths>' 或 'git rm <paths>'\n"
 "对修正后的文件做标记,然后用 'git commit' 提交"
 
-#: sequencer.c:245 sequencer.c:869 sequencer.c:952
+#: sequencer.c:245 sequencer.c:870 sequencer.c:953
 #, c-format
 msgid "Could not write to %s"
 msgstr "不能写入 %s"
@@ -1000,197 +1068,197 @@
 msgstr "提交您的修改或保存进度后再继续。"
 
 #. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:324
+#: sequencer.c:325
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s:无法写入新索引文件"
 
-#: sequencer.c:355
+#: sequencer.c:356
 msgid "Could not resolve HEAD commit\n"
 msgstr "不能解析 HEAD 提交\n"
 
-#: sequencer.c:377
+#: sequencer.c:378
 msgid "Unable to update cache tree\n"
 msgstr "不能更新缓存\n"
 
-#: sequencer.c:422
+#: sequencer.c:423
 #, c-format
 msgid "Could not parse commit %s\n"
 msgstr "不能解析提交 %s\n"
 
-#: sequencer.c:427
+#: sequencer.c:428
 #, c-format
 msgid "Could not parse parent commit %s\n"
 msgstr "不能解析父提交 %s\n"
 
-#: sequencer.c:493
+#: sequencer.c:494
 msgid "Your index file is unmerged."
 msgstr "您的索引文件未完成合并。"
 
-#: sequencer.c:512
+#: sequencer.c:513
 #, c-format
 msgid "Commit %s is a merge but no -m option was given."
 msgstr "提交 %s 是一个合并提交但未提供 -m 选项。"
 
-#: sequencer.c:520
+#: sequencer.c:521
 #, c-format
 msgid "Commit %s does not have parent %d"
 msgstr "提交 %s 没有父提交 %d"
 
-#: sequencer.c:524
+#: sequencer.c:525
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
 msgstr "指定了主线但提交 %s 不是一个合并。"
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
-#: sequencer.c:537
+#: sequencer.c:538
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s:不能解析父提交 %s"
 
-#: sequencer.c:541
+#: sequencer.c:542
 #, c-format
 msgid "Cannot get commit message for %s"
 msgstr "不能得到 %s 的提交说明"
 
-#: sequencer.c:627
+#: sequencer.c:628
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "不能还原 %s... %s"
 
-#: sequencer.c:628
+#: sequencer.c:629
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "不能应用 %s... %s"
 
-#: sequencer.c:664
+#: sequencer.c:665
 msgid "empty commit set passed"
 msgstr "提供了空的提交集"
 
-#: sequencer.c:672
+#: sequencer.c:673
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s:无法读取索引"
 
-#: sequencer.c:677
+#: sequencer.c:678
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s:无法刷新索引"
 
-#: sequencer.c:735
+#: sequencer.c:736
 #, c-format
 msgid "Cannot %s during a %s"
 msgstr "无法 %s 在一个 %s 过程中"
 
-#: sequencer.c:757
+#: sequencer.c:758
 #, c-format
 msgid "Could not parse line %d."
 msgstr "不能解析第 %d 行。"
 
-#: sequencer.c:762
+#: sequencer.c:763
 msgid "No commits parsed."
 msgstr "没有提交被解析。"
 
-#: sequencer.c:775
+#: sequencer.c:776
 #, c-format
 msgid "Could not open %s"
 msgstr "不能打开 %s"
 
-#: sequencer.c:779
+#: sequencer.c:780
 #, c-format
 msgid "Could not read %s."
 msgstr "不能读取 %s。"
 
-#: sequencer.c:786
+#: sequencer.c:787
 #, c-format
 msgid "Unusable instruction sheet: %s"
 msgstr "无用的指令表单:%s"
 
-#: sequencer.c:814
+#: sequencer.c:815
 #, c-format
 msgid "Invalid key: %s"
 msgstr "无效键名:%s"
 
-#: sequencer.c:817
+#: sequencer.c:818
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "%s 的值无效:%s"
 
-#: sequencer.c:829
+#: sequencer.c:830
 #, c-format
 msgid "Malformed options sheet: %s"
 msgstr "非法的选项表单:%s"
 
-#: sequencer.c:850
+#: sequencer.c:851
 msgid "a cherry-pick or revert is already in progress"
 msgstr "一个拣选或还原操作已在进行"
 
-#: sequencer.c:851
+#: sequencer.c:852
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "尝试 \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:855
+#: sequencer.c:856
 #, c-format
 msgid "Could not create sequencer directory %s"
 msgstr "不能创建序列目录 %s"
 
-#: sequencer.c:871 sequencer.c:956
+#: sequencer.c:872 sequencer.c:957
 #, c-format
 msgid "Error wrapping up %s."
 msgstr "错误收尾 %s。"
 
-#: sequencer.c:890 sequencer.c:1024
+#: sequencer.c:891 sequencer.c:1025
 msgid "no cherry-pick or revert in progress"
 msgstr "拣选或还原操作并未进行"
 
-#: sequencer.c:892
+#: sequencer.c:893
 msgid "cannot resolve HEAD"
 msgstr "不能解析 HEAD"
 
-#: sequencer.c:894
+#: sequencer.c:895
 msgid "cannot abort from a branch yet to be born"
 msgstr "不能从尚未建立的分支终止"
 
-#: sequencer.c:916 builtin/apply.c:4061
+#: sequencer.c:917 builtin/apply.c:4061
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "不能打开 %s:%s"
 
-#: sequencer.c:919
+#: sequencer.c:920
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "不能读取 %s:%s"
 
-#: sequencer.c:920
+#: sequencer.c:921
 msgid "unexpected end of file"
 msgstr "意外的文件结束"
 
-#: sequencer.c:926
+#: sequencer.c:927
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "保存拣选提交前的 HEAD 文件 '%s' 损坏"
 
-#: sequencer.c:949
+#: sequencer.c:950
 #, c-format
 msgid "Could not format %s."
 msgstr "不能格式化 %s。"
 
-#: sequencer.c:1092
+#: sequencer.c:1093
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s:不能拣选一个%s"
 
-#: sequencer.c:1095
+#: sequencer.c:1096
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s:错误的版本"
 
-#: sequencer.c:1129
+#: sequencer.c:1130
 msgid "Can't revert as initial commit"
 msgstr "不能作为初始提交还原"
 
-#: sequencer.c:1130
+#: sequencer.c:1131
 msgid "Can't cherry-pick into empty head"
 msgstr "不能拣选到空分支"
 
@@ -1215,400 +1283,493 @@
 "可能需要删除它们。用 \"git config advice.objectNameWarning false\"\n"
 "命令关闭本消息通知。"
 
-#: sha1_name.c:1097
+#: sha1_name.c:1112
 msgid "HEAD does not point to a branch"
 msgstr "HEAD 没有指向一个分支"
 
-#: sha1_name.c:1100
+#: sha1_name.c:1115
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "没有此分支:'%s'"
 
-#: sha1_name.c:1102
+#: sha1_name.c:1117
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "尚未给分支 '%s' 设置上游"
 
-#: sha1_name.c:1106
+#: sha1_name.c:1121
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "上游分支 '%s' 没有存储为一个远程跟踪分支"
 
-#: wrapper.c:408
+#: submodule.c:64 submodule.c:98
+msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
+msgstr "无法修改未合并的 .gitmodules,先解决合并冲突"
+
+#: submodule.c:68 submodule.c:102
+#, c-format
+msgid "Could not find section in .gitmodules where path=%s"
+msgstr "无法在 .gitmodules 中找到 path=%s 的小节"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:76
+#, c-format
+msgid "Could not update .gitmodules entry %s"
+msgstr "不能更新 .gitmodules 条目 %s"
+
+#. Maybe the user already did that, don't error out here
+#: submodule.c:109
+#, c-format
+msgid "Could not remove .gitmodules entry for %s"
+msgstr "无法移除 %s 的 .gitmodules 条目"
+
+#: submodule.c:127
+msgid "could not find .gitmodules in index"
+msgstr "无法在索引中找到 .gitmodules"
+
+#: submodule.c:133
+msgid "reading updated .gitmodules failed"
+msgstr "读取更新后的 .gitmodules 失败"
+
+#: submodule.c:135
+msgid "unable to stat updated .gitmodules"
+msgstr "不能枚举更新后的 .gitmodules"
+
+#: submodule.c:139
+msgid "unable to remove .gitmodules from index"
+msgstr "不能从索引中移除 .gitmodules"
+
+#: submodule.c:141
+msgid "adding updated .gitmodules failed"
+msgstr "添加更新后的 .gitmodules 失败"
+
+#: submodule.c:143
+msgid "staging updated .gitmodules failed"
+msgstr "将更新后 .gitmodules 添加暂存区失败"
+
+#: submodule.c:1144 builtin/init-db.c:363
+#, c-format
+msgid "Could not create git link %s"
+msgstr "不能创建 git link %s"
+
+#: submodule.c:1155
+#, c-format
+msgid "Could not set core.worktree in %s"
+msgstr "不能在 %s 中设置 core.worktree"
+
+#: urlmatch.c:120
+msgid "invalid URL scheme name or missing '://' suffix"
+msgstr "无效的 URL 方案名称或丢失 '://' 后缀"
+
+#: urlmatch.c:144 urlmatch.c:297 urlmatch.c:356
+#, c-format
+msgid "invalid %XX escape sequence"
+msgstr "无效的 %XX 转义序列"
+
+#: urlmatch.c:172
+msgid "missing host and scheme is not 'file:'"
+msgstr "缺失主机名且URL方案不是 'file:'"
+
+#: urlmatch.c:189
+msgid "a 'file:' URL may not have a port number"
+msgstr "一个 'file:' URL 不应该包含端口号"
+
+#: urlmatch.c:199
+msgid "invalid characters in host name"
+msgstr "主机名中包含无效的字符"
+
+#: urlmatch.c:244 urlmatch.c:255
+msgid "invalid port number"
+msgstr "无效的端口号"
+
+#: urlmatch.c:322
+msgid "invalid '..' path segment"
+msgstr "无效的 '..' 路径片段"
+
+#: wrapper.c:422
 #, c-format
 msgid "unable to access '%s': %s"
 msgstr "不能访问 '%s':%s"
 
-#: wrapper.c:429
+#: wrapper.c:443
 #, c-format
 msgid "unable to access '%s'"
 msgstr "不能访问 '%s'"
 
-#: wrapper.c:440
+#: wrapper.c:454
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
 msgstr "无法在口令文件中查询到当前用户:%s"
 
-#: wrapper.c:441
+#: wrapper.c:455
 msgid "no such user"
 msgstr "无此用户"
 
-#: wt-status.c:141
+#: wt-status.c:146
 msgid "Unmerged paths:"
 msgstr "未合并的路径:"
 
 #  译者:注意保持前导空格
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:173 wt-status.c:200
 #, 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:175 wt-status.c:202
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (使用 \"git rm --cached <file>...\" 撤出暂存区)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:174
+#: wt-status.c:179
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (使用 \"git add <file>...\" 标记解决方案)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:176 wt-status.c:180
+#: wt-status.c:181 wt-status.c:185
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr "  (酌情使用 \"git add/rm <file>...\" 标记解决方案)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:178
+#: wt-status.c:183
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (使用 \"git rm <file>...\" 标记解决方案)"
 
-#: wt-status.c:189
+#: wt-status.c:194
 msgid "Changes to be committed:"
 msgstr "要提交的变更:"
 
-#: wt-status.c:207
+#: wt-status.c:212
 msgid "Changes not staged for commit:"
 msgstr "尚未暂存以备提交的变更:"
 
 #  译者:注意保持前导空格
-#: wt-status.c:211
+#: wt-status.c:216
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add <file>...\" 更新要提交的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:213
+#: wt-status.c:218
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add/rm <file>...\" 更新要提交的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:214
+#: wt-status.c:219
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr "  (使用 \"git checkout -- <file>...\" 丢弃工作区的改动)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:216
+#: wt-status.c:221
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr "  (提交或丢弃子模组中未跟踪或修改的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:228
+#: wt-status.c:233
 #, 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:250
 msgid "bug"
 msgstr "bug"
 
-#: wt-status.c:250
+#: wt-status.c:255
 msgid "both deleted:"
 msgstr "双方删除:"
 
-#: wt-status.c:251
+#: wt-status.c:256
 msgid "added by us:"
 msgstr "由我们添加:"
 
-#: wt-status.c:252
+#: wt-status.c:257
 msgid "deleted by them:"
 msgstr "由他们删除:"
 
-#: wt-status.c:253
+#: wt-status.c:258
 msgid "added by them:"
 msgstr "由他们添加:"
 
-#: wt-status.c:254
+#: wt-status.c:259
 msgid "deleted by us:"
 msgstr "由我们删除:"
 
-#: wt-status.c:255
+#: wt-status.c:260
 msgid "both added:"
 msgstr "双方添加:"
 
-#: wt-status.c:256
+#: wt-status.c:261
 msgid "both modified:"
 msgstr "双方修改:"
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:286
+#: wt-status.c:291
 msgid "new commits, "
 msgstr "新提交, "
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:288
+#: wt-status.c:293
 msgid "modified content, "
 msgstr "修改的内容, "
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:290
+#: wt-status.c:295
 msgid "untracked content, "
 msgstr "未跟踪的内容, "
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:307
+#: wt-status.c:312
 #, c-format
 msgid "new file:   %s"
 msgstr "新文件:    %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:310
+#: wt-status.c:315
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "拷贝:      %s -> %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:313
+#: wt-status.c:318
 #, c-format
 msgid "deleted:    %s"
 msgstr "删除:      %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:316
+#: wt-status.c:321
 #, c-format
 msgid "modified:   %s"
 msgstr "修改:      %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:319
+#: wt-status.c:324
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "重命名:    %s -> %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:322
+#: wt-status.c:327
 #, c-format
 msgid "typechange: %s"
 msgstr "类型变更:  %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:325
+#: wt-status.c:330
 #, c-format
 msgid "unknown:    %s"
 msgstr "未知:      %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:328
+#: wt-status.c:333
 #, c-format
 msgid "unmerged:   %s"
 msgstr "未合并:    %s"
 
-#: wt-status.c:331
+#: wt-status.c:336
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "bug:未处理的差异状态 %c"
 
-#: wt-status.c:803
+#: wt-status.c:703
+msgid "Submodules changed but not updated:"
+msgstr "子模组已修改但尚未更新:"
+
+#: wt-status.c:705
+msgid "Submodule changes to be committed:"
+msgstr "要提交的子模组变更:"
+
+#: wt-status.c:848
 msgid "You have unmerged paths."
 msgstr "您有尚未合并的路径。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:806
+#: wt-status.c:851
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (解决冲突并运行 \"git commit\")"
 
-#: wt-status.c:809
+#: wt-status.c:854
 msgid "All conflicts fixed but you are still merging."
 msgstr "所有冲突已解决但您仍处于合并中。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:812
+#: wt-status.c:857
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (使用 \"git commit\" 结束合并)"
 
-#: wt-status.c:822
+#: wt-status.c:867
 msgid "You are in the middle of an am session."
 msgstr "您正处于一个 am 过程中。"
 
-#: wt-status.c:825
+#: wt-status.c:870
 msgid "The current patch is empty."
 msgstr "当前的补丁为空。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:829
+#: wt-status.c:874
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (解决冲突,然后运行 \"git am --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:831
+#: wt-status.c:876
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (使用 \"git am --skip\" 跳过此补丁)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:833
+#: wt-status.c:878
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (使用 \"git am --abort\" 恢复原有分支)"
 
-#: wt-status.c:893 wt-status.c:910
+#: wt-status.c:938 wt-status.c:955
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "您正在将分支 '%s' 变基到 '%s'。"
 
-#: wt-status.c:898 wt-status.c:915
+#: wt-status.c:943 wt-status.c:960
 msgid "You are currently rebasing."
 msgstr "您正在变基。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:901
+#: wt-status.c:946
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (解决冲突,然后运行 \"git rebase --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:903
+#: wt-status.c:948
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (使用 \"git rebase --skip\" 跳过此补丁)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:905
+#: wt-status.c:950
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (使用 \"git rebase --abort\" 以检出原有分支)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:918
+#: wt-status.c:963
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (所有冲突已解决:运行 \"git rebase --continue\")"
 
-#: wt-status.c:922
+#: wt-status.c:967
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr "您正在将分支 '%s' 变基到 '%s' 过程中拆分一个提交。"
 
-#: wt-status.c:927
+#: wt-status.c:972
 msgid "You are currently splitting a commit during a rebase."
 msgstr "您正在变基过程中拆分一个提交。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:930
+#: wt-status.c:975
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr "  (一旦您工作目录提交干净后,运行 \"git rebase --continue\")"
 
-#: wt-status.c:934
+#: wt-status.c:979
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr "您正在将分支 '%s' 变基到 '%s' 过程中编辑一个提交。"
 
-#: wt-status.c:939
+#: wt-status.c:984
 msgid "You are currently editing a commit during a rebase."
 msgstr "您正在变基过程中编辑一个提交。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:942
+#: wt-status.c:987
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (使用 \"git commit --amend\" 修补当前提交)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:944
+#: wt-status.c:989
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr "  (当您对您的修改满意后执行 \"git rebase --continue\")"
 
-#: wt-status.c:954
-msgid "You are currently cherry-picking."
-msgstr "您正在做拣选操作。"
+#: wt-status.c:999
+#, c-format
+msgid "You are currently cherry-picking commit %s."
+msgstr "您正在做拣选提交 %s。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:958
+#: wt-status.c:1004
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (解决冲突并运行 \"git cherry-pick --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:961
+#: wt-status.c:1007
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr "  (所有冲突已解决:运行 \"git cherry-pick --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:963
+#: wt-status.c:1009
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr "  (使用 \"git cherry-pick --abort\" 以取消拣选操作)"
 
-#: wt-status.c:972
+#: wt-status.c:1018
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "您正在反转提交 %s 。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:977
+#: wt-status.c:1023
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (解决冲突并运行 \"git revert --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:980
+#: wt-status.c:1026
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (所有冲突已解决:运行 \"git revert --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:982
+#: wt-status.c:1028
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (使用 \"git revert --abort\" 以取消反转提交操作)"
 
-#: wt-status.c:993
+#: wt-status.c:1039
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "您正在从分支 '%s' 开始做二分查找。"
 
-#: wt-status.c:997
+#: wt-status.c:1043
 msgid "You are currently bisecting."
 msgstr "您正在做二分查找。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1000
+#: wt-status.c:1046
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (使用 \"git bisect reset\" 以回到原有分支)"
 
-#: wt-status.c:1173
+#: wt-status.c:1221
 msgid "On branch "
 msgstr "位于分支 "
 
-#: wt-status.c:1180
+#: wt-status.c:1228
 msgid "rebase in progress; onto "
 msgstr "变基正在进行中;至 "
 
-#: wt-status.c:1187
+#: wt-status.c:1235
 msgid "HEAD detached at "
 msgstr "头指针分离于 "
 
-#: wt-status.c:1189
+#: wt-status.c:1237
 msgid "HEAD detached from "
 msgstr "头指针分离自 "
 
-#: wt-status.c:1192
+#: wt-status.c:1240
 msgid "Not currently on any branch."
 msgstr "当前不在任何分支上。"
 
-#: wt-status.c:1209
+#: wt-status.c:1257
 msgid "Initial commit"
 msgstr "初始提交"
 
-#: wt-status.c:1223
+#: wt-status.c:1271
 msgid "Untracked files"
 msgstr "未跟踪的文件"
 
-#: wt-status.c:1225
+#: wt-status.c:1273
 msgid "Ignored files"
 msgstr "忽略的文件"
 
-#: wt-status.c:1229
+#: wt-status.c:1277
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -1618,97 +1779,101 @@
 "耗费了 %.2f 秒以枚举未跟踪的文件。'status -uno' 也许能提高速度,\n"
 "但您需要小心不要忘了添加新文件(参见 'git help status')。"
 
-#: wt-status.c:1235
+#: wt-status.c:1283
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "未跟踪的文件没有列出%s"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1237
+#: wt-status.c:1285
 msgid " (use -u option to show untracked files)"
 msgstr "(使用 -u 参数显示未跟踪的文件)"
 
-#: wt-status.c:1243
+#: wt-status.c:1291
 msgid "No changes"
 msgstr "没有修改"
 
-#: wt-status.c:1248
+#: wt-status.c:1296
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr "修改尚未加入提交(使用 \"git add\" 和/或 \"git commit -a\")\n"
 
-#: wt-status.c:1251
+#: wt-status.c:1299
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "修改尚未加入提交\n"
 
-#: wt-status.c:1254
+#: wt-status.c:1302
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
 "track)\n"
 msgstr "提交为空,但是存在尚未跟踪的文件(使用 \"git add\" 建立跟踪)\n"
 
-#: wt-status.c:1257
+#: wt-status.c:1305
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr "提交为空,但是存在尚未跟踪的文件\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1260
+#: wt-status.c:1308
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr "无文件要提交(创建/拷贝文件并使用 \"git add\" 建立跟踪)\n"
 
-#: wt-status.c:1263 wt-status.c:1268
+#: wt-status.c:1311 wt-status.c:1316
 #, c-format
 msgid "nothing to commit\n"
 msgstr "无文件要提交\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1266
+#: wt-status.c:1314
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr "无文件要提交(使用 -u 显示未跟踪的文件)\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1270
+#: wt-status.c:1318
 #, c-format
 msgid "nothing to commit, working directory clean\n"
 msgstr "无文件要提交,干净的工作区\n"
 
-#: wt-status.c:1378
+#: wt-status.c:1427
 msgid "HEAD (no branch)"
 msgstr "HEAD(非分支)"
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1384
+#: wt-status.c:1433
 msgid "Initial commit on "
 msgstr "初始提交于 "
 
+#: wt-status.c:1463
+msgid "gone"
+msgstr "丢失"
+
 #  译者:注意保持句尾空格
-#: wt-status.c:1399
+#: wt-status.c:1465
 msgid "behind "
 msgstr "落后 "
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1402 wt-status.c:1405
+#: wt-status.c:1468 wt-status.c:1471
 msgid "ahead "
 msgstr "领先 "
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1407
+#: wt-status.c:1473
 msgid ", behind "
 msgstr ",落后 "
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:351
+#: compat/precompose_utf8.c:55 builtin/clone.c:350
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "无法删除 '%s'"
 
 #: builtin/add.c:20
 msgid "git add [options] [--] <pathspec>..."
-msgstr "git add [选项] [--] <路径匹配>..."
+msgstr "git add [选项] [--] <路径规则>..."
 
 #  译者:字符串首行行首要添加“warning: ”字串,故此首行要较其余行短
 #.
@@ -1774,10 +1939,10 @@
 "像本地工作区移除的路径 '%s'\n"
 "在此版本的 Git 中被忽略。\n"
 "\n"
-"* 'git add --ignore-removal <pathspec>',是当前版本的默认操作,\n"
+"* 'git add --ignore-removal <路径规则>',是当前版本的默认操作,\n"
 "  忽略您本地工作区中移除的文件。\n"
 "\n"
-"* 'git add --all <pathspec>' 将让您同时对删除操作进行记录。\n"
+"* 'git add --all <路径规则>' 将让您同时对删除操作进行记录。\n"
 "\n"
 "运行 'git status' 来检查您本地工作区中移除的路径。\n"
 
@@ -1786,7 +1951,7 @@
 msgid "unexpected diff status %c"
 msgstr "意外的差异状态 %c"
 
-#: builtin/add.c:149 builtin/commit.c:252
+#: builtin/add.c:149 builtin/commit.c:260
 msgid "updating files failed"
 msgstr "更新文件失败"
 
@@ -1795,140 +1960,135 @@
 msgid "remove '%s'\n"
 msgstr "删除 '%s'\n"
 
-#: builtin/add.c:253
+#: builtin/add.c:237
 msgid "Unstaged changes after refreshing the index:"
 msgstr "刷新索引之后尚未被暂存的变更:"
 
-#: builtin/add.c:256 builtin/add.c:573 builtin/rm.c:337
-#, c-format
-msgid "pathspec '%s' did not match any files"
-msgstr "路径 '%s' 未匹配任何文件"
-
-#: builtin/add.c:339
+#: builtin/add.c:299
 msgid "Could not read the index"
 msgstr "不能读取索引"
 
-#: builtin/add.c:350
+#: builtin/add.c:310
 #, c-format
 msgid "Could not open '%s' for writing."
 msgstr "不能打开 '%s' 以写入。"
 
-#: builtin/add.c:354
+#: builtin/add.c:314
 msgid "Could not write patch"
 msgstr "不能生成补丁"
 
-#: builtin/add.c:359
+#: builtin/add.c:319
 #, c-format
 msgid "Could not stat '%s'"
 msgstr "不能查看文件状态 '%s'"
 
-#: builtin/add.c:361
+#: builtin/add.c:321
 msgid "Empty patch. Aborted."
 msgstr "空补丁。异常终止。"
 
-#: builtin/add.c:367
+#: builtin/add.c:327
 #, c-format
 msgid "Could not apply '%s'"
 msgstr "不能应用 '%s'"
 
-#: builtin/add.c:377
+#: builtin/add.c:337
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr "下列路径根据您的一个 .gitignore 文件而被忽略:\n"
 
-#: builtin/add.c:394 builtin/clean.c:875 builtin/fetch.c:78 builtin/mv.c:63
-#: builtin/prune-packed.c:73 builtin/push.c:451 builtin/remote.c:1253
-#: builtin/rm.c:268
+#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:92 builtin/mv.c:66
+#: builtin/prune-packed.c:73 builtin/push.c:459 builtin/remote.c:1253
+#: builtin/rm.c:269
 msgid "dry run"
 msgstr "演习"
 
-#: builtin/add.c:395 builtin/apply.c:4410 builtin/check-ignore.c:19
-#: builtin/commit.c:1220 builtin/count-objects.c:95 builtin/fsck.c:613
-#: builtin/log.c:1573 builtin/mv.c:62 builtin/read-tree.c:113
+#: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19
+#: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612
+#: builtin/log.c:1592 builtin/mv.c:65 builtin/read-tree.c:113
 msgid "be verbose"
 msgstr "冗长输出"
 
-#: builtin/add.c:397
+#: builtin/add.c:357
 msgid "interactive picking"
 msgstr "交互式拣选"
 
-#: builtin/add.c:398 builtin/checkout.c:1073 builtin/reset.c:261
+#: builtin/add.c:358 builtin/checkout.c:1109 builtin/reset.c:272
 msgid "select hunks interactively"
 msgstr "交互式挑选数据块"
 
-#: builtin/add.c:399
+#: builtin/add.c:359
 msgid "edit current diff and apply"
 msgstr "编辑当前差异并应用"
 
-#: builtin/add.c:400
+#: builtin/add.c:360
 msgid "allow adding otherwise ignored files"
 msgstr "允许添加忽略的文件"
 
-#: builtin/add.c:401
+#: builtin/add.c:361
 msgid "update tracked files"
 msgstr "更新已跟踪的文件"
 
-#: builtin/add.c:402
+#: builtin/add.c:362
 msgid "record only the fact that the path will be added later"
 msgstr "只记录,该路径稍后再添加"
 
-#: builtin/add.c:403
+#: builtin/add.c:363
 msgid "add changes from all tracked and untracked files"
 msgstr "添加所有改变的已跟踪文件和未跟踪文件"
 
 #. takes no arguments
-#: builtin/add.c:406
+#: builtin/add.c:366
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr "忽略工作区中移除的路径(和 --no-all 相同)"
 
-#: builtin/add.c:408
+#: builtin/add.c:368
 msgid "don't add, only refresh the index"
 msgstr "不添加,只刷新索引"
 
-#: builtin/add.c:409
+#: builtin/add.c:369
 msgid "just skip files which cannot be added because of errors"
 msgstr "跳过因出错不能添加的文件"
 
-#: builtin/add.c:410
+#: builtin/add.c:370
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "检查在演习模式下文件(即使不存在)是否被忽略"
 
-#: builtin/add.c:432
+#: builtin/add.c:392
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "使用 -f 参数如果您确实要添加它们。\n"
 
-#: builtin/add.c:433
+#: builtin/add.c:393
 msgid "no files added"
 msgstr "没有文件被添加"
 
-#: builtin/add.c:439
+#: builtin/add.c:399
 msgid "adding files failed"
 msgstr "添加文件失败"
 
-#: builtin/add.c:478
+#: builtin/add.c:438
 msgid "-A and -u are mutually incompatible"
 msgstr "-A 和 -u 选项互斥"
 
-#: builtin/add.c:496
+#: builtin/add.c:456
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "选项 --ignore-missing 只能和 --dry-run 同时使用"
 
-#: builtin/add.c:526
+#: builtin/add.c:486
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "没有指定文件,也没有文件被添加。\n"
 
-#: builtin/add.c:527
+#: builtin/add.c:487
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "也许您想要执行 'git add .'?\n"
 
-#: builtin/add.c:533 builtin/check-ignore.c:161 builtin/clean.c:919
-#: builtin/commit.c:312 builtin/mv.c:82 builtin/rm.c:297
+#: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919
+#: builtin/commit.c:320 builtin/mv.c:86 builtin/reset.c:224 builtin/rm.c:299
 msgid "index file corrupt"
 msgstr "索引文件损坏"
 
-#: builtin/add.c:605 builtin/apply.c:4506 builtin/mv.c:229 builtin/rm.c:432
+#: builtin/add.c:589 builtin/apply.c:4506 builtin/mv.c:259 builtin/rm.c:432
 msgid "Unable to write new index file"
 msgstr "无法写入新索引文件"
 
@@ -2176,7 +2336,7 @@
 msgid "Checking patch %s..."
 msgstr "检查补丁 %s..."
 
-#: builtin/apply.c:3680 builtin/checkout.c:216 builtin/reset.c:127
+#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:127
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "对路径 '%s' 的 make_cache_entry 操作失败"
@@ -2256,8 +2416,8 @@
 msgid "unable to read index file"
 msgstr "无法读取索引文件"
 
-#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:91
-#: builtin/fetch.c:63
+#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90
+#: builtin/fetch.c:77
 msgid "path"
 msgstr "路径"
 
@@ -2317,7 +2477,7 @@
 msgid "build a temporary index based on embedded index information"
 msgstr "创建一个临时索引基于嵌入的索引信息"
 
-#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:462
+#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:452
 msgid "paths are separated with NUL character"
 msgstr "路径以 NUL 字符分隔"
 
@@ -2447,103 +2607,103 @@
 msgid "update BISECT_HEAD instead of checking out the current commit"
 msgstr "更新 BISECT_HEAD 而非检出当前提交"
 
-#: builtin/blame.c:26
+#: builtin/blame.c:27
 msgid "git blame [options] [rev-opts] [rev] [--] file"
 msgstr "git blame [选项] [版本选项] [版本] [--] 文件"
 
-#: builtin/blame.c:31
+#: builtin/blame.c:32
 msgid "[rev-opts] are documented in git-rev-list(1)"
 msgstr "[版本选项] 的文档记录在 git-rev-list(1) 中"
 
-#: builtin/blame.c:2276
+#: builtin/blame.c:2248
 msgid "Show blame entries as we find them, incrementally"
 msgstr "增量式地显示发现的 blame 条目"
 
-#: builtin/blame.c:2277
+#: builtin/blame.c:2249
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "边界提交显示空的 SHA-1(默认:关闭)"
 
-#: builtin/blame.c:2278
+#: builtin/blame.c:2250
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "不把根提交作为边界(默认:关闭)"
 
-#: builtin/blame.c:2279
+#: builtin/blame.c:2251
 msgid "Show work cost statistics"
 msgstr "显示命令消耗统计"
 
-#: builtin/blame.c:2280
+#: builtin/blame.c:2252
 msgid "Show output score for blame entries"
 msgstr "显示判断 blame 条目位移的得分诊断信息"
 
-#: builtin/blame.c:2281
+#: builtin/blame.c:2253
 msgid "Show original filename (Default: auto)"
 msgstr "显示原始文件名(默认:自动)"
 
-#: builtin/blame.c:2282
+#: builtin/blame.c:2254
 msgid "Show original linenumber (Default: off)"
 msgstr "显示原始的行号(默认:关闭)"
 
-#: builtin/blame.c:2283
+#: builtin/blame.c:2255
 msgid "Show in a format designed for machine consumption"
 msgstr "显示为一个适合机器读取的格式"
 
-#: builtin/blame.c:2284
+#: builtin/blame.c:2256
 msgid "Show porcelain format with per-line commit information"
 msgstr "为每一行显示机器适用的提交信息"
 
-#: builtin/blame.c:2285
+#: builtin/blame.c:2257
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "使用和 git-annotate 相同的输出模式(默认:关闭)"
 
-#: builtin/blame.c:2286
+#: builtin/blame.c:2258
 msgid "Show raw timestamp (Default: off)"
 msgstr "显示原始时间戳(默认:关闭)"
 
-#: builtin/blame.c:2287
+#: builtin/blame.c:2259
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "显示长的SHA1提交号(默认:关闭)"
 
-#: builtin/blame.c:2288
+#: builtin/blame.c:2260
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "隐藏作者名字和时间戳(默认:关闭)"
 
-#: builtin/blame.c:2289
+#: builtin/blame.c:2261
 msgid "Show author email instead of name (Default: off)"
 msgstr "显示作者的邮箱而不是名字(默认:关闭)"
 
-#: builtin/blame.c:2290
+#: builtin/blame.c:2262
 msgid "Ignore whitespace differences"
 msgstr "忽略空白差异"
 
-#: builtin/blame.c:2291
+#: builtin/blame.c:2263
 msgid "Spend extra cycles to find better match"
 msgstr "花费额外的循环来找到更好的匹配"
 
-#: builtin/blame.c:2292
+#: builtin/blame.c:2264
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "使用来自 <file> 的修订集而不是调用 git-rev-list"
 
-#: builtin/blame.c:2293
+#: builtin/blame.c:2265
 msgid "Use <file>'s contents as the final image"
 msgstr "使用 <file> 的内容作为最终的图片"
 
-#: builtin/blame.c:2294 builtin/blame.c:2295
+#: builtin/blame.c:2266 builtin/blame.c:2267
 msgid "score"
 msgstr "得分"
 
-#: builtin/blame.c:2294
+#: builtin/blame.c:2266
 msgid "Find line copies within and across files"
 msgstr "找到文件内及跨文件的行拷贝"
 
-#: builtin/blame.c:2295
+#: builtin/blame.c:2267
 msgid "Find line movements within and across files"
 msgstr "找到文件内及跨文件的行移动"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:2296
+#: builtin/blame.c:2268
 msgid "Process only line range n,m, counting from 1"
 msgstr "只处理行范围在 n 和 m 之间的,从 1 开始"
 
@@ -2651,273 +2811,283 @@
 
 #: builtin/branch.c:453
 #, c-format
+msgid "[%s: gone]"
+msgstr "[%s: 丢失]"
+
+#: builtin/branch.c:456
+#, c-format
+msgid "[%s]"
+msgstr "[%s]"
+
+#: builtin/branch.c:459
+#, c-format
 msgid "[%s: behind %d]"
 msgstr "[%s:落后 %d]"
 
-#: builtin/branch.c:455
+#: builtin/branch.c:461
 #, c-format
 msgid "[behind %d]"
 msgstr "[落后 %d]"
 
-#: builtin/branch.c:459
+#: builtin/branch.c:465
 #, c-format
 msgid "[%s: ahead %d]"
 msgstr "[%s:领先 %d]"
 
-#: builtin/branch.c:461
+#: builtin/branch.c:467
 #, c-format
 msgid "[ahead %d]"
 msgstr "[领先 %d]"
 
-#: builtin/branch.c:464
+#: builtin/branch.c:470
 #, c-format
 msgid "[%s: ahead %d, behind %d]"
 msgstr "[%s:领先 %d,落后 %d]"
 
-#: builtin/branch.c:467
+#: builtin/branch.c:473
 #, c-format
 msgid "[ahead %d, behind %d]"
 msgstr "[领先 %d,落后 %d]"
 
-#: builtin/branch.c:490
+#: builtin/branch.c:496
 msgid " **** invalid ref ****"
 msgstr " **** 无效引用 ****"
 
-#: builtin/branch.c:582
+#: builtin/branch.c:588
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(非分支,正变基 %s)"
 
-#: builtin/branch.c:585
+#: builtin/branch.c:591
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(非分支,二分查找开始于 %s)"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:594
 #, c-format
 msgid "(detached from %s)"
 msgstr "(分离自 %s)"
 
-#: builtin/branch.c:591
+#: builtin/branch.c:597
 msgid "(no branch)"
 msgstr "(非分支)"
 
-#: builtin/branch.c:637
+#: builtin/branch.c:643
 #, c-format
 msgid "object '%s' does not point to a commit"
 msgstr "对象 '%s' 没有指向一个提交"
 
-#: builtin/branch.c:669
+#: builtin/branch.c:675
 msgid "some refs could not be read"
 msgstr "一些引用不能读取"
 
-#: builtin/branch.c:682
+#: builtin/branch.c:688
 msgid "cannot rename the current branch while not on any."
 msgstr "无法重命名当前分支因为不处于任何分支上。"
 
-#: builtin/branch.c:692
+#: builtin/branch.c:698
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "无效的分支名:'%s'"
 
-#: builtin/branch.c:707
+#: builtin/branch.c:713
 msgid "Branch rename failed"
 msgstr "分支重命名失败"
 
-#: builtin/branch.c:711
+#: builtin/branch.c:717
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "重命名掉一个错误命名的旧分支 '%s'"
 
-#: builtin/branch.c:715
+#: builtin/branch.c:721
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "分支重命名为 %s,但 HEAD 没有更新!"
 
-#: builtin/branch.c:722
+#: builtin/branch.c:728
 msgid "Branch is renamed, but update of config-file failed"
 msgstr "分支被重命名,但更新 config 文件失败"
 
-#: builtin/branch.c:737
+#: builtin/branch.c:743
 #, c-format
 msgid "malformed object name %s"
 msgstr "非法的对象名 %s"
 
-#: builtin/branch.c:761
+#: builtin/branch.c:767
 #, c-format
 msgid "could not write branch description template: %s"
 msgstr "不能写分支描述模版:%s"
 
-#: builtin/branch.c:791
+#: builtin/branch.c:797
 msgid "Generic options"
 msgstr "通用选项"
 
-#: builtin/branch.c:793
+#: builtin/branch.c:799
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "显示哈希值和主题,若参数出现两次则显示上游分支"
 
-#: builtin/branch.c:794
+#: builtin/branch.c:800
 msgid "suppress informational messages"
 msgstr "不显示信息"
 
-#: builtin/branch.c:795
+#: builtin/branch.c:801
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "设置跟踪模式(参见 git-pull(1))"
 
-#: builtin/branch.c:797
+#: builtin/branch.c:803
 msgid "change upstream info"
 msgstr "改变上游信息"
 
-#: builtin/branch.c:801
+#: builtin/branch.c:807
 msgid "use colored output"
 msgstr "使用彩色输出"
 
-#: builtin/branch.c:802
+#: builtin/branch.c:808
 msgid "act on remote-tracking branches"
 msgstr "作用于远程跟踪分支"
 
-#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832
-#: builtin/branch.c:838 builtin/commit.c:1433 builtin/commit.c:1434
-#: builtin/commit.c:1435 builtin/commit.c:1436 builtin/tag.c:468
+#: builtin/branch.c:811 builtin/branch.c:817 builtin/branch.c:838
+#: builtin/branch.c:844 builtin/commit.c:1460 builtin/commit.c:1461
+#: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468
 msgid "commit"
 msgstr "提交"
 
-#: builtin/branch.c:806 builtin/branch.c:812
+#: builtin/branch.c:812 builtin/branch.c:818
 msgid "print only branches that contain the commit"
 msgstr "只打印包含该提交的分支"
 
-#: builtin/branch.c:818
+#: builtin/branch.c:824
 msgid "Specific git-branch actions:"
 msgstr "具体的 git-branch 动作:"
 
-#: builtin/branch.c:819
+#: builtin/branch.c:825
 msgid "list both remote-tracking and local branches"
 msgstr "列出远程跟踪及本地分支"
 
-#: builtin/branch.c:821
+#: builtin/branch.c:827
 msgid "delete fully merged branch"
 msgstr "删除完全合并的分支"
 
-#: builtin/branch.c:822
+#: builtin/branch.c:828
 msgid "delete branch (even if not merged)"
 msgstr "删除分支(即使没有合并)"
 
-#: builtin/branch.c:823
+#: builtin/branch.c:829
 msgid "move/rename a branch and its reflog"
 msgstr "移动/重命名一个分支,以及它的引用日志"
 
-#: builtin/branch.c:824
+#: builtin/branch.c:830
 msgid "move/rename a branch, even if target exists"
 msgstr "移动/重命名一个分支,即使目标已存在"
 
-#: builtin/branch.c:825
+#: builtin/branch.c:831
 msgid "list branch names"
 msgstr "列出分支名"
 
-#: builtin/branch.c:826
+#: builtin/branch.c:832
 msgid "create the branch's reflog"
 msgstr "创建分支的引用日志"
 
-#: builtin/branch.c:828
+#: builtin/branch.c:834
 msgid "edit the description for the branch"
 msgstr "标记分支的描述"
 
-#: builtin/branch.c:829
+#: builtin/branch.c:835
 msgid "force creation (when already exists)"
 msgstr "强制创建(当已经存在)"
 
-#: builtin/branch.c:832
+#: builtin/branch.c:838
 msgid "print only not merged branches"
 msgstr "只打印没有合并的分支"
 
-#: builtin/branch.c:838
+#: builtin/branch.c:844
 msgid "print only merged branches"
 msgstr "只打印合并的分支"
 
-#: builtin/branch.c:842
+#: builtin/branch.c:848
 msgid "list branches in columns"
 msgstr "以列的方式显示分支"
 
-#: builtin/branch.c:855
+#: builtin/branch.c:861
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "无法将 HEAD 解析为有效引用。"
 
-#: builtin/branch.c:860 builtin/clone.c:630
+#: builtin/branch.c:866 builtin/clone.c:629
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD 没有位于 /refs/heads 之下!"
 
-#: builtin/branch.c:883
+#: builtin/branch.c:890
 msgid "--column and --verbose are incompatible"
 msgstr "--column 和 --verbose 不兼容"
 
-#: builtin/branch.c:889 builtin/branch.c:928
+#: builtin/branch.c:896 builtin/branch.c:935
 msgid "branch name required"
 msgstr "必须提供分支名"
 
-#: builtin/branch.c:904
+#: builtin/branch.c:911
 msgid "Cannot give description to detached HEAD"
 msgstr "不能向分离头指针提供描述"
 
-#: builtin/branch.c:909
+#: builtin/branch.c:916
 msgid "cannot edit description of more than one branch"
 msgstr "不能为一个以上的分支编辑描述"
 
-#: builtin/branch.c:916
+#: builtin/branch.c:923
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "分支 '%s' 尚无提交。"
 
-#: builtin/branch.c:919
+#: builtin/branch.c:926
 #, c-format
 msgid "No branch named '%s'."
 msgstr "没有分支 '%s'。"
 
-#: builtin/branch.c:934
+#: builtin/branch.c:941
 msgid "too many branches for a rename operation"
 msgstr "为重命名操作提供了太多的分支名"
 
-#: builtin/branch.c:939
+#: builtin/branch.c:946
 msgid "too many branches to set new upstream"
 msgstr "为设置新上游提供了太多的分支名"
 
-#: builtin/branch.c:943
+#: builtin/branch.c:950
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr "无法设置 HEAD 的上游为 %s,因为 HEAD 没有指向任何分支。"
 
-#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990
+#: builtin/branch.c:953 builtin/branch.c:975 builtin/branch.c:997
 #, c-format
 msgid "no such branch '%s'"
 msgstr "没有此分支 '%s'"
 
-#: builtin/branch.c:950
+#: builtin/branch.c:957
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "分支 '%s' 不存在"
 
-#: builtin/branch.c:962
+#: builtin/branch.c:969
 msgid "too many branches to unset upstream"
 msgstr "为取消上游设置操作提供了太多的分支名"
 
-#: builtin/branch.c:966
+#: builtin/branch.c:973
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr "无法取消 HEAD 的上游设置因为它没有指向一个分支"
 
-#: builtin/branch.c:972
+#: builtin/branch.c:979
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "分支 '%s' 没有上游信息"
 
-#: builtin/branch.c:987
+#: builtin/branch.c:994
 msgid "it does not make sense to create 'HEAD' manually"
 msgstr "手工创建 'HEAD' 没有意义"
 
-#: builtin/branch.c:993
+#: builtin/branch.c:1000
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr "'git branch' 的 -a 和 -r 选项带一个分支名参数没有意义"
 
-#: builtin/branch.c:996
+#: builtin/branch.c:1003
 #, c-format
 msgid ""
 "The --set-upstream flag is deprecated and will be removed. Consider using --"
@@ -2925,7 +3095,7 @@
 msgstr ""
 "选项 --set-upstream 已弃用并将被移除。考虑使用 --track 或 --set-upstream-to\n"
 
-#: builtin/branch.c:1013
+#: builtin/branch.c:1020
 #, c-format
 msgid ""
 "\n"
@@ -2936,12 +3106,12 @@
 "如果你想用 '%s' 跟踪 '%s', 这么做:\n"
 "\n"
 
-#: builtin/branch.c:1014
+#: builtin/branch.c:1021
 #, c-format
 msgid "    git branch -d %s\n"
 msgstr "    git branch -d %s\n"
 
-#: builtin/branch.c:1015
+#: builtin/branch.c:1022
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
 msgstr "    git branch --set-upstream-to %s\n"
@@ -2959,43 +3129,43 @@
 msgid "Need a repository to unbundle."
 msgstr "需要一个版本库来解包。"
 
-#: builtin/cat-file.c:285
+#: builtin/cat-file.c:312
 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"
 msgstr "git cat-file (-t|-s|-e|-p|<类型>|--textconv) <对象>"
 
-#: builtin/cat-file.c:286
+#: builtin/cat-file.c:313
 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>"
 msgstr "git cat-file (--batch|--batch-check) < <对象列表>"
 
-#: builtin/cat-file.c:323
+#: builtin/cat-file.c:350
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<类型> 可以是其中之一:blob、tree、commit、tag"
 
-#: builtin/cat-file.c:324
+#: builtin/cat-file.c:351
 msgid "show object type"
 msgstr "显示对象类型"
 
-#: builtin/cat-file.c:325
+#: builtin/cat-file.c:352
 msgid "show object size"
 msgstr "显示对象大小"
 
-#: builtin/cat-file.c:327
+#: builtin/cat-file.c:354
 msgid "exit with zero when there's no error"
 msgstr "当没有错误时退出并返回零"
 
-#: builtin/cat-file.c:328
+#: builtin/cat-file.c:355
 msgid "pretty-print object's content"
 msgstr "美观地打印对象的内容"
 
-#: builtin/cat-file.c:330
+#: builtin/cat-file.c:357
 msgid "for blob objects, run textconv on object's content"
 msgstr "对于数据(blob)对象,对其内容执行 textconv"
 
-#: builtin/cat-file.c:332
+#: builtin/cat-file.c:359
 msgid "show info and content of objects fed from the standard input"
 msgstr "显示从标准输入提供的对象的信息和内容"
 
-#: builtin/cat-file.c:335
+#: builtin/cat-file.c:362
 msgid "show info about objects fed from the standard input"
 msgstr "显示从标准输入提供的对象的信息"
 
@@ -3020,10 +3190,10 @@
 msgstr "从标准输入读出文件名"
 
 #: builtin/check-attr.c:23 builtin/check-ignore.c:24
-msgid "input paths are terminated by a null character"
-msgstr "输入路径以null字符终止"
+msgid "terminate input and output records by a NUL character"
+msgstr "输入和输出的记录使用 NUL 字符终结"
 
-#: builtin/check-ignore.c:18 builtin/checkout.c:1054 builtin/gc.c:177
+#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:259
 msgid "suppress progress reporting"
 msgstr "不显示进度报告"
 
@@ -3031,27 +3201,31 @@
 msgid "show non-matching input paths"
 msgstr "显示未匹配的输入路径"
 
-#: builtin/check-ignore.c:143
+#: builtin/check-ignore.c:28
+msgid "ignore index when checking"
+msgstr "检查时忽略索引"
+
+#: builtin/check-ignore.c:154
 msgid "cannot specify pathnames with --stdin"
 msgstr "不能同时提供路径及 --stdin 参数"
 
-#: builtin/check-ignore.c:146
+#: builtin/check-ignore.c:157
 msgid "-z only makes sense with --stdin"
 msgstr "-z 需要和 --stdin 参数共用才有意义"
 
-#: builtin/check-ignore.c:148
+#: builtin/check-ignore.c:159
 msgid "no path specified"
 msgstr "未指定路径"
 
-#: builtin/check-ignore.c:152
+#: builtin/check-ignore.c:163
 msgid "--quiet is only valid with a single pathname"
 msgstr "参数 --quiet 只在提供一个路径名时有效"
 
-#: builtin/check-ignore.c:154
+#: builtin/check-ignore.c:165
 msgid "cannot have both --quiet and --verbose"
 msgstr "不能同时提供 --quiet 和 --verbose 参数"
 
-#: builtin/check-ignore.c:157
+#: builtin/check-ignore.c:168
 msgid "--non-matching is only valid with --verbose"
 msgstr "--non-matching 选项只在使用 --verbose 时有效"
 
@@ -3124,107 +3298,107 @@
 msgid "git checkout [options] [<branch>] -- <file>..."
 msgstr "git checkout [选项] [<分支>] -- <文件>..."
 
-#: builtin/checkout.c:117 builtin/checkout.c:150
+#: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr "路径 '%s' 没有我们的版本"
 
-#: builtin/checkout.c:119 builtin/checkout.c:152
+#: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr "路径 '%s' 没有他们的版本"
 
-#: builtin/checkout.c:135
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr "路径 '%s' 没有全部必须的版本"
 
-#: builtin/checkout.c:179
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr "路径 '%s' 没有必须的版本"
 
-#: builtin/checkout.c:196
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "path '%s':无法合并"
 
-#: builtin/checkout.c:213
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr "无法为 '%s' 添加合并结果"
 
-#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243
-#: builtin/checkout.c:246
+#: builtin/checkout.c:232 builtin/checkout.c:235 builtin/checkout.c:238
+#: builtin/checkout.c:241
 #, c-format
 msgid "'%s' cannot be used with updating paths"
 msgstr "'%s' 不能在更新路径时使用"
 
-#: builtin/checkout.c:249 builtin/checkout.c:252
+#: builtin/checkout.c:244 builtin/checkout.c:247
 #, c-format
 msgid "'%s' cannot be used with %s"
 msgstr "'%s' 不能和 %s 同时使用"
 
-#: builtin/checkout.c:255
+#: builtin/checkout.c:250
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
 msgstr "不能同时更新路径并切换到分支'%s'。"
 
-#: builtin/checkout.c:266 builtin/checkout.c:458
+#: builtin/checkout.c:261 builtin/checkout.c:451
 msgid "corrupt index file"
 msgstr "损坏的索引文件"
 
-#: builtin/checkout.c:329 builtin/checkout.c:336
+#: builtin/checkout.c:322 builtin/checkout.c:329
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "路径 '%s' 未合并"
 
-#: builtin/checkout.c:480
+#: builtin/checkout.c:473
 msgid "you need to resolve your current index first"
 msgstr "您需要先解决当前索引的冲突"
 
-#: builtin/checkout.c:601
+#: builtin/checkout.c:594
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "不能对 '%s' 执行 reflog 操作\n"
 
-#: builtin/checkout.c:639
+#: builtin/checkout.c:632
 msgid "HEAD is now at"
 msgstr "HEAD 目前位于"
 
-#: builtin/checkout.c:646
+#: builtin/checkout.c:639
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "重置分支 '%s'\n"
 
-#: builtin/checkout.c:649
+#: builtin/checkout.c:642
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "已经位于 '%s'\n"
 
-#: builtin/checkout.c:653
+#: builtin/checkout.c:646
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "切换并重置分支 '%s'\n"
 
-#: builtin/checkout.c:655 builtin/checkout.c:997
+#: builtin/checkout.c:648 builtin/checkout.c:1033
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "切换到一个新分支 '%s'\n"
 
-#: builtin/checkout.c:657
+#: builtin/checkout.c:650
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "切换到分支 '%s'\n"
 
 #  译者:注意保持前导空格
-#: builtin/checkout.c:713
+#: builtin/checkout.c:706
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... 及其它 %d 个。\n"
 
 #. The singular version
-#: builtin/checkout.c:719
+#: builtin/checkout.c:712
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -3245,7 +3419,7 @@
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:737
+#: builtin/checkout.c:730
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -3260,136 +3434,140 @@
 " git branch new_branch_name %s\n"
 "\n"
 
-#: builtin/checkout.c:767
+#: builtin/checkout.c:760
 msgid "internal error in revision walk"
 msgstr "在版本遍历时遇到内部错误"
 
-#: builtin/checkout.c:771
+#: builtin/checkout.c:764
 msgid "Previous HEAD position was"
 msgstr "之前的 HEAD 位置是"
 
-#: builtin/checkout.c:798 builtin/checkout.c:992
+#: builtin/checkout.c:791 builtin/checkout.c:1028
 msgid "You are on a branch yet to be born"
 msgstr "您位于一个尚未初始化的分支"
 
-#. case (1)
-#: builtin/checkout.c:928
+#: builtin/checkout.c:935
+#, c-format
+msgid "only one reference expected, %d given."
+msgstr "只要一个引用,却给出了 %d 个"
+
+#: builtin/checkout.c:974
 #, c-format
 msgid "invalid reference: %s"
 msgstr "无效引用:%s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:967
+#: builtin/checkout.c:1003
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "引用不是一个树:%s"
 
-#: builtin/checkout.c:1006
+#: builtin/checkout.c:1042
 msgid "paths cannot be used with switching branches"
 msgstr "路径不能和切换分支同时使用"
 
-#: builtin/checkout.c:1009 builtin/checkout.c:1013
+#: builtin/checkout.c:1045 builtin/checkout.c:1049
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "'%s' 不能和切换分支同时使用"
 
-#: builtin/checkout.c:1017 builtin/checkout.c:1020 builtin/checkout.c:1025
-#: builtin/checkout.c:1028
+#: builtin/checkout.c:1053 builtin/checkout.c:1056 builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "'%s' 不能和 '%s' 同时使用"
 
-#: builtin/checkout.c:1033
+#: builtin/checkout.c:1069
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "不能切换分支到一个非提交 '%s'"
 
-#: builtin/checkout.c:1055 builtin/checkout.c:1057 builtin/clone.c:89
+#: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88
 #: builtin/remote.c:169 builtin/remote.c:171
 msgid "branch"
 msgstr "分支"
 
-#: builtin/checkout.c:1056
+#: builtin/checkout.c:1092
 msgid "create and checkout a new branch"
 msgstr "创建并检出一个新的分支"
 
-#: builtin/checkout.c:1058
+#: builtin/checkout.c:1094
 msgid "create/reset and checkout a branch"
 msgstr "创建/重置并检出一个分支"
 
-#: builtin/checkout.c:1059
+#: builtin/checkout.c:1095
 msgid "create reflog for new branch"
 msgstr "为新的分支创建引用日志"
 
-#: builtin/checkout.c:1060
+#: builtin/checkout.c:1096
 msgid "detach the HEAD at named commit"
 msgstr "成为指向该提交的分离头指针"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1097
 msgid "set upstream info for new branch"
 msgstr "为新的分支设置上游信息"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new branch"
 msgstr "新分支"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1099
 msgid "new unparented branch"
 msgstr "新的没有父提交的分支"
 
-#: builtin/checkout.c:1064
+#: builtin/checkout.c:1100
 msgid "checkout our version for unmerged files"
 msgstr "对尚未合并的文件检出我们的版本"
 
-#: builtin/checkout.c:1066
+#: builtin/checkout.c:1102
 msgid "checkout their version for unmerged files"
 msgstr "对尚未合并的文件检出他们的版本"
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1104
 msgid "force checkout (throw away local modifications)"
 msgstr "强制检出(丢弃本地修改)"
 
-#: builtin/checkout.c:1069
+#: builtin/checkout.c:1105
 msgid "perform a 3-way merge with the new branch"
 msgstr "和新的分支执行三路合并"
 
-#: builtin/checkout.c:1070 builtin/merge.c:232
+#: builtin/checkout.c:1106 builtin/merge.c:232
 msgid "update ignored files (default)"
 msgstr "更新忽略的文件(默认)"
 
-#: builtin/checkout.c:1071 builtin/log.c:1208 parse-options.h:249
+#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:251
 msgid "style"
 msgstr "风格"
 
-#: builtin/checkout.c:1072
+#: builtin/checkout.c:1108
 msgid "conflict style (merge or diff3)"
 msgstr "冲突输出风格(merge 或 diff3)"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1111
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "对路径不做稀疏检出的限制"
 
-#: builtin/checkout.c:1077
+#: builtin/checkout.c:1113
 msgid "second guess 'git checkout no-such-branch'"
 msgstr "再者猜测'git checkout no-such-branch'"
 
-#: builtin/checkout.c:1101
+#: builtin/checkout.c:1136
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b、-B 和 --orphan 是互斥的"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1153
 msgid "--track needs a branch name"
 msgstr "--track 需要一个分支名"
 
-#: builtin/checkout.c:1125
+#: builtin/checkout.c:1160
 msgid "Missing branch name; try -b"
 msgstr "缺少分支名;尝试 -b"
 
-#: builtin/checkout.c:1160
+#: builtin/checkout.c:1197
 msgid "invalid path specification"
 msgstr "无效的路径规格"
 
-#: builtin/checkout.c:1167
+#: builtin/checkout.c:1204
 #, c-format
 msgid ""
 "Cannot update paths and switch to branch '%s' at the same time.\n"
@@ -3398,50 +3576,50 @@
 "不能同时更新路径并切换到分支'%s'。\n"
 "您是想要检出 '%s' 但其未能解析为提交么?"
 
-#: builtin/checkout.c:1172
+#: builtin/checkout.c:1209
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout:--detach 不能接收路径参数 '%s'"
 
-#: builtin/checkout.c:1176
+#: builtin/checkout.c:1213
 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/clean.c:25
+#: builtin/clean.c:26
 msgid ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
 msgstr ""
 "git clean [-d] [-f] [-i] [-n] [-q] [-e <模式>] [-x | -X] [--] <路径>..."
 
-#: builtin/clean.c:29
+#: builtin/clean.c:30
 #, c-format
 msgid "Removing %s\n"
 msgstr "正删除 %s\n"
 
-#: builtin/clean.c:30
+#: builtin/clean.c:31
 #, c-format
 msgid "Would remove %s\n"
 msgstr "将删除 %s\n"
 
-#: builtin/clean.c:31
+#: builtin/clean.c:32
 #, c-format
 msgid "Skipping repository %s\n"
 msgstr "忽略版本库 %s\n"
 
-#: builtin/clean.c:32
+#: builtin/clean.c:33
 #, c-format
 msgid "Would skip repository %s\n"
 msgstr "将忽略版本库 %s\n"
 
-#: builtin/clean.c:33
+#: builtin/clean.c:34
 #, c-format
 msgid "failed to remove %s"
 msgstr "无法删除 %s"
 
-#: builtin/clean.c:293
+#: builtin/clean.c:294
 msgid ""
 "Prompt help:\n"
 "1          - select a numbered item\n"
@@ -3453,7 +3631,7 @@
 "foo        - 通过标题选择一个选项\n"
 "           - (空)什么也不选择"
 
-#: builtin/clean.c:297
+#: builtin/clean.c:298
 msgid ""
 "Prompt help:\n"
 "1          - select a single item\n"
@@ -3473,35 +3651,35 @@
 "*          - 选择所有选项\n"
 "           - (空)结束选择"
 
-#: builtin/clean.c:515
+#: builtin/clean.c:516
 #, c-format
 msgid "Huh (%s)?"
 msgstr "嗯(%s)?"
 
-#: builtin/clean.c:658
+#: builtin/clean.c:659
 #, c-format
 msgid "Input ignore patterns>> "
 msgstr "输入模版以排除条目>> "
 
-#: builtin/clean.c:695
+#: builtin/clean.c:696
 #, c-format
 msgid "WARNING: Cannot find items matched by: %s"
 msgstr "警告:无法找到和 %s 匹配的条目"
 
-#: builtin/clean.c:716
+#: builtin/clean.c:717
 msgid "Select items to delete"
 msgstr "选择要删除的条目"
 
-#: builtin/clean.c:756
+#: builtin/clean.c:757
 #, c-format
 msgid "remove %s? "
 msgstr "删除 %s?"
 
-#: builtin/clean.c:781
+#: builtin/clean.c:782
 msgid "Bye."
 msgstr "再见。"
 
-#: builtin/clean.c:789
+#: builtin/clean.c:790
 msgid ""
 "clean               - start cleaning\n"
 "filter by pattern   - exclude items from deletion\n"
@@ -3519,21 +3697,21 @@
 "help                - 显示本帮助\n"
 "?                   - 显示如何在提示符下选择的帮助"
 
-#: builtin/clean.c:816
+#: builtin/clean.c:817
 msgid "*** Commands ***"
 msgstr "*** 命令 ***"
 
-#: builtin/clean.c:817
+#: builtin/clean.c:818
 msgid "What now"
 msgstr "请选择"
 
-#: builtin/clean.c:825
+#: builtin/clean.c:826
 msgid "Would remove the following item:"
 msgid_plural "Would remove the following items:"
 msgstr[0] "将删除如下条目:"
 msgstr[1] "将删除如下条目:"
 
-#: builtin/clean.c:842
+#: builtin/clean.c:843
 msgid "No more files to clean, exiting."
 msgstr "没有要清理的文件,退出。"
 
@@ -3553,8 +3731,8 @@
 msgid "remove whole directories"
 msgstr "删除整个目录"
 
-#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:716
-#: builtin/ls-files.c:493 builtin/name-rev.c:315 builtin/show-ref.c:186
+#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718
+#: builtin/ls-files.c:483 builtin/name-rev.c:315 builtin/show-ref.c:185
 msgid "pattern"
 msgstr "模式"
 
@@ -3592,8 +3770,8 @@
 msgid "git clone [options] [--] <repo> [<dir>]"
 msgstr "git clone [选项] [--] <版本库> [<路径>]"
 
-#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:229
-#: builtin/push.c:462
+#: builtin/clone.c:64 builtin/fetch.c:96 builtin/merge.c:229
+#: builtin/push.c:474
 msgid "force progress reporting"
 msgstr "强制显示进度报告"
 
@@ -3605,123 +3783,123 @@
 msgid "create a bare repository"
 msgstr "创建一个裸版本库"
 
-#: builtin/clone.c:72
+#: builtin/clone.c:71
 msgid "create a mirror repository (implies bare)"
 msgstr "创建一个镜像版本库(也是裸版本库)"
 
-#: builtin/clone.c:74
+#: builtin/clone.c:73
 msgid "to clone from a local repository"
 msgstr "从本地版本库克隆"
 
-#: builtin/clone.c:76
+#: builtin/clone.c:75
 msgid "don't use local hardlinks, always copy"
 msgstr "不使用本地硬链接,始终复制"
 
-#: builtin/clone.c:78
+#: builtin/clone.c:77
 msgid "setup as shared repository"
 msgstr "设置为共享版本库"
 
-#: builtin/clone.c:80 builtin/clone.c:82
+#: builtin/clone.c:79 builtin/clone.c:81
 msgid "initialize submodules in the clone"
 msgstr "在克隆时初始化子模组"
 
-#: builtin/clone.c:83 builtin/init-db.c:485
+#: builtin/clone.c:82 builtin/init-db.c:485
 msgid "template-directory"
 msgstr "模板目录"
 
-#: builtin/clone.c:84 builtin/init-db.c:486
+#: builtin/clone.c:83 builtin/init-db.c:486
 msgid "directory from which templates will be used"
 msgstr "模板目录将被使用"
 
-#: builtin/clone.c:86
+#: builtin/clone.c:85
 msgid "reference repository"
 msgstr "引用版本库"
 
-#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44
+#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44
 msgid "name"
 msgstr "名称"
 
-#: builtin/clone.c:88
+#: builtin/clone.c:87
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "使用<名称>而不是 'origin' 去跟踪上游"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:89
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "检出<分支>而不是远程HEAD"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:91
 msgid "path to git-upload-pack on the remote"
 msgstr "远程 git-upload-pack 路径"
 
-#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:661
+#: builtin/clone.c:92 builtin/fetch.c:97 builtin/grep.c:663
 msgid "depth"
 msgstr "深度"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:93
 msgid "create a shallow clone of that depth"
 msgstr "创建一个指定深度的浅克隆"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:95
 msgid "clone only one branch, HEAD or --branch"
 msgstr "只克隆一个分支、HEAD 或 --branch"
 
-#: builtin/clone.c:97 builtin/init-db.c:494
+#: builtin/clone.c:96 builtin/init-db.c:494
 msgid "gitdir"
 msgstr "git目录"
 
-#: builtin/clone.c:98 builtin/init-db.c:495
+#: builtin/clone.c:97 builtin/init-db.c:495
 msgid "separate git dir from working tree"
 msgstr "git目录和工作区分离"
 
-#: builtin/clone.c:99
+#: builtin/clone.c:98
 msgid "key=value"
 msgstr "key=value"
 
-#: builtin/clone.c:100
+#: builtin/clone.c:99
 msgid "set config inside the new repository"
 msgstr "在新版本库中设置配置信息"
 
-#: builtin/clone.c:253
+#: builtin/clone.c:252
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "引用版本库 '%s' 不是一个本地版本库。"
 
-#: builtin/clone.c:316
+#: builtin/clone.c:315
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "无法创建目录 '%s'"
 
-#: builtin/clone.c:318 builtin/diff.c:77
+#: builtin/clone.c:317 builtin/diff.c:77
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "无法枚举 '%s' 状态"
 
-#: builtin/clone.c:320
+#: builtin/clone.c:319
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s 存在且不是一个目录"
 
-#: builtin/clone.c:334
+#: builtin/clone.c:333
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "无法枚举 %s 状态\n"
 
-#: builtin/clone.c:356
+#: builtin/clone.c:355
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "无法创建链接 '%s'"
 
-#: builtin/clone.c:360
+#: builtin/clone.c:359
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "无法拷贝文件至 '%s'"
 
-#: builtin/clone.c:383
+#: builtin/clone.c:382 builtin/clone.c:559
 #, c-format
 msgid "done.\n"
 msgstr "完成。\n"
 
-#: builtin/clone.c:396
+#: builtin/clone.c:395
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -3731,104 +3909,99 @@
 "您可以通过 'git status' 检查哪些已被检出,然后使用命令\n"
 "'git checkout -f HEAD' 重试\n"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:474
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "不能发现要克隆的远程分支 %s。"
 
-#: builtin/clone.c:555
+#: builtin/clone.c:554
 #, c-format
 msgid "Checking connectivity... "
 msgstr "检查连接... "
 
-#: builtin/clone.c:558
+#: builtin/clone.c:557
 msgid "remote did not send all necessary objects"
 msgstr "远程没有发送所有必须的对象"
 
-#: builtin/clone.c:560
-#, c-format
-msgid "done\n"
-msgstr "完成\n"
-
-#: builtin/clone.c:621
+#: builtin/clone.c:620
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr "远程 HEAD 指向一个不存在的引用,无法检出。\n"
 
-#: builtin/clone.c:652
+#: builtin/clone.c:651
 msgid "unable to checkout working tree"
 msgstr "不能检出工作区"
 
-#: builtin/clone.c:760
+#: builtin/clone.c:759
 msgid "Too many arguments."
 msgstr "太多参数。"
 
-#: builtin/clone.c:764
+#: builtin/clone.c:763
 msgid "You must specify a repository to clone."
 msgstr "您必须指定一个版本库来克隆。"
 
-#: builtin/clone.c:775
+#: builtin/clone.c:774
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "--bare 和 --origin %s 选项不兼容。"
 
-#: builtin/clone.c:778
+#: builtin/clone.c:777
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "--bare 和 --separate-git-dir 选项不兼容。"
 
-#: builtin/clone.c:791
+#: builtin/clone.c:790
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "版本库 '%s' 不存在"
 
-#: builtin/clone.c:796
+#: builtin/clone.c:795
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr "--depth 在本地克隆被忽略,改为 file:// 协议试试。"
 
-#: builtin/clone.c:798
+#: builtin/clone.c:797
 msgid "--local is ignored"
 msgstr "--local 被忽略"
 
-#: builtin/clone.c:808
+#: builtin/clone.c:807
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "目标路径 '%s' 已经存在,并且不是一个空目录。"
 
-#: builtin/clone.c:818
+#: builtin/clone.c:817
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "工作区 '%s' 已经存在。"
 
-#: builtin/clone.c:831 builtin/clone.c:843
+#: builtin/clone.c:830 builtin/clone.c:842
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "不能为 '%s' 创建先导目录"
 
-#: builtin/clone.c:834
+#: builtin/clone.c:833
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "不能为 '%s' 创建工作区目录。"
 
-#: builtin/clone.c:853
+#: builtin/clone.c:852
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "克隆到裸版本库 '%s'...\n"
 
-#: builtin/clone.c:855
+#: builtin/clone.c:854
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "正克隆到 '%s'...\n"
 
-#: builtin/clone.c:890
+#: builtin/clone.c:888
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "不知道如何克隆 %s"
 
-#: builtin/clone.c:942
+#: builtin/clone.c:939 builtin/clone.c:947
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "远程分支 %s 在上游 %s 未发现"
 
-#: builtin/clone.c:949
+#: builtin/clone.c:950
 msgid "You appear to have cloned an empty repository."
 msgstr "您似乎克隆了一个空版本库。"
 
@@ -3864,15 +4037,15 @@
 msgid "--command must be the first argument"
 msgstr "--command 必须是第一个参数"
 
-#: builtin/commit.c:35
+#: builtin/commit.c:36
 msgid "git commit [options] [--] <pathspec>..."
-msgstr "git commit [选项] [--] <路径匹配>..."
+msgstr "git commit [选项] [--] <路径规则>..."
 
-#: builtin/commit.c:40
+#: builtin/commit.c:41
 msgid "git status [options] [--] <pathspec>..."
-msgstr "git status [选项] [--] <路径匹配>..."
+msgstr "git status [选项] [--] <路径规则>..."
 
-#: builtin/commit.c:45
+#: builtin/commit.c:46
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3895,7 +4068,7 @@
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: builtin/commit.c:57
+#: builtin/commit.c:58
 msgid ""
 "You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
@@ -3904,7 +4077,7 @@
 "您要修补最近的提交,但这么做会让它成为空提交。您可以重复您的命令并带上\n"
 "--allow-empty 选项,或者您可用命令 \"git reset HEAD^\" 整个删除该提交。\n"
 
-#: builtin/commit.c:62
+#: builtin/commit.c:63
 msgid ""
 "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 "If you wish to commit it anyway, use:\n"
@@ -3918,11 +4091,11 @@
 "    git commit --allow-empty\n"
 "\n"
 
-#: builtin/commit.c:69
+#: builtin/commit.c:70
 msgid "Otherwise, please use 'git reset'\n"
 msgstr "否则,请使用命令 'git reset'\n"
 
-#: builtin/commit.c:72
+#: builtin/commit.c:73
 msgid ""
 "If you wish to skip this commit, use:\n"
 "\n"
@@ -3938,93 +4111,93 @@
 "然后执行 \"git cherry-pick --continue\" 继续对其余提交执行拣选\n"
 "操作。\n"
 
-#: builtin/commit.c:279
+#: builtin/commit.c:287
 msgid "failed to unpack HEAD tree object"
 msgstr "无法解包 HEAD 树对象"
 
-#: builtin/commit.c:321
+#: builtin/commit.c:329
 msgid "unable to create temporary index"
 msgstr "不能创建临时索引"
 
-#: builtin/commit.c:327
+#: builtin/commit.c:335
 msgid "interactive add failed"
 msgstr "交互式添加失败"
 
-#: builtin/commit.c:360 builtin/commit.c:381 builtin/commit.c:431
+#: builtin/commit.c:368 builtin/commit.c:389 builtin/commit.c:439
 msgid "unable to write new_index file"
 msgstr "无法写 new_index 文件"
 
-#: builtin/commit.c:412
+#: builtin/commit.c:420
 msgid "cannot do a partial commit during a merge."
 msgstr "在合并过程中不能做部分提交。"
 
-#: builtin/commit.c:414
+#: builtin/commit.c:422
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "在拣选过程中不能做部分提交。"
 
-#: builtin/commit.c:424
+#: builtin/commit.c:432
 msgid "cannot read the index"
 msgstr "无法读取索引"
 
-#: builtin/commit.c:444
+#: builtin/commit.c:452
 msgid "unable to write temporary index file"
 msgstr "无法写临时索引文件"
 
-#: builtin/commit.c:535 builtin/commit.c:541
+#: builtin/commit.c:543 builtin/commit.c:549
 #, c-format
 msgid "invalid commit: %s"
 msgstr "无效的提交:%s"
 
-#: builtin/commit.c:563
+#: builtin/commit.c:571
 msgid "malformed --author parameter"
 msgstr "非法的 --author 参数"
 
-#: builtin/commit.c:583
+#: builtin/commit.c:591
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "非法的身份字符串:'%s'"
 
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:982
+#: builtin/commit.c:630 builtin/commit.c:663 builtin/commit.c:1007
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "不能查询提交 %s"
 
-#: builtin/commit.c:633 builtin/shortlog.c:271
+#: builtin/commit.c:642 builtin/shortlog.c:273
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(正从标准输入中读取日志信息)\n"
 
-#: builtin/commit.c:635
+#: builtin/commit.c:644
 msgid "could not read log from standard input"
 msgstr "不能从标准输入中读取日志信息"
 
-#: builtin/commit.c:639
+#: builtin/commit.c:648
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "不能读取日志文件 '%s'"
 
-#: builtin/commit.c:645
+#: builtin/commit.c:654
 msgid "commit has empty message"
 msgstr "提交说明为空"
 
-#: builtin/commit.c:661
+#: builtin/commit.c:670
 msgid "could not read MERGE_MSG"
 msgstr "不能读取 MERGE_MSG"
 
-#: builtin/commit.c:665
+#: builtin/commit.c:674
 msgid "could not read SQUASH_MSG"
 msgstr "不能读取 SQUASH_MSG"
 
-#: builtin/commit.c:669
+#: builtin/commit.c:678
 #, c-format
 msgid "could not read '%s'"
 msgstr "不能读取 '%s'"
 
-#: builtin/commit.c:730
+#: builtin/commit.c:749
 msgid "could not write commit template"
 msgstr "不能写提交模版"
 
-#: builtin/commit.c:741
+#: builtin/commit.c:760
 #, c-format
 msgid ""
 "\n"
@@ -4038,7 +4211,7 @@
 "\t%s\n"
 "然后重试。\n"
 
-#: builtin/commit.c:746
+#: builtin/commit.c:765
 #, c-format
 msgid ""
 "\n"
@@ -4052,7 +4225,7 @@
 "\t%s\n"
 "然后重试。\n"
 
-#: builtin/commit.c:758
+#: builtin/commit.c:777
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4061,7 +4234,7 @@
 "请为您的变更输入提交说明。以 '%c' 开始的行将被忽略,而一个空的提交\n"
 "说明将会终止提交。\n"
 
-#: builtin/commit.c:763
+#: builtin/commit.c:782
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -4072,355 +4245,355 @@
 "也可以删除它们。一个空的提交说明将会终止提交。\n"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:776
+#: builtin/commit.c:795
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%s作者:     %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:783
+#: builtin/commit.c:802
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%s提交者:   %s"
 
-#: builtin/commit.c:803
+#: builtin/commit.c:822
 msgid "Cannot read index"
 msgstr "无法读取索引"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:865
 msgid "Error building trees"
 msgstr "无法创建树对象"
 
-#: builtin/commit.c:860 builtin/tag.c:359
+#: builtin/commit.c:880 builtin/tag.c:359
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "请使用 -m 或 -F 选项提供提交说明。\n"
 
-#: builtin/commit.c:957
+#: builtin/commit.c:982
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "没有找到匹配 '%s' 的作者"
 
-#: builtin/commit.c:972 builtin/commit.c:1208
+#: builtin/commit.c:997 builtin/commit.c:1237
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "无效的未追踪文件参数 '%s'"
 
-#: builtin/commit.c:1009
+#: builtin/commit.c:1034
 msgid "--long and -z are incompatible"
 msgstr "--long 和 -z 选项不兼容"
 
-#: builtin/commit.c:1039
+#: builtin/commit.c:1064
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "同时使用 --reset-author 和 --author 没有意义"
 
-#: builtin/commit.c:1050
+#: builtin/commit.c:1075
 msgid "You have nothing to amend."
 msgstr "您没有可修补的提交。"
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1078
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "您正处于一个合并过程中 -- 无法修补提交。"
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1080
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "您正处于一个拣选过程中 -- 无法修补提交。"
 
-#: builtin/commit.c:1058
+#: builtin/commit.c:1083
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "选项 --squash 和 --fixup 不能同时使用"
 
-#: builtin/commit.c:1068
+#: builtin/commit.c:1093
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "只能用一个 -c/-C/-F/--fixup 选项。"
 
-#: builtin/commit.c:1070
+#: builtin/commit.c:1095
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr "选项 -m 不能和 -c/-C/-F/--fixup 同时使用。"
 
-#: builtin/commit.c:1078
+#: builtin/commit.c:1103
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author 只能和 -C、-c 或 --amend 同时使用。"
 
-#: builtin/commit.c:1095
+#: builtin/commit.c:1120
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr "只能用一个 --include/--only/--all/--interactive/--patch 选项。"
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1122
 msgid "No paths with --include/--only does not make sense."
 msgstr "参数 --include/--only 不跟路径没有意义。"
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1124
 msgid "Clever... amending the last one with dirty index."
 msgstr "聪明... 在索引不干净下修补最后的提交。"
 
-#: builtin/commit.c:1101
+#: builtin/commit.c:1126
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
 msgstr "指定了明确的路径而没有使用 -i 或 -o 选项;认为是 --only paths..."
 
-#: builtin/commit.c:1111 builtin/tag.c:575
+#: builtin/commit.c:1136 builtin/tag.c:572
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "无效的清理模式 %s"
 
-#: builtin/commit.c:1116
+#: builtin/commit.c:1141
 msgid "Paths with -a does not make sense."
 msgstr "路径和 -a 选项同时使用没有意义。"
 
-#: builtin/commit.c:1222 builtin/commit.c:1455
+#: builtin/commit.c:1251 builtin/commit.c:1482
 msgid "show status concisely"
 msgstr "以简洁的格式显示状态"
 
-#: builtin/commit.c:1224 builtin/commit.c:1457
+#: builtin/commit.c:1253 builtin/commit.c:1484
 msgid "show branch information"
 msgstr "显示分支信息"
 
-#: builtin/commit.c:1226 builtin/commit.c:1459 builtin/push.c:452
+#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:460
 msgid "machine-readable output"
 msgstr "机器可读的输出"
 
-#: builtin/commit.c:1229 builtin/commit.c:1461
+#: builtin/commit.c:1258 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "以长格式显示状态(默认)"
 
-#: builtin/commit.c:1232 builtin/commit.c:1464
+#: builtin/commit.c:1261 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "条目以NUL字符结尾"
 
-#: builtin/commit.c:1234 builtin/commit.c:1467 builtin/fast-export.c:667
-#: builtin/fast-export.c:670 builtin/tag.c:459
+#: builtin/commit.c:1263 builtin/commit.c:1494 builtin/fast-export.c:674
+#: builtin/fast-export.c:677 builtin/tag.c:459
 msgid "mode"
 msgstr "模式"
 
-#: builtin/commit.c:1235 builtin/commit.c:1467
+#: builtin/commit.c:1264 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr "显示未跟踪的文件,“模式”的可选参数:all、normal、no。(默认:all)"
 
-#: builtin/commit.c:1238
+#: builtin/commit.c:1267
 msgid "show ignored files"
 msgstr "显示忽略的文件"
 
-#: builtin/commit.c:1239 parse-options.h:154
+#: builtin/commit.c:1268 parse-options.h:156
 msgid "when"
 msgstr "何时"
 
-#: builtin/commit.c:1240
+#: builtin/commit.c:1269
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
 msgstr ""
 "忽略子模组的更改,“何时”的可选参数:all、dirty、untracked。(默认:all)"
 
-#: builtin/commit.c:1242
+#: builtin/commit.c:1271
 msgid "list untracked files in columns"
 msgstr "以列的方式显示未跟踪的文件"
 
-#: builtin/commit.c:1313
+#: builtin/commit.c:1340
 msgid "couldn't look up newly created commit"
 msgstr "无法找到新创建的提交"
 
-#: builtin/commit.c:1315
+#: builtin/commit.c:1342
 msgid "could not parse newly created commit"
 msgstr "不能解析新创建的提交"
 
-#: builtin/commit.c:1356
+#: builtin/commit.c:1383
 msgid "detached HEAD"
 msgstr "分离头指针"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: builtin/commit.c:1358
+#: builtin/commit.c:1385
 msgid " (root-commit)"
 msgstr "(根提交)"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1452
 msgid "suppress summary after successful commit"
 msgstr "提交成功后不显示概述信息"
 
-#: builtin/commit.c:1426
+#: builtin/commit.c:1453
 msgid "show diff in commit message template"
 msgstr "在提交说明模板里显示差异"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1455
 msgid "Commit message options"
 msgstr "提交说明选项"
 
-#: builtin/commit.c:1429 builtin/tag.c:457
+#: builtin/commit.c:1456 builtin/tag.c:457
 msgid "read message from file"
 msgstr "从文件中读取提交说明"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "author"
 msgstr "作者"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1457
 msgid "override author for commit"
 msgstr "提交时覆盖作者"
 
-#: builtin/commit.c:1431 builtin/gc.c:178
+#: builtin/commit.c:1458 builtin/gc.c:260
 msgid "date"
 msgstr "日期"
 
-#: builtin/commit.c:1431
+#: builtin/commit.c:1458
 msgid "override date for commit"
 msgstr "提交时覆盖日期"
 
-#: builtin/commit.c:1432 builtin/merge.c:223 builtin/notes.c:405
+#: builtin/commit.c:1459 builtin/merge.c:223 builtin/notes.c:405
 #: builtin/notes.c:562 builtin/tag.c:455
 msgid "message"
 msgstr "说明"
 
-#: builtin/commit.c:1432
+#: builtin/commit.c:1459
 msgid "commit message"
 msgstr "提交说明"
 
-#: builtin/commit.c:1433
+#: builtin/commit.c:1460
 msgid "reuse and edit message from specified commit"
 msgstr "重用并编辑指定提交的提交说明"
 
-#: builtin/commit.c:1434
+#: builtin/commit.c:1461
 msgid "reuse message from specified commit"
 msgstr "重用指定提交的提交说明"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1462
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr "使用 autosquash 格式的提交说明用以修正指定的提交"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1463
 msgid "use autosquash formatted message to squash specified commit"
 msgstr "使用 autosquash 格式的提交说明用以压缩至指定的提交"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1464
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "现在将该提交的作者改为我(和 -C/-c/--amend 参数共用)"
 
-#: builtin/commit.c:1438 builtin/log.c:1160 builtin/revert.c:111
+#: builtin/commit.c:1465 builtin/log.c:1180 builtin/revert.c:86
 msgid "add Signed-off-by:"
 msgstr "添加 Signed-off-by: 签名"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1466
 msgid "use specified template file"
 msgstr "使用指定的模板文件"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1467
 msgid "force edit of commit"
 msgstr "强制编辑提交"
 
 #  译者:可选值,不能翻译(或是原文中笔误,应为 mode)
-#: builtin/commit.c:1441
+#: builtin/commit.c:1468
 msgid "default"
 msgstr "default"
 
-#: builtin/commit.c:1441 builtin/tag.c:460
+#: builtin/commit.c:1468 builtin/tag.c:460
 msgid "how to strip spaces and #comments from message"
 msgstr "设置如何删除提交说明里的空格和#注释"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1469
 msgid "include status in commit message template"
 msgstr "在提交说明模板里包含状态信息"
 
-#: builtin/commit.c:1443 builtin/merge.c:230 builtin/tag.c:461
+#: builtin/commit.c:1470 builtin/merge.c:230 builtin/tag.c:461
 msgid "key id"
 msgstr "key id"
 
-#: builtin/commit.c:1444 builtin/merge.c:231
+#: builtin/commit.c:1471 builtin/merge.c:231
 msgid "GPG sign commit"
 msgstr "GPG 提交签名"
 
 #. end commit message options
-#: builtin/commit.c:1447
+#: builtin/commit.c:1474
 msgid "Commit contents options"
 msgstr "提交内容选项"
 
-#: builtin/commit.c:1448
+#: builtin/commit.c:1475
 msgid "commit all changed files"
 msgstr "提交所有改动的文件"
 
-#: builtin/commit.c:1449
+#: builtin/commit.c:1476
 msgid "add specified files to index for commit"
 msgstr "添加指定的文件到索引区等待提交"
 
-#: builtin/commit.c:1450
+#: builtin/commit.c:1477
 msgid "interactively add files"
 msgstr "交互式添加文件"
 
-#: builtin/commit.c:1451
+#: builtin/commit.c:1478
 msgid "interactively add changes"
 msgstr "交互式添加变更"
 
-#: builtin/commit.c:1452
+#: builtin/commit.c:1479
 msgid "commit only specified files"
 msgstr "只提交指定的文件"
 
-#: builtin/commit.c:1453
+#: builtin/commit.c:1480
 msgid "bypass pre-commit hook"
 msgstr "绕过 pre-commit 钩子"
 
-#: builtin/commit.c:1454
+#: builtin/commit.c:1481
 msgid "show what would be committed"
 msgstr "显示将要提交的内容"
 
-#: builtin/commit.c:1465
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "修改先前的提交"
 
-#: builtin/commit.c:1466
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "绕过 post-rewrite 钩子"
 
-#: builtin/commit.c:1471
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "允许一个空提交"
 
-#: builtin/commit.c:1474
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "允许空的提交说明"
 
-#: builtin/commit.c:1507
+#: builtin/commit.c:1529
 msgid "could not parse HEAD commit"
 msgstr "不能解析 HEAD 提交"
 
-#: builtin/commit.c:1545 builtin/merge.c:525
+#: builtin/commit.c:1567 builtin/merge.c:525
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "不能为读入打开 '%s'"
 
-#: builtin/commit.c:1552
+#: builtin/commit.c:1574
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "损坏的 MERGE_HEAD 文件(%s)"
 
-#: builtin/commit.c:1559
+#: builtin/commit.c:1581
 msgid "could not read MERGE_MODE"
 msgstr "不能读取 MERGE_MODE"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1600
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "不能读取提交说明:%s"
 
-#: builtin/commit.c:1592
+#: builtin/commit.c:1614
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "终止提交;您未更改来自模版的提交说明。\n"
 
-#: builtin/commit.c:1597
+#: builtin/commit.c:1619
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "终止提交因为提交说明为空。\n"
 
-#: builtin/commit.c:1612 builtin/merge.c:861 builtin/merge.c:886
+#: builtin/commit.c:1634 builtin/merge.c:861 builtin/merge.c:886
 msgid "failed to write commit object"
 msgstr "无法写提交对象"
 
-#: builtin/commit.c:1633
+#: builtin/commit.c:1655
 msgid "cannot lock HEAD ref"
 msgstr "无法锁定 HEAD 引用"
 
-#: builtin/commit.c:1637
+#: builtin/commit.c:1659
 msgid "cannot update HEAD ref"
 msgstr "无法更新 HEAD 引用"
 
-#: builtin/commit.c:1648
+#: builtin/commit.c:1670
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -4429,127 +4602,131 @@
 "版本库已更新,但无法写 new_index 文件。检查是否磁盘已满\n"
 "或磁盘配额已耗尽,然后执行 \"git reset HEAD\" 恢复。"
 
-#: builtin/config.c:7
+#: builtin/config.c:8
 msgid "git config [options]"
 msgstr "git config [选项]"
 
-#: builtin/config.c:52
+#: builtin/config.c:54
 msgid "Config file location"
 msgstr "配置文件位置"
 
-#: builtin/config.c:53
+#: builtin/config.c:55
 msgid "use global config file"
 msgstr "使用全局配置文件"
 
-#: builtin/config.c:54
+#: builtin/config.c:56
 msgid "use system config file"
 msgstr "使用系统级配置文件"
 
-#: builtin/config.c:55
+#: builtin/config.c:57
 msgid "use repository config file"
 msgstr "使用版本库级配置文件"
 
-#: builtin/config.c:56
+#: builtin/config.c:58
 msgid "use given config file"
 msgstr "使用指定的配置文件"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "blob-id"
 msgstr "数据对象ID"
 
-#: builtin/config.c:57
+#: builtin/config.c:59
 msgid "read config from given blob object"
 msgstr "从给定的数据对象读取配置"
 
-#: builtin/config.c:58
+#: builtin/config.c:60
 msgid "Action"
 msgstr "操作"
 
-#: builtin/config.c:59
+#: builtin/config.c:61
 msgid "get value: name [value-regex]"
 msgstr "获取值:name [value-regex]"
 
-#: builtin/config.c:60
+#: builtin/config.c:62
 msgid "get all values: key [value-regex]"
 msgstr "获得所有的值:key [value-regex]"
 
-#: builtin/config.c:61
+#: builtin/config.c:63
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "根据正则表达式获得值:name-regex [value-regex]"
 
-#: builtin/config.c:62
+#: builtin/config.c:64
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "获得 URL 取值:section[.var] URL"
+
+#: builtin/config.c:65
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "替换所有匹配的变量:name value [value_regex]"
 
-#: builtin/config.c:63
+#: builtin/config.c:66
 msgid "add a new variable: name value"
 msgstr "添加一个新的变量:name value"
 
-#: builtin/config.c:64
+#: builtin/config.c:67
 msgid "remove a variable: name [value-regex]"
 msgstr "删除一个变量:name [value-regex]"
 
-#: builtin/config.c:65
+#: builtin/config.c:68
 msgid "remove all matches: name [value-regex]"
 msgstr "删除所有匹配项:name [value-regex]"
 
-#: builtin/config.c:66
+#: builtin/config.c:69
 msgid "rename section: old-name new-name"
 msgstr "重命名小节:old-name new-name"
 
-#: builtin/config.c:67
+#: builtin/config.c:70
 msgid "remove a section: name"
 msgstr "删除一个小节:name"
 
-#: builtin/config.c:68
+#: builtin/config.c:71
 msgid "list all"
 msgstr "列出所有"
 
-#: builtin/config.c:69
+#: builtin/config.c:72
 msgid "open an editor"
 msgstr "打开一个编辑器"
 
-#: builtin/config.c:70 builtin/config.c:71
+#: builtin/config.c:73 builtin/config.c:74
 msgid "slot"
 msgstr "slot"
 
-#: builtin/config.c:70
+#: builtin/config.c:73
 msgid "find the color configured: [default]"
 msgstr "找到配置的颜色:[默认]"
 
-#: builtin/config.c:71
+#: builtin/config.c:74
 msgid "find the color setting: [stdout-is-tty]"
 msgstr "找到颜色设置:[stdout-is-tty]"
 
-#: builtin/config.c:72
+#: builtin/config.c:75
 msgid "Type"
 msgstr "类型"
 
-#: builtin/config.c:73
+#: builtin/config.c:76
 msgid "value is \"true\" or \"false\""
 msgstr "值是 \"true\" 或 \"false\""
 
-#: builtin/config.c:74
+#: builtin/config.c:77
 msgid "value is decimal number"
 msgstr "值是十进制数"
 
-#: builtin/config.c:75
+#: builtin/config.c:78
 msgid "value is --bool or --int"
 msgstr "值是 --bool or --int"
 
-#: builtin/config.c:76
+#: builtin/config.c:79
 msgid "value is a path (file or directory name)"
 msgstr "值是一个路径(文件或目录名)"
 
-#: builtin/config.c:77
+#: builtin/config.c:80
 msgid "Other"
 msgstr "其它"
 
-#: builtin/config.c:78
+#: builtin/config.c:81
 msgid "terminate values with NUL byte"
 msgstr "终止值是NUL字节"
 
-#: builtin/config.c:79
+#: builtin/config.c:82
 msgid "respect include directives on lookup"
 msgstr "查询时参照 include 指令递归查找"
 
@@ -4562,7 +4739,7 @@
 msgstr "以用户可读的格式显示大小"
 
 #: builtin/describe.c:16
-msgid "git describe [options] <committish>*"
+msgid "git describe [options] <commit-ish>*"
 msgstr "git describe [选项] <提交号>*"
 
 #: builtin/describe.c:17
@@ -4698,7 +4875,7 @@
 msgstr "没有发现名称,无法描述任何东西。"
 
 #: builtin/describe.c:489
-msgid "--dirty is incompatible with committishes"
+msgid "--dirty is incompatible with commit-ishes"
 msgstr "--dirty 不能与提交同时使用"
 
 #: builtin/diff.c:79
@@ -4734,45 +4911,45 @@
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-opts]"
 
-#: builtin/fast-export.c:666
+#: builtin/fast-export.c:673
 msgid "show progress after <n> objects"
 msgstr "在 <n> 个对象之后显示进度"
 
-#: builtin/fast-export.c:668
+#: builtin/fast-export.c:675
 msgid "select handling of signed tags"
 msgstr "选择如何处理签名 tags"
 
-#: builtin/fast-export.c:671
+#: builtin/fast-export.c:678
 msgid "select handling of tags that tag filtered objects"
 msgstr "选择当 tag 指向被过滤时 tags 的处理方式"
 
-#: builtin/fast-export.c:674
+#: builtin/fast-export.c:681
 msgid "Dump marks to this file"
 msgstr "把标记存储到这个文件"
 
-#: builtin/fast-export.c:676
+#: builtin/fast-export.c:683
 msgid "Import marks from this file"
 msgstr "从这个文件导入标记"
 
-#: builtin/fast-export.c:678
+#: builtin/fast-export.c:685
 msgid "Fake a tagger when tags lack one"
 msgstr "当 tags 缺少标记者字段时,假装提供一个"
 
-#: builtin/fast-export.c:680
+#: builtin/fast-export.c:687
 msgid "Output full tree for each commit"
 msgstr "每次提交都输出整个树"
 
-#: builtin/fast-export.c:682
+#: builtin/fast-export.c:689
 msgid "Use the done feature to terminate the stream"
 msgstr "使用 done 功能来终止流"
 
-#: builtin/fast-export.c:683
+#: builtin/fast-export.c:690
 msgid "Skip output of blob data"
 msgstr "跳过数据对象的输出"
 
 #: builtin/fetch.c:20
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
-msgstr "git fetch [<选项>] [<版本库> [<引用表达式>...]]"
+msgstr "git fetch [<选项>] [<版本库> [<引用规则>...]]"
 
 #: builtin/fetch.c:21
 msgid "git fetch [<options>] <group>"
@@ -4786,146 +4963,146 @@
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<选项>]"
 
-#: builtin/fetch.c:60
+#: builtin/fetch.c:74
 msgid "fetch from all remotes"
 msgstr "从所有的远程抓取"
 
-#: builtin/fetch.c:62
+#: builtin/fetch.c:76
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "追加到 .git/FETCH_HEAD 而不是覆盖它"
 
-#: builtin/fetch.c:64
+#: builtin/fetch.c:78
 msgid "path to upload pack on remote end"
 msgstr "上传包到远程的路径"
 
-#: builtin/fetch.c:65
+#: builtin/fetch.c:79
 msgid "force overwrite of local branch"
 msgstr "强制覆盖本地分支"
 
-#: builtin/fetch.c:67
+#: builtin/fetch.c:81
 msgid "fetch from multiple remotes"
 msgstr "从多个远程抓取"
 
-#: builtin/fetch.c:69
+#: builtin/fetch.c:83
 msgid "fetch all tags and associated objects"
 msgstr "抓取所有的 tags 和关联对象"
 
-#: builtin/fetch.c:71
+#: builtin/fetch.c:85
 msgid "do not fetch all tags (--no-tags)"
 msgstr "不抓取任何 tags (--no-tags)"
 
-#: builtin/fetch.c:73
+#: builtin/fetch.c:87
 msgid "prune remote-tracking branches no longer on remote"
 msgstr "清除远程已经不存在的分支的跟踪分支"
 
 #  译者:可选值,不能翻译
-#: builtin/fetch.c:74
+#: builtin/fetch.c:88
 msgid "on-demand"
 msgstr "on-demand"
 
-#: builtin/fetch.c:75
+#: builtin/fetch.c:89
 msgid "control recursive fetching of submodules"
 msgstr "控制子模组的递归抓取"
 
-#: builtin/fetch.c:79
+#: builtin/fetch.c:93
 msgid "keep downloaded pack"
 msgstr "保持下载包"
 
-#: builtin/fetch.c:81
+#: builtin/fetch.c:95
 msgid "allow updating of HEAD ref"
 msgstr "允许更新 HEAD 引用"
 
-#: builtin/fetch.c:84
+#: builtin/fetch.c:98
 msgid "deepen history of shallow clone"
 msgstr "深化浅克隆的历史"
 
-#: builtin/fetch.c:86
+#: builtin/fetch.c:100
 msgid "convert to a complete repository"
 msgstr "转换为一个完整的版本库"
 
-#: builtin/fetch.c:88 builtin/log.c:1177
+#: builtin/fetch.c:102 builtin/log.c:1197
 msgid "dir"
 msgstr "目录"
 
-#: builtin/fetch.c:89
+#: builtin/fetch.c:103
 msgid "prepend this to submodule path output"
 msgstr "在子模组路径输出的前面加上此目录"
 
-#: builtin/fetch.c:92
+#: builtin/fetch.c:106
 msgid "default mode for recursion"
 msgstr "递归的默认模式"
 
-#: builtin/fetch.c:220
+#: builtin/fetch.c:236
 msgid "Couldn't find remote ref HEAD"
 msgstr "无法发现远程 HEAD 引用"
 
-#: builtin/fetch.c:273
+#: builtin/fetch.c:290
 #, c-format
 msgid "object %s not found"
 msgstr "对象 %s 未发现"
 
-#: builtin/fetch.c:278
+#: builtin/fetch.c:295
 msgid "[up to date]"
 msgstr "[最新]"
 
-#: builtin/fetch.c:292
+#: builtin/fetch.c:309
 #, c-format
 msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
 msgstr "! %-*s %-*s -> %s  (在当前分支下不能获取)"
 
-#: builtin/fetch.c:293 builtin/fetch.c:379
+#: builtin/fetch.c:310 builtin/fetch.c:396
 msgid "[rejected]"
 msgstr "[已拒绝]"
 
-#: builtin/fetch.c:304
+#: builtin/fetch.c:321
 msgid "[tag update]"
 msgstr "[tag更新]"
 
 #  译者:注意保持前导空格
-#: builtin/fetch.c:306 builtin/fetch.c:341 builtin/fetch.c:359
+#: builtin/fetch.c:323 builtin/fetch.c:358 builtin/fetch.c:376
 msgid "  (unable to update local ref)"
 msgstr "  (不能更新本地引用)"
 
-#: builtin/fetch.c:324
+#: builtin/fetch.c:341
 msgid "[new tag]"
 msgstr "[新tag]"
 
-#: builtin/fetch.c:327
+#: builtin/fetch.c:344
 msgid "[new branch]"
 msgstr "[新分支]"
 
-#: builtin/fetch.c:330
+#: builtin/fetch.c:347
 msgid "[new ref]"
 msgstr "[新引用]"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "unable to update local ref"
 msgstr "不能更新本地引用"
 
-#: builtin/fetch.c:375
+#: builtin/fetch.c:392
 msgid "forced update"
 msgstr "强制更新"
 
-#: builtin/fetch.c:381
+#: builtin/fetch.c:398
 msgid "(non-fast-forward)"
 msgstr "(非快进式)"
 
-#: builtin/fetch.c:412 builtin/fetch.c:718
+#: builtin/fetch.c:429 builtin/fetch.c:735
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr "无法打开 %s:%s\n"
 
-#: builtin/fetch.c:421
+#: builtin/fetch.c:438
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s 未发送所有必须的对象\n"
 
-#: builtin/fetch.c:520
+#: builtin/fetch.c:537
 #, c-format
 msgid "From %.*s\n"
 msgstr "来自 %.*s\n"
 
-#: builtin/fetch.c:531
+#: builtin/fetch.c:548
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -4935,98 +5112,98 @@
 " 'git remote prune %s' 来删除旧的、有冲突的分支"
 
 #  译者:注意保持前导空格
-#: builtin/fetch.c:581
+#: builtin/fetch.c:598
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s 将成为摇摆状态)"
 
 #  译者:注意保持前导空格
-#: builtin/fetch.c:582
+#: builtin/fetch.c:599
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s 已成为摇摆状态)"
 
-#: builtin/fetch.c:589
+#: builtin/fetch.c:606
 msgid "[deleted]"
 msgstr "[已删除]"
 
-#: builtin/fetch.c:590 builtin/remote.c:1055
+#: builtin/fetch.c:607 builtin/remote.c:1055
 msgid "(none)"
 msgstr "(无)"
 
-#: builtin/fetch.c:708
+#: builtin/fetch.c:725
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "拒绝获取到非裸版本库的当前分支 %s"
 
-#: builtin/fetch.c:742
-#, c-format
-msgid "Don't know how to fetch from %s"
-msgstr "不知道如何从 %s 获取"
-
-#: builtin/fetch.c:823
+#: builtin/fetch.c:744
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "选项 \"%s\" 的值 \"%s\" 对于 %s 是无效的"
 
-#: builtin/fetch.c:826
+#: builtin/fetch.c:747
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "选项 \"%s\" 为 %s 所忽略\n"
 
-#: builtin/fetch.c:928
+#: builtin/fetch.c:801
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr "不知道如何从 %s 获取"
+
+#: builtin/fetch.c:976
 #, c-format
 msgid "Fetching %s\n"
 msgstr "正在获取 %s\n"
 
-#: builtin/fetch.c:930 builtin/remote.c:100
+#: builtin/fetch.c:978 builtin/remote.c:100
 #, c-format
 msgid "Could not fetch %s"
 msgstr "不能获取 %s"
 
-#: builtin/fetch.c:949
+#: builtin/fetch.c:997
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
 msgstr "未指定远程版本库。请通过一个URL或远程版本库名指定,用以获取新提交。"
 
-#: builtin/fetch.c:969
+#: builtin/fetch.c:1020
 msgid "You need to specify a tag name."
 msgstr "您需要指定一个 tag 名称。"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1068
 msgid "--depth and --unshallow cannot be used together"
 msgstr "--depth 和 --unshallow 不能同时使用"
 
-#: builtin/fetch.c:1017
+#: builtin/fetch.c:1070
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "对于一个完整的版本库,参数 --unshallow 没有意义"
 
-#: builtin/fetch.c:1036
+#: builtin/fetch.c:1089
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all 不能带一个版本库参数"
 
-#: builtin/fetch.c:1038
+#: builtin/fetch.c:1091
 msgid "fetch --all does not make sense with refspecs"
-msgstr "fetch --all 带引用表达式没有任何意义"
+msgstr "fetch --all 带引用规则没有任何意义"
 
-#: builtin/fetch.c:1049
+#: builtin/fetch.c:1102
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "没有这样的远程或远程组:%s"
 
-#: builtin/fetch.c:1057
+#: builtin/fetch.c:1110
 msgid "Fetching a group and specifying refspecs does not make sense"
-msgstr "获取组并指定引用表达式没有意义"
+msgstr "获取组并指定引用规则没有意义"
 
 #: builtin/fmt-merge-msg.c:13
 msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]"
 msgstr ""
 "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]"
 
-#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:700
-#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:179
-#: builtin/tag.c:446 parse-options.h:133 parse-options.h:243
+#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:702
+#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:178
+#: builtin/tag.c:446 parse-options.h:135 parse-options.h:245
 msgid "n"
 msgstr "n"
 
@@ -5050,117 +5227,121 @@
 msgid "file to read from"
 msgstr "从文件中读取"
 
-#: builtin/for-each-ref.c:979
+#: builtin/for-each-ref.c:995
 msgid "git for-each-ref [options] [<pattern>]"
 msgstr "git for-each-ref [选项] [<模式>]"
 
-#: builtin/for-each-ref.c:994
+#: builtin/for-each-ref.c:1010
 msgid "quote placeholders suitably for shells"
 msgstr "引用占位符适用于 shells"
 
-#: builtin/for-each-ref.c:996
+#: builtin/for-each-ref.c:1012
 msgid "quote placeholders suitably for perl"
 msgstr "引用占位符适用于 perl"
 
-#: builtin/for-each-ref.c:998
+#: builtin/for-each-ref.c:1014
 msgid "quote placeholders suitably for python"
 msgstr "引用占位符适用于 python"
 
-#: builtin/for-each-ref.c:1000
+#: builtin/for-each-ref.c:1016
 msgid "quote placeholders suitably for tcl"
 msgstr "引用占位符适用于 tcl"
 
-#: builtin/for-each-ref.c:1003
+#: builtin/for-each-ref.c:1019
 msgid "show only <n> matched refs"
 msgstr "只显示 <n> 个匹配的引用"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format"
 msgstr "格式"
 
-#: builtin/for-each-ref.c:1004
+#: builtin/for-each-ref.c:1020
 msgid "format to use for the output"
 msgstr "输出格式"
 
-#: builtin/for-each-ref.c:1005
+#: builtin/for-each-ref.c:1021
 msgid "key"
 msgstr "key"
 
-#: builtin/for-each-ref.c:1006
+#: builtin/for-each-ref.c:1022
 msgid "field name to sort on"
 msgstr "排序的字段名"
 
-#: builtin/fsck.c:608
+#: builtin/fsck.c:607
 msgid "git fsck [options] [<object>...]"
 msgstr "git fsck [选项] [<对象>...]"
 
-#: builtin/fsck.c:614
+#: builtin/fsck.c:613
 msgid "show unreachable objects"
 msgstr "显示不可达的对象"
 
-#: builtin/fsck.c:615
+#: builtin/fsck.c:614
 msgid "show dangling objects"
 msgstr "显示摇摆的对象"
 
-#: builtin/fsck.c:616
+#: builtin/fsck.c:615
 msgid "report tags"
 msgstr "报告 tags"
 
-#: builtin/fsck.c:617
+#: builtin/fsck.c:616
 msgid "report root nodes"
 msgstr "报告根节点"
 
-#: builtin/fsck.c:618
+#: builtin/fsck.c:617
 msgid "make index objects head nodes"
 msgstr "将索引亦作为检查的头节点"
 
-#: builtin/fsck.c:619
+#: builtin/fsck.c:618
 msgid "make reflogs head nodes (default)"
 msgstr "将引用日志作为检查的头节点(默认)"
 
-#: builtin/fsck.c:620
+#: builtin/fsck.c:619
 msgid "also consider packs and alternate objects"
 msgstr "也考虑包和备用对象"
 
-#: builtin/fsck.c:621
+#: builtin/fsck.c:620
 msgid "enable more strict checking"
 msgstr "启用更严格的检查"
 
-#: builtin/fsck.c:623
+#: builtin/fsck.c:622
 msgid "write dangling objects in .git/lost-found"
 msgstr "将摇摆对象写入 .git/lost-found 中"
 
-#: builtin/fsck.c:624 builtin/prune.c:134
+#: builtin/fsck.c:623 builtin/prune.c:134
 msgid "show progress"
 msgstr "显示进度"
 
-#: builtin/gc.c:22
+#: builtin/gc.c:23
 msgid "git gc [options]"
 msgstr "git gc [选项]"
 
-#: builtin/gc.c:63
+#: builtin/gc.c:79
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "无效的 %s:'%s'"
 
-#: builtin/gc.c:90
+#: builtin/gc.c:106
 #, c-format
 msgid "insanely long object directory %.*s"
 msgstr "不正常的长对象目录 %.*s"
 
-#: builtin/gc.c:179
+#: builtin/gc.c:261
 msgid "prune unreferenced objects"
 msgstr "清除未引用的对象"
 
-#: builtin/gc.c:181
+#: builtin/gc.c:263
 msgid "be more thorough (increased runtime)"
 msgstr "更彻底(增加运行时间)"
 
-#: builtin/gc.c:182
+#: builtin/gc.c:264
 msgid "enable auto-gc mode"
 msgstr "启用自动垃圾回收模式"
 
-#: builtin/gc.c:222
+#: builtin/gc.c:265
+msgid "force running gc even if there may be another gc running"
+msgstr "强制执行 gc 即使另外一个 gc 正在执行"
+
+#: builtin/gc.c:305
 #, c-format
 msgid ""
 "Auto packing the repository for optimum performance. You may also\n"
@@ -5169,41 +5350,49 @@
 "自动打包版本库以求最佳性能。您还可以手动运行 \"git gc\"。\n"
 "参见 \"git help gc\" 以获取更多信息。\n"
 
-#: builtin/gc.c:249
+#. be quiet on --auto
+#: builtin/gc.c:315
+#, c-format
+msgid ""
+"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
+msgstr ""
+"已经有一个 gc 正运行在机器 '%s' pid %<PRIuMAX> (如果不是,使用 --force)"
+
+#: builtin/gc.c:340
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr "有太多不可达的松散对象,运行 'git prune' 删除它们。"
 
-#: builtin/grep.c:22
+#: builtin/grep.c:23
 msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [选项] [-e] <模式> [<修订>...] [[--] <路径>...]"
 
-#: builtin/grep.c:217
+#: builtin/grep.c:218
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep:无法创建线程:%s"
 
-#: builtin/grep.c:364
+#: builtin/grep.c:365
 #, c-format
 msgid "Failed to chdir: %s"
 msgstr "无法切换目录:%s"
 
-#: builtin/grep.c:442 builtin/grep.c:477
+#: builtin/grep.c:443 builtin/grep.c:478
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "无法读取树(%s)"
 
-#: builtin/grep.c:492
+#: builtin/grep.c:493
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "无法抓取来自于 %s 类型的对象"
 
-#: builtin/grep.c:550
+#: builtin/grep.c:551
 #, c-format
 msgid "switch `%c' expects a numerical value"
 msgstr "开关 `%c' 期望一个数字值"
 
-#: builtin/grep.c:567
+#: builtin/grep.c:568
 #, c-format
 msgid "cannot open '%s'"
 msgstr "不能打开 '%s'"
@@ -5246,158 +5435,162 @@
 msgstr "不在二进制文件中匹配模式"
 
 #: builtin/grep.c:662
+msgid "process binary files with textconv filters"
+msgstr "用 textconv 过滤器处理二进制文件"
+
+#: builtin/grep.c:664
 msgid "descend at most <depth> levels"
 msgstr "最多以指定的深度向下寻找"
 
-#: builtin/grep.c:666
+#: builtin/grep.c:668
 msgid "use extended POSIX regular expressions"
 msgstr "使用扩展的 POSIX 正则表达式"
 
-#: builtin/grep.c:669
+#: builtin/grep.c:671
 msgid "use basic POSIX regular expressions (default)"
 msgstr "使用基本的 POSIX 正则表达式(默认)"
 
-#: builtin/grep.c:672
+#: builtin/grep.c:674
 msgid "interpret patterns as fixed strings"
 msgstr "把模式解析为固定的字符串"
 
-#: builtin/grep.c:675
+#: builtin/grep.c:677
 msgid "use Perl-compatible regular expressions"
 msgstr "使用 Perl 兼容的正则表达式"
 
-#: builtin/grep.c:678
+#: builtin/grep.c:680
 msgid "show line numbers"
 msgstr "显示行号"
 
-#: builtin/grep.c:679
+#: builtin/grep.c:681
 msgid "don't show filenames"
 msgstr "不显示文件名"
 
-#: builtin/grep.c:680
+#: builtin/grep.c:682
 msgid "show filenames"
 msgstr "显示文件名"
 
-#: builtin/grep.c:682
+#: builtin/grep.c:684
 msgid "show filenames relative to top directory"
 msgstr "显示相对于顶级目录的文件名"
 
-#: builtin/grep.c:684
+#: builtin/grep.c:686
 msgid "show only filenames instead of matching lines"
 msgstr "只显示文件名而不显示匹配的行"
 
-#: builtin/grep.c:686
+#: builtin/grep.c:688
 msgid "synonym for --files-with-matches"
 msgstr "和 --files-with-matches 同义"
 
-#: builtin/grep.c:689
+#: builtin/grep.c:691
 msgid "show only the names of files without match"
 msgstr "只显示未匹配的文件名"
 
-#: builtin/grep.c:691
+#: builtin/grep.c:693
 msgid "print NUL after filenames"
 msgstr "在文件名后输出 NUL 字符"
 
-#: builtin/grep.c:693
+#: builtin/grep.c:695
 msgid "show the number of matches instead of matching lines"
 msgstr "显示总匹配行数,而不显示匹配的行"
 
-#: builtin/grep.c:694
+#: builtin/grep.c:696
 msgid "highlight matches"
 msgstr "高亮显示匹配项"
 
-#: builtin/grep.c:696
+#: builtin/grep.c:698
 msgid "print empty line between matches from different files"
 msgstr "在不同文件的匹配项之间打印空行"
 
-#: builtin/grep.c:698
+#: builtin/grep.c:700
 msgid "show filename only once above matches from same file"
 msgstr "只在同一文件的匹配项的上面显示一次文件名"
 
-#: builtin/grep.c:701
+#: builtin/grep.c:703
 msgid "show <n> context lines before and after matches"
 msgstr "显示匹配项前后的 <n> 行上下文"
 
-#: builtin/grep.c:704
+#: builtin/grep.c:706
 msgid "show <n> context lines before matches"
 msgstr "显示匹配项前 <n> 行上下文"
 
-#: builtin/grep.c:706
+#: builtin/grep.c:708
 msgid "show <n> context lines after matches"
 msgstr "显示匹配项后 <n> 行上下文"
 
-#: builtin/grep.c:707
+#: builtin/grep.c:709
 msgid "shortcut for -C NUM"
 msgstr "快捷键 -C 数字"
 
-#: builtin/grep.c:710
+#: builtin/grep.c:712
 msgid "show a line with the function name before matches"
 msgstr "在匹配的前面显示一行函数名"
 
-#: builtin/grep.c:712
+#: builtin/grep.c:714
 msgid "show the surrounding function"
 msgstr "显示所在函数的前后内容"
 
-#: builtin/grep.c:715
+#: builtin/grep.c:717
 msgid "read patterns from file"
 msgstr "从文件读取模式"
 
-#: builtin/grep.c:717
+#: builtin/grep.c:719
 msgid "match <pattern>"
 msgstr "匹配 <模式>"
 
-#: builtin/grep.c:719
+#: builtin/grep.c:721
 msgid "combine patterns specified with -e"
 msgstr "组合用 -e 参数设定的模式"
 
-#: builtin/grep.c:731
+#: builtin/grep.c:733
 msgid "indicate hit with exit status without output"
 msgstr "不输出,而用退出码标识命中状态"
 
-#: builtin/grep.c:733
+#: builtin/grep.c:735
 msgid "show only matches from files that match all patterns"
 msgstr "只显示匹配所有模式的文件中的匹配"
 
-#: builtin/grep.c:735
+#: builtin/grep.c:737
 msgid "show parse tree for grep expression"
 msgstr "显示 grep 表达式的解析树"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "pager"
 msgstr "分页"
 
-#: builtin/grep.c:739
+#: builtin/grep.c:741
 msgid "show matching files in the pager"
 msgstr "分页显示匹配的文件"
 
-#: builtin/grep.c:742
+#: builtin/grep.c:744
 msgid "allow calling of grep(1) (ignored by this build)"
 msgstr "允许调用 grep(1)(本次构建忽略)"
 
-#: builtin/grep.c:743 builtin/show-ref.c:188
+#: builtin/grep.c:745 builtin/show-ref.c:187
 msgid "show usage"
 msgstr "显示用法"
 
-#: builtin/grep.c:810
+#: builtin/grep.c:812
 msgid "no pattern given."
 msgstr "未提供模式匹配。"
 
-#: builtin/grep.c:865
+#: builtin/grep.c:870
 msgid "--open-files-in-pager only works on the worktree"
 msgstr "--open-files-in-pager 仅用于工作区"
 
-#: builtin/grep.c:888
+#: builtin/grep.c:893
 msgid "--cached or --untracked cannot be used with --no-index."
 msgstr "--cached 或 --untracked 不能与 --no-index 同时使用。"
 
-#: builtin/grep.c:893
+#: builtin/grep.c:898
 msgid "--no-index or --untracked cannot be used with revs."
 msgstr "--no-index 或 --untracked 不能和版本同时使用。"
 
-#: builtin/grep.c:896
+#: builtin/grep.c:901
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
 msgstr "--[no-]exclude-standard 不能用于已跟踪内容。"
 
-#: builtin/grep.c:904
+#: builtin/grep.c:909
 msgid "both --cached and trees are given."
 msgstr "同时给出了 --cached 和树对象。"
 
@@ -5652,8 +5845,8 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "发现 %s 出现 SHA1 冲突!"
 
-#: builtin/index-pack.c:669 builtin/pack-objects.c:170
-#: builtin/pack-objects.c:262
+#: builtin/index-pack.c:669 builtin/pack-objects.c:171
+#: builtin/pack-objects.c:263
 #, c-format
 msgid "unable to read %s"
 msgstr "不能读 %s"
@@ -5682,155 +5875,155 @@
 msgid "Not all child objects of %s are reachable"
 msgstr "%s 的所有子对象并非都可达"
 
-#: builtin/index-pack.c:838 builtin/index-pack.c:868
+#: builtin/index-pack.c:839 builtin/index-pack.c:869
 msgid "failed to apply delta"
 msgstr "无法应用 delta"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Receiving objects"
 msgstr "接收对象中"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1010
 msgid "Indexing objects"
 msgstr "索引对象中"
 
-#: builtin/index-pack.c:1035
+#: builtin/index-pack.c:1036
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "包冲突(SHA1 不匹配)"
 
-#: builtin/index-pack.c:1040
+#: builtin/index-pack.c:1041
 msgid "cannot fstat packfile"
 msgstr "不能枚举包文件状态"
 
-#: builtin/index-pack.c:1043
+#: builtin/index-pack.c:1044
 msgid "pack has junk at the end"
 msgstr "包的结尾有垃圾数据"
 
-#: builtin/index-pack.c:1054
+#: builtin/index-pack.c:1055
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "parse_pack_objects() 中遇到不可理喻的问题"
 
-#: builtin/index-pack.c:1077
+#: builtin/index-pack.c:1078
 msgid "Resolving deltas"
 msgstr "处理 delta 中"
 
-#: builtin/index-pack.c:1087
+#: builtin/index-pack.c:1088
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "不能创建线程:%s"
 
-#: builtin/index-pack.c:1129
+#: builtin/index-pack.c:1130
 msgid "confusion beyond insanity"
 msgstr "不可理喻"
 
-#: builtin/index-pack.c:1137
+#: builtin/index-pack.c:1138
 #, c-format
 msgid "completed with %d local objects"
 msgstr "完成 %d 个本地对象"
 
-#: builtin/index-pack.c:1147
+#: builtin/index-pack.c:1148
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "对 %s 的尾部校验出现意外(磁盘损坏?)"
 
-#: builtin/index-pack.c:1151
+#: builtin/index-pack.c:1152
 #, 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:1176
+#: builtin/index-pack.c:1177
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "不能压缩附加对象(%d)"
 
-#: builtin/index-pack.c:1255
+#: builtin/index-pack.c:1256
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "本地对象 %s 已损坏"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1280
 msgid "error while closing pack file"
 msgstr "关闭包文件时出错"
 
-#: builtin/index-pack.c:1292
+#: builtin/index-pack.c:1293
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "无法写保留文件 '%s'"
 
-#: builtin/index-pack.c:1300
+#: builtin/index-pack.c:1301
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr "无法关闭保留文件 '%s'"
 
-#: builtin/index-pack.c:1313
+#: builtin/index-pack.c:1314
 msgid "cannot store pack file"
 msgstr "无法存储包文件"
 
-#: builtin/index-pack.c:1324
+#: builtin/index-pack.c:1325
 msgid "cannot store index file"
 msgstr "无法存储索引文件"
 
-#: builtin/index-pack.c:1357
+#: builtin/index-pack.c:1358
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "坏的 pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1363
+#: builtin/index-pack.c:1364
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "指定的线程数无效(%d)"
 
-#: builtin/index-pack.c:1367 builtin/index-pack.c:1545
+#: builtin/index-pack.c:1368 builtin/index-pack.c:1546
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "没有线程支持,忽略 %s"
 
-#: builtin/index-pack.c:1425
+#: builtin/index-pack.c:1426
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "无法打开现存包文件 '%s'"
 
-#: builtin/index-pack.c:1427
+#: builtin/index-pack.c:1428
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "无法为 %s 打开包索引文件"
 
-#: builtin/index-pack.c:1474
+#: builtin/index-pack.c:1475
 #, 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:1481
+#: builtin/index-pack.c:1482
 #, 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:1509
+#: builtin/index-pack.c:1510
 msgid "Cannot come back to cwd"
 msgstr "无法返回当前工作目录"
 
-#: builtin/index-pack.c:1557 builtin/index-pack.c:1560
-#: builtin/index-pack.c:1572 builtin/index-pack.c:1576
+#: builtin/index-pack.c:1558 builtin/index-pack.c:1561
+#: builtin/index-pack.c:1573 builtin/index-pack.c:1577
 #, c-format
 msgid "bad %s"
 msgstr "错误选项 %s"
 
-#: builtin/index-pack.c:1590
+#: builtin/index-pack.c:1591
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin 不能和 --stdin 同时使用"
 
-#: builtin/index-pack.c:1594 builtin/index-pack.c:1604
+#: builtin/index-pack.c:1595 builtin/index-pack.c:1605
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "包名 '%s' 没有以 '.pack' 结尾"
 
-#: builtin/index-pack.c:1613
+#: builtin/index-pack.c:1614
 msgid "--verify with no packfile name given"
 msgstr "--verify 没有提供包名参数"
 
@@ -5919,11 +6112,6 @@
 msgid "unable to move %s to %s"
 msgstr "不能移动 %s 至 %s"
 
-#: builtin/init-db.c:363
-#, c-format
-msgid "Could not create git link %s"
-msgstr "不能创建 git link %s"
-
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
 #. * existing" or "Initialized empty", the second " shared" or
@@ -5967,7 +6155,7 @@
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "指定 git 版本库是多个用户之间共享的"
 
-#: builtin/init-db.c:493 builtin/prune-packed.c:75
+#: builtin/init-db.c:493 builtin/prune-packed.c:75 builtin/repack.c:155
 msgid "be quiet"
 msgstr "保持安静"
 
@@ -6007,381 +6195,381 @@
 msgid "   or: git show [options] <object>..."
 msgstr "   或者:git show [选项] <对象>..."
 
-#: builtin/log.c:124
+#: builtin/log.c:125
 msgid "suppress diff output"
 msgstr "不显示差异输出"
 
-#: builtin/log.c:125
+#: builtin/log.c:126
 msgid "show source"
 msgstr "显示源"
 
-#: builtin/log.c:126
+#: builtin/log.c:127
 msgid "Use mail map file"
 msgstr "使用邮件映射文件"
 
-#: builtin/log.c:127
+#: builtin/log.c:128
 msgid "decorate options"
 msgstr "修饰选项"
 
-#: builtin/log.c:230
+#: builtin/log.c:231
 #, c-format
 msgid "Final output: %d %s\n"
 msgstr "最终输出:%d %s\n"
 
-#: builtin/log.c:453 builtin/log.c:545
+#: builtin/log.c:473 builtin/log.c:565
 #, c-format
 msgid "Could not read object %s"
 msgstr "不能读取对象 %s"
 
-#: builtin/log.c:569
+#: builtin/log.c:589
 #, c-format
 msgid "Unknown type: %d"
 msgstr "未知类型:%d"
 
-#: builtin/log.c:669
+#: builtin/log.c:689
 msgid "format.headers without value"
 msgstr "format.headers 没有值"
 
-#: builtin/log.c:751
+#: builtin/log.c:771
 msgid "name of output directory is too long"
 msgstr "输出目录名太长"
 
-#: builtin/log.c:767
+#: builtin/log.c:787
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "无法打开补丁文件 %s"
 
-#: builtin/log.c:781
+#: builtin/log.c:801
 msgid "Need exactly one range."
 msgstr "只需要一个范围。"
 
-#: builtin/log.c:789
+#: builtin/log.c:809
 msgid "Not a range."
 msgstr "不是一个范围。"
 
-#: builtin/log.c:891
+#: builtin/log.c:911
 msgid "Cover letter needs email format"
 msgstr "信封需要邮件地址格式"
 
-#: builtin/log.c:967
+#: builtin/log.c:987
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "不正常的 in-reply-to:%s"
 
-#: builtin/log.c:995
+#: builtin/log.c:1015
 msgid "git format-patch [options] [<since> | <revision range>]"
 msgstr "git format-patch [选项] [<从> | <修订集范围>]"
 
-#: builtin/log.c:1040
+#: builtin/log.c:1060
 msgid "Two output directories?"
 msgstr "两个输出目录?"
 
-#: builtin/log.c:1155
+#: builtin/log.c:1175
 msgid "use [PATCH n/m] even with a single patch"
 msgstr "使用 [PATCH n/m],即使只有一个补丁"
 
-#: builtin/log.c:1158
+#: builtin/log.c:1178
 msgid "use [PATCH] even with multiple patches"
 msgstr "使用 [PATCH],即使有多个补丁"
 
-#: builtin/log.c:1162
+#: builtin/log.c:1182
 msgid "print patches to standard out"
 msgstr "打印补丁到标准输出"
 
-#: builtin/log.c:1164
+#: builtin/log.c:1184
 msgid "generate a cover letter"
 msgstr "生成一封附信"
 
-#: builtin/log.c:1166
+#: builtin/log.c:1186
 msgid "use simple number sequence for output file names"
 msgstr "使用简单的数字序列作为输出文件名"
 
-#: builtin/log.c:1167
+#: builtin/log.c:1187
 msgid "sfx"
 msgstr "后缀"
 
-#: builtin/log.c:1168
+#: builtin/log.c:1188
 msgid "use <sfx> instead of '.patch'"
 msgstr "使用 <后缀> 代替 '.patch'"
 
-#: builtin/log.c:1170
+#: builtin/log.c:1190
 msgid "start numbering patches at <n> instead of 1"
 msgstr "补丁以 <n> 开始编号,而不是1"
 
-#: builtin/log.c:1172
+#: builtin/log.c:1192
 msgid "mark the series as Nth re-roll"
 msgstr "标记补丁系列是第几次重制"
 
-#: builtin/log.c:1174
+#: builtin/log.c:1194
 msgid "Use [<prefix>] instead of [PATCH]"
 msgstr "使用 [<前缀>] 代替 [PATCH]"
 
-#: builtin/log.c:1177
+#: builtin/log.c:1197
 msgid "store resulting files in <dir>"
 msgstr "把结果文件存储在 <dir>"
 
-#: builtin/log.c:1180
+#: builtin/log.c:1200
 msgid "don't strip/add [PATCH]"
 msgstr "不删除/添加 [PATCH]"
 
-#: builtin/log.c:1183
+#: builtin/log.c:1203
 msgid "don't output binary diffs"
 msgstr "不输出二进制差异"
 
-#: builtin/log.c:1185
+#: builtin/log.c:1205
 msgid "don't include a patch matching a commit upstream"
 msgstr "不包含已在上游提交中的补丁"
 
-#: builtin/log.c:1187
+#: builtin/log.c:1207
 msgid "show patch format instead of default (patch + stat)"
 msgstr "显示纯补丁格式而非默认的(补丁+状态)"
 
-#: builtin/log.c:1189
+#: builtin/log.c:1209
 msgid "Messaging"
 msgstr "邮件发送"
 
-#: builtin/log.c:1190
+#: builtin/log.c:1210
 msgid "header"
 msgstr "header"
 
-#: builtin/log.c:1191
+#: builtin/log.c:1211
 msgid "add email header"
 msgstr "添加邮件头"
 
-#: builtin/log.c:1192 builtin/log.c:1194
+#: builtin/log.c:1212 builtin/log.c:1214
 msgid "email"
 msgstr "邮件地址"
 
-#: builtin/log.c:1192
+#: builtin/log.c:1212
 msgid "add To: header"
 msgstr "添加收件人"
 
-#: builtin/log.c:1194
+#: builtin/log.c:1214
 msgid "add Cc: header"
 msgstr "添加抄送"
 
-#: builtin/log.c:1196
+#: builtin/log.c:1216
 msgid "ident"
 msgstr "ident"
 
-#: builtin/log.c:1197
+#: builtin/log.c:1217
 msgid "set From address to <ident> (or committer ident if absent)"
 msgstr "设置 From 地址为 <ident>(如若不提供,用提交者ID做为地址)"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1219
 msgid "message-id"
 msgstr "message-id"
 
-#: builtin/log.c:1200
+#: builtin/log.c:1220
 msgid "make first mail a reply to <message-id>"
 msgstr "使第一封邮件作为对 <message-id> 的回复"
 
-#: builtin/log.c:1201 builtin/log.c:1204
+#: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
 msgstr "边界"
 
-#: builtin/log.c:1202
+#: builtin/log.c:1222
 msgid "attach the patch"
 msgstr "附件方式添加补丁"
 
-#: builtin/log.c:1205
+#: builtin/log.c:1225
 msgid "inline the patch"
 msgstr "内联显示补丁"
 
-#: builtin/log.c:1209
+#: builtin/log.c:1229
 msgid "enable message threading, styles: shallow, deep"
 msgstr "启用邮件线索,风格:浅,深"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1231
 msgid "signature"
 msgstr "签名"
 
-#: builtin/log.c:1212
+#: builtin/log.c:1232
 msgid "add a signature"
 msgstr "添加一个签名"
 
-#: builtin/log.c:1214
+#: builtin/log.c:1233
 msgid "don't print the patch filenames"
 msgstr "不要打印补丁文件名"
 
-#: builtin/log.c:1288
+#: builtin/log.c:1307
 #, c-format
 msgid "invalid ident line: %s"
 msgstr "包含无效的身份标识:%s"
 
-#: builtin/log.c:1303
+#: builtin/log.c:1322
 msgid "-n and -k are mutually exclusive."
 msgstr "-n 和 -k 互斥。"
 
-#: builtin/log.c:1305
+#: builtin/log.c:1324
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "--subject-prefix 和 -k 互斥。"
 
-#: builtin/log.c:1313
+#: builtin/log.c:1332
 msgid "--name-only does not make sense"
 msgstr "--name-only 无意义"
 
-#: builtin/log.c:1315
+#: builtin/log.c:1334
 msgid "--name-status does not make sense"
 msgstr "--name-status 无意义"
 
-#: builtin/log.c:1317
+#: builtin/log.c:1336
 msgid "--check does not make sense"
 msgstr "--check 无意义"
 
-#: builtin/log.c:1340
+#: builtin/log.c:1359
 msgid "standard output, or directory, which one?"
 msgstr "标准输出或目录,哪一个?"
 
-#: builtin/log.c:1342
+#: builtin/log.c:1361
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "不能创建目录 '%s'"
 
-#: builtin/log.c:1490
+#: builtin/log.c:1509
 msgid "Failed to create output files"
 msgstr "无法创建输出文件"
 
-#: builtin/log.c:1539
+#: builtin/log.c:1558
 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
 msgstr "git cherry [-v] [<上游> [<头> [<限制>]]]"
 
-#: builtin/log.c:1594
+#: builtin/log.c:1613
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr "不能找到跟踪的远程分支,请手工指定 <upstream>。\n"
 
-#: builtin/log.c:1607 builtin/log.c:1609 builtin/log.c:1621
+#: builtin/log.c:1626 builtin/log.c:1628 builtin/log.c:1640
 #, c-format
 msgid "Unknown commit %s"
 msgstr "未知提交 %s"
 
-#: builtin/ls-files.c:408
+#: builtin/ls-files.c:398
 msgid "git ls-files [options] [<file>...]"
 msgstr "git ls-files [选项] [<文件>...]"
 
-#: builtin/ls-files.c:465
+#: builtin/ls-files.c:455
 msgid "identify the file status with tags"
 msgstr "用标签标识文件的状态"
 
-#: builtin/ls-files.c:467
+#: builtin/ls-files.c:457
 msgid "use lowercase letters for 'assume unchanged' files"
 msgstr "使用小写字母表示 '假设未改变的' 文件"
 
-#: builtin/ls-files.c:469
+#: builtin/ls-files.c:459
 msgid "show cached files in the output (default)"
 msgstr "显示缓存的文件(默认)"
 
-#: builtin/ls-files.c:471
+#: builtin/ls-files.c:461
 msgid "show deleted files in the output"
 msgstr "显示已删除的文件"
 
-#: builtin/ls-files.c:473
+#: builtin/ls-files.c:463
 msgid "show modified files in the output"
 msgstr "显示已修改的文件"
 
-#: builtin/ls-files.c:475
+#: builtin/ls-files.c:465
 msgid "show other files in the output"
 msgstr "显示其它文件"
 
-#: builtin/ls-files.c:477
+#: builtin/ls-files.c:467
 msgid "show ignored files in the output"
 msgstr "显示忽略的文件"
 
-#: builtin/ls-files.c:480
+#: builtin/ls-files.c:470
 msgid "show staged contents' object name in the output"
 msgstr "显示暂存区内容的对象名称"
 
-#: builtin/ls-files.c:482
+#: builtin/ls-files.c:472
 msgid "show files on the filesystem that need to be removed"
 msgstr "显示文件系统需要删除的文件"
 
-#: builtin/ls-files.c:484
+#: builtin/ls-files.c:474
 msgid "show 'other' directories' name only"
 msgstr "只显示“其他”目录的名称"
 
-#: builtin/ls-files.c:487
+#: builtin/ls-files.c:477
 msgid "don't show empty directories"
 msgstr "不显示空目录"
 
-#: builtin/ls-files.c:490
+#: builtin/ls-files.c:480
 msgid "show unmerged files in the output"
 msgstr "显示未合并的文件"
 
-#: builtin/ls-files.c:492
+#: builtin/ls-files.c:482
 msgid "show resolve-undo information"
 msgstr "显示 resolve-undo 信息"
 
-#: builtin/ls-files.c:494
+#: builtin/ls-files.c:484
 msgid "skip files matching pattern"
 msgstr "匹配排除文件的模式"
 
-#: builtin/ls-files.c:497
+#: builtin/ls-files.c:487
 msgid "exclude patterns are read from <file>"
 msgstr "从 <文件> 中读取排除模式"
 
-#: builtin/ls-files.c:500
+#: builtin/ls-files.c:490
 msgid "read additional per-directory exclude patterns in <file>"
 msgstr "从 <文件> 读取额外的每个目录的排除模式"
 
-#: builtin/ls-files.c:502
+#: builtin/ls-files.c:492
 msgid "add the standard git exclusions"
 msgstr "添加标准的 git 排除"
 
-#: builtin/ls-files.c:505
+#: builtin/ls-files.c:495
 msgid "make the output relative to the project top directory"
 msgstr "显示相对于顶级目录的文件名"
 
-#: builtin/ls-files.c:508
+#: builtin/ls-files.c:498
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr "如果任何 <文件> 都不在索引区,视为错误"
 
-#: builtin/ls-files.c:509
+#: builtin/ls-files.c:499
 msgid "tree-ish"
 msgstr "树或提交"
 
-#: builtin/ls-files.c:510
+#: builtin/ls-files.c:500
 msgid "pretend that paths removed since <tree-ish> are still present"
 msgstr "假装自从 <树或提交> 之后删除的路径仍然存在"
 
-#: builtin/ls-files.c:512
+#: builtin/ls-files.c:502
 msgid "show debugging data"
 msgstr "显示调试数据"
 
-#: builtin/ls-tree.c:27
+#: builtin/ls-tree.c:28
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<选项>] <树或提交> [<路径>...]"
 
-#: builtin/ls-tree.c:125
+#: builtin/ls-tree.c:126
 msgid "only show trees"
 msgstr "只显示树"
 
-#: builtin/ls-tree.c:127
+#: builtin/ls-tree.c:128
 msgid "recurse into subtrees"
 msgstr "递归到子树"
 
-#: builtin/ls-tree.c:129
+#: builtin/ls-tree.c:130
 msgid "show trees when recursing"
 msgstr "当递归时显示树"
 
-#: builtin/ls-tree.c:132
+#: builtin/ls-tree.c:133
 msgid "terminate entries with NUL byte"
 msgstr "条目以NUL字符终止"
 
-#: builtin/ls-tree.c:133
+#: builtin/ls-tree.c:134
 msgid "include object size"
 msgstr "包括对象大小"
 
-#: builtin/ls-tree.c:135 builtin/ls-tree.c:137
+#: builtin/ls-tree.c:136 builtin/ls-tree.c:138
 msgid "list only filenames"
 msgstr "只列出文件名"
 
-#: builtin/ls-tree.c:140
+#: builtin/ls-tree.c:141
 msgid "use full path names"
 msgstr "使用文件的全路径"
 
-#: builtin/ls-tree.c:142
+#: builtin/ls-tree.c:143
 msgid "list entire tree; not just current directory (implies --full-name)"
 msgstr "列出整个树;不仅仅当前目录(隐含 --full-name)"
 
@@ -6456,7 +6644,7 @@
 msgid "Verify that the named commit has a valid GPG signature"
 msgstr "验证指定的提交是否包含一个有效的 GPG 签名"
 
-#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:114
+#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:89
 msgid "strategy"
 msgstr "策略"
 
@@ -6818,76 +7006,85 @@
 msgid "allow creation of more than one tree"
 msgstr "允许创建一个以上的树"
 
-#: builtin/mv.c:14
+#: builtin/mv.c:15
 msgid "git mv [options] <source>... <destination>"
 msgstr "git mv [选项] <源>... <目标>"
 
-#: builtin/mv.c:64
+#: builtin/mv.c:67
 msgid "force move/rename even if target exists"
 msgstr "强制移动/重命令,即使目标存在"
 
-#: builtin/mv.c:65
+#: builtin/mv.c:68
 msgid "skip move/rename errors"
 msgstr "跳过移动/重命名错误"
 
-#: builtin/mv.c:108
+#: builtin/mv.c:113
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
 msgstr "检查 '%s' 到 '%s' 的重命名\n"
 
-#: builtin/mv.c:112
+#: builtin/mv.c:117
 msgid "bad source"
 msgstr "坏的源"
 
-#: builtin/mv.c:115
+#: builtin/mv.c:120
 msgid "can not move directory into itself"
 msgstr "不能将目录移动到自身"
 
-#: builtin/mv.c:118
+#: builtin/mv.c:123
 msgid "cannot move directory over file"
 msgstr "不能将目录移动到文件"
 
-#: builtin/mv.c:128
+#: builtin/mv.c:129
+#, c-format
+msgid "Huh? Directory %s is in index and no submodule?"
+msgstr "嗯?目录 %s 在索引中并且不是子模组?"
+
+#: builtin/mv.c:131 builtin/rm.c:318
+msgid "Please, stage your changes to .gitmodules or stash them to proceed"
+msgstr "请将您的修改缓存到 .gitmodules 中或保存进度后再继续"
+
+#: builtin/mv.c:147
 #, c-format
 msgid "Huh? %.*s is in index?"
 msgstr "嗯?%.*s 在索引中?"
 
-#: builtin/mv.c:140
+#: builtin/mv.c:159
 msgid "source directory is empty"
 msgstr "源目录为空"
 
-#: builtin/mv.c:171
+#: builtin/mv.c:191
 msgid "not under version control"
 msgstr "不在版本控制之下"
 
-#: builtin/mv.c:173
+#: builtin/mv.c:193
 msgid "destination exists"
 msgstr "目标已存在"
 
-#: builtin/mv.c:181
+#: builtin/mv.c:201
 #, c-format
 msgid "overwriting '%s'"
 msgstr "覆盖 '%s'"
 
-#: builtin/mv.c:184
+#: builtin/mv.c:204
 msgid "Cannot overwrite"
 msgstr "不能覆盖"
 
-#: builtin/mv.c:187
+#: builtin/mv.c:207
 msgid "multiple sources for the same target"
 msgstr "同一目标具有多个源"
 
-#: builtin/mv.c:202
+#: builtin/mv.c:222
 #, c-format
 msgid "%s, source=%s, destination=%s"
 msgstr "%s,源=%s,目标=%s"
 
-#: builtin/mv.c:212
+#: builtin/mv.c:232
 #, c-format
 msgid "Renaming %s to %s\n"
 msgstr "重命名 %s 至 %s\n"
 
-#: builtin/mv.c:215 builtin/remote.c:731
+#: builtin/mv.c:235 builtin/remote.c:731 builtin/repack.c:330
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "重命名 '%s' 失败"
@@ -6925,8 +7122,8 @@
 msgstr "从标准输入读取"
 
 #: builtin/name-rev.c:320
-msgid "allow to print `undefined` names"
-msgstr "允许打印 `未定义` 的名称"
+msgid "allow to print `undefined` names (default)"
+msgstr "允许打印 `未定义` 的名称(默认)"
 
 #: builtin/name-rev.c:326
 msgid "dereference tags in the input (internal use)"
@@ -7078,12 +7275,12 @@
 msgid "The note contents has been left in %s"
 msgstr "注解内容被留在文件 %s 中"
 
-#: builtin/notes.c:248 builtin/tag.c:540
+#: builtin/notes.c:248 builtin/tag.c:537
 #, c-format
 msgid "cannot read '%s'"
 msgstr "不能读取 '%s'"
 
-#: builtin/notes.c:250 builtin/tag.c:543
+#: builtin/notes.c:250 builtin/tag.c:540
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "不能打开或读取 '%s'"
@@ -7091,7 +7288,7 @@
 #: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318
 #: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515
 #: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637
-#: builtin/notes.c:839 builtin/tag.c:556
+#: builtin/notes.c:839 builtin/tag.c:553
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "无法解析 '%s' 为一个有效引用。"
@@ -7256,148 +7453,148 @@
 msgid "git pack-objects [options...] base-name [< ref-list | < object-list]"
 msgstr "git pack-objects [选项...] base-name [< 引用列表 | < 对象列表]"
 
-#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#: builtin/pack-objects.c:184 builtin/pack-objects.c:187
 #, c-format
 msgid "deflate error (%d)"
 msgstr "压缩错误 (%d)"
 
-#: builtin/pack-objects.c:2397
+#: builtin/pack-objects.c:2398
 #, c-format
 msgid "unsupported index version %s"
 msgstr "不支持的索引版本 %s"
 
-#: builtin/pack-objects.c:2401
+#: builtin/pack-objects.c:2402
 #, c-format
 msgid "bad index version '%s'"
 msgstr "坏的索引版本 '%s'"
 
-#: builtin/pack-objects.c:2424
+#: builtin/pack-objects.c:2425
 #, c-format
 msgid "option %s does not accept negative form"
 msgstr "选项 %s 不接受否定格式"
 
-#: builtin/pack-objects.c:2428
+#: builtin/pack-objects.c:2429
 #, c-format
 msgid "unable to parse value '%s' for option %s"
 msgstr "不能解析选项 %1$s 的值 '%2$s'"
 
-#: builtin/pack-objects.c:2447
+#: builtin/pack-objects.c:2448
 msgid "do not show progress meter"
 msgstr "不显示进度表"
 
-#: builtin/pack-objects.c:2449
+#: builtin/pack-objects.c:2450
 msgid "show progress meter"
 msgstr "显示进度表"
 
-#: builtin/pack-objects.c:2451
+#: builtin/pack-objects.c:2452
 msgid "show progress meter during object writing phase"
 msgstr "在对象写入阶段显示进度表"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:2455
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "当进度表显示时类似于 --all-progress"
 
-#: builtin/pack-objects.c:2455
+#: builtin/pack-objects.c:2456
 msgid "version[,offset]"
 msgstr "版本[,偏移]"
 
-#: builtin/pack-objects.c:2456
+#: builtin/pack-objects.c:2457
 msgid "write the pack index file in the specified idx format version"
 msgstr "用指定的 idx 格式版本来写包索引文件"
 
-#: builtin/pack-objects.c:2459
+#: builtin/pack-objects.c:2460
 msgid "maximum size of each output pack file"
 msgstr "每个输出包的最大尺寸"
 
-#: builtin/pack-objects.c:2461
+#: builtin/pack-objects.c:2462
 msgid "ignore borrowed objects from alternate object store"
 msgstr "忽略从替代对象存储里借用对象"
 
-#: builtin/pack-objects.c:2463
+#: builtin/pack-objects.c:2464
 msgid "ignore packed objects"
 msgstr "忽略包对象"
 
-#: builtin/pack-objects.c:2465
+#: builtin/pack-objects.c:2466
 msgid "limit pack window by objects"
 msgstr "限制打包窗口的对象数"
 
-#: builtin/pack-objects.c:2467
+#: builtin/pack-objects.c:2468
 msgid "limit pack window by memory in addition to object limit"
 msgstr "除对象数量限制外设置打包窗口的内存限制"
 
-#: builtin/pack-objects.c:2469
+#: builtin/pack-objects.c:2470
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr "打包允许的 delta 链的最大长度"
 
-#: builtin/pack-objects.c:2471
+#: builtin/pack-objects.c:2472
 msgid "reuse existing deltas"
 msgstr "重用已存在的 deltas"
 
-#: builtin/pack-objects.c:2473
+#: builtin/pack-objects.c:2474
 msgid "reuse existing objects"
 msgstr "重用已存在的对象"
 
-#: builtin/pack-objects.c:2475
+#: builtin/pack-objects.c:2476
 msgid "use OFS_DELTA objects"
 msgstr "使用 OFS_DELTA 对象"
 
-#: builtin/pack-objects.c:2477
+#: builtin/pack-objects.c:2478
 msgid "use threads when searching for best delta matches"
 msgstr "使用线程查询最佳 delta 匹配"
 
-#: builtin/pack-objects.c:2479
+#: builtin/pack-objects.c:2480
 msgid "do not create an empty pack output"
 msgstr "不创建空的包输出"
 
-#: builtin/pack-objects.c:2481
+#: builtin/pack-objects.c:2482
 msgid "read revision arguments from standard input"
 msgstr "从标准输入读取修订号参数"
 
-#: builtin/pack-objects.c:2483
+#: builtin/pack-objects.c:2484
 msgid "limit the objects to those that are not yet packed"
 msgstr "限制那些尚未打包的对象"
 
-#: builtin/pack-objects.c:2486
+#: builtin/pack-objects.c:2487
 msgid "include objects reachable from any reference"
 msgstr "包括可以从任何引用访问到的对象"
 
-#: builtin/pack-objects.c:2489
+#: builtin/pack-objects.c:2490
 msgid "include objects referred by reflog entries"
 msgstr "包括被引用日志引用到的对象"
 
-#: builtin/pack-objects.c:2492
+#: builtin/pack-objects.c:2493
 msgid "output pack to stdout"
 msgstr "输出包到标准输出"
 
-#: builtin/pack-objects.c:2494
+#: builtin/pack-objects.c:2495
 msgid "include tag objects that refer to objects to be packed"
 msgstr "包括引用了打包对象的 tag"
 
-#: builtin/pack-objects.c:2496
+#: builtin/pack-objects.c:2497
 msgid "keep unreachable objects"
 msgstr "维持不可达的对象"
 
-#: builtin/pack-objects.c:2497 parse-options.h:141
+#: builtin/pack-objects.c:2498 parse-options.h:143
 msgid "time"
 msgstr "时间"
 
-#: builtin/pack-objects.c:2498
+#: builtin/pack-objects.c:2499
 msgid "unpack unreachable objects newer than <time>"
 msgstr "将比给定 <时间> 新的无法访问的对象解包"
 
-#: builtin/pack-objects.c:2501
+#: builtin/pack-objects.c:2502
 msgid "create thin packs"
 msgstr "创建精简包"
 
-#: builtin/pack-objects.c:2503
+#: builtin/pack-objects.c:2504
 msgid "ignore packs that have companion .keep file"
 msgstr "忽略配有 .keep 文件的包"
 
-#: builtin/pack-objects.c:2505
+#: builtin/pack-objects.c:2506
 msgid "pack compression level"
 msgstr "打包压缩级别"
 
-#: builtin/pack-objects.c:2507
+#: builtin/pack-objects.c:2508
 msgid "do not hide commits by grafts"
 msgstr "不隐藏移植覆盖的提交"
 
@@ -7435,17 +7632,17 @@
 
 #: builtin/push.c:14
 msgid "git push [<options>] [<repository> [<refspec>...]]"
-msgstr "git push [<选项>] [<版本库> [<引用表达式>...]]"
+msgstr "git push [<选项>] [<版本库> [<引用规则>...]]"
 
-#: builtin/push.c:45
+#: builtin/push.c:47
 msgid "tag shorthand without <tag>"
 msgstr "tag 简写没有跟 <tag> 参数"
 
-#: builtin/push.c:64
+#: builtin/push.c:66
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete 只接受简单的目标引用名"
 
-#: builtin/push.c:99
+#: builtin/push.c:101
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -7453,7 +7650,7 @@
 "\n"
 "为了永久地选择任一选项,参见 'git help config' 中的 push.default。"
 
-#: builtin/push.c:102
+#: builtin/push.c:104
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -7477,7 +7674,7 @@
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:117
+#: builtin/push.c:119
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -7491,7 +7688,7 @@
 "\n"
 "    git push %s HEAD:<name-of-remote-branch>\n"
 
-#: builtin/push.c:131
+#: builtin/push.c:133
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -7504,12 +7701,12 @@
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:139
+#: builtin/push.c:141
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "当前分支 %s 有多个上游分支,拒绝推送。"
 
-#: builtin/push.c:142
+#: builtin/push.c:144
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -7520,7 +7717,7 @@
 "而没有告诉我要推送什么、更新哪个远程分支。"
 
 #  译者:字符串首行行首要添加“warning: ”字串,故此首行要较其余行短
-#: builtin/push.c:165
+#: builtin/push.c:167
 msgid ""
 "push.default is unset; its implicit value is changing in\n"
 "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -7537,9 +7734,8 @@
 "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n"
 "'current' instead of 'simple' if you sometimes use older versions of Git)"
 msgstr ""
-"push.default 未设置,它的默认值将会在 Git 2.0 由 'matching'\n"
-"修改为 'simple'。若要不再显示本信息并在其默认值改变后维持当前使用习惯,\n"
-"进行如下设置:\n"
+"push.default 未设置,它的默认值将在 Git 2.0 由 'matching'\n"
+"改变为 'simple'。若要不再显示本信息并保持传统习惯,进行如下设置:\n"
 "\n"
 "  git config --global push.default matching\n"
 "\n"
@@ -7549,14 +7745,14 @@
 "\n"
 "参见 'git help config' 并查找 'push.default' 以获取更多信息。\n"
 "('simple' 模式由 Git 1.7.11 版本引入。如果您有时要使用老版本的 Git,\n"
-"为保持兼容,请用 'current' 代替 'simple' 模式)"
+"为保持兼容,请用 'current' 代替 'simple')"
 
-#: builtin/push.c:225
+#: builtin/push.c:227
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
-msgstr "您没有为推送指定任何引用表达式,并且 push.default 为 \"nothing\"。"
+msgstr "您没有为推送指定任何引用规则,并且 push.default 为 \"nothing\"。"
 
-#: builtin/push.c:232
+#: builtin/push.c:234
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -7567,7 +7763,7 @@
 "再次推送前,先与远程变更合并(如 'git pull ...')。详见\n"
 "'git push --help' 中的 'Note about fast-forwards' 小节。"
 
-#: builtin/push.c:238
+#: builtin/push.c:240
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. If you did not intend to push that branch, you may want to\n"
@@ -7579,7 +7775,7 @@
 "配置变量 'push.default' 设置为 'simple'、'current' 或 'upstream'\n"
 "以便只推送当前分支。"
 
-#: builtin/push.c:244
+#: builtin/push.c:246
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. Check out this branch and integrate the remote changes\n"
@@ -7590,7 +7786,7 @@
 "检出该分支并整合远程变更(如 'git pull ...'),然后再推送。详见\n"
 "'git push --help' 中的 'Note about fast-forwards' 小节。"
 
-#: builtin/push.c:250
+#: builtin/push.c:252
 msgid ""
 "Updates were rejected because the remote contains work that you do\n"
 "not have locally. This is usually caused by another repository pushing\n"
@@ -7603,11 +7799,11 @@
 "(如 'git pull ...')。\n"
 "详见 'git push --help' 中的 'Note about fast-forwards' 小节。"
 
-#: builtin/push.c:257
+#: builtin/push.c:259
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr "更新被拒绝因为 tag 在远程已经存在。"
 
-#: builtin/push.c:260
+#: builtin/push.c:262
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -7616,22 +7812,22 @@
 "如果不使用 '--force' 参数,您不能更新一个指向非提交对象的远程引用,\n"
 "也不能更新远程引用让其指向一个非提交对象。\n"
 
-#: builtin/push.c:320
+#: builtin/push.c:328
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "推送到 %s\n"
 
-#: builtin/push.c:324
+#: builtin/push.c:332
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "无法推送一些引用到 '%s'"
 
-#: builtin/push.c:357
+#: builtin/push.c:365
 #, c-format
 msgid "bad repository '%s'"
 msgstr "坏的版本库 '%s'"
 
-#: builtin/push.c:358
+#: builtin/push.c:366
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -7652,87 +7848,95 @@
 "\n"
 "    git push <name>\n"
 
-#: builtin/push.c:373
+#: builtin/push.c:381
 msgid "--all and --tags are incompatible"
 msgstr "--all 和 --tags 不兼容"
 
-#: builtin/push.c:374
+#: builtin/push.c:382
 msgid "--all can't be combined with refspecs"
-msgstr "--all 不能和引用表达式同时使用"
+msgstr "--all 不能和引用规则同时使用"
 
-#: builtin/push.c:379
+#: builtin/push.c:387
 msgid "--mirror and --tags are incompatible"
 msgstr "--mirror 和 --tags 不兼容"
 
-#: builtin/push.c:380
+#: builtin/push.c:388
 msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror 不能和引用表达式同时使用"
+msgstr "--mirror 不能和引用规则同时使用"
 
-#: builtin/push.c:385
+#: builtin/push.c:393
 msgid "--all and --mirror are incompatible"
 msgstr "--all 和 --mirror 不兼容"
 
-#: builtin/push.c:445
+#: builtin/push.c:453
 msgid "repository"
 msgstr "版本库"
 
-#: builtin/push.c:446
+#: builtin/push.c:454
 msgid "push all refs"
 msgstr "推送所有引用"
 
-#: builtin/push.c:447
+#: builtin/push.c:455
 msgid "mirror all refs"
 msgstr "镜像所有引用"
 
-#: builtin/push.c:449
+#: builtin/push.c:457
 msgid "delete refs"
 msgstr "删除引用"
 
-#: builtin/push.c:450
+#: builtin/push.c:458
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "推送 tags(不能使用 --all or --mirror)"
 
-#: builtin/push.c:453
+#: builtin/push.c:461
 msgid "force updates"
 msgstr "强制更新"
 
-#: builtin/push.c:454
+#: builtin/push.c:463
+msgid "refname>:<expect"
+msgstr "引用名>:<期望值"
+
+#: builtin/push.c:464
+msgid "require old value of ref to be at this value"
+msgstr "要求引用旧的取值为设定值"
+
+#: builtin/push.c:466
 msgid "check"
 msgstr "检查"
 
-#: builtin/push.c:455
+#: builtin/push.c:467
 msgid "control recursive pushing of submodules"
 msgstr "控制子模组的递归推送"
 
-#: builtin/push.c:457
+#: builtin/push.c:469
 msgid "use thin pack"
 msgstr "使用精简打包"
 
-#: builtin/push.c:458 builtin/push.c:459
+#: builtin/push.c:470 builtin/push.c:471
 msgid "receive pack program"
 msgstr "接收包程序"
 
-#: builtin/push.c:460
+#: builtin/push.c:472
 msgid "set upstream for git pull/status"
 msgstr "设置 git pull/status 的上游"
 
-#: builtin/push.c:463
+#: builtin/push.c:475
 msgid "prune locally removed refs"
 msgstr "清除本地删除的引用"
 
-#: builtin/push.c:465
+#: builtin/push.c:477
 msgid "bypass pre-push hook"
 msgstr "绕过 pre-push 钩子"
 
-#: builtin/push.c:466
+#: builtin/push.c:478
 msgid "push missing but relevant tags"
 msgstr "推送缺失的有关的 tags"
 
-#: builtin/push.c:476
+#: builtin/push.c:488
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete 与 --all、--mirror 及 --tags 不兼容"
 
-#: builtin/push.c:478
+#: builtin/push.c:490
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete 未接任何引用没有意义"
 
@@ -7810,12 +8014,12 @@
 msgid "debug unpack-trees"
 msgstr "调试 unpack-trees"
 
-#: builtin/reflog.c:500
+#: builtin/reflog.c:499
 #, c-format
 msgid "%s' for '%s' is not a valid timestamp"
 msgstr "'%2$s' 的值 '%1$s' 不是一个有效的时间戳"
 
-#: builtin/reflog.c:616 builtin/reflog.c:621
+#: builtin/reflog.c:615 builtin/reflog.c:620
 #, c-format
 msgid "'%s' is not a valid timestamp"
 msgstr "'%s' 不是一个有效的时间戳"
@@ -7840,9 +8044,9 @@
 msgid "git remote remove <name>"
 msgstr "git remote remove <名称>"
 
-#: builtin/remote.c:15 builtin/remote.c:42
-msgid "git remote set-head <name> (-a | -d | <branch>)"
-msgstr "git remote set-head <名称> (-a | -d | <分支>)"
+#: builtin/remote.c:15
+msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"
+msgstr "git remote set-head <名称> (-a | --auto | -d | --delete |<分支>)"
 
 #: builtin/remote.c:16
 msgid "git remote [-v | --verbose] show [-n] <name>"
@@ -7877,6 +8081,10 @@
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<选项>] <名称> <地址>"
 
+#: builtin/remote.c:42
+msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
+msgstr "git remote set-head <名称> (-a | --auto | -d | --delete | <分支>)"
+
 #: builtin/remote.c:47
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <名称> <分支>..."
@@ -7974,7 +8182,7 @@
 #: builtin/remote.c:339
 #, c-format
 msgid "Could not get fetch map for refspec %s"
-msgstr "无法得到引用表达式 %s 的获取列表"
+msgstr "无法得到引用规则 %s 的获取列表"
 
 #: builtin/remote.c:440 builtin/remote.c:448
 msgid "(matching)"
@@ -8011,7 +8219,7 @@
 "\t%s\n"
 "\tPlease update the configuration manually if necessary."
 msgstr ""
-"没有更新非默认的获取引用表达式\n"
+"没有更新非默认的获取引用规则\n"
 "\t%s\n"
 "\t如果必要请手动更新配置。"
 
@@ -8312,6 +8520,67 @@
 msgid "be verbose; must be placed before a subcommand"
 msgstr "冗长输出;必须置于子命令之前"
 
+#: builtin/repack.c:15
+msgid "git repack [options]"
+msgstr "git repack [选项]"
+
+#: builtin/repack.c:143
+msgid "pack everything in a single pack"
+msgstr "所有内容打包到一个包文件中"
+
+#: builtin/repack.c:145
+msgid "same as -a, and turn unreachable objects loose"
+msgstr "和 -a 相同,并将不可达的对象设为松散对象"
+
+#: builtin/repack.c:148
+msgid "remove redundant packs, and run git-prune-packed"
+msgstr "删除多余的包,运行 git-prune-packed"
+
+#: builtin/repack.c:150
+msgid "pass --no-reuse-delta to git-pack-objects"
+msgstr "向 git-pack-objects 传递参数 --no-reuse-delta"
+
+#: builtin/repack.c:152
+msgid "pass --no-reuse-object to git-pack-objects"
+msgstr "向 git-pack-objects 传递参数 --no-reuse-object"
+
+#: builtin/repack.c:154
+msgid "do not run git-update-server-info"
+msgstr "不运行 git-update-server-info"
+
+#: builtin/repack.c:157
+msgid "pass --local to git-pack-objects"
+msgstr "向 git-pack-objects 传递参数 --local"
+
+#: builtin/repack.c:158
+msgid "approxidate"
+msgstr "近似日期"
+
+#: builtin/repack.c:159
+msgid "with -A, do not loosen objects older than this"
+msgstr "使用 -A,不要将早于给定时间的对象过期"
+
+#: builtin/repack.c:161
+msgid "size of the window used for delta compression"
+msgstr "用于增量压缩的窗口值"
+
+#: builtin/repack.c:163
+msgid "same as the above, but limit memory size instead of entries count"
+msgstr "和上面的相似,但限制内存大小而非条目数"
+
+#: builtin/repack.c:165
+msgid "limits the maximum delta depth"
+msgstr "限制最大增量深度"
+
+#: builtin/repack.c:167
+msgid "maximum size of each packfile"
+msgstr "每个包的最大尺寸"
+
+#: builtin/repack.c:345
+#, c-format
+msgid "removing '%s' failed"
+msgstr "删除 '%s' 失败"
+
 #: builtin/replace.c:17
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <对象> <替换物>"
@@ -8324,23 +8593,23 @@
 msgid "git replace -l [<pattern>]"
 msgstr "git replace -l [<模式>]"
 
-#: builtin/replace.c:121
+#: builtin/replace.c:131
 msgid "list replace refs"
 msgstr "列出替换的引用"
 
-#: builtin/replace.c:122
+#: builtin/replace.c:132
 msgid "delete replace refs"
 msgstr "删除替换的引用"
 
-#: builtin/replace.c:123
+#: builtin/replace.c:133
 msgid "replace the ref if it exists"
 msgstr "如果存在则替换引用"
 
-#: builtin/rerere.c:11
+#: builtin/rerere.c:12
 msgid "git rerere [clear | forget path... | status | remaining | diff | gc]"
 msgstr "git rerere [clear | forget path... | status | remaining | diff | gc]"
 
-#: builtin/rerere.c:56
+#: builtin/rerere.c:57
 msgid "register clean resolutions in index"
 msgstr "在索引中注册干净的解决方案"
 
@@ -8401,71 +8670,71 @@
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr "在合并过程中不能做%s重置操作。"
 
-#: builtin/reset.c:251
+#: builtin/reset.c:262
 msgid "be quiet, only report errors"
 msgstr "安静模式,只报告错误"
 
-#: builtin/reset.c:253
+#: builtin/reset.c:264
 msgid "reset HEAD and index"
 msgstr "重置 HEAD 和索引"
 
-#: builtin/reset.c:254
+#: builtin/reset.c:265
 msgid "reset only HEAD"
 msgstr "只重置 HEAD"
 
-#: builtin/reset.c:256 builtin/reset.c:258
+#: builtin/reset.c:267 builtin/reset.c:269
 msgid "reset HEAD, index and working tree"
 msgstr "重置 HEAD、索引和工作区"
 
-#: builtin/reset.c:260
+#: builtin/reset.c:271
 msgid "reset HEAD but keep local changes"
 msgstr "重置 HEAD 但保存本地变更"
 
-#: builtin/reset.c:278
+#: builtin/reset.c:289
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
 msgstr "无法将 '%s' 解析为一个有效的版本。"
 
-#: builtin/reset.c:281 builtin/reset.c:289
+#: builtin/reset.c:292 builtin/reset.c:300
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "不能解析对象 '%s'。"
 
-#: builtin/reset.c:286
+#: builtin/reset.c:297
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
 msgstr "无法将 '%s' 解析为一个有效的树对象。"
 
-#: builtin/reset.c:295
+#: builtin/reset.c:306
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch 与 --{hard、mixed、soft} 选项不兼容"
 
-#: builtin/reset.c:304
+#: builtin/reset.c:315
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr "--mixed 带路径已弃用,而是用 'git reset -- <paths>'。"
 
 #  译者:汉字之间无空格,故删除%s前后空格
-#: builtin/reset.c:306
+#: builtin/reset.c:317
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "不能带路径进行%s重置。"
 
 #  译者:汉字之间无空格,故删除%s前后空格
-#: builtin/reset.c:316
+#: builtin/reset.c:327
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr "不能对裸版本库进行%s重置"
 
-#: builtin/reset.c:336
+#: builtin/reset.c:344
+msgid "Unstaged changes after reset:"
+msgstr "重置后撤出暂存区的变更:"
+
+#: builtin/reset.c:350
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "不能重置索引文件至版本 '%s'。"
 
-#: builtin/reset.c:342
-msgid "Unstaged changes after reset:"
-msgstr "重置后撤出暂存区的变更:"
-
-#: builtin/reset.c:347
+#: builtin/reset.c:355
 msgid "Could not write new index file."
 msgstr "不能写入新的索引文件。"
 
@@ -8490,8 +8759,8 @@
 "Run \"git rev-parse --parseopt -h\" for more information on the first usage."
 msgstr ""
 "git rev-parse --parseopt [选项] -- [<参数>...]\n"
-"   或者:git rev-parse --sq-quote [<选项>...]\n"
-"   或者:git rev-parse [options] [<选项>...]\n"
+"   或者:git rev-parse --sq-quote [<参数>...]\n"
+"   或者:git rev-parse [选项] [<参数>...]\n"
 "\n"
 "初次使用时执行 \"git rev-parse --parseopt -h\" 来获得更多信息。"
 
@@ -8511,84 +8780,84 @@
 msgid "git cherry-pick <subcommand>"
 msgstr "git cherry-pick <子命令>"
 
-#: builtin/revert.c:71 builtin/revert.c:94
+#: builtin/revert.c:71
 #, c-format
 msgid "%s: %s cannot be used with %s"
 msgstr "%s:%s 不能和 %s 同时使用"
 
-#: builtin/revert.c:105
+#: builtin/revert.c:80
 msgid "end revert or cherry-pick sequence"
 msgstr "终止反转或拣选操作"
 
-#: builtin/revert.c:106
+#: builtin/revert.c:81
 msgid "resume revert or cherry-pick sequence"
 msgstr "继续反转或拣选操作"
 
-#: builtin/revert.c:107
+#: builtin/revert.c:82
 msgid "cancel revert or cherry-pick sequence"
 msgstr "取消反转或拣选操作"
 
-#: builtin/revert.c:108
+#: builtin/revert.c:83
 msgid "don't automatically commit"
 msgstr "不要自动提交"
 
-#: builtin/revert.c:109
+#: builtin/revert.c:84
 msgid "edit the commit message"
 msgstr "编辑提交说明"
 
-#: builtin/revert.c:112
+#: builtin/revert.c:87
 msgid "parent number"
 msgstr "父编号"
 
-#: builtin/revert.c:114
+#: builtin/revert.c:89
 msgid "merge strategy"
 msgstr "合并策略"
 
-#: builtin/revert.c:115
+#: builtin/revert.c:90
 msgid "option"
 msgstr "选项"
 
-#: builtin/revert.c:116
+#: builtin/revert.c:91
 msgid "option for merge strategy"
 msgstr "合并策略的选项"
 
-#: builtin/revert.c:127
+#: builtin/revert.c:102
 msgid "append commit name"
 msgstr "追加提交名称"
 
-#: builtin/revert.c:128
+#: builtin/revert.c:103
 msgid "allow fast-forward"
 msgstr "允许快进式"
 
-#: builtin/revert.c:129
+#: builtin/revert.c:104
 msgid "preserve initially empty commits"
 msgstr "保留初始化的空提交"
 
-#: builtin/revert.c:130
+#: builtin/revert.c:105
 msgid "allow commits with empty messages"
 msgstr "允许提交说明为空"
 
-#: builtin/revert.c:131
+#: builtin/revert.c:106
 msgid "keep redundant, empty commits"
 msgstr "保持多余的、空的提交"
 
-#: builtin/revert.c:135
+#: builtin/revert.c:110
 msgid "program error"
 msgstr "程序错误"
 
-#: builtin/revert.c:225
+#: builtin/revert.c:195
 msgid "revert failed"
 msgstr "还原失败"
 
-#: builtin/revert.c:240
+#: builtin/revert.c:210
 msgid "cherry-pick failed"
 msgstr "拣选失败"
 
-#: builtin/rm.c:16
+#: builtin/rm.c:17
 msgid "git rm [options] [--] <file>..."
 msgstr "git rm [选项] [--] <文件>..."
 
-#: builtin/rm.c:64
+#: builtin/rm.c:65
 msgid ""
 "the following submodule (or one of its nested submodules)\n"
 "uses a .git directory:"
@@ -8598,7 +8867,7 @@
 msgstr[0] "如下子模组(或一个其嵌套子模组)使用了一个 .git 目录:"
 msgstr[1] "如下子模组(或一个其嵌套子模组)使用了一个 .git 目录:"
 
-#: builtin/rm.c:70
+#: builtin/rm.c:71
 msgid ""
 "\n"
 "(use 'rm -rf' if you really want to remove it including all of its history)"
@@ -8606,7 +8875,7 @@
 "\n"
 "(使用 'rm -rf' 命令如果您真的想删除它及其全部历史)"
 
-#: builtin/rm.c:230
+#: builtin/rm.c:231
 msgid ""
 "the following file has staged content different from both the\n"
 "file and the HEAD:"
@@ -8616,7 +8885,7 @@
 msgstr[0] "如下文件其暂存的内容和工作区及 HEAD 中的都不一样:"
 msgstr[1] "如下文件其暂存的内容和工作区及 HEAD 中的都不一样:"
 
-#: builtin/rm.c:235
+#: builtin/rm.c:236
 msgid ""
 "\n"
 "(use -f to force removal)"
@@ -8624,13 +8893,13 @@
 "\n"
 "(使用 -f 强制删除)"
 
-#: builtin/rm.c:239
+#: builtin/rm.c:240
 msgid "the following file has changes staged in the index:"
 msgid_plural "the following files have changes staged in the index:"
 msgstr[0] "如下文件相对索引区的内容有修改"
 msgstr[1] "如下文件相对索引区的内容有修改"
 
-#: builtin/rm.c:243 builtin/rm.c:254
+#: builtin/rm.c:244 builtin/rm.c:255
 msgid ""
 "\n"
 "(use --cached to keep the file, or -f to force removal)"
@@ -8638,38 +8907,38 @@
 "\n"
 "(使用 --cached 保留本地文件,或用 -f 强制删除)"
 
-#: builtin/rm.c:251
+#: builtin/rm.c:252
 msgid "the following file has local modifications:"
 msgid_plural "the following files have local modifications:"
 msgstr[0] "如下文件有本地修改:"
 msgstr[1] "如下文件有本地修改:"
 
-#: builtin/rm.c:269
+#: builtin/rm.c:270
 msgid "do not list removed files"
 msgstr "不列出删除的文件"
 
-#: builtin/rm.c:270
+#: builtin/rm.c:271
 msgid "only remove from the index"
 msgstr "只从索引区删除"
 
-#: builtin/rm.c:271
+#: builtin/rm.c:272
 msgid "override the up-to-date check"
 msgstr "忽略文件更新状态检查"
 
-#: builtin/rm.c:272
+#: builtin/rm.c:273
 msgid "allow recursive removal"
 msgstr "允许递归删除"
 
-#: builtin/rm.c:274
+#: builtin/rm.c:275
 msgid "exit with a zero status even if nothing matched"
 msgstr "即使没有匹配,也以零状态退出"
 
-#: builtin/rm.c:345
+#: builtin/rm.c:336
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "未提供 -r 选项不会递归删除 '%s'"
 
-#: builtin/rm.c:384
+#: builtin/rm.c:375
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm:不能删除 %s"
@@ -8683,23 +8952,23 @@
 msgid "Missing author: %s"
 msgstr "缺少作者:%s"
 
-#: builtin/shortlog.c:228
+#: builtin/shortlog.c:230
 msgid "sort output according to the number of commits per author"
 msgstr "根据每个作者的提交数量排序"
 
-#: builtin/shortlog.c:230
+#: builtin/shortlog.c:232
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "隐藏提交说明,只提供提交数量"
 
-#: builtin/shortlog.c:232
+#: builtin/shortlog.c:234
 msgid "Show the email address of each author"
 msgstr "显示每个作者的电子邮件地址"
 
-#: builtin/shortlog.c:233
+#: builtin/shortlog.c:235
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:234
+#: builtin/shortlog.c:236
 msgid "Linewrap output"
 msgstr "折行输出"
 
@@ -8807,23 +9076,23 @@
 msgid "stricter reference checking, requires exact ref path"
 msgstr "更严格的引用检测,需要精确的引用路径"
 
-#: builtin/show-ref.c:173 builtin/show-ref.c:176
+#: builtin/show-ref.c:173 builtin/show-ref.c:175
 msgid "show the HEAD reference, even if it would be filtered out"
 msgstr "显示 HEAD 引用,即使被过滤掉"
 
-#: builtin/show-ref.c:178
+#: builtin/show-ref.c:177
 msgid "dereference tags into object IDs"
 msgstr "转换 tags 到对象ID"
 
-#: builtin/show-ref.c:180
+#: builtin/show-ref.c:179
 msgid "only show SHA1 hash using <n> digits"
 msgstr "只显示使用 <n> 个数字的 SHA1 哈希"
 
-#: builtin/show-ref.c:184
+#: builtin/show-ref.c:183
 msgid "do not print results to stdout (useful with --verify)"
 msgstr "不打印结果到标准输出(例如与 --verify 参数共用)"
 
-#: builtin/show-ref.c:186
+#: builtin/show-ref.c:185
 msgid "show refs from stdin that aren't in local repository"
 msgstr "显示从标准输入中读入的不在本地版本库中的引用"
 
@@ -8847,11 +9116,11 @@
 msgid "shorten ref output"
 msgstr "简短的引用输出"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason"
 msgstr "原因"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
 msgid "reason of the update"
 msgstr "更新的原因"
 
@@ -9014,183 +9283,195 @@
 msgid "print only tags of the object"
 msgstr "只打印tags对象"
 
-#: builtin/tag.c:504
+#: builtin/tag.c:501
 msgid "--column and -n are incompatible"
 msgstr "--column 和 -n 不兼容"
 
-#: builtin/tag.c:521
+#: builtin/tag.c:518
 msgid "-n option is only allowed with -l."
 msgstr "-n 选项只允许和 -l 同时使用。"
 
-#: builtin/tag.c:523
+#: builtin/tag.c:520
 msgid "--contains option is only allowed with -l."
 msgstr "--contains 选项只允许和 -l 同时使用。"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:522
 msgid "--points-at option is only allowed with -l."
 msgstr "--points-at 选项只允许和 -l 同时使用。"
 
-#: builtin/tag.c:533
+#: builtin/tag.c:530
 msgid "only one -F or -m option is allowed."
 msgstr "只允许一个 -F 或 -m 选项。"
 
-#: builtin/tag.c:553
+#: builtin/tag.c:550
 msgid "too many params"
 msgstr "太多参数"
 
-#: builtin/tag.c:559
+#: builtin/tag.c:556
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "'%s' 不是一个有效的tag名称。"
 
-#: builtin/tag.c:564
+#: builtin/tag.c:561
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "tag '%s' 已存在"
 
-#: builtin/tag.c:582
+#: builtin/tag.c:579
 #, c-format
 msgid "%s: cannot lock the ref"
 msgstr "%s:不能锁定引用"
 
-#: builtin/tag.c:584
+#: builtin/tag.c:581
 #, c-format
 msgid "%s: cannot update the ref"
 msgstr "%s:不能更新引用"
 
-#: builtin/tag.c:586
+#: builtin/tag.c:583
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "已更新tag '%s'(曾为 %s)\n"
 
-#: builtin/update-index.c:401
+#: builtin/update-index.c:402
 msgid "git update-index [options] [--] [<file>...]"
 msgstr "git update-index [选项] [--] [<文件>...]"
 
-#: builtin/update-index.c:718
+#: builtin/update-index.c:720
 msgid "continue refresh even when index needs update"
 msgstr "当索引需要更新时继续刷新"
 
-#: builtin/update-index.c:721
+#: builtin/update-index.c:723
 msgid "refresh: ignore submodules"
 msgstr "刷新:忽略子模组"
 
-#: builtin/update-index.c:724
+#: builtin/update-index.c:726
 msgid "do not ignore new files"
 msgstr "不忽略新的文件"
 
-#: builtin/update-index.c:726
+#: builtin/update-index.c:728
 msgid "let files replace directories and vice-versa"
 msgstr "让文件替换目录(反之亦然)"
 
-#: builtin/update-index.c:728
+#: builtin/update-index.c:730
 msgid "notice files missing from worktree"
 msgstr "通知文件从工作区丢失"
 
-#: builtin/update-index.c:730
+#: builtin/update-index.c:732
 msgid "refresh even if index contains unmerged entries"
 msgstr "即使索引区包含未合并的条目也执行刷新"
 
-#: builtin/update-index.c:733
+#: builtin/update-index.c:735
 msgid "refresh stat information"
 msgstr "刷新统计信息"
 
-#: builtin/update-index.c:737
+#: builtin/update-index.c:739
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "类似于 --refresh,但是忽略 assume-unchanged 设置"
 
-#: builtin/update-index.c:741
+#: builtin/update-index.c:743
 msgid "<mode> <object> <path>"
 msgstr "<mode> <object> <path>"
 
-#: builtin/update-index.c:742
+#: builtin/update-index.c:744
 msgid "add the specified entry to the index"
 msgstr "添加指定的条目到索引区"
 
-#: builtin/update-index.c:746
+#: builtin/update-index.c:748
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/update-index.c:747
+#: builtin/update-index.c:749
 msgid "override the executable bit of the listed files"
 msgstr "覆盖列表里文件的可执行位"
 
-#: builtin/update-index.c:751
+#: builtin/update-index.c:753
 msgid "mark files as \"not changing\""
 msgstr "把文件标记为 \"没有变更\""
 
-#: builtin/update-index.c:754
+#: builtin/update-index.c:756
 msgid "clear assumed-unchanged bit"
 msgstr "清除 assumed-unchanged 位"
 
-#: builtin/update-index.c:757
+#: builtin/update-index.c:759
 msgid "mark files as \"index-only\""
 msgstr "把文件标记为 \"仅索引\""
 
-#: builtin/update-index.c:760
+#: builtin/update-index.c:762
 msgid "clear skip-worktree bit"
 msgstr "清除 skip-worktree 位"
 
-#: builtin/update-index.c:763
+#: builtin/update-index.c:765
 msgid "add to index only; do not add content to object database"
 msgstr "只添加到索引区;不添加对象到对象库"
 
-#: builtin/update-index.c:765
+#: builtin/update-index.c:767
 msgid "remove named paths even if present in worktree"
 msgstr "即使存在工作区里,也删除路径"
 
-#: builtin/update-index.c:767
+#: builtin/update-index.c:769
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "携带 --stdin:输入的行以 null 字符终止"
 
-#: builtin/update-index.c:769
+#: builtin/update-index.c:771
 msgid "read list of paths to be updated from standard input"
 msgstr "从标准输入中读取需要更新的路径列表"
 
-#: builtin/update-index.c:773
+#: builtin/update-index.c:775
 msgid "add entries from standard input to the index"
 msgstr "从标准输入添加条目到索引区"
 
-#: builtin/update-index.c:777
+#: builtin/update-index.c:779
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "为指定文件重新生成第2和第3暂存区"
 
-#: builtin/update-index.c:781
+#: builtin/update-index.c:783
 msgid "only update entries that differ from HEAD"
 msgstr "只更新与 HEAD 不同的条目"
 
-#: builtin/update-index.c:785
+#: builtin/update-index.c:787
 msgid "ignore files missing from worktree"
 msgstr "忽略工作区丢失的文件"
 
-#: builtin/update-index.c:788
+#: builtin/update-index.c:790
 msgid "report actions to standard output"
 msgstr "在标准输出显示操作"
 
-#: builtin/update-index.c:790
+#: builtin/update-index.c:792
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(for porcelains) 忘记保存的未解决的冲突"
 
-#: builtin/update-index.c:794
+#: builtin/update-index.c:796
 msgid "write index in this format"
 msgstr "以这种格式写入索引区"
 
-#: builtin/update-ref.c:7
+#: builtin/update-ref.c:9
 msgid "git update-ref [options] -d <refname> [<oldval>]"
-msgstr "git update-ref [options] -d <引用名> [<旧值>]"
+msgstr "git update-ref [选项] -d <引用名> [<旧值>]"
 
-#: builtin/update-ref.c:8
+#: builtin/update-ref.c:10
 msgid "git update-ref [options]    <refname> <newval> [<oldval>]"
-msgstr "git update-ref [options]    <引用名> <新值> [<旧值>]"
+msgstr "git update-ref [选项]    <引用名> <新值> [<旧值>]"
 
-#: builtin/update-ref.c:19
+#: builtin/update-ref.c:11
+msgid "git update-ref [options] --stdin [-z]"
+msgstr "git update-ref [选项] --stdin [-z]"
+
+#: builtin/update-ref.c:255
 msgid "delete the reference"
 msgstr "删除引用"
 
-#: builtin/update-ref.c:21
+#: builtin/update-ref.c:257
 msgid "update <refname> not the one it points to"
 msgstr "更新 <引用名> 本身而不是它指向的引用"
 
+#: builtin/update-ref.c:258
+msgid "stdin has NUL-terminated arguments"
+msgstr "标准输入有以 NUL 字符终止的参数"
+
+#: builtin/update-ref.c:259
+msgid "read updates from stdin"
+msgstr "从标准输入读取更新"
+
 #: builtin/update-server-info.c:6
 msgid "git update-server-info [--force]"
 msgstr "git update-server-info [--force]"
@@ -9244,23 +9525,23 @@
 "命令 'git help -a' 和 'git help -g' 显示可用的子命令和一些指南。参见\n"
 "'git help <命令>' 或 'git help <指南>' 来查看给定的子命令帮助或指南。"
 
-#: parse-options.h:144
+#: parse-options.h:146
 msgid "expiry date"
 msgstr "逾期日期"
 
-#: parse-options.h:159
+#: parse-options.h:161
 msgid "no-op (backward compatibility)"
 msgstr "空操作(向后兼容)"
 
-#: parse-options.h:236
+#: parse-options.h:238
 msgid "be more verbose"
 msgstr "更加详细"
 
-#: parse-options.h:238
+#: parse-options.h:240
 msgid "be more quiet"
 msgstr "更加安静"
 
-#: parse-options.h:244
+#: parse-options.h:246
 msgid "use <n> digits to display SHA-1s"
 msgstr "用 <n> 位数字显示 SHA-1 哈希值"
 
@@ -9690,7 +9971,7 @@
 msgid "Pull is not possible because you have unmerged files."
 msgstr "Pull 不可用,因为您尚有未合并的文件。"
 
-#: git-pull.sh:203
+#: git-pull.sh:223
 msgid "updating an unborn branch with changes added to the index"
 msgstr "更新尚未诞生的分支,变更添加至索引"
 
@@ -9698,7 +9979,7 @@
 #. The working tree and the index file is still based on the
 #. $orig_head commit, but we are merging into $curr_head.
 #. First update the working tree to match $curr_head.
-#: git-pull.sh:235
+#: git-pull.sh:255
 #, sh-format
 msgid ""
 "Warning: fetch updated the current branch head.\n"
@@ -9708,11 +9989,11 @@
 "警告:fetch 更新了当前的分支。您的工作区\n"
 "警告:从原提交 $orig_head 快进。"
 
-#: git-pull.sh:260
+#: git-pull.sh:280
 msgid "Cannot merge multiple branches into empty head"
 msgstr "无法将多个分支合并到空分支"
 
-#: git-pull.sh:264
+#: git-pull.sh:284
 msgid "Cannot rebase onto multiple branches"
 msgstr "无法变基到多个分支"
 
@@ -9746,31 +10027,31 @@
 "您的修改安全地保存在 stash 中。\n"
 "您可以在任何时候运行 \"git stash pop\" 或 \"git stash drop\"。\n"
 
-#: git-rebase.sh:190
+#: git-rebase.sh:199
 msgid "The pre-rebase hook refused to rebase."
 msgstr "钩子 pre-rebase 拒绝变基。"
 
-#: git-rebase.sh:195
+#: git-rebase.sh:204
 msgid "It looks like git-am is in progress. Cannot rebase."
 msgstr "似乎正处于在 git-am 的执行过程中。无法变基。"
 
-#: git-rebase.sh:329
+#: git-rebase.sh:338
 msgid "The --exec option must be used with the --interactive option"
 msgstr "选项 --exec 必须和选项 --interactive 同时使用"
 
-#: git-rebase.sh:334
+#: git-rebase.sh:343
 msgid "No rebase in progress?"
 msgstr "没有正在进行的变基?"
 
-#: git-rebase.sh:345
+#: git-rebase.sh:354
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "动作 --edit-todo 只能用在交互式变基过程中。"
 
-#: git-rebase.sh:352
+#: git-rebase.sh:361
 msgid "Cannot read HEAD"
 msgstr "不能读取 HEAD"
 
-#: git-rebase.sh:355
+#: git-rebase.sh:364
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -9778,12 +10059,12 @@
 "您必须编辑所有的合并冲突,然后通过 git add\n"
 "命令将它们标记为已解决"
 
-#: git-rebase.sh:373
+#: git-rebase.sh:382
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "无法移回 $head_name"
 
-#: git-rebase.sh:392
+#: git-rebase.sh:401
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -9802,65 +10083,65 @@
 "\t$cmd_clear_stale_rebase\n"
 "然后再重新执行变基。为避免您丢失重要数据,我已经停止当前操作。"
 
-#: git-rebase.sh:437
+#: git-rebase.sh:446
 #, sh-format
 msgid "invalid upstream $upstream_name"
 msgstr "无效的上游 $upstream_name"
 
-#: git-rebase.sh:461
+#: git-rebase.sh:470
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: 有一个以上的合并基准"
 
-#: git-rebase.sh:464 git-rebase.sh:468
+#: git-rebase.sh:473 git-rebase.sh:477
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: 没有合并基准"
 
-#: git-rebase.sh:473
+#: git-rebase.sh:482
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "没有指向一个有效的提交:$onto_name"
 
-#: git-rebase.sh:496
+#: git-rebase.sh:505
 #, sh-format
 msgid "fatal: no such branch: $branch_name"
 msgstr "严重错误:无此分支:$branch_name"
 
-#: git-rebase.sh:519
+#: git-rebase.sh:528
 msgid "Cannot autostash"
 msgstr "无法 autostash"
 
-#: git-rebase.sh:524
+#: git-rebase.sh:533
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "创建了 autostash: $stash_abbrev"
 
-#: git-rebase.sh:528
+#: git-rebase.sh:537
 msgid "Please commit or stash them."
 msgstr "请提交或为它们保存进度。"
 
-#: git-rebase.sh:548
+#: git-rebase.sh:557
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "当前分支 $branch_name 是最新的。"
 
-#: git-rebase.sh:552
+#: git-rebase.sh:561
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "当前分支 $branch_name 是最新的,强制变基。"
 
-#: git-rebase.sh:563
+#: git-rebase.sh:572
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "变更从 $mb 到 $onto:"
 
 #. Detach HEAD and reset the tree
-#: git-rebase.sh:572
+#: git-rebase.sh:581
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr "首先,重置头指针以便在上面重放您的工作..."
 
-#: git-rebase.sh:582
+#: git-rebase.sh:591
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "快进 $branch_name 至 $onto_name。"
@@ -9908,7 +10189,7 @@
 #. $ git stash save --blah-blah 2>&1 | head -n 2
 #. error: unknown option for 'stash save': --blah-blah
 #. To provide a message, use git stash save -- '--blah-blah'
-#: git-stash.sh:241
+#: git-stash.sh:237
 #, sh-format
 msgid ""
 "error: unknown option for 'stash save': $option\n"
@@ -9917,96 +10198,85 @@
 "错误:'stash save' 的未知选项:$option\n"
 "      要提供一个描述信息,使用 git stash save -- '$option'"
 
-#: git-stash.sh:262
+#: git-stash.sh:258
 msgid "No local changes to save"
 msgstr "没有要保存的本地修改"
 
-#: git-stash.sh:268
-msgid ""
-"The following untracked files would NOT be saved but need to be removed by "
-"stash save:"
-msgstr "如下未跟踪文件将不会被保存但是将会因为进度保存而需要被删除:"
-
-#: git-stash.sh:270
-msgid ""
-"Aborting. Consider using either the --force or --include-untracked option."
-msgstr "终止。考虑使用 --force 或者 --include-untracked 选项。"
-
-#: git-stash.sh:274
+#: git-stash.sh:262
 msgid "Cannot initialize stash"
 msgstr "无法初始化 stash"
 
-#: git-stash.sh:278
+#: git-stash.sh:266
 msgid "Cannot save the current status"
 msgstr "无法保存当前状态"
 
-#: git-stash.sh:296
+#: git-stash.sh:284
 msgid "Cannot remove worktree changes"
 msgstr "无法删除工作区变更"
 
-#: git-stash.sh:395
+#: git-stash.sh:383
 msgid "No stash found."
 msgstr "未发现 stash。"
 
-#: git-stash.sh:402
+#: git-stash.sh:390
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "指定了太多的版本:$REV"
 
-#: git-stash.sh:408
+#: git-stash.sh:396
 #, sh-format
 msgid "$reference is not valid reference"
 msgstr "$reference 不是有效的引用"
 
-#: git-stash.sh:436
+#: git-stash.sh:424
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "'$args' 不是 stash 样提交"
 
-#: git-stash.sh:447
+#: git-stash.sh:435
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "'$args' 不是一个 stash 引用"
 
-#: git-stash.sh:455
+#: git-stash.sh:443
 msgid "unable to refresh index"
 msgstr "无法刷新索引"
 
-#: git-stash.sh:459
+#: git-stash.sh:447
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "无法在合并过程中恢复进度"
 
-#: git-stash.sh:467
+#: git-stash.sh:455
 msgid "Conflicts in index. Try without --index."
 msgstr "索引中有冲突。尝试不使用 --index。"
 
-#: git-stash.sh:469
+#: git-stash.sh:457
 msgid "Could not save index tree"
 msgstr "不能保存索引树"
 
-#: git-stash.sh:503
+#: git-stash.sh:491
 msgid "Cannot unstage modified files"
 msgstr "无法还原修改的文件"
 
-#: git-stash.sh:518
+#: git-stash.sh:506
 msgid "Index was not unstashed."
 msgstr "索引的进度没有被恢复。"
 
-#: git-stash.sh:535
+#: git-stash.sh:523
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "丢弃了 ${REV} ($s)"
 
-#: git-stash.sh:536
+#: git-stash.sh:524
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}:不能丢弃进度条目"
 
-#: git-stash.sh:543
+#: git-stash.sh:531
 msgid "No branch name specified"
 msgstr "未指定分支名"
 
-#: git-stash.sh:615
+#: git-stash.sh:603
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(为恢复数据输入 \"git stash apply\")"
 
@@ -10257,51 +10527,58 @@
 msgstr "选项 --cached 不能和选项 --files 同时使用"
 
 #. unexpected type
-#: git-submodule.sh:1066
+#: git-submodule.sh:1073
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "意外的模式 $mod_dst"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:1086
+#: git-submodule.sh:1093
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  警告:$display_name 未包含提交 $sha1_src"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:1089
+#: git-submodule.sh:1096
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  警告:$display_name 未包含提交 $sha1_dst"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:1092
+#: git-submodule.sh:1099
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr "  警告:$display_name 未包含提交 $sha1_src 和 $sha1_dst"
 
-#: git-submodule.sh:1117
+#: git-submodule.sh:1124
 msgid "blob"
 msgstr "数据对象"
 
-#: git-submodule.sh:1155
-msgid "Submodules changed but not updated:"
-msgstr "子模组已修改但尚未更新:"
-
-#: git-submodule.sh:1157
-msgid "Submodule changes to be committed:"
-msgstr "要提交的子模组变更:"
-
-#: git-submodule.sh:1242
+#: git-submodule.sh:1238
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "无法递归进子模组路径 '$sm_path'"
 
-#: git-submodule.sh:1306
+#: git-submodule.sh:1302
 #, sh-format
 msgid "Synchronizing submodule url for '$displaypath'"
 msgstr "为 '$displaypath' 同步子模组 url"
 
+#~ msgid "done\n"
+#~ msgstr "完成\n"
+
+#~ msgid "input paths are terminated by a null character"
+#~ msgstr "输入路径以null字符终止"
+
+#~ msgid ""
+#~ "The following untracked files would NOT be saved but need to be removed "
+#~ "by stash save:"
+#~ msgstr "如下未跟踪文件将不会被保存但是将会因为进度保存而需要被删除:"
+
+#~ msgid ""
+#~ "Aborting. Consider using either the --force or --include-untracked option."
+#~ msgstr "终止。考虑使用 --force 或者 --include-untracked 选项。"
+
 #~ msgid ""
 #~ "the following submodule (or one of its nested submodule)\n"
 #~ "uses a .git directory:"
@@ -10311,39 +10588,6 @@
 #~ msgstr[0] "如下子模组(或一个其嵌套的子模组)使用了一个 .git 目录:"
 #~ msgstr[1] "如下子模组(或一个其嵌套的子模组)使用了一个 .git 目录:"
 
-#~ msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
-#~ msgstr "无法修改未合并的 .gitmodules,先解决合并冲突"
-
-#~ msgid "Could not find section in .gitmodules where path=%s"
-#~ msgstr "无法在 .gitmodules 中找到 path=%s 的小节"
-
-#~ msgid "Could not update .gitmodules entry %s"
-#~ msgstr "不能更新 .gitmodules 条目 %s"
-
-#~ msgid "Could not remove .gitmodules entry for %s"
-#~ msgstr "无法移除 %s 的 .gitmodules 条目"
-
-#~ msgid "could not find .gitmodules in index"
-#~ msgstr "无法在索引中找到 .gitmodules"
-
-#~ msgid "reading updated .gitmodules failed"
-#~ msgstr "读取更新后的 .gitmodules 失败"
-
-#~ msgid "unable to stat updated .gitmodules"
-#~ msgstr "不能枚举更新后的 .gitmodules"
-
-#~ msgid "unable to remove .gitmodules from index"
-#~ msgstr "不能从索引中移除 .gitmodules"
-
-#~ msgid "adding updated .gitmodules failed"
-#~ msgstr "添加更新后的 .gitmodules 失败"
-
-#~ msgid "staging updated .gitmodules failed"
-#~ msgstr "将更新后 .gitmodules 添加暂存区失败"
-
-#~ msgid "Could not set core.worktree in %s"
-#~ msgstr "不能在 %s 中设置 core.worktree"
-
 #  译者:注意保持前导空格
 #~ msgid "  (fix conflicts and then run \"git am --resolved\")"
 #~ msgstr "  (解决冲突,然后运行 \"git am --resolved\")"
@@ -10358,9 +10602,6 @@
 #~ msgid "You cannot combine --no-ff with --ff-only."
 #~ msgstr "您不能将 --no-ff 与 --ff-only 同时使用。"
 
-#~ msgid "Huh? Directory %s is in index and no submodule?"
-#~ msgstr "嗯?目录 %s 在索引中并且不是子模组?"
-
 #~ msgid ""
 #~ "submodule '%s' (or one of its nested submodules) uses a .git directory\n"
 #~ "(use 'rm -rf' if you really want to remove it including all of its "
@@ -10479,9 +10720,6 @@
 #~ msgid "-B cannot be used with -b"
 #~ msgstr "-B 不能和 -b 同时使用"
 
-#~ msgid "--patch is incompatible with all other options"
-#~ msgstr "--patch 选项和其他选项不兼容"
-
 #~ msgid "--detach cannot be used with -b/-B/--orphan"
 #~ msgstr "--detach 不能和 -b/-B/--orphan 同时使用"
 
diff --git a/preload-index.c b/preload-index.c
index 49cb08d..8c44ceb 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -2,9 +2,11 @@
  * Copyright (C) 2008 Linus Torvalds
  */
 #include "cache.h"
+#include "pathspec.h"
 
 #ifdef NO_PTHREADS
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+			  const struct pathspec *pathspec)
 {
 	; /* nothing */
 }
@@ -24,7 +26,7 @@
 struct thread_data {
 	pthread_t pthread;
 	struct index_state *index;
-	const char **pathspec;
+	struct pathspec pathspec;
 	int offset, nr;
 };
 
@@ -35,9 +37,7 @@
 	struct index_state *index = p->index;
 	struct cache_entry **cep = index->cache + p->offset;
 	struct cache_def cache;
-	struct pathspec pathspec;
 
-	init_pathspec(&pathspec, p->pathspec);
 	memset(&cache, 0, sizeof(cache));
 	nr = p->nr;
 	if (nr + p->offset > index->cache_nr)
@@ -53,7 +53,7 @@
 			continue;
 		if (ce_uptodate(ce))
 			continue;
-		if (!ce_path_match(ce, &pathspec))
+		if (!ce_path_match(ce, &p->pathspec))
 			continue;
 		if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
 			continue;
@@ -63,11 +63,11 @@
 			continue;
 		ce_mark_uptodate(ce);
 	} while (--nr > 0);
-	free_pathspec(&pathspec);
 	return NULL;
 }
 
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+			  const struct pathspec *pathspec)
 {
 	int threads, i, work, offset;
 	struct thread_data data[MAX_PARALLEL];
@@ -82,10 +82,12 @@
 		threads = MAX_PARALLEL;
 	offset = 0;
 	work = DIV_ROUND_UP(index->cache_nr, threads);
+	memset(&data, 0, sizeof(data));
 	for (i = 0; i < threads; i++) {
 		struct thread_data *p = data+i;
 		p->index = index;
-		p->pathspec = pathspec;
+		if (pathspec)
+			copy_pathspec(&p->pathspec, pathspec);
 		p->offset = offset;
 		p->nr = work;
 		offset += work;
@@ -100,7 +102,8 @@
 }
 #endif
 
-int read_index_preload(struct index_state *index, const char **pathspec)
+int read_index_preload(struct index_state *index,
+		       const struct pathspec *pathspec)
 {
 	int retval = read_index(index);
 
diff --git a/pretty.c b/pretty.c
index b4e32b7..87db08b 100644
--- a/pretty.c
+++ b/pretty.c
@@ -40,7 +40,7 @@
 	const char *fmt;
 	int i;
 
-	if (prefixcmp(var, "pretty."))
+	if (!starts_with(var, "pretty."))
 		return 0;
 
 	name = var + strlen("pretty.");
@@ -67,7 +67,7 @@
 	commit_format->name = xstrdup(name);
 	commit_format->format = CMIT_FMT_USERFORMAT;
 	git_config_string(&fmt, var, value);
-	if (!prefixcmp(fmt, "format:") || !prefixcmp(fmt, "tformat:")) {
+	if (starts_with(fmt, "format:") || starts_with(fmt, "tformat:")) {
 		commit_format->is_tformat = fmt[0] == 't';
 		fmt = strchr(fmt, ':') + 1;
 	} else if (strchr(fmt, '%'))
@@ -115,7 +115,7 @@
 	for (i = 0; i < commit_formats_len; i++) {
 		size_t match_len;
 
-		if (prefixcmp(commit_formats[i].name, sought))
+		if (!starts_with(commit_formats[i].name, sought))
 			continue;
 
 		match_len = strlen(commit_formats[i].name);
@@ -151,7 +151,7 @@
 		rev->commit_format = CMIT_FMT_DEFAULT;
 		return;
 	}
-	if (!prefixcmp(arg, "format:") || !prefixcmp(arg, "tformat:")) {
+	if (starts_with(arg, "format:") || starts_with(arg, "tformat:")) {
 		save_user_format(rev, strchr(arg, ':') + 1, arg[0] == 't');
 		return;
 	}
@@ -497,7 +497,7 @@
 static int is_empty_line(const char *line, int *len_p)
 {
 	int len = *len_p;
-	while (len && isspace(line[len-1]))
+	while (len && isspace(line[len - 1]))
 		len--;
 	*len_p = len;
 	return !len;
@@ -840,10 +840,10 @@
 
 		if (i == eol) {
 			break;
-		} else if (!prefixcmp(msg + i, "author ")) {
+		} else if (starts_with(msg + i, "author ")) {
 			context->author.off = i + 7;
 			context->author.len = eol - i - 7;
-		} else if (!prefixcmp(msg + i, "committer ")) {
+		} else if (starts_with(msg + i, "committer ")) {
 			context->committer.off = i + 10;
 			context->committer.len = eol - i - 10;
 		}
@@ -983,7 +983,7 @@
 
 		if (!end)
 			return 0;
-		if (!prefixcmp(begin, "auto,")) {
+		if (starts_with(begin, "auto,")) {
 			if (!want_color(c->pretty_ctx->color))
 				return end - placeholder + 1;
 			begin += 5;
@@ -994,16 +994,16 @@
 		strbuf_addstr(sb, color);
 		return end - placeholder + 1;
 	}
-	if (!prefixcmp(placeholder + 1, "red")) {
+	if (starts_with(placeholder + 1, "red")) {
 		strbuf_addstr(sb, GIT_COLOR_RED);
 		return 4;
-	} else if (!prefixcmp(placeholder + 1, "green")) {
+	} else if (starts_with(placeholder + 1, "green")) {
 		strbuf_addstr(sb, GIT_COLOR_GREEN);
 		return 6;
-	} else if (!prefixcmp(placeholder + 1, "blue")) {
+	} else if (starts_with(placeholder + 1, "blue")) {
 		strbuf_addstr(sb, GIT_COLOR_BLUE);
 		return 5;
-	} else if (!prefixcmp(placeholder + 1, "reset")) {
+	} else if (starts_with(placeholder + 1, "reset")) {
 		strbuf_addstr(sb, GIT_COLOR_RESET);
 		return 6;
 	} else
@@ -1060,11 +1060,11 @@
 			end = strchr(start, ')');
 			if (!end || end == start)
 				return 0;
-			if (!prefixcmp(start, "trunc)"))
+			if (starts_with(start, "trunc)"))
 				c->truncate = trunc_right;
-			else if (!prefixcmp(start, "ltrunc)"))
+			else if (starts_with(start, "ltrunc)"))
 				c->truncate = trunc_left;
-			else if (!prefixcmp(start, "mtrunc)"))
+			else if (starts_with(start, "mtrunc)"))
 				c->truncate = trunc_middle;
 			else
 				return 0;
@@ -1089,7 +1089,7 @@
 	/* these are independent of the commit */
 	switch (placeholder[0]) {
 	case 'C':
-		if (!prefixcmp(placeholder + 1, "(auto)")) {
+		if (starts_with(placeholder + 1, "(auto)")) {
 			c->auto_color = 1;
 			return 7; /* consumed 7 bytes, "C(auto)" */
 		} else {
@@ -1556,7 +1556,7 @@
 			continue;
 		}
 
-		if (!prefixcmp(line, "parent ")) {
+		if (starts_with(line, "parent ")) {
 			if (linelen != 48)
 				die("bad parent line in commit");
 			continue;
@@ -1580,11 +1580,11 @@
 		 * FULL shows both authors but not dates.
 		 * FULLER shows both authors and dates.
 		 */
-		if (!prefixcmp(line, "author ")) {
+		if (starts_with(line, "author ")) {
 			strbuf_grow(sb, linelen + 80);
 			pp_user_info(pp, "Author", sb, line + 7, encoding);
 		}
-		if (!prefixcmp(line, "committer ") &&
+		if (starts_with(line, "committer ") &&
 		    (pp->fmt == CMIT_FMT_FULL || pp->fmt == CMIT_FMT_FULLER)) {
 			strbuf_grow(sb, linelen + 80);
 			pp_user_info(pp, "Commit", sb, line + 10, encoding);
diff --git a/prompt.c b/prompt.c
index d851807..d7bb17c 100644
--- a/prompt.c
+++ b/prompt.c
@@ -22,6 +22,7 @@
 	if (start_command(&pass))
 		return NULL;
 
+	strbuf_reset(&buffer);
 	if (strbuf_read(&buffer, pass.out, 20) < 0)
 		err = 1;
 
@@ -38,7 +39,7 @@
 
 	strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
 
-	return strbuf_detach(&buffer, NULL);
+	return buffer.buf;
 }
 
 char *git_prompt(const char *prompt, int flags)
diff --git a/quote.c b/quote.c
index 5c88081..45e3db1 100644
--- a/quote.c
+++ b/quote.c
@@ -42,23 +42,6 @@
 	free(to_free);
 }
 
-void sq_quote_print(FILE *stream, const char *src)
-{
-	char c;
-
-	fputc('\'', stream);
-	while ((c = *src++)) {
-		if (need_bs_quote(c)) {
-			fputs("'\\", stream);
-			fputc(c, stream);
-			fputc('\'', stream);
-		} else {
-			fputc(c, stream);
-		}
-	}
-	fputc('\'', stream);
-}
-
 void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen)
 {
 	int i;
@@ -408,72 +391,72 @@
 
 /* quoting as a string literal for other languages */
 
-void perl_quote_print(FILE *stream, const char *src)
+void perl_quote_buf(struct strbuf *sb, const char *src)
 {
 	const char sq = '\'';
 	const char bq = '\\';
 	char c;
 
-	fputc(sq, stream);
+	strbuf_addch(sb, sq);
 	while ((c = *src++)) {
 		if (c == sq || c == bq)
-			fputc(bq, stream);
-		fputc(c, stream);
+			strbuf_addch(sb, bq);
+		strbuf_addch(sb, c);
 	}
-	fputc(sq, stream);
+	strbuf_addch(sb, sq);
 }
 
-void python_quote_print(FILE *stream, const char *src)
+void python_quote_buf(struct strbuf *sb, const char *src)
 {
 	const char sq = '\'';
 	const char bq = '\\';
 	const char nl = '\n';
 	char c;
 
-	fputc(sq, stream);
+	strbuf_addch(sb, sq);
 	while ((c = *src++)) {
 		if (c == nl) {
-			fputc(bq, stream);
-			fputc('n', stream);
+			strbuf_addch(sb, bq);
+			strbuf_addch(sb, 'n');
 			continue;
 		}
 		if (c == sq || c == bq)
-			fputc(bq, stream);
-		fputc(c, stream);
+			strbuf_addch(sb, bq);
+		strbuf_addch(sb, c);
 	}
-	fputc(sq, stream);
+	strbuf_addch(sb, sq);
 }
 
-void tcl_quote_print(FILE *stream, const char *src)
+void tcl_quote_buf(struct strbuf *sb, const char *src)
 {
 	char c;
 
-	fputc('"', stream);
+	strbuf_addch(sb, '"');
 	while ((c = *src++)) {
 		switch (c) {
 		case '[': case ']':
 		case '{': case '}':
 		case '$': case '\\': case '"':
-			fputc('\\', stream);
+			strbuf_addch(sb, '\\');
 		default:
-			fputc(c, stream);
+			strbuf_addch(sb, c);
 			break;
 		case '\f':
-			fputs("\\f", stream);
+			strbuf_addstr(sb, "\\f");
 			break;
 		case '\r':
-			fputs("\\r", stream);
+			strbuf_addstr(sb, "\\r");
 			break;
 		case '\n':
-			fputs("\\n", stream);
+			strbuf_addstr(sb, "\\n");
 			break;
 		case '\t':
-			fputs("\\t", stream);
+			strbuf_addstr(sb, "\\t");
 			break;
 		case '\v':
-			fputs("\\v", stream);
+			strbuf_addstr(sb, "\\v");
 			break;
 		}
 	}
-	fputc('"', stream);
+	strbuf_addch(sb, '"');
 }
diff --git a/quote.h b/quote.h
index ed110a5..71dcc3a 100644
--- a/quote.h
+++ b/quote.h
@@ -27,8 +27,6 @@
  * excluding the final null regardless of the buffer size.
  */
 
-extern void sq_quote_print(FILE *stream, const char *src);
-
 extern void sq_quote_buf(struct strbuf *, const char *src);
 extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
 
@@ -68,8 +66,8 @@
 			  struct strbuf *out);
 
 /* quoting as a string literal for other languages */
-extern void perl_quote_print(FILE *stream, const char *src);
-extern void python_quote_print(FILE *stream, const char *src);
-extern void tcl_quote_print(FILE *stream, const char *src);
+extern void perl_quote_buf(struct strbuf *sb, const char *src);
+extern void python_quote_buf(struct strbuf *sb, const char *src);
+extern void tcl_quote_buf(struct strbuf *sb, const char *src);
 
 #endif
diff --git a/reachable.c b/reachable.c
index e7e6a1e..654a8c5 100644
--- a/reachable.c
+++ b/reachable.c
@@ -80,8 +80,7 @@
 		else
 			process_blob(lookup_blob(entry.sha1), p, &me, entry.path, cp);
 	}
-	free(tree->buffer);
-	tree->buffer = NULL;
+	free_tree_buffer(tree);
 }
 
 static void process_tag(struct tag *tag, struct object_array *p,
diff --git a/read-cache.c b/read-cache.c
index c3d5e35..33dd676 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -643,7 +643,7 @@
 			if (*ptr == '/') {
 				struct cache_entry *foundce;
 				++ptr;
-				foundce = index_name_exists(istate, ce->name, ptr - ce->name, ignore_case);
+				foundce = index_dir_exists(istate, ce->name, ptr - ce->name - 1);
 				if (foundce) {
 					memcpy((void *)startPtr, foundce->name + (startPtr - ce->name), ptr - startPtr);
 					startPtr = ptr;
@@ -652,7 +652,7 @@
 		}
 	}
 
-	alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
+	alias = index_file_exists(istate, ce->name, ce_namelen(ce), ignore_case);
 	if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
 		/* Nothing changed, really */
 		free(ce);
@@ -1114,7 +1114,8 @@
 	printf(fmt, name);
 }
 
-int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec,
+int refresh_index(struct index_state *istate, unsigned int flags,
+		  const struct pathspec *pathspec,
 		  char *seen, const char *header_msg)
 {
 	int i;
@@ -1149,7 +1150,7 @@
 			continue;
 
 		if (pathspec &&
-		    !match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+		    !match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen))
 			filtered = 1;
 
 		if (ce_stage(ce)) {
@@ -1229,14 +1230,14 @@
 struct ondisk_cache_entry {
 	struct cache_time ctime;
 	struct cache_time mtime;
-	unsigned int dev;
-	unsigned int ino;
-	unsigned int mode;
-	unsigned int uid;
-	unsigned int gid;
-	unsigned int size;
+	uint32_t dev;
+	uint32_t ino;
+	uint32_t mode;
+	uint32_t uid;
+	uint32_t gid;
+	uint32_t size;
 	unsigned char sha1[20];
-	unsigned short flags;
+	uint16_t flags;
 	char name[FLEX_ARRAY]; /* more */
 };
 
@@ -1248,15 +1249,15 @@
 struct ondisk_cache_entry_extended {
 	struct cache_time ctime;
 	struct cache_time mtime;
-	unsigned int dev;
-	unsigned int ino;
-	unsigned int mode;
-	unsigned int uid;
-	unsigned int gid;
-	unsigned int size;
+	uint32_t dev;
+	uint32_t ino;
+	uint32_t mode;
+	uint32_t uid;
+	uint32_t gid;
+	uint32_t size;
 	unsigned char sha1[20];
-	unsigned short flags;
-	unsigned short flags2;
+	uint16_t flags;
+	uint16_t flags2;
 	char name[FLEX_ARRAY]; /* more */
 };
 
@@ -1817,8 +1818,17 @@
 			continue;
 		if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
 			ce_smudge_racily_clean_entry(ce);
-		if (is_null_sha1(ce->sha1))
-			return error("cache entry has null sha1: %s", ce->name);
+		if (is_null_sha1(ce->sha1)) {
+			static const char msg[] = "cache entry has null sha1: %s";
+			static int allow = -1;
+
+			if (allow < 0)
+				allow = git_env_bool("GIT_ALLOW_NULL_SHA1", 0);
+			if (allow)
+				warning(msg, ce->name);
+			else
+				return error(msg, ce->name);
+		}
 		if (ce_write_entry(&c, newfd, ce, previous_name) < 0)
 			return -1;
 	}
diff --git a/refs.c b/refs.c
index 7922261..89228e2 100644
--- a/refs.c
+++ b/refs.c
@@ -72,6 +72,10 @@
 {
 	int component_len, component_count = 0;
 
+	if (!strcmp(refname, "@"))
+		/* Refname is a single character '@'. */
+		return -1;
+
 	while (1) {
 		/* We are at the start of a path component. */
 		component_len = check_refname_component(refname, flags);
@@ -633,7 +637,7 @@
 	struct ref_entry *old_current_ref;
 	int retval;
 
-	if (prefixcmp(entry->name, data->base))
+	if (!starts_with(entry->name, data->base))
 		return 0;
 
 	if (!(data->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
@@ -943,13 +947,6 @@
 	return refs;
 }
 
-void invalidate_ref_cache(const char *submodule)
-{
-	struct ref_cache *refs = get_ref_cache(submodule);
-	clear_packed_ref_cache(refs);
-	clear_loose_ref_cache(refs);
-}
-
 /* The length of a peeled reference line in packed-refs, including EOL: */
 #define PEELED_LINE_LENGTH 42
 
@@ -1045,7 +1042,7 @@
 		if (refname) {
 			last = create_ref_entry(refname, sha1, REF_ISPACKED, 1);
 			if (peeled == PEELED_FULLY ||
-			    (peeled == PEELED_TAGS && !prefixcmp(refname, "refs/tags/")))
+			    (peeled == PEELED_TAGS && starts_with(refname, "refs/tags/")))
 				last->flag |= REF_KNOWS_PEELED;
 			add_ref(dir, last);
 			continue;
@@ -1379,7 +1376,7 @@
 					return NULL;
 			}
 			buffer[len] = 0;
-			if (!prefixcmp(buffer, "refs/") &&
+			if (starts_with(buffer, "refs/") &&
 					!check_refname_format(buffer, 0)) {
 				strcpy(refname_buffer, buffer);
 				refname = refname_buffer;
@@ -1418,7 +1415,7 @@
 		/*
 		 * Is it a symbolic ref?
 		 */
-		if (prefixcmp(buffer, "ref:")) {
+		if (!starts_with(buffer, "ref:")) {
 			/*
 			 * Please note that FETCH_HEAD has a second
 			 * line containing other data.
@@ -1840,7 +1837,7 @@
 	struct ref_filter filter;
 	int ret;
 
-	if (!prefix && prefixcmp(pattern, "refs/"))
+	if (!prefix && !starts_with(pattern, "refs/"))
 		strbuf_addstr(&real_pattern, "refs/");
 	else if (prefix)
 		strbuf_addstr(&real_pattern, prefix);
@@ -1877,13 +1874,13 @@
 const char *prettify_refname(const char *name)
 {
 	return name + (
-		!prefixcmp(name, "refs/heads/") ? 11 :
-		!prefixcmp(name, "refs/tags/") ? 10 :
-		!prefixcmp(name, "refs/remotes/") ? 13 :
+		starts_with(name, "refs/heads/") ? 11 :
+		starts_with(name, "refs/tags/") ? 10 :
+		starts_with(name, "refs/remotes/") ? 13 :
 		0);
 }
 
-const char *ref_rev_parse_rules[] = {
+static const char *ref_rev_parse_rules[] = {
 	"%.*s",
 	"refs/%.*s",
 	"refs/tags/%.*s",
@@ -1893,12 +1890,12 @@
 	NULL
 };
 
-int refname_match(const char *abbrev_name, const char *full_name, const char **rules)
+int refname_match(const char *abbrev_name, const char *full_name)
 {
 	const char **p;
 	const int abbrev_name_len = strlen(abbrev_name);
 
-	for (p = rules; *p; p++) {
+	for (p = ref_rev_parse_rules; *p; p++) {
 		if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
 			return 1;
 		}
@@ -1951,7 +1948,7 @@
 static char *substitute_branch_name(const char **string, int *len)
 {
 	struct strbuf buf = STRBUF_INIT;
-	int ret = interpret_branch_name(*string, &buf);
+	int ret = interpret_branch_name(*string, *len, &buf);
 
 	if (ret == *len) {
 		size_t size;
@@ -2042,6 +2039,7 @@
 	int type, lflags;
 	int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
 	int missing = 0;
+	int attempts_remaining = 3;
 
 	lock = xcalloc(1, sizeof(struct ref_lock));
 	lock->lock_fd = -1;
@@ -2083,7 +2081,7 @@
 
 	lock->lk = xcalloc(1, sizeof(struct lock_file));
 
-	lflags = LOCK_DIE_ON_ERROR;
+	lflags = 0;
 	if (flags & REF_NODEREF) {
 		refname = orig_refname;
 		lflags |= LOCK_NODEREF;
@@ -2096,13 +2094,32 @@
 	if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
 		lock->force_write = 1;
 
-	if (safe_create_leading_directories(ref_file)) {
+ retry:
+	switch (safe_create_leading_directories(ref_file)) {
+	case SCLD_OK:
+		break; /* success */
+	case SCLD_VANISHED:
+		if (--attempts_remaining > 0)
+			goto retry;
+		/* fall through */
+	default:
 		last_errno = errno;
 		error("unable to create directory for %s", ref_file);
 		goto error_return;
 	}
 
 	lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags);
+	if (lock->lock_fd < 0) {
+		if (errno == ENOENT && --attempts_remaining > 0)
+			/*
+			 * Maybe somebody just deleted one of the
+			 * directories leading to ref_file.  Try
+			 * again:
+			 */
+			goto retry;
+		else
+			unable_to_lock_index_die(ref_file, errno);
+	}
 	return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
 
  error_return:
@@ -2121,11 +2138,12 @@
 }
 
 struct ref_lock *lock_any_ref_for_update(const char *refname,
-					 const unsigned char *old_sha1, int flags)
+					 const unsigned char *old_sha1,
+					 int flags, int *type_p)
 {
 	if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
 		return NULL;
-	return lock_ref_sha1_basic(refname, old_sha1, flags, NULL);
+	return lock_ref_sha1_basic(refname, old_sha1, flags, type_p);
 }
 
 /*
@@ -2246,7 +2264,7 @@
 	struct pack_refs_cb_data *cb = cb_data;
 	enum peel_status peel_status;
 	struct ref_entry *packed_entry;
-	int is_tag_ref = !prefixcmp(entry->name, "refs/tags/");
+	int is_tag_ref = starts_with(entry->name, "refs/tags/");
 
 	/* ALWAYS pack tags */
 	if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref)
@@ -2413,60 +2431,82 @@
 	return 0;
 }
 
-static int repack_without_ref(const char *refname)
+static int repack_without_refs(const char **refnames, int n)
 {
 	struct ref_dir *packed;
 	struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
 	struct string_list_item *ref_to_delete;
+	int i, removed = 0;
 
-	if (!get_packed_ref(refname))
-		return 0; /* refname does not exist in packed refs */
+	/* Look for a packed ref */
+	for (i = 0; i < n; i++)
+		if (get_packed_ref(refnames[i]))
+			break;
+
+	/* Avoid locking if we have nothing to do */
+	if (i == n)
+		return 0; /* no refname exists in packed refs */
 
 	if (lock_packed_refs(0)) {
 		unable_to_lock_error(git_path("packed-refs"), errno);
-		return error("cannot delete '%s' from packed refs", refname);
+		return error("cannot delete '%s' from packed refs", refnames[i]);
 	}
 	packed = get_packed_refs(&ref_cache);
 
-	/* Remove refname from the cache: */
-	if (remove_entry(packed, refname) == -1) {
+	/* Remove refnames from the cache */
+	for (i = 0; i < n; i++)
+		if (remove_entry(packed, refnames[i]) != -1)
+			removed = 1;
+	if (!removed) {
 		/*
-		 * The packed entry disappeared while we were
+		 * All packed entries disappeared while we were
 		 * acquiring the lock.
 		 */
 		rollback_packed_refs();
 		return 0;
 	}
 
-	/* Remove any other accumulated cruft: */
+	/* Remove any other accumulated cruft */
 	do_for_each_entry_in_dir(packed, 0, curate_packed_ref_fn, &refs_to_delete);
 	for_each_string_list_item(ref_to_delete, &refs_to_delete) {
 		if (remove_entry(packed, ref_to_delete->string) == -1)
 			die("internal error");
 	}
 
-	/* Write what remains: */
+	/* Write what remains */
 	return commit_packed_refs();
 }
 
+static int repack_without_ref(const char *refname)
+{
+	return repack_without_refs(&refname, 1);
+}
+
+static int delete_ref_loose(struct ref_lock *lock, int flag)
+{
+	if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
+		/* loose */
+		int err, i = strlen(lock->lk->filename) - 5; /* .lock */
+
+		lock->lk->filename[i] = 0;
+		err = unlink_or_warn(lock->lk->filename);
+		lock->lk->filename[i] = '.';
+		if (err && errno != ENOENT)
+			return 1;
+	}
+	return 0;
+}
+
 int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
 {
 	struct ref_lock *lock;
-	int err, i = 0, ret = 0, flag = 0;
+	int ret = 0, flag = 0;
 
 	lock = lock_ref_sha1_basic(refname, sha1, delopt, &flag);
 	if (!lock)
 		return 1;
-	if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
-		/* loose */
-		i = strlen(lock->lk->filename) - 5; /* .lock */
-		lock->lk->filename[i] = 0;
-		err = unlink_or_warn(lock->lk->filename);
-		if (err && errno != ENOENT)
-			ret = 1;
+	ret |= delete_ref_loose(lock, flag);
 
-		lock->lk->filename[i] = '.';
-	}
 	/* removing the loose one could have resurrected an earlier
 	 * packed one.  Also, if it was not loose we need to repack
 	 * without it.
@@ -2488,6 +2528,51 @@
  */
 #define TMP_RENAMED_LOG  "logs/refs/.tmp-renamed-log"
 
+static int rename_tmp_log(const char *newrefname)
+{
+	int attempts_remaining = 4;
+
+ retry:
+	switch (safe_create_leading_directories(git_path("logs/%s", newrefname))) {
+	case SCLD_OK:
+		break; /* success */
+	case SCLD_VANISHED:
+		if (--attempts_remaining > 0)
+			goto retry;
+		/* fall through */
+	default:
+		error("unable to create directory for %s", newrefname);
+		return -1;
+	}
+
+	if (rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newrefname))) {
+		if ((errno==EISDIR || errno==ENOTDIR) && --attempts_remaining > 0) {
+			/*
+			 * rename(a, b) when b is an existing
+			 * directory ought to result in ISDIR, but
+			 * Solaris 5.8 gives ENOTDIR.  Sheesh.
+			 */
+			if (remove_empty_directories(git_path("logs/%s", newrefname))) {
+				error("Directory not empty: logs/%s", newrefname);
+				return -1;
+			}
+			goto retry;
+		} else if (errno == ENOENT && --attempts_remaining > 0) {
+			/*
+			 * Maybe another process just deleted one of
+			 * the directories in the path to newrefname.
+			 * Try again from the beginning.
+			 */
+			goto retry;
+		} else {
+			error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
+				newrefname, strerror(errno));
+			return -1;
+		}
+	}
+	return 0;
+}
+
 int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg)
 {
 	unsigned char sha1[20], orig_sha1[20];
@@ -2535,30 +2620,9 @@
 		}
 	}
 
-	if (log && safe_create_leading_directories(git_path("logs/%s", newrefname))) {
-		error("unable to create directory for %s", newrefname);
+	if (log && rename_tmp_log(newrefname))
 		goto rollback;
-	}
 
- retry:
-	if (log && rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newrefname))) {
-		if (errno==EISDIR || errno==ENOTDIR) {
-			/*
-			 * rename(a, b) when b is an existing
-			 * directory ought to result in ISDIR, but
-			 * Solaris 5.8 gives ENOTDIR.  Sheesh.
-			 */
-			if (remove_empty_directories(git_path("logs/%s", newrefname))) {
-				error("Directory not empty: logs/%s", newrefname);
-				goto rollback;
-			}
-			goto retry;
-		} else {
-			error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
-				newrefname, strerror(errno));
-			goto rollback;
-		}
-	}
 	logmoved = log;
 
 	lock = lock_ref_sha1_basic(newrefname, NULL, 0, NULL);
@@ -2659,9 +2723,9 @@
 
 	git_snpath(logfile, bufsize, "logs/%s", refname);
 	if (log_all_ref_updates &&
-	    (!prefixcmp(refname, "refs/heads/") ||
-	     !prefixcmp(refname, "refs/remotes/") ||
-	     !prefixcmp(refname, "refs/notes/") ||
+	    (starts_with(refname, "refs/heads/") ||
+	     starts_with(refname, "refs/remotes/") ||
+	     starts_with(refname, "refs/notes/") ||
 	     !strcmp(refname, "HEAD"))) {
 		if (safe_create_leading_directories(logfile) < 0)
 			return error("unable to create directory for %s",
@@ -2731,7 +2795,7 @@
 
 static int is_branch(const char *refname)
 {
-	return !strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/");
+	return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
 }
 
 int write_ref_sha1(struct ref_lock *lock,
@@ -3169,12 +3233,13 @@
 	return retval;
 }
 
-int update_ref(const char *action, const char *refname,
-		const unsigned char *sha1, const unsigned char *oldval,
-		int flags, enum action_on_err onerr)
+static struct ref_lock *update_ref_lock(const char *refname,
+					const unsigned char *oldval,
+					int flags, int *type_p,
+					enum action_on_err onerr)
 {
-	static struct ref_lock *lock;
-	lock = lock_any_ref_for_update(refname, oldval, flags);
+	struct ref_lock *lock;
+	lock = lock_any_ref_for_update(refname, oldval, flags, type_p);
 	if (!lock) {
 		const char *str = "Cannot lock the ref '%s'.";
 		switch (onerr) {
@@ -3182,8 +3247,14 @@
 		case DIE_ON_ERR: die(str, refname); break;
 		case QUIET_ON_ERR: break;
 		}
-		return 1;
 	}
+	return lock;
+}
+
+static int update_ref_write(const char *action, const char *refname,
+			    const unsigned char *sha1, struct ref_lock *lock,
+			    enum action_on_err onerr)
+{
 	if (write_ref_sha1(lock, sha1, action) < 0) {
 		const char *str = "Cannot update the ref '%s'.";
 		switch (onerr) {
@@ -3196,35 +3267,115 @@
 	return 0;
 }
 
-struct ref *find_ref_by_name(const struct ref *list, const char *name)
+int update_ref(const char *action, const char *refname,
+	       const unsigned char *sha1, const unsigned char *oldval,
+	       int flags, enum action_on_err onerr)
 {
-	for ( ; list; list = list->next)
-		if (!strcmp(list->name, name))
-			return (struct ref *)list;
-	return NULL;
+	struct ref_lock *lock;
+	lock = update_ref_lock(refname, oldval, flags, NULL, onerr);
+	if (!lock)
+		return 1;
+	return update_ref_write(action, refname, sha1, lock, onerr);
 }
 
-/*
- * generate a format suitable for scanf from a ref_rev_parse_rules
- * rule, that is replace the "%.*s" spec with a "%s" spec
- */
-static void gen_scanf_fmt(char *scanf_fmt, const char *rule)
+static int ref_update_compare(const void *r1, const void *r2)
 {
-	char *spec;
+	const struct ref_update * const *u1 = r1;
+	const struct ref_update * const *u2 = r2;
+	return strcmp((*u1)->ref_name, (*u2)->ref_name);
+}
 
-	spec = strstr(rule, "%.*s");
-	if (!spec || strstr(spec + 4, "%.*s"))
-		die("invalid rule in ref_rev_parse_rules: %s", rule);
+static int ref_update_reject_duplicates(struct ref_update **updates, int n,
+					enum action_on_err onerr)
+{
+	int i;
+	for (i = 1; i < n; i++)
+		if (!strcmp(updates[i - 1]->ref_name, updates[i]->ref_name)) {
+			const char *str =
+				"Multiple updates for ref '%s' not allowed.";
+			switch (onerr) {
+			case MSG_ON_ERR:
+				error(str, updates[i]->ref_name); break;
+			case DIE_ON_ERR:
+				die(str, updates[i]->ref_name); break;
+			case QUIET_ON_ERR:
+				break;
+			}
+			return 1;
+		}
+	return 0;
+}
 
-	/* copy all until spec */
-	strncpy(scanf_fmt, rule, spec - rule);
-	scanf_fmt[spec - rule] = '\0';
-	/* copy new spec */
-	strcat(scanf_fmt, "%s");
-	/* copy remaining rule */
-	strcat(scanf_fmt, spec + 4);
+int update_refs(const char *action, const struct ref_update **updates_orig,
+		int n, enum action_on_err onerr)
+{
+	int ret = 0, delnum = 0, i;
+	struct ref_update **updates;
+	int *types;
+	struct ref_lock **locks;
+	const char **delnames;
 
-	return;
+	if (!updates_orig || !n)
+		return 0;
+
+	/* Allocate work space */
+	updates = xmalloc(sizeof(*updates) * n);
+	types = xmalloc(sizeof(*types) * n);
+	locks = xcalloc(n, sizeof(*locks));
+	delnames = xmalloc(sizeof(*delnames) * n);
+
+	/* Copy, sort, and reject duplicate refs */
+	memcpy(updates, updates_orig, sizeof(*updates) * n);
+	qsort(updates, n, sizeof(*updates), ref_update_compare);
+	ret = ref_update_reject_duplicates(updates, n, onerr);
+	if (ret)
+		goto cleanup;
+
+	/* Acquire all locks while verifying old values */
+	for (i = 0; i < n; i++) {
+		locks[i] = update_ref_lock(updates[i]->ref_name,
+					   (updates[i]->have_old ?
+					    updates[i]->old_sha1 : NULL),
+					   updates[i]->flags,
+					   &types[i], onerr);
+		if (!locks[i]) {
+			ret = 1;
+			goto cleanup;
+		}
+	}
+
+	/* Perform updates first so live commits remain referenced */
+	for (i = 0; i < n; i++)
+		if (!is_null_sha1(updates[i]->new_sha1)) {
+			ret = update_ref_write(action,
+					       updates[i]->ref_name,
+					       updates[i]->new_sha1,
+					       locks[i], onerr);
+			locks[i] = NULL; /* freed by update_ref_write */
+			if (ret)
+				goto cleanup;
+		}
+
+	/* Perform deletes now that updates are safely completed */
+	for (i = 0; i < n; i++)
+		if (locks[i]) {
+			delnames[delnum++] = locks[i]->ref_name;
+			ret |= delete_ref_loose(locks[i], types[i]);
+		}
+	ret |= repack_without_refs(delnames, delnum);
+	for (i = 0; i < delnum; i++)
+		unlink_or_warn(git_path("logs/%s", delnames[i]));
+	clear_loose_ref_cache(&ref_cache);
+
+cleanup:
+	for (i = 0; i < n; i++)
+		if (locks[i])
+			unlock_ref(locks[i]);
+	free(updates);
+	free(types);
+	free(locks);
+	free(delnames);
+	return ret;
 }
 
 char *shorten_unambiguous_ref(const char *refname, int strict)
@@ -3234,23 +3385,29 @@
 	static int nr_rules;
 	char *short_name;
 
-	/* pre generate scanf formats from ref_rev_parse_rules[] */
 	if (!nr_rules) {
+		/*
+		 * Pre-generate scanf formats from ref_rev_parse_rules[].
+		 * Generate a format suitable for scanf from a
+		 * ref_rev_parse_rules rule by interpolating "%s" at the
+		 * location of the "%.*s".
+		 */
 		size_t total_len = 0;
+		size_t offset = 0;
 
 		/* the rule list is NULL terminated, count them first */
-		for (; ref_rev_parse_rules[nr_rules]; nr_rules++)
-			/* no +1 because strlen("%s") < strlen("%.*s") */
-			total_len += strlen(ref_rev_parse_rules[nr_rules]);
+		for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
+			/* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
+			total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
 
 		scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);
 
-		total_len = 0;
+		offset = 0;
 		for (i = 0; i < nr_rules; i++) {
-			scanf_fmts[i] = (char *)&scanf_fmts[nr_rules]
-					+ total_len;
-			gen_scanf_fmt(scanf_fmts[i], ref_rev_parse_rules[i]);
-			total_len += strlen(ref_rev_parse_rules[i]);
+			assert(offset < total_len);
+			scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;
+			offset += snprintf(scanf_fmts[i], total_len - offset,
+					   ref_rev_parse_rules[i], 2, "%s") + 1;
 		}
 	}
 
@@ -3320,7 +3477,7 @@
 {
 	if (!strcmp("transfer.hiderefs", var) ||
 	    /* NEEDSWORK: use parse_config_key() once both are merged */
-	    (!prefixcmp(var, section) && var[strlen(section)] == '.' &&
+	    (starts_with(var, section) && var[strlen(section)] == '.' &&
 	     !strcmp(var + strlen(section), ".hiderefs"))) {
 		char *ref;
 		int len;
@@ -3348,7 +3505,7 @@
 		return 0;
 	for_each_string_list_item(item, hide_refs) {
 		int len;
-		if (prefixcmp(refname, item->string))
+		if (!starts_with(refname, item->string))
 			continue;
 		len = strlen(item->string);
 		if (!refname[len] || refname[len] == '/')
diff --git a/refs.h b/refs.h
index 9e5db3a..87a1a79 100644
--- a/refs.h
+++ b/refs.h
@@ -10,6 +10,20 @@
 	int force_write;
 };
 
+/**
+ * Information needed for a single ref update.  Set new_sha1 to the
+ * new value or to zero to delete the ref.  To check the old value
+ * while locking the ref, set have_old to 1 and set old_sha1 to the
+ * value or to zero to ensure the ref does not exist before update.
+ */
+struct ref_update {
+	const char *ref_name;
+	unsigned char new_sha1[20];
+	unsigned char old_sha1[20];
+	int flags; /* REF_NODEREF? */
+	int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
+};
+
 /*
  * Bit values set in the flags argument passed to each_ref_fn():
  */
@@ -137,7 +151,7 @@
 #define REF_NODEREF	0x01
 extern struct ref_lock *lock_any_ref_for_update(const char *refname,
 						const unsigned char *old_sha1,
-						int flags);
+						int flags, int *type_p);
 
 /** Close the file descriptor owned by a lock and return the status */
 extern int close_ref(struct ref_lock *lock);
@@ -151,14 +165,6 @@
 /** Writes sha1 into the ref specified by the lock. **/
 extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg);
 
-/*
- * Invalidate the reference cache for the specified submodule.  Use
- * submodule=NULL to invalidate the cache for the main module.  This
- * function must be called if references are changed via a mechanism
- * other than the refs API.
- */
-extern void invalidate_ref_cache(const char *submodule);
-
 /** Setup reflog before using. **/
 int log_ref_setup(const char *ref_name, char *logfile, int bufsize);
 
@@ -214,6 +220,12 @@
 		const unsigned char *sha1, const unsigned char *oldval,
 		int flags, enum action_on_err onerr);
 
+/**
+ * Lock all refs and then perform all modifications.
+ */
+int update_refs(const char *action, const struct ref_update **updates,
+		int n, enum action_on_err onerr);
+
 extern int parse_hide_refs_config(const char *var, const char *value, const char *);
 extern int ref_is_hidden(const char *);
 
diff --git a/remote-curl.c b/remote-curl.c
index ef1684b..10cb011 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -6,9 +6,11 @@
 #include "exec_cmd.h"
 #include "run-command.h"
 #include "pkt-line.h"
+#include "string-list.h"
 #include "sideband.h"
 #include "argv-array.h"
 #include "credential.h"
+#include "sha1-array.h"
 
 static struct remote *remote;
 /* always ends with a trailing slash */
@@ -18,11 +20,15 @@
 	int verbosity;
 	unsigned long depth;
 	unsigned progress : 1,
+		check_self_contained_and_connected : 1,
+		cloning : 1,
+		update_shallow : 1,
 		followtags : 1,
 		dry_run : 1,
 		thin : 1;
 };
 static struct options options;
+static struct string_list cas_options = STRING_LIST_INIT_DUP;
 
 static int set_option(const char *name, const char *value)
 {
@@ -69,7 +75,38 @@
 			return -1;
 		return 0;
 	}
-	else {
+	else if (!strcmp(name, "check-connectivity")) {
+		if (!strcmp(value, "true"))
+			options.check_self_contained_and_connected = 1;
+		else if (!strcmp(value, "false"))
+			options.check_self_contained_and_connected = 0;
+		else
+			return -1;
+		return 0;
+	}
+	else if (!strcmp(name, "cas")) {
+		struct strbuf val = STRBUF_INIT;
+		strbuf_addf(&val, "--" CAS_OPT_NAME "=%s", value);
+		string_list_append(&cas_options, val.buf);
+		strbuf_release(&val);
+		return 0;
+	} else if (!strcmp(name, "cloning")) {
+		if (!strcmp(value, "true"))
+			options.cloning = 1;
+		else if (!strcmp(value, "false"))
+			options.cloning = 0;
+		else
+			return -1;
+		return 0;
+	} else if (!strcmp(name, "update-shallow")) {
+		if (!strcmp(value, "true"))
+			options.update_shallow = 1;
+		else if (!strcmp(value, "false"))
+			options.update_shallow = 0;
+		else
+			return -1;
+		return 0;
+	} else {
 		return 1 /* unsupported */;
 	}
 }
@@ -80,6 +117,7 @@
 	char *buf;
 	size_t len;
 	struct ref *refs;
+	struct sha1_array shallow;
 	unsigned proto_git : 1;
 };
 static struct discovery *last_discovery;
@@ -88,7 +126,7 @@
 {
 	struct ref *list = NULL;
 	get_remote_heads(-1, heads->buf, heads->len, &list,
-			 for_push ? REF_NORMAL : 0, NULL);
+			 for_push ? REF_NORMAL : 0, NULL, &heads->shallow);
 	return list;
 }
 
@@ -149,6 +187,7 @@
 	if (d) {
 		if (d == last_discovery)
 			last_discovery = NULL;
+		free(d->shallow.sha1);
 		free(d->buf_alloc);
 		free_refs(d->refs);
 		free(d);
@@ -198,7 +237,7 @@
 	free_discovery(last);
 
 	strbuf_addf(&refs_url, "%sinfo/refs", url.buf);
-	if ((!prefixcmp(url.buf, "http://") || !prefixcmp(url.buf, "https://")) &&
+	if ((starts_with(url.buf, "http://") || starts_with(url.buf, "https://")) &&
 	     git_env_bool("GIT_SMART_HTTP", 1)) {
 		maybe_smart = 1;
 		if (!strchr(url.buf, '?'))
@@ -375,25 +414,29 @@
 	return size;
 }
 
-static int run_slot(struct active_request_slot *slot)
+static int run_slot(struct active_request_slot *slot,
+		    struct slot_results *results)
 {
 	int err;
-	struct slot_results results;
+	struct slot_results results_buf;
 
-	slot->results = &results;
+	if (!results)
+		results = &results_buf;
+
+	slot->results = results;
 	slot->curl_result = curl_easy_perform(slot->curl);
 	finish_active_slot(slot);
 
-	err = handle_curl_result(&results);
+	err = handle_curl_result(results);
 	if (err != HTTP_OK && err != HTTP_REAUTH) {
 		error("RPC failed; result=%d, HTTP code = %ld",
-		      results.curl_result, results.http_code);
+		      results->curl_result, results->http_code);
 	}
 
 	return err;
 }
 
-static int probe_rpc(struct rpc_state *rpc)
+static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)
 {
 	struct active_request_slot *slot;
 	struct curl_slist *headers = NULL;
@@ -415,7 +458,7 @@
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
 	curl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);
 
-	err = run_slot(slot);
+	err = run_slot(slot, results);
 
 	curl_slist_free_all(headers);
 	strbuf_release(&buf);
@@ -430,6 +473,7 @@
 	char *gzip_body = NULL;
 	size_t gzip_size = 0;
 	int err, large_request = 0;
+	int needs_100_continue = 0;
 
 	/* Try to load the entire request, if we can fit it into the
 	 * allocated buffer space we can use HTTP/1.0 and avoid the
@@ -453,18 +497,24 @@
 	}
 
 	if (large_request) {
+		struct slot_results results;
+
 		do {
-			err = probe_rpc(rpc);
+			err = probe_rpc(rpc, &results);
 			if (err == HTTP_REAUTH)
 				credential_fill(&http_auth);
 		} while (err == HTTP_REAUTH);
 		if (err != HTTP_OK)
 			return -1;
+
+		if (results.auth_avail & CURLAUTH_GSSNEGOTIATE)
+			needs_100_continue = 1;
 	}
 
 	headers = curl_slist_append(headers, rpc->hdr_content_type);
 	headers = curl_slist_append(headers, rpc->hdr_accept);
-	headers = curl_slist_append(headers, "Expect:");
+	headers = curl_slist_append(headers, needs_100_continue ?
+		"Expect: 100-continue" : "Expect:");
 
 retry:
 	slot = get_active_slot();
@@ -555,7 +605,7 @@
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, rpc_in);
 	curl_easy_setopt(slot->curl, CURLOPT_FILE, rpc);
 
-	err = run_slot(slot);
+	err = run_slot(slot, NULL);
 	if (err == HTTP_REAUTH && !large_request) {
 		credential_fill(&http_auth);
 		goto retry;
@@ -669,7 +719,7 @@
 	struct strbuf preamble = STRBUF_INIT;
 	char *depth_arg = NULL;
 	int argc = 0, i, err;
-	const char *argv[15];
+	const char *argv[17];
 
 	argv[argc++] = "fetch-pack";
 	argv[argc++] = "--stateless-rpc";
@@ -683,6 +733,12 @@
 		argv[argc++] = "-v";
 		argv[argc++] = "-v";
 	}
+	if (options.check_self_contained_and_connected)
+		argv[argc++] = "--check-self-contained-and-connected";
+	if (options.cloning)
+		argv[argc++] = "--cloning";
+	if (options.update_shallow)
+		argv[argc++] = "--update-shallow";
 	if (!options.progress)
 		argv[argc++] = "--no-progress";
 	if (options.depth) {
@@ -698,7 +754,8 @@
 		struct ref *ref = to_fetch[i];
 		if (!ref->name || !*ref->name)
 			die("cannot fetch by sha1 over smart http");
-		packet_buf_write(&preamble, "%s\n", ref->name);
+		packet_buf_write(&preamble, "%s %s\n",
+				 sha1_to_hex(ref->old_sha1), ref->name);
 	}
 	packet_buf_flush(&preamble);
 
@@ -734,7 +791,7 @@
 	int alloc_heads = 0, nr_heads = 0;
 
 	do {
-		if (!prefixcmp(buf->buf, "fetch ")) {
+		if (starts_with(buf->buf, "fetch ")) {
 			char *p = buf->buf + strlen("fetch ");
 			char *name;
 			struct ref *ref;
@@ -805,6 +862,7 @@
 	struct rpc_state rpc;
 	int i, err;
 	struct argv_array args;
+	struct string_list_item *cas_option;
 
 	argv_array_init(&args);
 	argv_array_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status",
@@ -819,6 +877,8 @@
 	else if (options.verbosity > 1)
 		argv_array_push(&args, "--verbose");
 	argv_array_push(&args, options.progress ? "--progress" : "--no-progress");
+	for_each_string_list_item(cas_option, &cas_options)
+		argv_array_push(&args, cas_option->string);
 	argv_array_push(&args, url.buf);
 	for (i = 0; i < nr_spec; i++)
 		argv_array_push(&args, specs[i]);
@@ -854,7 +914,7 @@
 	int alloc_spec = 0, nr_spec = 0, i, ret;
 
 	do {
-		if (!prefixcmp(buf->buf, "push ")) {
+		if (starts_with(buf->buf, "push ")) {
 			ALLOC_GROW(specs, nr_spec + 1, alloc_spec);
 			specs[nr_spec++] = xstrdup(buf->buf + 5);
 		}
@@ -917,19 +977,19 @@
 		}
 		if (buf.len == 0)
 			break;
-		if (!prefixcmp(buf.buf, "fetch ")) {
+		if (starts_with(buf.buf, "fetch ")) {
 			if (nongit)
 				die("Fetch attempted without a local repo");
 			parse_fetch(&buf);
 
-		} else if (!strcmp(buf.buf, "list") || !prefixcmp(buf.buf, "list ")) {
+		} else if (!strcmp(buf.buf, "list") || starts_with(buf.buf, "list ")) {
 			int for_push = !!strstr(buf.buf + 4, "for-push");
 			output_refs(get_refs(for_push));
 
-		} else if (!prefixcmp(buf.buf, "push ")) {
+		} else if (starts_with(buf.buf, "push ")) {
 			parse_push(&buf);
 
-		} else if (!prefixcmp(buf.buf, "option ")) {
+		} else if (starts_with(buf.buf, "option ")) {
 			char *name = buf.buf + strlen("option ");
 			char *value = strchr(name, ' ');
 			int result;
@@ -952,6 +1012,7 @@
 			printf("fetch\n");
 			printf("option\n");
 			printf("push\n");
+			printf("check-connectivity\n");
 			printf("\n");
 			fflush(stdout);
 		} else {
diff --git a/remote-testsvn.c b/remote-testsvn.c
index d7cd5d2..078f1ff 100644
--- a/remote-testsvn.c
+++ b/remote-testsvn.c
@@ -82,7 +82,7 @@
 		len = end ? end - msg : strlen(msg);
 
 		key = "Revision-number: ";
-		if (!prefixcmp(msg, key)) {
+		if (starts_with(msg, key)) {
 			long i;
 			char *end;
 			value = msg + strlen(key);
@@ -154,7 +154,7 @@
 	} else {
 		strbuf_addf(&sb, ":%d ", latestrev);
 		while (strbuf_getline(&line, marksfile, '\n') != EOF) {
-			if (!prefixcmp(line.buf, sb.buf)) {
+			if (starts_with(line.buf, sb.buf)) {
 				found++;
 				break;
 			}
@@ -264,7 +264,7 @@
 		return 1;	/* end of command stream, quit */
 	}
 	if (batch_cmd) {
-		if (prefixcmp(batch_cmd->name, line->buf))
+		if (!starts_with(batch_cmd->name, line->buf))
 			die("Active %s batch interrupted by %s", batch_cmd->name, line->buf);
 		/* buffer batch lines */
 		string_list_append(&batchlines, line->buf);
@@ -272,7 +272,7 @@
 	}
 
 	for (p = input_command_list; p->name; p++) {
-		if (!prefixcmp(line->buf, p->name) && (strlen(p->name) == line->len ||
+		if (starts_with(line->buf, p->name) && (strlen(p->name) == line->len ||
 				line->buf[strlen(p->name)] == ' ')) {
 			if (p->batchable) {
 				batch_cmd = p;
@@ -304,7 +304,7 @@
 	remote = remote_get(argv[1]);
 	url_in = (argc == 3) ? argv[2] : remote->url[0];
 
-	if (!prefixcmp(url_in, "file://")) {
+	if (starts_with(url_in, "file://")) {
 		dump_from_file = 1;
 		url = url_decode(url_in + sizeof("file://")-1);
 	} else {
diff --git a/remote.c b/remote.c
index efcba93..e41251e 100644
--- a/remote.c
+++ b/remote.c
@@ -76,7 +76,7 @@
 		if (!r->rewrite[i])
 			continue;
 		for (j = 0; j < r->rewrite[i]->instead_of_nr; j++) {
-			if (!prefixcmp(url, r->rewrite[i]->instead_of[j].s) &&
+			if (starts_with(url, r->rewrite[i]->instead_of[j].s) &&
 			    (!longest ||
 			     longest->len < r->rewrite[i]->instead_of[j].len)) {
 				longest = &(r->rewrite[i]->instead_of[j]);
@@ -148,6 +148,7 @@
 	}
 
 	ret = xcalloc(1, sizeof(struct remote));
+	ret->prune = -1;  /* unspecified */
 	ALLOC_GROW(remotes, remotes_nr + 1, remotes_alloc);
 	remotes[remotes_nr++] = ret;
 	if (len)
@@ -238,13 +239,13 @@
 		int value_list;
 		char *s, *p;
 
-		if (!prefixcmp(buffer, "URL:")) {
+		if (starts_with(buffer, "URL:")) {
 			value_list = 0;
 			s = buffer + 4;
-		} else if (!prefixcmp(buffer, "Push:")) {
+		} else if (starts_with(buffer, "Push:")) {
 			value_list = 1;
 			s = buffer + 5;
-		} else if (!prefixcmp(buffer, "Pull:")) {
+		} else if (starts_with(buffer, "Pull:")) {
 			value_list = 2;
 			s = buffer + 5;
 		} else
@@ -336,7 +337,7 @@
 	const char *subkey;
 	struct remote *remote;
 	struct branch *branch;
-	if (!prefixcmp(key, "branch.")) {
+	if (starts_with(key, "branch.")) {
 		name = key + 7;
 		subkey = strrchr(name, '.');
 		if (!subkey)
@@ -360,7 +361,7 @@
 		}
 		return 0;
 	}
-	if (!prefixcmp(key, "url.")) {
+	if (starts_with(key, "url.")) {
 		struct rewrite *rewrite;
 		name = key + 4;
 		subkey = strrchr(name, '.');
@@ -379,7 +380,7 @@
 		}
 	}
 
-	if (prefixcmp(key,  "remote."))
+	if (!starts_with(key,  "remote."))
 		return 0;
 	name = key + 7;
 
@@ -404,6 +405,8 @@
 		remote->skip_default_update = git_config_bool(key, value);
 	else if (!strcmp(subkey, ".skipfetchall"))
 		remote->skip_default_update = git_config_bool(key, value);
+	else if (!strcmp(subkey, ".prune"))
+		remote->prune = git_config_bool(key, value);
 	else if (!strcmp(subkey, ".url")) {
 		const char *v;
 		if (git_config_string(&v, key, value))
@@ -480,11 +483,11 @@
 	int flag;
 	if (default_remote_name) /* did this already */
 		return;
-	default_remote_name = xstrdup("origin");
+	default_remote_name = "origin";
 	current_branch = NULL;
 	head_ref = resolve_ref_unsafe("HEAD", sha1, 0, &flag);
 	if (head_ref && (flag & REF_ISSYMREF) &&
-	    !prefixcmp(head_ref, "refs/heads/")) {
+	    starts_with(head_ref, "refs/heads/")) {
 		current_branch =
 			make_branch(head_ref + strlen("refs/heads/"), 0);
 	}
@@ -742,35 +745,66 @@
 	return result;
 }
 
-void ref_remove_duplicates(struct ref *ref_map)
+static void handle_duplicate(struct ref *ref1, struct ref *ref2)
+{
+	if (strcmp(ref1->name, ref2->name)) {
+		if (ref1->fetch_head_status != FETCH_HEAD_IGNORE &&
+		    ref2->fetch_head_status != FETCH_HEAD_IGNORE) {
+			die(_("Cannot fetch both %s and %s to %s"),
+			    ref1->name, ref2->name, ref2->peer_ref->name);
+		} else if (ref1->fetch_head_status != FETCH_HEAD_IGNORE &&
+			   ref2->fetch_head_status == FETCH_HEAD_IGNORE) {
+			warning(_("%s usually tracks %s, not %s"),
+				ref2->peer_ref->name, ref2->name, ref1->name);
+		} else if (ref1->fetch_head_status == FETCH_HEAD_IGNORE &&
+			   ref2->fetch_head_status == FETCH_HEAD_IGNORE) {
+			die(_("%s tracks both %s and %s"),
+			    ref2->peer_ref->name, ref1->name, ref2->name);
+		} else {
+			/*
+			 * This last possibility doesn't occur because
+			 * FETCH_HEAD_IGNORE entries always appear at
+			 * the end of the list.
+			 */
+			die(_("Internal error"));
+		}
+	}
+	free(ref2->peer_ref);
+	free(ref2);
+}
+
+struct ref *ref_remove_duplicates(struct ref *ref_map)
 {
 	struct string_list refs = STRING_LIST_INIT_NODUP;
-	struct string_list_item *item = NULL;
-	struct ref *prev = NULL, *next = NULL;
-	for (; ref_map; prev = ref_map, ref_map = next) {
-		next = ref_map->next;
-		if (!ref_map->peer_ref)
-			continue;
+	struct ref *retval = NULL;
+	struct ref **p = &retval;
 
-		item = string_list_lookup(&refs, ref_map->peer_ref->name);
-		if (item) {
-			if (strcmp(((struct ref *)item->util)->name,
-				   ref_map->name))
-				die("%s tracks both %s and %s",
-				    ref_map->peer_ref->name,
-				    ((struct ref *)item->util)->name,
-				    ref_map->name);
-			prev->next = ref_map->next;
-			free(ref_map->peer_ref);
-			free(ref_map);
-			ref_map = prev; /* skip this; we freed it */
-			continue;
+	while (ref_map) {
+		struct ref *ref = ref_map;
+
+		ref_map = ref_map->next;
+		ref->next = NULL;
+
+		if (!ref->peer_ref) {
+			*p = ref;
+			p = &ref->next;
+		} else {
+			struct string_list_item *item =
+				string_list_insert(&refs, ref->peer_ref->name);
+
+			if (item->util) {
+				/* Entry already existed */
+				handle_duplicate((struct ref *)item->util, ref);
+			} else {
+				*p = ref;
+				p = &ref->next;
+				item->util = ref;
+			}
 		}
-
-		item = string_list_insert(&refs, ref_map->peer_ref->name);
-		item->util = ref_map;
 	}
+
 	string_list_clear(&refs, 0);
+	return retval;
 }
 
 int remote_has_url(struct remote *remote, const char *url)
@@ -818,10 +852,12 @@
 	return ret;
 }
 
-static int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
+int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
 {
 	int i;
 	int find_src = !query->src;
+	const char *needle = find_src ? query->dst : query->src;
+	char **result = find_src ? &query->src : &query->dst;
 
 	if (find_src && !query->dst)
 		return error("query_refspecs: need either src or dst");
@@ -830,8 +866,6 @@
 		struct refspec *refspec = &refs[i];
 		const char *key = find_src ? refspec->dst : refspec->src;
 		const char *value = find_src ? refspec->src : refspec->dst;
-		const char *needle = find_src ? query->dst : query->src;
-		char **result = find_src ? &query->src : &query->dst;
 
 		if (!refspec->dst)
 			continue;
@@ -952,9 +986,9 @@
 	*l = llist_mergesort(*l, ref_list_get_next, ref_list_set_next, cmp);
 }
 
-static int count_refspec_match(const char *pattern,
-			       struct ref *refs,
-			       struct ref **matched_ref)
+int count_refspec_match(const char *pattern,
+			struct ref *refs,
+			struct ref **matched_ref)
 {
 	int patlen = strlen(pattern);
 	struct ref *matched_weak = NULL;
@@ -966,7 +1000,7 @@
 		char *name = refs->name;
 		int namelen = strlen(name);
 
-		if (!refname_match(pattern, name, ref_rev_parse_rules))
+		if (!refname_match(pattern, name))
 			continue;
 
 		/* A match is "weak" if it is with refs outside
@@ -979,8 +1013,8 @@
 		 */
 		if (namelen != patlen &&
 		    patlen != namelen - 5 &&
-		    prefixcmp(name, "refs/heads/") &&
-		    prefixcmp(name, "refs/tags/")) {
+		    !starts_with(name, "refs/heads/") &&
+		    !starts_with(name, "refs/tags/")) {
 			/* We want to catch the case where only weak
 			 * matches are found and there are multiple
 			 * matches, and where more than one strong
@@ -1051,9 +1085,9 @@
 	if (!r)
 		return NULL;
 
-	if (!prefixcmp(r, "refs/heads/"))
+	if (starts_with(r, "refs/heads/"))
 		strbuf_addstr(&buf, "refs/heads/");
-	else if (!prefixcmp(r, "refs/tags/"))
+	else if (starts_with(r, "refs/tags/"))
 		strbuf_addstr(&buf, "refs/tags/");
 	else
 		return NULL;
@@ -1101,7 +1135,7 @@
 		dst_value = resolve_ref_unsafe(matched_src->name, sha1, 1, &flag);
 		if (!dst_value ||
 		    ((flag & REF_ISSYMREF) &&
-		     prefixcmp(dst_value, "refs/heads/")))
+		     !starts_with(dst_value, "refs/heads/")))
 			die("%s cannot be resolved to branch.",
 			    matched_src->name);
 	}
@@ -1190,7 +1224,7 @@
 		 * including refs outside refs/heads/ hierarchy, but
 		 * that does not make much sense these days.
 		 */
-		if (!send_mirror && prefixcmp(ref->name, "refs/heads/"))
+		if (!send_mirror && !starts_with(ref->name, "refs/heads/"))
 			return NULL;
 		name = xstrdup(ref->name);
 	}
@@ -1245,7 +1279,7 @@
 			add_to_tips(&sent_tips, ref->peer_ref->new_sha1);
 		else
 			add_to_tips(&sent_tips, ref->old_sha1);
-		if (!prefixcmp(ref->name, "refs/tags/"))
+		if (starts_with(ref->name, "refs/tags/"))
 			string_list_append(&dst_tag, ref->name);
 	}
 	clear_commit_marks_many(sent_tips.nr, sent_tips.tip, TMP_MARK);
@@ -1254,7 +1288,7 @@
 
 	/* Collect tags they do not have. */
 	for (ref = src; ref; ref = ref->next) {
-		if (prefixcmp(ref->name, "refs/tags/"))
+		if (!starts_with(ref->name, "refs/tags/"))
 			continue; /* not a tag */
 		if (string_list_has_string(&dst_tag, ref->name))
 			continue; /* they already have it */
@@ -1302,6 +1336,14 @@
 	free(sent_tips.tip);
 }
 
+struct ref *find_ref_by_name(const struct ref *list, const char *name)
+{
+	for ( ; list; list = list->next)
+		if (!strcmp(list->name, name))
+			return (struct ref *)list;
+	return NULL;
+}
+
 static void prepare_ref_index(struct string_list *ref_index, struct ref *ref)
 {
 	for ( ; ref; ref = ref->next)
@@ -1411,12 +1453,13 @@
 }
 
 void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
-	int force_update)
+			     int force_update)
 {
 	struct ref *ref;
 
 	for (ref = remote_refs; ref; ref = ref->next) {
 		int force_ref_update = ref->force || force_update;
+		int reject_reason = 0;
 
 		if (ref->peer_ref)
 			hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
@@ -1431,6 +1474,26 @@
 		}
 
 		/*
+		 * Bypass the usual "must fast-forward" check but
+		 * replace it with a weaker "the old value must be
+		 * this value we observed".  If the remote ref has
+		 * moved and is now different from what we expect,
+		 * reject any push.
+		 *
+		 * It also is an error if the user told us to check
+		 * with the remote-tracking branch to find the value
+		 * to expect, but we did not have such a tracking
+		 * branch.
+		 */
+		if (ref->expect_old_sha1) {
+			if (ref->expect_old_no_trackback ||
+			    hashcmp(ref->old_sha1, ref->old_sha1_expect))
+				reject_reason = REF_STATUS_REJECT_STALE;
+		}
+
+		/*
+		 * The usual "must fast-forward" rules.
+		 *
 		 * Decide whether an individual refspec A:B can be
 		 * pushed.  The push will succeed if any of the
 		 * following are true:
@@ -1448,24 +1511,26 @@
 		 *     passing the --force argument
 		 */
 
-		if (!ref->deletion && !is_null_sha1(ref->old_sha1)) {
-			int why = 0; /* why would this push require --force? */
-
-			if (!prefixcmp(ref->name, "refs/tags/"))
-				why = REF_STATUS_REJECT_ALREADY_EXISTS;
+		else if (!ref->deletion && !is_null_sha1(ref->old_sha1)) {
+			if (starts_with(ref->name, "refs/tags/"))
+				reject_reason = REF_STATUS_REJECT_ALREADY_EXISTS;
 			else if (!has_sha1_file(ref->old_sha1))
-				why = REF_STATUS_REJECT_FETCH_FIRST;
+				reject_reason = REF_STATUS_REJECT_FETCH_FIRST;
 			else if (!lookup_commit_reference_gently(ref->old_sha1, 1) ||
 				 !lookup_commit_reference_gently(ref->new_sha1, 1))
-				why = REF_STATUS_REJECT_NEEDS_FORCE;
+				reject_reason = REF_STATUS_REJECT_NEEDS_FORCE;
 			else if (!ref_newer(ref->new_sha1, ref->old_sha1))
-				why = REF_STATUS_REJECT_NONFASTFORWARD;
-
-			if (!force_ref_update)
-				ref->status = why;
-			else if (why)
-				ref->forced_update = 1;
+				reject_reason = REF_STATUS_REJECT_NONFASTFORWARD;
 		}
+
+		/*
+		 * "--force" will defeat any rejection implemented
+		 * by the rules above.
+		 */
+		if (!force_ref_update)
+			ref->status = reject_reason;
+		else if (reject_reason)
+			ref->forced_update = 1;
 	}
 }
 
@@ -1506,7 +1571,7 @@
 {
 	if (!branch || i < 0 || i >= branch->merge_nr)
 		return 0;
-	return refname_match(branch->merge[i]->src, refname, ref_fetch_rules);
+	return refname_match(branch->merge[i]->src, refname);
 }
 
 static int ignore_symref_update(const char *refname)
@@ -1519,6 +1584,13 @@
 	return (flag & REF_ISSYMREF);
 }
 
+/*
+ * Create and return a list of (struct ref) consisting of copies of
+ * each remote_ref that matches refspec.  refspec must be a pattern.
+ * Fill in the copies' peer_ref to describe the local tracking refs to
+ * which they map.  Omit any references that would map to an existing
+ * local symbolic ref.
+ */
 static struct ref *get_expanded_map(const struct ref *remote_refs,
 				    const struct refspec *refspec)
 {
@@ -1526,9 +1598,9 @@
 	struct ref *ret = NULL;
 	struct ref **tail = &ret;
 
-	char *expn_name;
-
 	for (ref = remote_refs; ref; ref = ref->next) {
+		char *expn_name = NULL;
+
 		if (strchr(ref->name, '^'))
 			continue; /* a dereference item */
 		if (match_name_with_pattern(refspec->src, ref->name,
@@ -1537,12 +1609,12 @@
 			struct ref *cpy = copy_ref(ref);
 
 			cpy->peer_ref = alloc_ref(expn_name);
-			free(expn_name);
 			if (refspec->force)
 				cpy->peer_ref->force = 1;
 			*tail = cpy;
 			tail = &cpy->next;
 		}
+		free(expn_name);
 	}
 
 	return ret;
@@ -1552,7 +1624,7 @@
 {
 	const struct ref *ref;
 	for (ref = refs; ref; ref = ref->next) {
-		if (refname_match(name, ref->name, ref_fetch_rules))
+		if (refname_match(name, ref->name))
 			return ref;
 	}
 	return NULL;
@@ -1573,12 +1645,12 @@
 	if (!name || name[0] == '\0')
 		return NULL;
 
-	if (!prefixcmp(name, "refs/"))
+	if (starts_with(name, "refs/"))
 		return alloc_ref(name);
 
-	if (!prefixcmp(name, "heads/") ||
-	    !prefixcmp(name, "tags/") ||
-	    !prefixcmp(name, "remotes/"))
+	if (starts_with(name, "heads/") ||
+	    starts_with(name, "tags/") ||
+	    starts_with(name, "remotes/"))
 		return alloc_ref_with_prefix("refs/", 5, name);
 
 	return alloc_ref_with_prefix("refs/heads/", 11, name);
@@ -1613,7 +1685,7 @@
 
 	for (rmp = &ref_map; *rmp; ) {
 		if ((*rmp)->peer_ref) {
-			if (prefixcmp((*rmp)->peer_ref->name, "refs/") ||
+			if (!starts_with((*rmp)->peer_ref->name, "refs/") ||
 			    check_refname_format((*rmp)->peer_ref->name, 0)) {
 				struct ref *ignore = *rmp;
 				error("* Ignoring funny ref '%s' locally",
@@ -1695,7 +1767,11 @@
 }
 
 /*
- * Return true if there is anything to report, otherwise false.
+ * Compare a branch with its upstream, and save their differences (number
+ * of commits) in *num_ours and *num_theirs.
+ *
+ * Return 0 if branch has no upstream (no base), -1 if upstream is missing
+ * (with "gone" base), otherwise 1 (with base).
  */
 int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
 {
@@ -1706,34 +1782,30 @@
 	const char *rev_argv[10], *base;
 	int rev_argc;
 
-	/*
-	 * Nothing to report unless we are marked to build on top of
-	 * somebody else.
-	 */
+	/* Cannot stat unless we are marked to build on top of somebody else. */
 	if (!branch ||
 	    !branch->merge || !branch->merge[0] || !branch->merge[0]->dst)
 		return 0;
 
-	/*
-	 * If what we used to build on no longer exists, there is
-	 * nothing to report.
-	 */
+	/* Cannot stat if what we used to build on no longer exists */
 	base = branch->merge[0]->dst;
 	if (read_ref(base, sha1))
-		return 0;
+		return -1;
 	theirs = lookup_commit_reference(sha1);
 	if (!theirs)
-		return 0;
+		return -1;
 
 	if (read_ref(branch->refname, sha1))
-		return 0;
+		return -1;
 	ours = lookup_commit_reference(sha1);
 	if (!ours)
-		return 0;
+		return -1;
 
 	/* are we the same? */
-	if (theirs == ours)
-		return 0;
+	if (theirs == ours) {
+		*num_theirs = *num_ours = 0;
+		return 1;
+	}
 
 	/* Run "rev-list --left-right ours...theirs" internally... */
 	rev_argc = 0;
@@ -1775,31 +1847,53 @@
  */
 int format_tracking_info(struct branch *branch, struct strbuf *sb)
 {
-	int num_ours, num_theirs;
+	int ours, theirs;
 	const char *base;
+	int upstream_is_gone = 0;
 
-	if (!stat_tracking_info(branch, &num_ours, &num_theirs))
+	switch (stat_tracking_info(branch, &ours, &theirs)) {
+	case 0:
+		/* no base */
 		return 0;
+	case -1:
+		/* with "gone" base */
+		upstream_is_gone = 1;
+		break;
+	default:
+		/* with base */
+		break;
+	}
 
 	base = branch->merge[0]->dst;
 	base = shorten_unambiguous_ref(base, 0);
-	if (!num_theirs) {
+	if (upstream_is_gone) {
+		strbuf_addf(sb,
+			_("Your branch is based on '%s', but the upstream is gone.\n"),
+			base);
+		if (advice_status_hints)
+			strbuf_addf(sb,
+				_("  (use \"git branch --unset-upstream\" to fixup)\n"));
+	} else if (!ours && !theirs) {
+		strbuf_addf(sb,
+			_("Your branch is up-to-date with '%s'.\n"),
+			base);
+	} else if (!theirs) {
 		strbuf_addf(sb,
 			Q_("Your branch is ahead of '%s' by %d commit.\n",
 			   "Your branch is ahead of '%s' by %d commits.\n",
-			   num_ours),
-			base, num_ours);
+			   ours),
+			base, ours);
 		if (advice_status_hints)
 			strbuf_addf(sb,
 				_("  (use \"git push\" to publish your local commits)\n"));
-	} else if (!num_ours) {
+	} else if (!ours) {
 		strbuf_addf(sb,
 			Q_("Your branch is behind '%s' by %d commit, "
 			       "and can be fast-forwarded.\n",
 			   "Your branch is behind '%s' by %d commits, "
 			       "and can be fast-forwarded.\n",
-			   num_theirs),
-			base, num_theirs);
+			   theirs),
+			base, theirs);
 		if (advice_status_hints)
 			strbuf_addf(sb,
 				_("  (use \"git pull\" to update your local branch)\n"));
@@ -1811,8 +1905,8 @@
 			   "Your branch and '%s' have diverged,\n"
 			       "and have %d and %d different commits each, "
 			       "respectively.\n",
-			   num_theirs),
-			base, num_ours, num_theirs);
+			   theirs),
+			base, ours, theirs);
 		if (advice_status_hints)
 			strbuf_addf(sb,
 				_("  (use \"git pull\" to merge the remote branch into yours)\n"));
@@ -1875,7 +1969,7 @@
 	/* Look for another ref that points there */
 	for (r = refs; r; r = r->next) {
 		if (r != head &&
-		    !prefixcmp(r->name, "refs/heads/") &&
+		    starts_with(r->name, "refs/heads/") &&
 		    !hashcmp(r->old_sha1, head->old_sha1)) {
 			*tail = copy_ref(r);
 			tail = &((*tail)->next);
@@ -1936,3 +2030,121 @@
 	string_list_clear(&ref_names, 0);
 	return stale_refs;
 }
+
+/*
+ * Compare-and-swap
+ */
+void clear_cas_option(struct push_cas_option *cas)
+{
+	int i;
+
+	for (i = 0; i < cas->nr; i++)
+		free(cas->entry[i].refname);
+	free(cas->entry);
+	memset(cas, 0, sizeof(*cas));
+}
+
+static struct push_cas *add_cas_entry(struct push_cas_option *cas,
+				      const char *refname,
+				      size_t refnamelen)
+{
+	struct push_cas *entry;
+	ALLOC_GROW(cas->entry, cas->nr + 1, cas->alloc);
+	entry = &cas->entry[cas->nr++];
+	memset(entry, 0, sizeof(*entry));
+	entry->refname = xmemdupz(refname, refnamelen);
+	return entry;
+}
+
+int parse_push_cas_option(struct push_cas_option *cas, const char *arg, int unset)
+{
+	const char *colon;
+	struct push_cas *entry;
+
+	if (unset) {
+		/* "--no-<option>" */
+		clear_cas_option(cas);
+		return 0;
+	}
+
+	if (!arg) {
+		/* just "--<option>" */
+		cas->use_tracking_for_rest = 1;
+		return 0;
+	}
+
+	/* "--<option>=refname" or "--<option>=refname:value" */
+	colon = strchrnul(arg, ':');
+	entry = add_cas_entry(cas, arg, colon - arg);
+	if (!*colon)
+		entry->use_tracking = 1;
+	else if (get_sha1(colon + 1, entry->expect))
+		return error("cannot parse expected object name '%s'", colon + 1);
+	return 0;
+}
+
+int parseopt_push_cas_option(const struct option *opt, const char *arg, int unset)
+{
+	return parse_push_cas_option(opt->value, arg, unset);
+}
+
+int is_empty_cas(const struct push_cas_option *cas)
+{
+	return !cas->use_tracking_for_rest && !cas->nr;
+}
+
+/*
+ * Look at remote.fetch refspec and see if we have a remote
+ * tracking branch for the refname there.  Fill its current
+ * value in sha1[].
+ * If we cannot do so, return negative to signal an error.
+ */
+static int remote_tracking(struct remote *remote, const char *refname,
+			   unsigned char sha1[20])
+{
+	char *dst;
+
+	dst = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
+	if (!dst)
+		return -1; /* no tracking ref for refname at remote */
+	if (read_ref(dst, sha1))
+		return -1; /* we know what the tracking ref is but we cannot read it */
+	return 0;
+}
+
+static void apply_cas(struct push_cas_option *cas,
+		      struct remote *remote,
+		      struct ref *ref)
+{
+	int i;
+
+	/* Find an explicit --<option>=<name>[:<value>] entry */
+	for (i = 0; i < cas->nr; i++) {
+		struct push_cas *entry = &cas->entry[i];
+		if (!refname_match(entry->refname, ref->name))
+			continue;
+		ref->expect_old_sha1 = 1;
+		if (!entry->use_tracking)
+			hashcpy(ref->old_sha1_expect, cas->entry[i].expect);
+		else if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
+			ref->expect_old_no_trackback = 1;
+		return;
+	}
+
+	/* Are we using "--<option>" to cover all? */
+	if (!cas->use_tracking_for_rest)
+		return;
+
+	ref->expect_old_sha1 = 1;
+	if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
+		ref->expect_old_no_trackback = 1;
+}
+
+void apply_push_cas(struct push_cas_option *cas,
+		    struct remote *remote,
+		    struct ref *remote_refs)
+{
+	struct ref *ref;
+	for (ref = remote_refs; ref; ref = ref->next)
+		apply_cas(cas, remote, ref);
+}
diff --git a/remote.h b/remote.h
index cf56724..fb7647f 100644
--- a/remote.h
+++ b/remote.h
@@ -1,6 +1,8 @@
 #ifndef REMOTE_H
 #define REMOTE_H
 
+#include "parse-options.h"
+
 enum {
 	REMOTE_CONFIG,
 	REMOTE_REMOTES,
@@ -40,6 +42,7 @@
 	int fetch_tags;
 	int skip_default_update;
 	int mirror;
+	int prune;
 
 	const char *receivepack;
 	const char *uploadpack;
@@ -71,10 +74,62 @@
 
 extern const struct refspec *tag_refspec;
 
+struct ref {
+	struct ref *next;
+	unsigned char old_sha1[20];
+	unsigned char new_sha1[20];
+	unsigned char old_sha1_expect[20]; /* used by expect-old */
+	char *symref;
+	unsigned int
+		force:1,
+		forced_update:1,
+		expect_old_sha1:1,
+		expect_old_no_trackback:1,
+		deletion:1,
+		matched:1;
+
+	/*
+	 * Order is important here, as we write to FETCH_HEAD
+	 * in numeric order. And the default NOT_FOR_MERGE
+	 * should be 0, so that xcalloc'd structures get it
+	 * by default.
+	 */
+	enum {
+		FETCH_HEAD_MERGE = -1,
+		FETCH_HEAD_NOT_FOR_MERGE = 0,
+		FETCH_HEAD_IGNORE = 1
+	} fetch_head_status;
+
+	enum {
+		REF_STATUS_NONE = 0,
+		REF_STATUS_OK,
+		REF_STATUS_REJECT_NONFASTFORWARD,
+		REF_STATUS_REJECT_ALREADY_EXISTS,
+		REF_STATUS_REJECT_NODELETE,
+		REF_STATUS_REJECT_FETCH_FIRST,
+		REF_STATUS_REJECT_NEEDS_FORCE,
+		REF_STATUS_REJECT_STALE,
+		REF_STATUS_REJECT_SHALLOW,
+		REF_STATUS_UPTODATE,
+		REF_STATUS_REMOTE_REJECT,
+		REF_STATUS_EXPECTING_REPORT
+	} status;
+	char *remote_status;
+	struct ref *peer_ref; /* when renaming */
+	char name[FLEX_ARRAY]; /* more */
+};
+
+#define REF_NORMAL	(1u << 0)
+#define REF_HEADS	(1u << 1)
+#define REF_TAGS	(1u << 2)
+
+extern struct ref *find_ref_by_name(const struct ref *list, const char *name);
+
 struct ref *alloc_ref(const char *name);
 struct ref *copy_ref(const struct ref *ref);
 struct ref *copy_ref_list(const struct ref *ref);
 void sort_ref_list(struct ref **, int (*cmp)(const void *, const void *));
+extern int count_refspec_match(const char *, struct ref *refs, struct ref **matched_ref);
 int ref_compare_name(const void *, const void *);
 
 int check_ref_type(const struct ref *ref, int flags);
@@ -84,19 +139,30 @@
  */
 void free_refs(struct ref *ref);
 
+struct sha1_array;
+extern struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
+				     struct ref **list, unsigned int flags,
+				     struct sha1_array *extra_have,
+				     struct sha1_array *shallow);
+
 int resolve_remote_symref(struct ref *ref, struct ref *list);
 int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1);
 
 /*
- * Removes and frees any duplicate refs in the map.
+ * Remove and free all but the first of any entries in the input list
+ * that map the same remote reference to the same local reference.  If
+ * there are two entries that map different remote references to the
+ * same local reference, emit an error message and die.  Return a
+ * pointer to the head of the resulting list.
  */
-void ref_remove_duplicates(struct ref *ref_map);
+struct ref *ref_remove_duplicates(struct ref *ref_map);
 
 int valid_fetch_refspec(const char *refspec);
 struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec);
 
 void free_refspec(int nr_refspec, struct refspec *refspec);
 
+extern int query_refspecs(struct refspec *specs, int nr, struct refspec *query);
 char *apply_refspecs(struct refspec *refspecs, int nr_refspec,
 		     const char *name);
 
@@ -172,4 +238,27 @@
 /* Return refs which no longer exist on remote */
 struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fetch_map);
 
+/*
+ * Compare-and-swap
+ */
+#define CAS_OPT_NAME "force-with-lease"
+
+struct push_cas_option {
+	unsigned use_tracking_for_rest:1;
+	struct push_cas {
+		unsigned char expect[20];
+		unsigned use_tracking:1;
+		char *refname;
+	} *entry;
+	int nr;
+	int alloc;
+};
+
+extern int parseopt_push_cas_option(const struct option *, const char *arg, int unset);
+extern int parse_push_cas_option(struct push_cas_option *, const char *arg, int unset);
+extern void clear_cas_option(struct push_cas_option *);
+
+extern int is_empty_cas(const struct push_cas_option *);
+void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);
+
 #endif
diff --git a/replace_object.c b/replace_object.c
index d0b1548..cdcaf8c 100644
--- a/replace_object.c
+++ b/replace_object.c
@@ -97,9 +97,6 @@
 	int pos, depth = MAXREPLACEDEPTH;
 	const unsigned char *cur = sha1;
 
-	if (!read_replace_refs)
-		return sha1;
-
 	prepare_replace_object();
 
 	/* Try to recursively replace the object */
diff --git a/rerere.c b/rerere.c
index 6fde8f9..1f2d21a 100644
--- a/rerere.c
+++ b/rerere.c
@@ -6,6 +6,7 @@
 #include "resolve-undo.h"
 #include "ll-merge.h"
 #include "attr.h"
+#include "pathspec.h"
 
 #define RESOLVED 0
 #define PUNTED 1
@@ -656,7 +657,7 @@
 	return 0;
 }
 
-int rerere_forget(const char **pathspec)
+int rerere_forget(struct pathspec *pathspec)
 {
 	int i, fd;
 	struct string_list conflict = STRING_LIST_INIT_DUP;
@@ -671,8 +672,8 @@
 	find_conflict(&conflict);
 	for (i = 0; i < conflict.nr; i++) {
 		struct string_list_item *it = &conflict.items[i];
-		if (!match_pathspec(pathspec, it->string, strlen(it->string),
-				    0, NULL))
+		if (!match_pathspec_depth(pathspec, it->string, strlen(it->string),
+					  0, NULL))
 			continue;
 		rerere_forget_one_path(it->string, &merge_rr);
 	}
diff --git a/rerere.h b/rerere.h
index 156d2aa..4aa06c9 100644
--- a/rerere.h
+++ b/rerere.h
@@ -3,6 +3,8 @@
 
 #include "string-list.h"
 
+struct pathspec;
+
 #define RERERE_AUTOUPDATE   01
 #define RERERE_NOAUTOUPDATE 02
 
@@ -16,7 +18,7 @@
 extern int setup_rerere(struct string_list *, int);
 extern int rerere(int);
 extern const char *rerere_path(const char *hex, const char *file);
-extern int rerere_forget(const char **);
+extern int rerere_forget(struct pathspec *);
 extern int rerere_remaining(struct string_list *);
 extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
diff --git a/resolve-undo.c b/resolve-undo.c
index 77101f5..c09b006 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -173,7 +173,7 @@
 	}
 }
 
-void unmerge_index(struct index_state *istate, const char **pathspec)
+void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
 {
 	int i;
 
@@ -182,7 +182,7 @@
 
 	for (i = 0; i < istate->cache_nr; i++) {
 		const struct cache_entry *ce = istate->cache[i];
-		if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL))
+		if (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))
 			continue;
 		i = unmerge_index_entry_at(istate, i);
 	}
diff --git a/resolve-undo.h b/resolve-undo.h
index 7a30206..4630645 100644
--- a/resolve-undo.h
+++ b/resolve-undo.h
@@ -11,7 +11,7 @@
 extern struct string_list *resolve_undo_read(const char *, unsigned long);
 extern void resolve_undo_clear_index(struct index_state *);
 extern int unmerge_index_entry_at(struct index_state *, int);
-extern void unmerge_index(struct index_state *, const char **);
+extern void unmerge_index(struct index_state *, const struct pathspec *);
 extern void unmerge_marked_index(struct index_state *);
 
 #endif
diff --git a/revision.c b/revision.c
index f82b833..a0df72f 100644
--- a/revision.c
+++ b/revision.c
@@ -104,17 +104,12 @@
 	blob->object.flags |= UNINTERESTING;
 }
 
-void mark_tree_uninteresting(struct tree *tree)
+static void mark_tree_contents_uninteresting(struct tree *tree)
 {
 	struct tree_desc desc;
 	struct name_entry entry;
 	struct object *obj = &tree->object;
 
-	if (!tree)
-		return;
-	if (obj->flags & UNINTERESTING)
-		return;
-	obj->flags |= UNINTERESTING;
 	if (!has_sha1_file(obj->sha1))
 		return;
 	if (parse_tree(tree) < 0)
@@ -139,8 +134,19 @@
 	 * We don't care about the tree any more
 	 * after it has been marked uninteresting.
 	 */
-	free(tree->buffer);
-	tree->buffer = NULL;
+	free_tree_buffer(tree);
+}
+
+void mark_tree_uninteresting(struct tree *tree)
+{
+	struct object *obj = &tree->object;
+
+	if (!tree)
+		return;
+	if (obj->flags & UNINTERESTING)
+		return;
+	obj->flags |= UNINTERESTING;
+	mark_tree_contents_uninteresting(tree);
 }
 
 void mark_parents_uninteresting(struct commit *commit)
@@ -201,7 +207,7 @@
 		revs->no_walk = 0;
 	if (revs->reflog_info && obj->type == OBJ_COMMIT) {
 		struct strbuf buf = STRBUF_INIT;
-		int len = interpret_branch_name(name, &buf);
+		int len = interpret_branch_name(name, 0, &buf);
 		int st;
 
 		if (0 < len && name[len] && buf.len)
@@ -277,6 +283,7 @@
 				return NULL;
 			die("bad object %s", sha1_to_hex(tag->tagged->sha1));
 		}
+		object->flags |= flags;
 	}
 
 	/*
@@ -288,7 +295,6 @@
 		if (parse_commit(commit) < 0)
 			die("unable to parse commit %s", name);
 		if (flags & UNINTERESTING) {
-			commit->object.flags |= UNINTERESTING;
 			mark_parents_uninteresting(commit);
 			revs->limited = 1;
 		}
@@ -306,7 +312,7 @@
 		if (!revs->tree_objects)
 			return NULL;
 		if (flags & UNINTERESTING) {
-			mark_tree_uninteresting(tree);
+			mark_tree_contents_uninteresting(tree);
 			return NULL;
 		}
 		add_pending_object(revs, object, "");
@@ -317,13 +323,10 @@
 	 * Blob object? You know the drill by now..
 	 */
 	if (object->type == OBJ_BLOB) {
-		struct blob *blob = (struct blob *)object;
 		if (!revs->blob_objects)
 			return NULL;
-		if (flags & UNINTERESTING) {
-			mark_blob_uninteresting(blob);
+		if (flags & UNINTERESTING)
 			return NULL;
-		}
 		add_pending_object(revs, object, "");
 		return NULL;
 	}
@@ -1181,11 +1184,28 @@
 	const char *name_for_errormsg;
 };
 
+int ref_excluded(struct string_list *ref_excludes, const char *path)
+{
+	struct string_list_item *item;
+
+	if (!ref_excludes)
+		return 0;
+	for_each_string_list_item(item, ref_excludes) {
+		if (!fnmatch(item->string, path, 0))
+			return 1;
+	}
+	return 0;
+}
+
 static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
 {
 	struct all_refs_cb *cb = cb_data;
-	struct object *object = get_reference(cb->all_revs, path, sha1,
-					      cb->all_flags);
+	struct object *object;
+
+	if (ref_excluded(cb->all_revs->ref_excludes, path))
+	    return 0;
+
+	object = get_reference(cb->all_revs, path, sha1, cb->all_flags);
 	add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags);
 	add_pending_sha1(cb->all_revs, path, sha1, cb->all_flags);
 	return 0;
@@ -1198,6 +1218,24 @@
 	cb->all_flags = flags;
 }
 
+void clear_ref_exclusion(struct string_list **ref_excludes_p)
+{
+	if (*ref_excludes_p) {
+		string_list_clear(*ref_excludes_p, 0);
+		free(*ref_excludes_p);
+	}
+	*ref_excludes_p = NULL;
+}
+
+void add_ref_exclusion(struct string_list **ref_excludes_p, const char *exclude)
+{
+	if (!*ref_excludes_p) {
+		*ref_excludes_p = xcalloc(1, sizeof(**ref_excludes_p));
+		(*ref_excludes_p)->strdup_strings = 1;
+	}
+	string_list_append(*ref_excludes_p, exclude);
+}
+
 static void handle_refs(const char *submodule, struct rev_info *revs, unsigned flags,
 		int (*for_each)(const char *, each_ref_fn, void *))
 {
@@ -1373,7 +1411,8 @@
 			i++;
 	}
 	free_pathspec(&revs->prune_data);
-	init_pathspec(&revs->prune_data, prune);
+	parse_pathspec(&revs->prune_data, PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
+		       PATHSPEC_PREFER_FULL | PATHSPEC_LITERAL_PATH, "", prune);
 	revs->limited = 1;
 }
 
@@ -1519,7 +1558,7 @@
 static void append_prune_data(struct cmdline_pathspec *prune, const char **av)
 {
 	while (*av) {
-		ALLOC_GROW(prune->path, prune->nr+1, prune->alloc);
+		ALLOC_GROW(prune->path, prune->nr + 1, prune->alloc);
 		prune->path[prune->nr++] = *(av++);
 	}
 }
@@ -1531,7 +1570,7 @@
 		int len = sb->len;
 		if (len && sb->buf[len - 1] == '\n')
 			sb->buf[--len] = '\0';
-		ALLOC_GROW(prune->path, prune->nr+1, prune->alloc);
+		ALLOC_GROW(prune->path, prune->nr + 1, prune->alloc);
 		prune->path[prune->nr++] = xstrdup(sb->buf);
 	}
 }
@@ -1592,9 +1631,9 @@
 	    !strcmp(arg, "--tags") || !strcmp(arg, "--remotes") ||
 	    !strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
 	    !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
-	    !strcmp(arg, "--bisect") || !prefixcmp(arg, "--glob=") ||
-	    !prefixcmp(arg, "--branches=") || !prefixcmp(arg, "--tags=") ||
-	    !prefixcmp(arg, "--remotes=") || !prefixcmp(arg, "--no-walk="))
+	    !strcmp(arg, "--bisect") || starts_with(arg, "--glob=") ||
+	    starts_with(arg, "--branches=") || starts_with(arg, "--tags=") ||
+	    starts_with(arg, "--remotes=") || starts_with(arg, "--no-walk="))
 	{
 		unkv[(*unkc)++] = arg;
 		return 1;
@@ -1617,7 +1656,7 @@
 		revs->max_count = atoi(argv[1]);
 		revs->no_walk = 0;
 		return 2;
-	} else if (!prefixcmp(arg, "-n")) {
+	} else if (starts_with(arg, "-n")) {
 		revs->max_count = atoi(arg + 2);
 		revs->no_walk = 0;
 	} else if ((argcount = parse_long_opt("max-age", argv, &optarg))) {
@@ -1677,7 +1716,7 @@
 	} else if (!strcmp(arg, "--author-date-order")) {
 		revs->sort_order = REV_SORT_BY_AUTHOR_DATE;
 		revs->topo_order = 1;
-	} else if (!prefixcmp(arg, "--early-output")) {
+	} else if (starts_with(arg, "--early-output")) {
 		int count = 100;
 		switch (arg[14]) {
 		case '=':
@@ -1702,13 +1741,13 @@
 		revs->min_parents = 2;
 	} else if (!strcmp(arg, "--no-merges")) {
 		revs->max_parents = 1;
-	} else if (!prefixcmp(arg, "--min-parents=")) {
+	} else if (starts_with(arg, "--min-parents=")) {
 		revs->min_parents = atoi(arg+14);
-	} else if (!prefixcmp(arg, "--no-min-parents")) {
+	} else if (starts_with(arg, "--no-min-parents")) {
 		revs->min_parents = 0;
-	} else if (!prefixcmp(arg, "--max-parents=")) {
+	} else if (starts_with(arg, "--max-parents=")) {
 		revs->max_parents = atoi(arg+14);
-	} else if (!prefixcmp(arg, "--no-max-parents")) {
+	} else if (starts_with(arg, "--no-max-parents")) {
 		revs->max_parents = -1;
 	} else if (!strcmp(arg, "--boundary")) {
 		revs->boundary = 1;
@@ -1758,7 +1797,7 @@
 		revs->verify_objects = 1;
 	} else if (!strcmp(arg, "--unpacked")) {
 		revs->unpacked = 1;
-	} else if (!prefixcmp(arg, "--unpacked=")) {
+	} else if (starts_with(arg, "--unpacked=")) {
 		die("--unpacked=<packfile> no longer supported.");
 	} else if (!strcmp(arg, "-r")) {
 		revs->diff = 1;
@@ -1783,7 +1822,7 @@
 		revs->verbose_header = 1;
 		revs->pretty_given = 1;
 		get_commit_format(arg+8, revs);
-	} else if (!prefixcmp(arg, "--pretty=") || !prefixcmp(arg, "--format=")) {
+	} else if (starts_with(arg, "--pretty=") || starts_with(arg, "--format=")) {
 		/*
 		 * Detached form ("--pretty X" as opposed to "--pretty=X")
 		 * not allowed, since the argument is optional.
@@ -1797,12 +1836,12 @@
 		revs->notes_opt.use_default_notes = 1;
 	} else if (!strcmp(arg, "--show-signature")) {
 		revs->show_signature = 1;
-	} else if (!prefixcmp(arg, "--show-notes=") ||
-		   !prefixcmp(arg, "--notes=")) {
+	} else if (starts_with(arg, "--show-notes=") ||
+		   starts_with(arg, "--notes=")) {
 		struct strbuf buf = STRBUF_INIT;
 		revs->show_notes = 1;
 		revs->show_notes_given = 1;
-		if (!prefixcmp(arg, "--show-notes")) {
+		if (starts_with(arg, "--show-notes")) {
 			if (revs->notes_opt.use_default_notes < 0)
 				revs->notes_opt.use_default_notes = 1;
 			strbuf_addstr(&buf, arg+13);
@@ -1845,7 +1884,7 @@
 		revs->abbrev = 0;
 	} else if (!strcmp(arg, "--abbrev")) {
 		revs->abbrev = DEFAULT_ABBREV;
-	} else if (!prefixcmp(arg, "--abbrev=")) {
+	} else if (starts_with(arg, "--abbrev=")) {
 		revs->abbrev = strtoul(arg + 9, NULL, 10);
 		if (revs->abbrev < MINIMUM_ABBREV)
 			revs->abbrev = MINIMUM_ABBREV;
@@ -1969,40 +2008,51 @@
 	if (!strcmp(arg, "--all")) {
 		handle_refs(submodule, revs, *flags, for_each_ref_submodule);
 		handle_refs(submodule, revs, *flags, head_ref_submodule);
+		clear_ref_exclusion(&revs->ref_excludes);
 	} else if (!strcmp(arg, "--branches")) {
 		handle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);
+		clear_ref_exclusion(&revs->ref_excludes);
 	} else if (!strcmp(arg, "--bisect")) {
 		handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);
 		handle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);
 		revs->bisect = 1;
 	} else if (!strcmp(arg, "--tags")) {
 		handle_refs(submodule, revs, *flags, for_each_tag_ref_submodule);
+		clear_ref_exclusion(&revs->ref_excludes);
 	} else if (!strcmp(arg, "--remotes")) {
 		handle_refs(submodule, revs, *flags, for_each_remote_ref_submodule);
+		clear_ref_exclusion(&revs->ref_excludes);
 	} else if ((argcount = parse_long_opt("glob", argv, &optarg))) {
 		struct all_refs_cb cb;
 		init_all_refs_cb(&cb, revs, *flags);
 		for_each_glob_ref(handle_one_ref, optarg, &cb);
+		clear_ref_exclusion(&revs->ref_excludes);
 		return argcount;
-	} else if (!prefixcmp(arg, "--branches=")) {
+	} else if ((argcount = parse_long_opt("exclude", argv, &optarg))) {
+		add_ref_exclusion(&revs->ref_excludes, optarg);
+		return argcount;
+	} else if (starts_with(arg, "--branches=")) {
 		struct all_refs_cb cb;
 		init_all_refs_cb(&cb, revs, *flags);
 		for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb);
-	} else if (!prefixcmp(arg, "--tags=")) {
+		clear_ref_exclusion(&revs->ref_excludes);
+	} else if (starts_with(arg, "--tags=")) {
 		struct all_refs_cb cb;
 		init_all_refs_cb(&cb, revs, *flags);
 		for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb);
-	} else if (!prefixcmp(arg, "--remotes=")) {
+		clear_ref_exclusion(&revs->ref_excludes);
+	} else if (starts_with(arg, "--remotes=")) {
 		struct all_refs_cb cb;
 		init_all_refs_cb(&cb, revs, *flags);
 		for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
+		clear_ref_exclusion(&revs->ref_excludes);
 	} else if (!strcmp(arg, "--reflog")) {
 		handle_reflog(revs, *flags);
 	} else if (!strcmp(arg, "--not")) {
 		*flags ^= UNINTERESTING | BOTTOM;
 	} else if (!strcmp(arg, "--no-walk")) {
 		revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
-	} else if (!prefixcmp(arg, "--no-walk=")) {
+	} else if (starts_with(arg, "--no-walk=")) {
 		/*
 		 * Detached form ("--no-walk X" as opposed to "--no-walk=X")
 		 * not allowed, since the argument is optional.
@@ -2134,10 +2184,10 @@
 		 *	call init_pathspec() to set revs->prune_data here.
 		 * }
 		 */
-		ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
+		ALLOC_GROW(prune_data.path, prune_data.nr + 1, prune_data.alloc);
 		prune_data.path[prune_data.nr++] = NULL;
-		init_pathspec(&revs->prune_data,
-			      get_pathspec(revs->prefix, prune_data.path));
+		parse_pathspec(&revs->prune_data, 0, 0,
+			       revs->prefix, prune_data.path);
 	}
 
 	if (revs->def == NULL)
@@ -2170,12 +2220,13 @@
 		revs->limited = 1;
 
 	if (revs->prune_data.nr) {
-		diff_tree_setup_paths(revs->prune_data.raw, &revs->pruning);
+		copy_pathspec(&revs->pruning.pathspec, &revs->prune_data);
 		/* Can't prune commits with rename following: the paths change.. */
 		if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
 			revs->prune = 1;
 		if (!revs->full_diff)
-			diff_tree_setup_paths(revs->prune_data.raw, &revs->diffopt);
+			copy_pathspec(&revs->diffopt.pathspec,
+				      &revs->prune_data);
 	}
 	if (revs->combine_merges)
 		revs->ignore_merges = 0;
@@ -2986,7 +3037,7 @@
 	if (revs->max_count) {
 		c = get_revision_1(revs);
 		if (c) {
-			while (0 < revs->skip_count) {
+			while (revs->skip_count > 0) {
 				revs->skip_count--;
 				c = get_revision_1(revs);
 				if (!c)
@@ -3001,9 +3052,8 @@
 	if (c)
 		c->object.flags |= SHOWN;
 
-	if (!revs->boundary) {
+	if (!revs->boundary)
 		return c;
-	}
 
 	if (!c) {
 		/*
@@ -3049,9 +3099,8 @@
 
 	if (revs->reverse) {
 		reversed = NULL;
-		while ((c = get_revision_internal(revs))) {
+		while ((c = get_revision_internal(revs)))
 			commit_list_insert(c, &reversed);
-		}
 		revs->commits = reversed;
 		revs->reverse = 0;
 		revs->reverse_output_stage = 1;
diff --git a/revision.h b/revision.h
index e7f1d21..88967d6 100644
--- a/revision.h
+++ b/revision.h
@@ -5,6 +5,7 @@
 #include "grep.h"
 #include "notes.h"
 #include "commit.h"
+#include "diff.h"
 
 #define SEEN		(1u<<0)
 #define UNINTERESTING   (1u<<1)
@@ -60,6 +61,9 @@
 	/* The end-points specified by the end user */
 	struct rev_cmdline_info cmdline;
 
+	/* excluding from --branches, --refs, etc. expansion */
+	struct string_list *ref_excludes;
+
 	/* Basic information */
 	const char *prefix;
 	const char *def;
@@ -193,6 +197,11 @@
 	struct saved_parents *saved_parents_slab;
 };
 
+extern int ref_excluded(struct string_list *, const char *path);
+void clear_ref_exclusion(struct string_list **);
+void add_ref_exclusion(struct string_list **, const char *exclude);
+
+
 #define REV_TREE_SAME		0
 #define REV_TREE_NEW		1	/* Only new files */
 #define REV_TREE_OLD		2	/* Only files removed */
diff --git a/run-command.c b/run-command.c
index 1b7f88e..3914d9c 100644
--- a/run-command.c
+++ b/run-command.c
@@ -406,13 +406,12 @@
 					unsetenv(*cmd->env);
 			}
 		}
-		if (cmd->git_cmd) {
+		if (cmd->git_cmd)
 			execv_git_cmd(cmd->argv);
-		} else if (cmd->use_shell) {
+		else if (cmd->use_shell)
 			execv_shell_cmd(cmd->argv);
-		} else {
+		else
 			sane_execvp(cmd->argv[0], (char *const*) cmd->argv);
-		}
 		if (errno == ENOENT) {
 			if (!cmd->silent_exec_failure)
 				error("cannot run %s: %s", cmd->argv[0],
@@ -446,7 +445,6 @@
 		cmd->pid = -1;
 	}
 	close(notify_pipe[0]);
-
 }
 #else
 {
@@ -480,11 +478,10 @@
 	if (cmd->env)
 		env = make_augmented_environ(cmd->env);
 
-	if (cmd->git_cmd) {
+	if (cmd->git_cmd)
 		cmd->argv = prepare_git_cmd(cmd->argv);
-	} else if (cmd->use_shell) {
+	else if (cmd->use_shell)
 		cmd->argv = prepare_shell_cmd(cmd->argv);
-	}
 
 	cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env, cmd->dir,
 				  fhin, fhout, fherr);
diff --git a/send-pack.c b/send-pack.c
index 7d172ef..6129b0f 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -5,10 +5,12 @@
 #include "sideband.h"
 #include "run-command.h"
 #include "remote.h"
+#include "connect.h"
 #include "send-pack.h"
 #include "quote.h"
 #include "transport.h"
 #include "version.h"
+#include "sha1-array.h"
 
 static int feed_object(const unsigned char *sha1, int fd, int negative)
 {
@@ -27,7 +29,7 @@
 /*
  * Make a pack stream and spit it out into file descriptor fd
  */
-static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args)
+static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, struct send_pack_args *args)
 {
 	/*
 	 * The child becomes pack-objects --revs; we feed
@@ -70,7 +72,7 @@
 	 * parameters by writing to the pipe.
 	 */
 	for (i = 0; i < extra->nr; i++)
-		if (!feed_object(extra->array[i], po.in, 1))
+		if (!feed_object(extra->sha1[i], po.in, 1))
 			break;
 
 	while (refs) {
@@ -108,7 +110,7 @@
 	struct ref *hint;
 	int ret = 0;
 	char *line = packet_read_line(in, NULL);
-	if (prefixcmp(line, "unpack "))
+	if (!starts_with(line, "unpack "))
 		return error("did not receive remote status");
 	if (strcmp(line, "unpack ok")) {
 		error("unpack failed: %s", line + 7);
@@ -121,7 +123,7 @@
 		line = packet_read_line(in, NULL);
 		if (!line)
 			break;
-		if (prefixcmp(line, "ok ") && prefixcmp(line, "ng ")) {
+		if (!starts_with(line, "ok ") && !starts_with(line, "ng ")) {
 			error("invalid ref status from remote: %s", line);
 			ret = -1;
 			break;
@@ -173,10 +175,25 @@
 	return ret;
 }
 
+static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *cb)
+{
+	struct strbuf *sb = cb;
+	if (graft->nr_parent == -1)
+		packet_buf_write(sb, "shallow %s\n", sha1_to_hex(graft->sha1));
+	return 0;
+}
+
+static void advertise_shallow_grafts_buf(struct strbuf *sb)
+{
+	if (!is_repository_shallow())
+		return;
+	for_each_commit_graft(advertise_shallow_grafts_cb, sb);
+}
+
 int send_pack(struct send_pack_args *args,
 	      int fd[], struct child_process *conn,
 	      struct ref *remote_refs,
-	      struct extra_have_objects *extra_have)
+	      struct sha1_array *extra_have)
 {
 	int in = fd[0];
 	int out = fd[1];
@@ -205,6 +222,8 @@
 		quiet_supported = 1;
 	if (server_supports("agent"))
 		agent_supported = 1;
+	if (server_supports("no-thin"))
+		args->use_thin_pack = 0;
 
 	if (!remote_refs) {
 		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
@@ -212,6 +231,9 @@
 		return 0;
 	}
 
+	if (!args->dry_run)
+		advertise_shallow_grafts_buf(&req_buf);
+
 	/*
 	 * Finally, tell the other end!
 	 */
@@ -226,6 +248,7 @@
 		case REF_STATUS_REJECT_ALREADY_EXISTS:
 		case REF_STATUS_REJECT_FETCH_FIRST:
 		case REF_STATUS_REJECT_NEEDS_FORCE:
+		case REF_STATUS_REJECT_STALE:
 		case REF_STATUS_UPTODATE:
 			continue;
 		default:
@@ -270,7 +293,7 @@
 	}
 
 	if (args->stateless_rpc) {
-		if (!args->dry_run && cmds_sent) {
+		if (!args->dry_run && (cmds_sent || is_repository_shallow())) {
 			packet_buf_flush(&req_buf);
 			send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX);
 		}
@@ -300,8 +323,12 @@
 				shutdown(fd[0], SHUT_WR);
 			if (use_sideband)
 				finish_async(&demux);
+			fd[1] = -1;
 			return -1;
 		}
+		if (!args->stateless_rpc)
+			/* Closed by pack_objects() via start_command() */
+			fd[1] = -1;
 	}
 	if (args->stateless_rpc && cmds_sent)
 		packet_flush(out);
diff --git a/send-pack.h b/send-pack.h
index 05d7ab1..8e84392 100644
--- a/send-pack.h
+++ b/send-pack.h
@@ -16,6 +16,6 @@
 
 int send_pack(struct send_pack_args *args,
 	      int fd[], struct child_process *conn,
-	      struct ref *remote_refs, struct extra_have_objects *extra_have);
+	      struct ref *remote_refs, struct sha1_array *extra_have);
 
 #endif
diff --git a/sequencer.c b/sequencer.c
index 351548f..90cac7b 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -41,7 +41,7 @@
 	 * We only care that it looks roughly like (cherry picked from ...)
 	 */
 	return len > strlen(cherry_picked_prefix) + 1 &&
-		!prefixcmp(buf, cherry_picked_prefix) && buf[len - 1] == ')';
+		starts_with(buf, cherry_picked_prefix) && buf[len - 1] == ')';
 }
 
 /*
@@ -180,7 +180,7 @@
 	while (*p && *p != '\n') {
 		for (eol = p + 1; *eol && *eol != '\n'; eol++)
 			; /* do nothing */
-		if (!prefixcmp(p, "encoding ")) {
+		if (starts_with(p, "encoding ")) {
 			char *result = xmalloc(eol - 8 - p);
 			strlcpy(result, p + 9, eol - 8 - p);
 			return result;
@@ -279,7 +279,8 @@
 	read_cache();
 	if (checkout_fast_forward(from, to, 1))
 		exit(1); /* the callee should have complained already */
-	ref_lock = lock_any_ref_for_update("HEAD", unborn ? null_sha1 : from, 0);
+	ref_lock = lock_any_ref_for_update("HEAD", unborn ? null_sha1 : from,
+					   0, NULL);
 	strbuf_addf(&sb, "%s: fast-forward", action_name(opts));
 	ret = write_ref_sha1(ref_lock, to, sb.buf);
 	strbuf_release(&sb);
@@ -704,10 +705,10 @@
 	char *end_of_object_name;
 	int saved, status, padding;
 
-	if (!prefixcmp(bol, "pick")) {
+	if (starts_with(bol, "pick")) {
 		action = REPLAY_PICK;
 		bol += strlen("pick");
-	} else if (!prefixcmp(bol, "revert")) {
+	} else if (starts_with(bol, "revert")) {
 		action = REPLAY_REVERT;
 		bol += strlen("revert");
 	} else
diff --git a/setup.c b/setup.c
index 5262319..6c3f85f 100644
--- a/setup.c
+++ b/setup.c
@@ -5,7 +5,19 @@
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
 
-static char *prefix_path_gently(const char *prefix, int len, const char *path)
+/*
+ * Normalize "path", prepending the "prefix" for relative paths. If
+ * remaining_prefix is not NULL, return the actual prefix still
+ * remains in the path. For example, prefix = sub1/sub2/ and path is
+ *
+ *  foo          -> sub1/sub2/foo  (full prefix)
+ *  ../foo       -> sub1/foo       (remaining prefix is sub1/)
+ *  ../../bar    -> bar            (no remaining prefix)
+ *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)
+ *  `pwd`/../bar -> sub1/bar       (no remaining prefix)
+ */
+char *prefix_path_gently(const char *prefix, int len,
+			 int *remaining_prefix, const char *path)
 {
 	const char *orig = path;
 	char *sanitized;
@@ -13,13 +25,17 @@
 		const char *temp = real_path(path);
 		sanitized = xmalloc(len + strlen(temp) + 1);
 		strcpy(sanitized, temp);
+		if (remaining_prefix)
+			*remaining_prefix = 0;
 	} else {
 		sanitized = xmalloc(len + strlen(path) + 1);
 		if (len)
 			memcpy(sanitized, prefix, len);
 		strcpy(sanitized + len, path);
+		if (remaining_prefix)
+			*remaining_prefix = len;
 	}
-	if (normalize_path_copy(sanitized, sanitized))
+	if (normalize_path_copy_len(sanitized, sanitized, remaining_prefix))
 		goto error_out;
 	if (is_absolute_path(orig)) {
 		size_t root_len, len, total;
@@ -44,7 +60,7 @@
 
 char *prefix_path(const char *prefix, int len, const char *path)
 {
-	char *r = prefix_path_gently(prefix, len, path);
+	char *r = prefix_path_gently(prefix, len, NULL, path);
 	if (!r)
 		die("'%s' is outside repository", path);
 	return r;
@@ -53,7 +69,7 @@
 int path_inside_repo(const char *prefix, const char *path)
 {
 	int len = prefix ? strlen(prefix) : 0;
-	char *r = prefix_path_gently(prefix, len, path);
+	char *r = prefix_path_gently(prefix, len, NULL, path);
 	if (r) {
 		free(r);
 		return 1;
@@ -66,7 +82,7 @@
 	const char *name;
 	struct stat st;
 
-	if (!prefixcmp(arg, ":/")) {
+	if (starts_with(arg, ":/")) {
 		if (arg[2] == '\0') /* ":/" is root dir, always exists */
 			return 1;
 		name = arg + 2;
@@ -154,155 +170,6 @@
 	    "'git <command> [<revision>...] -- [<file>...]'", arg);
 }
 
-/*
- * Magic pathspec
- *
- * NEEDSWORK: These need to be moved to dir.h or even to a new
- * pathspec.h when we restructure get_pathspec() users to use the
- * "struct pathspec" interface.
- *
- * Possible future magic semantics include stuff like:
- *
- *	{ PATHSPEC_NOGLOB, '!', "noglob" },
- *	{ PATHSPEC_ICASE, '\0', "icase" },
- *	{ PATHSPEC_RECURSIVE, '*', "recursive" },
- *	{ PATHSPEC_REGEXP, '\0', "regexp" },
- *
- */
-#define PATHSPEC_FROMTOP    (1<<0)
-
-static struct pathspec_magic {
-	unsigned bit;
-	char mnemonic; /* this cannot be ':'! */
-	const char *name;
-} pathspec_magic[] = {
-	{ PATHSPEC_FROMTOP, '/', "top" },
-};
-
-/*
- * Take an element of a pathspec and check for magic signatures.
- * Append the result to the prefix.
- *
- * For now, we only parse the syntax and throw out anything other than
- * "top" magic.
- *
- * NEEDSWORK: This needs to be rewritten when we start migrating
- * get_pathspec() users to use the "struct pathspec" interface.  For
- * example, a pathspec element may be marked as case-insensitive, but
- * the prefix part must always match literally, and a single stupid
- * string cannot express such a case.
- */
-static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
-{
-	unsigned magic = 0;
-	const char *copyfrom = elt;
-	int i;
-
-	if (elt[0] != ':') {
-		; /* nothing to do */
-	} else if (elt[1] == '(') {
-		/* longhand */
-		const char *nextat;
-		for (copyfrom = elt + 2;
-		     *copyfrom && *copyfrom != ')';
-		     copyfrom = nextat) {
-			size_t len = strcspn(copyfrom, ",)");
-			if (copyfrom[len] == ',')
-				nextat = copyfrom + len + 1;
-			else
-				/* handle ')' and '\0' */
-				nextat = copyfrom + len;
-			if (!len)
-				continue;
-			for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
-				if (strlen(pathspec_magic[i].name) == len &&
-				    !strncmp(pathspec_magic[i].name, copyfrom, len)) {
-					magic |= pathspec_magic[i].bit;
-					break;
-				}
-			if (ARRAY_SIZE(pathspec_magic) <= i)
-				die("Invalid pathspec magic '%.*s' in '%s'",
-				    (int) len, copyfrom, elt);
-		}
-		if (*copyfrom != ')')
-			die("Missing ')' at the end of pathspec magic in '%s'", elt);
-		copyfrom++;
-	} else {
-		/* shorthand */
-		for (copyfrom = elt + 1;
-		     *copyfrom && *copyfrom != ':';
-		     copyfrom++) {
-			char ch = *copyfrom;
-
-			if (!is_pathspec_magic(ch))
-				break;
-			for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
-				if (pathspec_magic[i].mnemonic == ch) {
-					magic |= pathspec_magic[i].bit;
-					break;
-				}
-			if (ARRAY_SIZE(pathspec_magic) <= i)
-				die("Unimplemented pathspec magic '%c' in '%s'",
-				    ch, elt);
-		}
-		if (*copyfrom == ':')
-			copyfrom++;
-	}
-
-	if (magic & PATHSPEC_FROMTOP)
-		return xstrdup(copyfrom);
-	else
-		return prefix_path(prefix, prefixlen, copyfrom);
-}
-
-/*
- * N.B. get_pathspec() is deprecated in favor of the "struct pathspec"
- * based interface - see pathspec_magic above.
- *
- * Arguments:
- *  - prefix - a path relative to the root of the working tree
- *  - pathspec - a list of paths underneath the prefix path
- *
- * Iterates over pathspec, prepending each path with prefix,
- * and return the resulting list.
- *
- * If pathspec is empty, return a singleton list containing prefix.
- *
- * If pathspec and prefix are both empty, return an empty list.
- *
- * This is typically used by built-in commands such as add.c, in order
- * to normalize argv arguments provided to the built-in into a list of
- * paths to process, all relative to the root of the working tree.
- */
-const char **get_pathspec(const char *prefix, const char **pathspec)
-{
-	const char *entry = *pathspec;
-	const char **src, **dst;
-	int prefixlen;
-
-	if (!prefix && !entry)
-		return NULL;
-
-	if (!entry) {
-		static const char *spec[2];
-		spec[0] = prefix;
-		spec[1] = NULL;
-		return spec;
-	}
-
-	/* Otherwise we have to re-write the entries.. */
-	src = pathspec;
-	dst = pathspec;
-	prefixlen = prefix ? strlen(prefix) : 0;
-	while (*src) {
-		*(dst++) = prefix_pathspec(prefix, prefixlen, *src);
-		src++;
-	}
-	*dst = NULL;
-	if (!*pathspec)
-		return NULL;
-	return pathspec;
-}
 
 /*
  * Test if it looks like we're at a git directory.
@@ -360,7 +227,6 @@
 
 void setup_work_tree(void)
 {
-	struct strbuf sb = STRBUF_INIT;
 	const char *work_tree, *git_dir;
 	static int initialized = 0;
 
@@ -380,10 +246,8 @@
 	if (getenv(GIT_WORK_TREE_ENVIRONMENT))
 		setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
 
-	set_git_dir(relative_path(git_dir, work_tree, &sb));
+	set_git_dir(remove_leading_path(git_dir, work_tree));
 	initialized = 1;
-
-	strbuf_release(&sb);
 }
 
 static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
@@ -440,7 +304,7 @@
 	if (len != st.st_size)
 		die("Error reading %s", path);
 	buf[len] = '\0';
-	if (prefixcmp(buf, "gitdir: "))
+	if (!starts_with(buf, "gitdir: "))
 		die("Invalid gitfile format: %s", path);
 	while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
 		len--;
@@ -699,7 +563,7 @@
 {
 	const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
 	struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
-	static char cwd[PATH_MAX+1];
+	static char cwd[PATH_MAX + 1];
 	const char *gitdirenv, *ret;
 	char *gitfile;
 	int len, offset, offset_parent, ceil_offset = -1;
@@ -714,7 +578,7 @@
 	if (nongit_ok)
 		*nongit_ok = 0;
 
-	if (!getcwd(cwd, sizeof(cwd)-1))
+	if (!getcwd(cwd, sizeof(cwd) - 1))
 		die_errno("Unable to read current working directory");
 	offset = len = strlen(cwd);
 
diff --git a/sha1-lookup.c b/sha1-lookup.c
index c4dc55d..2dd8515 100644
--- a/sha1-lookup.c
+++ b/sha1-lookup.c
@@ -204,7 +204,54 @@
 			 * byte 0 thru (ofs-1) are the same between
 			 * lo and hi; ofs is the first byte that is
 			 * different.
+			 *
+			 * If ofs==20, then no bytes are different,
+			 * meaning we have entries with duplicate
+			 * keys. We know that we are in a solid run
+			 * of this entry (because the entries are
+			 * sorted, and our lo and hi are the same,
+			 * there can be nothing but this single key
+			 * in between). So we can stop the search.
+			 * Either one of these entries is it (and
+			 * we do not care which), or we do not have
+			 * it.
+			 *
+			 * Furthermore, we know that one of our
+			 * endpoints must be the edge of the run of
+			 * duplicates. For example, given this
+			 * sequence:
+			 *
+			 *     idx 0 1 2 3 4 5
+			 *     key A C C C C D
+			 *
+			 * If we are searching for "B", we might
+			 * hit the duplicate run at lo=1, hi=3
+			 * (e.g., by first mi=3, then mi=0). But we
+			 * can never have lo > 1, because B < C.
+			 * That is, if our key is less than the
+			 * run, we know that "lo" is the edge, but
+			 * we can say nothing of "hi". Similarly,
+			 * if our key is greater than the run, we
+			 * know that "hi" is the edge, but we can
+			 * say nothing of "lo".
+			 *
+			 * Therefore if we do not find it, we also
+			 * know where it would go if it did exist:
+			 * just on the far side of the edge that we
+			 * know about.
 			 */
+			if (ofs == 20) {
+				mi = lo;
+				mi_key = base + elem_size * mi + key_offset;
+				cmp = memcmp(mi_key, key, 20);
+				if (!cmp)
+					return mi;
+				if (cmp < 0)
+					return -1 - hi;
+				else
+					return -1 - lo;
+			}
+
 			hiv = hi_key[ofs_0];
 			if (ofs_0 < 19)
 				hiv = (hiv << 8) | hi_key[ofs_0+1];
diff --git a/sha1_file.c b/sha1_file.c
index 613839d..6e8c05d 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -105,50 +105,63 @@
 	return adjust_shared_perm(path);
 }
 
-int safe_create_leading_directories(char *path)
+enum scld_error safe_create_leading_directories(char *path)
 {
-	char *pos = path + offset_1st_component(path);
-	struct stat st;
+	char *next_component = path + offset_1st_component(path);
+	enum scld_error ret = SCLD_OK;
 
-	while (pos) {
-		pos = strchr(pos, '/');
-		if (!pos)
+	while (ret == SCLD_OK && next_component) {
+		struct stat st;
+		char *slash = next_component, slash_character;
+
+		while (*slash && !is_dir_sep(*slash))
+			slash++;
+
+		if (!*slash)
 			break;
-		while (*++pos == '/')
-			;
-		if (!*pos)
+
+		next_component = slash + 1;
+		while (is_dir_sep(*next_component))
+			next_component++;
+		if (!*next_component)
 			break;
-		*--pos = '\0';
+
+		slash_character = *slash;
+		*slash = '\0';
 		if (!stat(path, &st)) {
 			/* path exists */
-			if (!S_ISDIR(st.st_mode)) {
-				*pos = '/';
-				return -3;
-			}
-		}
-		else if (mkdir(path, 0777)) {
+			if (!S_ISDIR(st.st_mode))
+				ret = SCLD_EXISTS;
+		} else if (mkdir(path, 0777)) {
 			if (errno == EEXIST &&
-			    !stat(path, &st) && S_ISDIR(st.st_mode)) {
+			    !stat(path, &st) && S_ISDIR(st.st_mode))
 				; /* somebody created it since we checked */
-			} else {
-				*pos = '/';
-				return -1;
-			}
+			else if (errno == ENOENT)
+				/*
+				 * Either mkdir() failed because
+				 * somebody just pruned the containing
+				 * directory, or stat() failed because
+				 * the file that was in our way was
+				 * just removed.  Either way, inform
+				 * the caller that it might be worth
+				 * trying again:
+				 */
+				ret = SCLD_VANISHED;
+			else
+				ret = SCLD_FAILED;
+		} else if (adjust_shared_perm(path)) {
+			ret = SCLD_PERMS;
 		}
-		else if (adjust_shared_perm(path)) {
-			*pos = '/';
-			return -2;
-		}
-		*pos++ = '/';
+		*slash = slash_character;
 	}
-	return 0;
+	return ret;
 }
 
-int safe_create_leading_directories_const(const char *path)
+enum scld_error safe_create_leading_directories_const(const char *path)
 {
 	/* path points to cache entries, so xstrdup before messing with it */
 	char *buf = xstrdup(path);
-	int result = safe_create_leading_directories(buf);
+	enum scld_error result = safe_create_leading_directories(buf);
 	free(buf);
 	return result;
 }
@@ -614,7 +627,7 @@
 	}
 }
 
-static int unuse_one_window(struct packed_git *current, int keep_fd)
+static int unuse_one_window(struct packed_git *current)
 {
 	struct packed_git *p, *lru_p = NULL;
 	struct pack_window *lru_w = NULL, *lru_l = NULL;
@@ -628,15 +641,8 @@
 		pack_mapped -= lru_w->len;
 		if (lru_l)
 			lru_l->next = lru_w->next;
-		else {
+		else
 			lru_p->windows = lru_w->next;
-			if (!lru_p->windows && lru_p->pack_fd != -1
-				&& lru_p->pack_fd != keep_fd) {
-				close(lru_p->pack_fd);
-				pack_open_fds--;
-				lru_p->pack_fd = -1;
-			}
-		}
 		free(lru_w);
 		pack_open_windows--;
 		return 1;
@@ -644,10 +650,10 @@
 	return 0;
 }
 
-void release_pack_memory(size_t need, int fd)
+void release_pack_memory(size_t need)
 {
 	size_t cur = pack_mapped;
-	while (need >= (cur - pack_mapped) && unuse_one_window(NULL, fd))
+	while (need >= (cur - pack_mapped) && unuse_one_window(NULL))
 		; /* nothing */
 }
 
@@ -658,7 +664,7 @@
 	if (ret == MAP_FAILED) {
 		if (!length)
 			return NULL;
-		release_pack_memory(length, fd);
+		release_pack_memory(length);
 		ret = mmap(start, length, prot, flags, fd, offset);
 		if (ret == MAP_FAILED)
 			die_errno("Out of memory? mmap failed");
@@ -682,6 +688,83 @@
 	}
 }
 
+/*
+ * The LRU pack is the one with the oldest MRU window, preferring packs
+ * with no used windows, or the oldest mtime if it has no windows allocated.
+ */
+static void find_lru_pack(struct packed_git *p, struct packed_git **lru_p, struct pack_window **mru_w, int *accept_windows_inuse)
+{
+	struct pack_window *w, *this_mru_w;
+	int has_windows_inuse = 0;
+
+	/*
+	 * Reject this pack if it has windows and the previously selected
+	 * one does not.  If this pack does not have windows, reject
+	 * it if the pack file is newer than the previously selected one.
+	 */
+	if (*lru_p && !*mru_w && (p->windows || p->mtime > (*lru_p)->mtime))
+		return;
+
+	for (w = this_mru_w = p->windows; w; w = w->next) {
+		/*
+		 * Reject this pack if any of its windows are in use,
+		 * but the previously selected pack did not have any
+		 * inuse windows.  Otherwise, record that this pack
+		 * has windows in use.
+		 */
+		if (w->inuse_cnt) {
+			if (*accept_windows_inuse)
+				has_windows_inuse = 1;
+			else
+				return;
+		}
+
+		if (w->last_used > this_mru_w->last_used)
+			this_mru_w = w;
+
+		/*
+		 * Reject this pack if it has windows that have been
+		 * used more recently than the previously selected pack.
+		 * If the previously selected pack had windows inuse and
+		 * we have not encountered a window in this pack that is
+		 * inuse, skip this check since we prefer a pack with no
+		 * inuse windows to one that has inuse windows.
+		 */
+		if (*mru_w && *accept_windows_inuse == has_windows_inuse &&
+		    this_mru_w->last_used > (*mru_w)->last_used)
+			return;
+	}
+
+	/*
+	 * Select this pack.
+	 */
+	*mru_w = this_mru_w;
+	*lru_p = p;
+	*accept_windows_inuse = has_windows_inuse;
+}
+
+static int close_one_pack(void)
+{
+	struct packed_git *p, *lru_p = NULL;
+	struct pack_window *mru_w = NULL;
+	int accept_windows_inuse = 1;
+
+	for (p = packed_git; p; p = p->next) {
+		if (p->pack_fd == -1)
+			continue;
+		find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
+	}
+
+	if (lru_p) {
+		close(lru_p->pack_fd);
+		pack_open_fds--;
+		lru_p->pack_fd = -1;
+		return 1;
+	}
+
+	return 0;
+}
+
 void unuse_pack(struct pack_window **w_cursor)
 {
 	struct pack_window *w = *w_cursor;
@@ -737,15 +820,38 @@
 static unsigned int get_max_fd_limit(void)
 {
 #ifdef RLIMIT_NOFILE
-	struct rlimit lim;
+	{
+		struct rlimit lim;
 
-	if (getrlimit(RLIMIT_NOFILE, &lim))
-		die_errno("cannot get RLIMIT_NOFILE");
+		if (!getrlimit(RLIMIT_NOFILE, &lim))
+			return lim.rlim_cur;
+	}
+#endif
 
-	return lim.rlim_cur;
-#elif defined(_SC_OPEN_MAX)
-	return sysconf(_SC_OPEN_MAX);
-#elif defined(OPEN_MAX)
+#ifdef _SC_OPEN_MAX
+	{
+		long open_max = sysconf(_SC_OPEN_MAX);
+		if (0 < open_max)
+			return open_max;
+		/*
+		 * Otherwise, we got -1 for one of the two
+		 * reasons:
+		 *
+		 * (1) sysconf() did not understand _SC_OPEN_MAX
+		 *     and signaled an error with -1; or
+		 * (2) sysconf() said there is no limit.
+		 *
+		 * We _could_ clear errno before calling sysconf() to
+		 * tell these two cases apart and return a huge number
+		 * in the latter case to let the caller cap it to a
+		 * value that is not so selfish, but letting the
+		 * fallback OPEN_MAX codepath take care of these cases
+		 * is a lot simpler.
+		 */
+	}
+#endif
+
+#ifdef OPEN_MAX
 	return OPEN_MAX;
 #else
 	return 1; /* see the caller ;-) */
@@ -777,7 +883,7 @@
 			pack_max_fds = 1;
 	}
 
-	while (pack_max_fds <= pack_open_fds && unuse_one_window(NULL, -1))
+	while (pack_max_fds <= pack_open_fds && close_one_pack())
 		; /* nothing */
 
 	p->pack_fd = git_open_noatime(p->pack_name);
@@ -893,7 +999,7 @@
 			win->len = (size_t)len;
 			pack_mapped += win->len;
 			while (packed_git_limit < pack_mapped
-				&& unuse_one_window(p, p->pack_fd))
+				&& unuse_one_window(p))
 				; /* nothing */
 			win->base = xmmap(NULL, win->len,
 				PROT_READ, MAP_PRIVATE,
@@ -939,7 +1045,7 @@
 
 static void try_to_free_pack_memory(size_t size)
 {
-	release_pack_memory(size, -1);
+	release_pack_memory(size);
 }
 
 struct packed_git *add_packed_git(const char *path, int path_len, int local)
@@ -1372,51 +1478,6 @@
 	return map;
 }
 
-/*
- * There used to be a second loose object header format which
- * was meant to mimic the in-pack format, allowing for direct
- * copy of the object data.  This format turned up not to be
- * really worth it and we no longer write loose objects in that
- * format.
- */
-static int experimental_loose_object(unsigned char *map)
-{
-	unsigned int word;
-
-	/*
-	 * We must determine if the buffer contains the standard
-	 * zlib-deflated stream or the experimental format based
-	 * on the in-pack object format. Compare the header byte
-	 * for each format:
-	 *
-	 * RFC1950 zlib w/ deflate : 0www1000 : 0 <= www <= 7
-	 * Experimental pack-based : Stttssss : ttt = 1,2,3,4
-	 *
-	 * If bit 7 is clear and bits 0-3 equal 8, the buffer MUST be
-	 * in standard loose-object format, UNLESS it is a Git-pack
-	 * format object *exactly* 8 bytes in size when inflated.
-	 *
-	 * However, RFC1950 also specifies that the 1st 16-bit word
-	 * must be divisible by 31 - this checksum tells us our buffer
-	 * is in the standard format, giving a false positive only if
-	 * the 1st word of the Git-pack format object happens to be
-	 * divisible by 31, ie:
-	 *      ((byte0 * 256) + byte1) % 31 = 0
-	 *   =>        0ttt10000www1000 % 31 = 0
-	 *
-	 * As it happens, this case can only arise for www=3 & ttt=1
-	 * - ie, a Commit object, which would have to be 8 bytes in
-	 * size. As no Commit can be that small, we find that the
-	 * combination of these two criteria (bitmask & checksum)
-	 * can always correctly determine the buffer format.
-	 */
-	word = (map[0] << 8) + map[1];
-	if ((map[0] & 0x8F) == 0x08 && !(word % 31))
-		return 0;
-	else
-		return 1;
-}
-
 unsigned long unpack_object_header_buffer(const unsigned char *buf,
 		unsigned long len, enum object_type *type, unsigned long *sizep)
 {
@@ -1444,14 +1505,6 @@
 
 int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
 {
-	unsigned long size, used;
-	static const char valid_loose_object_type[8] = {
-		0, /* OBJ_EXT */
-		1, 1, 1, 1, /* "commit", "tree", "blob", "tag" */
-		0, /* "delta" and others are invalid in a loose object */
-	};
-	enum object_type type;
-
 	/* Get the data stream */
 	memset(stream, 0, sizeof(*stream));
 	stream->next_in = map;
@@ -1459,27 +1512,6 @@
 	stream->next_out = buffer;
 	stream->avail_out = bufsiz;
 
-	if (experimental_loose_object(map)) {
-		/*
-		 * The old experimental format we no longer produce;
-		 * we can still read it.
-		 */
-		used = unpack_object_header_buffer(map, mapsize, &type, &size);
-		if (!used || !valid_loose_object_type[type])
-			return -1;
-		map += used;
-		mapsize -= used;
-
-		/* Set up the stream for the rest.. */
-		stream->next_in = map;
-		stream->avail_in = mapsize;
-		git_inflate_init(stream);
-
-		/* And generate the fake traditional header */
-		stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
-						 typename(type), size);
-		return 0;
-	}
 	git_inflate_init(stream);
 	return git_inflate(stream, 0);
 }
@@ -1671,6 +1703,38 @@
 	return base_offset;
 }
 
+/*
+ * Like get_delta_base above, but we return the sha1 instead of the pack
+ * offset. This means it is cheaper for REF deltas (we do not have to do
+ * the final object lookup), but more expensive for OFS deltas (we
+ * have to load the revidx to convert the offset back into a sha1).
+ */
+static const unsigned char *get_delta_base_sha1(struct packed_git *p,
+						struct pack_window **w_curs,
+						off_t curpos,
+						enum object_type type,
+						off_t delta_obj_offset)
+{
+	if (type == OBJ_REF_DELTA) {
+		unsigned char *base = use_pack(p, w_curs, curpos, NULL);
+		return base;
+	} else if (type == OBJ_OFS_DELTA) {
+		struct revindex_entry *revidx;
+		off_t base_offset = get_delta_base(p, w_curs, &curpos,
+						   type, delta_obj_offset);
+
+		if (!base_offset)
+			return NULL;
+
+		revidx = find_pack_revindex(p, base_offset);
+		if (!revidx)
+			return NULL;
+
+		return nth_packed_object_sha1(p, revidx->nr);
+	} else
+		return NULL;
+}
+
 int unpack_object_header(struct packed_git *p,
 			 struct pack_window **w_curs,
 			 off_t *curpos,
@@ -1828,6 +1892,22 @@
 		}
 	}
 
+	if (oi->delta_base_sha1) {
+		if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
+			const unsigned char *base;
+
+			base = get_delta_base_sha1(p, &w_curs, curpos,
+						   type, obj_offset);
+			if (!base) {
+				type = OBJ_BAD;
+				goto out;
+			}
+
+			hashcpy(oi->delta_base_sha1, base);
+		} else
+			hashclr(oi->delta_base_sha1);
+	}
+
 out:
 	unuse_pack(&w_curs);
 	return type;
@@ -2056,6 +2136,16 @@
 		int i;
 		struct delta_base_cache_entry *ent;
 
+		ent = get_delta_base_cache_entry(p, curpos);
+		if (eq_delta_base_cache_entry(ent, p, curpos)) {
+			type = ent->type;
+			data = ent->data;
+			size = ent->size;
+			clear_delta_base_cache_entry(ent);
+			base_from_cache = 1;
+			break;
+		}
+
 		if (do_check_packed_object_crc && p->index_version > 1) {
 			struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
 			unsigned long len = revidx[1].offset - obj_offset;
@@ -2070,16 +2160,6 @@
 			}
 		}
 
-		ent = get_delta_base_cache_entry(p, curpos);
-		if (eq_delta_base_cache_entry(ent, p, curpos)) {
-			type = ent->type;
-			data = ent->data;
-			size = ent->size;
-			clear_delta_base_cache_entry(ent);
-			base_from_cache = 1;
-			break;
-		}
-
 		type = unpack_object_header(p, &w_curs, &curpos, &size);
 		if (type != OBJ_OFS_DELTA && type != OBJ_REF_DELTA)
 			break;
@@ -2411,17 +2491,23 @@
 	git_zstream stream;
 	char hdr[32];
 
+	if (oi->delta_base_sha1)
+		hashclr(oi->delta_base_sha1);
+
 	/*
 	 * If we don't care about type or size, then we don't
-	 * need to look inside the object at all.
+	 * need to look inside the object at all. Note that we
+	 * do not optimize out the stat call, even if the
+	 * caller doesn't care about the disk-size, since our
+	 * return value implicitly indicates whether the
+	 * object even exists.
 	 */
 	if (!oi->typep && !oi->sizep) {
-		if (oi->disk_sizep) {
-			struct stat st;
-			if (stat_sha1_file(sha1, &st) < 0)
-				return -1;
+		struct stat st;
+		if (stat_sha1_file(sha1, &st) < 0)
+			return -1;
+		if (oi->disk_sizep)
 			*oi->disk_sizep = st.st_size;
-		}
 		return 0;
 	}
 
@@ -2444,13 +2530,14 @@
 	return 0;
 }
 
-int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
+int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags)
 {
 	struct cached_object *co;
 	struct pack_entry e;
 	int rtype;
+	const unsigned char *real = lookup_replace_object_extended(sha1, flags);
 
-	co = find_cached_object(sha1);
+	co = find_cached_object(real);
 	if (co) {
 		if (oi->typep)
 			*(oi->typep) = co->type;
@@ -2458,27 +2545,29 @@
 			*(oi->sizep) = co->size;
 		if (oi->disk_sizep)
 			*(oi->disk_sizep) = 0;
+		if (oi->delta_base_sha1)
+			hashclr(oi->delta_base_sha1);
 		oi->whence = OI_CACHED;
 		return 0;
 	}
 
-	if (!find_pack_entry(sha1, &e)) {
+	if (!find_pack_entry(real, &e)) {
 		/* Most likely it's a loose object. */
-		if (!sha1_loose_object_info(sha1, oi)) {
+		if (!sha1_loose_object_info(real, oi)) {
 			oi->whence = OI_LOOSE;
 			return 0;
 		}
 
 		/* Not a loose object; someone else may have just packed it. */
 		reprepare_packed_git();
-		if (!find_pack_entry(sha1, &e))
+		if (!find_pack_entry(real, &e))
 			return -1;
 	}
 
 	rtype = packed_object_info(e.p, e.offset, oi);
 	if (rtype < 0) {
-		mark_bad_packed_object(e.p, sha1);
-		return sha1_object_info_extended(sha1, oi);
+		mark_bad_packed_object(e.p, real);
+		return sha1_object_info_extended(real, oi, 0);
 	} else if (in_delta_base_cache(e.p, e.offset)) {
 		oi->whence = OI_DBCACHED;
 	} else {
@@ -2500,7 +2589,7 @@
 
 	oi.typep = &type;
 	oi.sizep = sizep;
-	if (sha1_object_info_extended(sha1, &oi) < 0)
+	if (sha1_object_info_extended(sha1, &oi, LOOKUP_REPLACE_OBJECT) < 0)
 		return -1;
 	return type;
 }
@@ -2592,8 +2681,7 @@
 	void *data;
 	char *path;
 	const struct packed_git *p;
-	const unsigned char *repl = (flag & READ_SHA1_FILE_REPLACE)
-		? lookup_replace_object(sha1) : sha1;
+	const unsigned char *repl = lookup_replace_object_extended(sha1, flag);
 
 	errno = 0;
 	data = read_object(repl, type, size);
@@ -2787,7 +2875,9 @@
 		/* Make sure the directory exists */
 		memcpy(buffer, filename, dirlen);
 		buffer[dirlen-1] = 0;
-		if (mkdir(buffer, 0777) || adjust_shared_perm(buffer))
+		if (mkdir(buffer, 0777) && errno != EEXIST)
+			return -1;
+		if (adjust_shared_perm(buffer))
 			return -1;
 
 		/* Try again */
diff --git a/sha1_name.c b/sha1_name.c
index 65ad066..6fca869 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -343,7 +343,6 @@
 	return status;
 }
 
-
 int for_each_abbrev(const char *prefix, each_abbrev_fn fn, void *cb_data)
 {
 	char hex_pfx[40];
@@ -431,7 +430,7 @@
 }
 
 static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags);
-static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf);
+static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf);
 
 static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 {
@@ -452,9 +451,9 @@
 	int at, reflog_len, nth_prior = 0;
 
 	if (len == 40 && !get_sha1_hex(str, sha1)) {
-		if (warn_on_object_refname_ambiguity) {
+		if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) {
 			refs_found = dwim_ref(str, len, tmp_sha1, &real_ref);
-			if (refs_found > 0 && warn_ambiguous_refs) {
+			if (refs_found > 0) {
 				warning(warn_msg, len, str);
 				if (advice_object_name_warning)
 					fprintf(stderr, "%s\n", _(object_name_msg));
@@ -493,7 +492,7 @@
 		struct strbuf buf = STRBUF_INIT;
 		int detached;
 
-		if (interpret_nth_prior_checkout(str, &buf) > 0) {
+		if (interpret_nth_prior_checkout(str, len, &buf) > 0) {
 			detached = (buf.len == 40 && !get_sha1_hex(buf.buf, sha1));
 			strbuf_release(&buf);
 			if (detached)
@@ -547,7 +546,7 @@
 		if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
 				&co_time, &co_tz, &co_cnt)) {
 			if (!len) {
-				if (!prefixcmp(real_ref, "refs/heads/")) {
+				if (starts_with(real_ref, "refs/heads/")) {
 					str = real_ref + 11;
 					len = strlen(real_ref + 11);
 				} else {
@@ -582,8 +581,6 @@
 	if (ret)
 		return ret;
 	commit = lookup_commit_reference(sha1);
-	if (!commit)
-		return -1;
 	if (parse_commit(commit))
 		return -1;
 	if (!idx) {
@@ -677,13 +674,15 @@
 		return -1;
 
 	sp++; /* beginning of type name, or closing brace for empty */
-	if (!strncmp(commit_type, sp, 6) && sp[6] == '}')
+	if (starts_with(sp, "commit}"))
 		expected_type = OBJ_COMMIT;
-	else if (!strncmp(tree_type, sp, 4) && sp[4] == '}')
+	else if (starts_with(sp, "tag}"))
+		expected_type = OBJ_TAG;
+	else if (starts_with(sp, "tree}"))
 		expected_type = OBJ_TREE;
-	else if (!strncmp(blob_type, sp, 4) && sp[4] == '}')
+	else if (starts_with(sp, "blob}"))
 		expected_type = OBJ_BLOB;
-	else if (!prefixcmp(sp, "object}"))
+	else if (starts_with(sp, "object}"))
 		expected_type = OBJ_ANY;
 	else if (sp[0] == '}')
 		expected_type = OBJ_NONE;
@@ -910,7 +909,7 @@
 	const char *match = NULL, *target = NULL;
 	size_t len;
 
-	if (!prefixcmp(message, "checkout: moving from ")) {
+	if (starts_with(message, "checkout: moving from ")) {
 		match = message + strlen("checkout: moving from ");
 		target = strstr(match, " to ");
 	}
@@ -930,7 +929,8 @@
  * Parse @{-N} syntax, return the number of characters parsed
  * if successful; otherwise signal an error with negative value.
  */
-static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf)
+static int interpret_nth_prior_checkout(const char *name, int namelen,
+					struct strbuf *buf)
 {
 	long nth;
 	int retval;
@@ -938,9 +938,11 @@
 	const char *brace;
 	char *num_end;
 
+	if (namelen < 4)
+		return -1;
 	if (name[0] != '@' || name[1] != '{' || name[2] != '-')
 		return -1;
-	brace = strchr(name, '}');
+	brace = memchr(name, '}', namelen);
 	if (!brace)
 		return -1;
 	nth = strtol(name + 3, &num_end, 10);
@@ -1004,6 +1006,28 @@
 	return st;
 }
 
+/* parse @something syntax, when 'something' is not {.*} */
+static int interpret_empty_at(const char *name, int namelen, int len, struct strbuf *buf)
+{
+	const char *next;
+
+	if (len || name[1] == '{')
+		return -1;
+
+	/* make sure it's a single @, or @@{.*}, not @foo */
+	next = memchr(name + len + 1, '@', namelen - len - 1);
+	if (next && next[1] != '{')
+		return -1;
+	if (!next)
+		next = name + namelen;
+	if (next != name + 1)
+		return -1;
+
+	strbuf_reset(buf);
+	strbuf_add(buf, "HEAD", 4);
+	return 1;
+}
+
 static int reinterpret(const char *name, int namelen, int len, struct strbuf *buf)
 {
 	/* we have extra data, which might need further processing */
@@ -1012,7 +1036,7 @@
 	int ret;
 
 	strbuf_add(buf, name + len, namelen - len);
-	ret = interpret_branch_name(buf->buf, &tmp);
+	ret = interpret_branch_name(buf->buf, buf->len, &tmp);
 	/* that data was not interpreted, remove our cruft */
 	if (ret < 0) {
 		strbuf_setlen(buf, used);
@@ -1025,6 +1049,57 @@
 	return ret - used + len;
 }
 
+static void set_shortened_ref(struct strbuf *buf, const char *ref)
+{
+	char *s = shorten_unambiguous_ref(ref, 0);
+	strbuf_reset(buf);
+	strbuf_addstr(buf, s);
+	free(s);
+}
+
+static const char *get_upstream_branch(const char *branch_buf, int len)
+{
+	char *branch = xstrndup(branch_buf, len);
+	struct branch *upstream = branch_get(*branch ? branch : NULL);
+
+	/*
+	 * Upstream can be NULL only if branch refers to HEAD and HEAD
+	 * points to something different than a branch.
+	 */
+	if (!upstream)
+		die(_("HEAD does not point to a branch"));
+	if (!upstream->merge || !upstream->merge[0]->dst) {
+		if (!ref_exists(upstream->refname))
+			die(_("No such branch: '%s'"), branch);
+		if (!upstream->merge) {
+			die(_("No upstream configured for branch '%s'"),
+				upstream->name);
+		}
+		die(
+			_("Upstream branch '%s' not stored as a remote-tracking branch"),
+			upstream->merge[0]->src);
+	}
+	free(branch);
+
+	return upstream->merge[0]->dst;
+}
+
+static int interpret_upstream_mark(const char *name, int namelen,
+				   int at, struct strbuf *buf)
+{
+	int len;
+
+	len = upstream_mark(name + at, namelen - at);
+	if (!len)
+		return -1;
+
+	if (memchr(name, ':', at))
+		return -1;
+
+	set_shortened_ref(buf, get_upstream_branch(name, at));
+	return len + at;
+}
+
 /*
  * This reads short-hand syntax that not only evaluates to a commit
  * object name, but also can act as if the end user spelled the name
@@ -1046,13 +1121,14 @@
  * If the input was ok but there are not N branch switches in the
  * reflog, it returns 0.
  */
-int interpret_branch_name(const char *name, struct strbuf *buf)
+int interpret_branch_name(const char *name, int namelen, struct strbuf *buf)
 {
-	char *cp;
-	struct branch *upstream;
-	int namelen = strlen(name);
-	int len = interpret_nth_prior_checkout(name, buf);
-	int tmp_len;
+	char *at;
+	const char *start;
+	int len = interpret_nth_prior_checkout(name, namelen, buf);
+
+	if (!namelen)
+		namelen = strlen(name);
 
 	if (!len) {
 		return len; /* syntax Ok, not enough switches */
@@ -1063,44 +1139,26 @@
 			return reinterpret(name, namelen, len, buf);
 	}
 
-	cp = strchr(name, '@');
-	if (!cp)
-		return -1;
-	tmp_len = upstream_mark(cp, namelen - (cp - name));
-	if (!tmp_len)
-		return -1;
-	len = cp + tmp_len - name;
-	cp = xstrndup(name, cp - name);
-	upstream = branch_get(*cp ? cp : NULL);
-	/*
-	 * Upstream can be NULL only if cp refers to HEAD and HEAD
-	 * points to something different than a branch.
-	 */
-	if (!upstream)
-		die(_("HEAD does not point to a branch"));
-	if (!upstream->merge || !upstream->merge[0]->dst) {
-		if (!ref_exists(upstream->refname))
-			die(_("No such branch: '%s'"), cp);
-		if (!upstream->merge) {
-			die(_("No upstream configured for branch '%s'"),
-				upstream->name);
-		}
-		die(
-			_("Upstream branch '%s' not stored as a remote-tracking branch"),
-			upstream->merge[0]->src);
+	for (start = name;
+	     (at = memchr(start, '@', namelen - (start - name)));
+	     start = at + 1) {
+
+		len = interpret_empty_at(name, namelen, at - name, buf);
+		if (len > 0)
+			return reinterpret(name, namelen, len, buf);
+
+		len = interpret_upstream_mark(name, namelen, at - name, buf);
+		if (len > 0)
+			return len;
 	}
-	free(cp);
-	cp = shorten_unambiguous_ref(upstream->merge[0]->dst, 0);
-	strbuf_reset(buf);
-	strbuf_addstr(buf, cp);
-	free(cp);
-	return len;
+
+	return -1;
 }
 
 int strbuf_branchname(struct strbuf *sb, const char *name)
 {
 	int len = strlen(name);
-	int used = interpret_branch_name(name, sb);
+	int used = interpret_branch_name(name, len, sb);
 
 	if (used == len)
 		return 0;
@@ -1130,13 +1188,13 @@
 }
 
 /*
- * Many callers know that the user meant to name a committish by
+ * Many callers know that the user meant to name a commit-ish by
  * syntactical positions where the object name appears.  Calling this
  * function allows the machinery to disambiguate shorter-than-unique
- * abbreviated object names between committish and others.
+ * abbreviated object names between commit-ish and others.
  *
  * Note that this does NOT error out when the named object is not a
- * committish. It is merely to give a hint to the disambiguation
+ * commit-ish. It is merely to give a hint to the disambiguation
  * machinery.
  */
 int get_sha1_committish(const char *name, unsigned char *sha1)
@@ -1273,7 +1331,7 @@
 
 static char *resolve_relative_path(const char *rel)
 {
-	if (prefixcmp(rel, "./") && prefixcmp(rel, "../"))
+	if (!starts_with(rel, "./") && !starts_with(rel, "../"))
 		return NULL;
 
 	if (!startup_info)
diff --git a/shallow.c b/shallow.c
index cdf37d6..bbc98b5 100644
--- a/shallow.c
+++ b/shallow.c
@@ -2,15 +2,23 @@
 #include "commit.h"
 #include "tag.h"
 #include "pkt-line.h"
+#include "remote.h"
+#include "refs.h"
+#include "sha1-array.h"
+#include "diff.h"
+#include "revision.h"
+#include "commit-slab.h"
 
 static int is_shallow = -1;
 static struct stat shallow_stat;
 static char *alternate_shallow_file;
 
-void set_alternate_shallow_file(const char *path)
+void set_alternate_shallow_file(const char *path, int override)
 {
 	if (is_shallow != -1)
 		die("BUG: is_repository_shallow must not be called before set_alternate_shallow_file");
+	if (alternate_shallow_file && !override)
+		return;
 	free(alternate_shallow_file);
 	alternate_shallow_file = path ? xstrdup(path) : NULL;
 }
@@ -69,6 +77,7 @@
 	struct commit_list *result = NULL;
 	struct object_array stack = OBJECT_ARRAY_INIT;
 	struct commit *commit = NULL;
+	struct commit_graft *graft;
 
 	while (commit || i < heads->nr || stack.nr) {
 		struct commit_list *p;
@@ -90,10 +99,12 @@
 				cur_depth = *(int *)commit->util;
 			}
 		}
-		if (parse_commit(commit))
-			die("invalid commit");
+		parse_commit_or_die(commit);
 		cur_depth++;
-		if (cur_depth >= depth) {
+		if ((depth != INFINITE_DEPTH && cur_depth >= depth) ||
+		    (is_repository_shallow() && !commit->parents &&
+		     (graft = lookup_commit_graft(commit->object.sha1)) != NULL &&
+		     graft->nr_parent < 0)) {
 			commit_list_insert(commit, &result);
 			commit->object.flags |= shallow_flag;
 			commit = NULL;
@@ -143,10 +154,14 @@
 		die("shallow file was changed during fetch");
 }
 
+#define SEEN_ONLY 1
+#define VERBOSE   2
+
 struct write_shallow_data {
 	struct strbuf *out;
 	int use_pack_protocol;
 	int count;
+	unsigned flags;
 };
 
 static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
@@ -155,6 +170,15 @@
 	const char *hex = sha1_to_hex(graft->sha1);
 	if (graft->nr_parent != -1)
 		return 0;
+	if (data->flags & SEEN_ONLY) {
+		struct commit *c = lookup_commit(graft->sha1);
+		if (!c || !(c->object.flags & SEEN)) {
+			if (data->flags & VERBOSE)
+				printf("Removing %s from .git/shallow\n",
+				       sha1_to_hex(c->object.sha1));
+			return 0;
+		}
+	}
 	data->count++;
 	if (data->use_pack_protocol)
 		packet_buf_write(data->out, "shallow %s", hex);
@@ -165,22 +189,39 @@
 	return 0;
 }
 
-int write_shallow_commits(struct strbuf *out, int use_pack_protocol)
+static int write_shallow_commits_1(struct strbuf *out, int use_pack_protocol,
+				   const struct sha1_array *extra,
+				   unsigned flags)
 {
 	struct write_shallow_data data;
+	int i;
 	data.out = out;
 	data.use_pack_protocol = use_pack_protocol;
 	data.count = 0;
+	data.flags = flags;
 	for_each_commit_graft(write_one_shallow, &data);
+	if (!extra)
+		return data.count;
+	for (i = 0; i < extra->nr; i++) {
+		strbuf_addstr(out, sha1_to_hex(extra->sha1[i]));
+		strbuf_addch(out, '\n');
+		data.count++;
+	}
 	return data.count;
 }
 
-char *setup_temporary_shallow(void)
+int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
+			  const struct sha1_array *extra)
+{
+	return write_shallow_commits_1(out, use_pack_protocol, extra, 0);
+}
+
+char *setup_temporary_shallow(const struct sha1_array *extra)
 {
 	struct strbuf sb = STRBUF_INIT;
 	int fd;
 
-	if (write_shallow_commits(&sb, 0)) {
+	if (write_shallow_commits(&sb, 0, extra)) {
 		struct strbuf path = STRBUF_INIT;
 		strbuf_addstr(&path, git_path("shallow_XXXXXX"));
 		fd = xmkstemp(path.buf);
@@ -199,7 +240,8 @@
 }
 
 void setup_alternate_shallow(struct lock_file *shallow_lock,
-			     const char **alternate_shallow_file)
+			     const char **alternate_shallow_file,
+			     const struct sha1_array *extra)
 {
 	struct strbuf sb = STRBUF_INIT;
 	int fd;
@@ -207,7 +249,7 @@
 	check_shallow_file_for_update();
 	fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
 				       LOCK_DIE_ON_ERROR);
-	if (write_shallow_commits(&sb, 0)) {
+	if (write_shallow_commits(&sb, 0, extra)) {
 		if (write_in_full(fd, sb.buf, sb.len) != sb.len)
 			die_errno("failed to write to %s",
 				  shallow_lock->filename);
@@ -220,3 +262,415 @@
 		*alternate_shallow_file = "";
 	strbuf_release(&sb);
 }
+
+static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *cb)
+{
+	int fd = *(int *)cb;
+	if (graft->nr_parent == -1)
+		packet_write(fd, "shallow %s\n", sha1_to_hex(graft->sha1));
+	return 0;
+}
+
+void advertise_shallow_grafts(int fd)
+{
+	if (!is_repository_shallow())
+		return;
+	for_each_commit_graft(advertise_shallow_grafts_cb, &fd);
+}
+
+/*
+ * mark_reachable_objects() should have been run prior to this and all
+ * reachable commits marked as "SEEN".
+ */
+void prune_shallow(int show_only)
+{
+	static struct lock_file shallow_lock;
+	struct strbuf sb = STRBUF_INIT;
+	int fd;
+
+	if (show_only) {
+		write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY | VERBOSE);
+		strbuf_release(&sb);
+		return;
+	}
+	check_shallow_file_for_update();
+	fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
+				       LOCK_DIE_ON_ERROR);
+	if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
+		if (write_in_full(fd, sb.buf, sb.len) != sb.len)
+			die_errno("failed to write to %s",
+				  shallow_lock.filename);
+		commit_lock_file(&shallow_lock);
+	} else {
+		unlink(git_path("shallow"));
+		rollback_lock_file(&shallow_lock);
+	}
+	strbuf_release(&sb);
+}
+
+#define TRACE_KEY "GIT_TRACE_SHALLOW"
+
+/*
+ * Step 1, split sender shallow commits into "ours" and "theirs"
+ * Step 2, clean "ours" based on .git/shallow
+ */
+void prepare_shallow_info(struct shallow_info *info, struct sha1_array *sa)
+{
+	int i;
+	trace_printf_key(TRACE_KEY, "shallow: prepare_shallow_info\n");
+	memset(info, 0, sizeof(*info));
+	info->shallow = sa;
+	if (!sa)
+		return;
+	info->ours = xmalloc(sizeof(*info->ours) * sa->nr);
+	info->theirs = xmalloc(sizeof(*info->theirs) * sa->nr);
+	for (i = 0; i < sa->nr; i++) {
+		if (has_sha1_file(sa->sha1[i])) {
+			struct commit_graft *graft;
+			graft = lookup_commit_graft(sa->sha1[i]);
+			if (graft && graft->nr_parent < 0)
+				continue;
+			info->ours[info->nr_ours++] = i;
+		} else
+			info->theirs[info->nr_theirs++] = i;
+	}
+}
+
+void clear_shallow_info(struct shallow_info *info)
+{
+	free(info->ours);
+	free(info->theirs);
+}
+
+/* Step 4, remove non-existent ones in "theirs" after getting the pack */
+
+void remove_nonexistent_theirs_shallow(struct shallow_info *info)
+{
+	unsigned char (*sha1)[20] = info->shallow->sha1;
+	int i, dst;
+	trace_printf_key(TRACE_KEY, "shallow: remove_nonexistent_theirs_shallow\n");
+	for (i = dst = 0; i < info->nr_theirs; i++) {
+		if (i != dst)
+			info->theirs[dst] = info->theirs[i];
+		if (has_sha1_file(sha1[info->theirs[i]]))
+			dst++;
+	}
+	info->nr_theirs = dst;
+}
+
+define_commit_slab(ref_bitmap, uint32_t *);
+
+struct paint_info {
+	struct ref_bitmap ref_bitmap;
+	unsigned nr_bits;
+	char **slab;
+	char *free, *end;
+	unsigned slab_count;
+};
+
+static uint32_t *paint_alloc(struct paint_info *info)
+{
+	unsigned nr = (info->nr_bits + 31) / 32;
+	unsigned size = nr * sizeof(uint32_t);
+	void *p;
+	if (!info->slab_count || info->free + size > info->end) {
+		info->slab_count++;
+		info->slab = xrealloc(info->slab,
+				      info->slab_count * sizeof(*info->slab));
+		info->free = xmalloc(COMMIT_SLAB_SIZE);
+		info->slab[info->slab_count - 1] = info->free;
+		info->end = info->free + COMMIT_SLAB_SIZE;
+	}
+	p = info->free;
+	info->free += size;
+	return p;
+}
+
+/*
+ * Given a commit SHA-1, walk down to parents until either SEEN,
+ * UNINTERESTING or BOTTOM is hit. Set the id-th bit in ref_bitmap for
+ * all walked commits.
+ */
+static void paint_down(struct paint_info *info, const unsigned char *sha1,
+		       int id)
+{
+	unsigned int i, nr;
+	struct commit_list *head = NULL;
+	int bitmap_nr = (info->nr_bits + 31) / 32;
+	int bitmap_size = bitmap_nr * sizeof(uint32_t);
+	uint32_t *tmp = xmalloc(bitmap_size); /* to be freed before return */
+	uint32_t *bitmap = paint_alloc(info);
+	struct commit *c = lookup_commit_reference_gently(sha1, 1);
+	if (!c)
+		return;
+	memset(bitmap, 0, bitmap_size);
+	bitmap[id / 32] |= (1 << (id % 32));
+	commit_list_insert(c, &head);
+	while (head) {
+		struct commit_list *p;
+		struct commit *c = head->item;
+		uint32_t **refs = ref_bitmap_at(&info->ref_bitmap, c);
+
+		p = head;
+		head = head->next;
+		free(p);
+
+		/* XXX check "UNINTERESTING" from pack bitmaps if available */
+		if (c->object.flags & (SEEN | UNINTERESTING))
+			continue;
+		else
+			c->object.flags |= SEEN;
+
+		if (*refs == NULL)
+			*refs = bitmap;
+		else {
+			memcpy(tmp, *refs, bitmap_size);
+			for (i = 0; i < bitmap_nr; i++)
+				tmp[i] |= bitmap[i];
+			if (memcmp(tmp, *refs, bitmap_size)) {
+				*refs = paint_alloc(info);
+				memcpy(*refs, tmp, bitmap_size);
+			}
+		}
+
+		if (c->object.flags & BOTTOM)
+			continue;
+
+		if (parse_commit(c))
+			die("unable to parse commit %s",
+			    sha1_to_hex(c->object.sha1));
+
+		for (p = c->parents; p; p = p->next) {
+			uint32_t **p_refs = ref_bitmap_at(&info->ref_bitmap,
+							  p->item);
+			if (p->item->object.flags & SEEN)
+				continue;
+			if (*p_refs == NULL || *p_refs == *refs)
+				*p_refs = *refs;
+			commit_list_insert(p->item, &head);
+		}
+	}
+
+	nr = get_max_object_index();
+	for (i = 0; i < nr; i++) {
+		struct object *o = get_indexed_object(i);
+		if (o && o->type == OBJ_COMMIT)
+			o->flags &= ~SEEN;
+	}
+
+	free(tmp);
+}
+
+static int mark_uninteresting(const char *refname,
+			      const unsigned char *sha1,
+			      int flags, void *cb_data)
+{
+	struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+	if (!commit)
+		return 0;
+	commit->object.flags |= UNINTERESTING;
+	mark_parents_uninteresting(commit);
+	return 0;
+}
+
+static void post_assign_shallow(struct shallow_info *info,
+				struct ref_bitmap *ref_bitmap,
+				int *ref_status);
+/*
+ * Step 6(+7), associate shallow commits with new refs
+ *
+ * info->ref must be initialized before calling this function.
+ *
+ * If used is not NULL, it's an array of info->shallow->nr
+ * bitmaps. The n-th bit set in the m-th bitmap if ref[n] needs the
+ * m-th shallow commit from info->shallow.
+ *
+ * If used is NULL, "ours" and "theirs" are updated. And if ref_status
+ * is not NULL it's an array of ref->nr ints. ref_status[i] is true if
+ * the ref needs some shallow commits from either info->ours or
+ * info->theirs.
+ */
+void assign_shallow_commits_to_refs(struct shallow_info *info,
+				    uint32_t **used, int *ref_status)
+{
+	unsigned char (*sha1)[20] = info->shallow->sha1;
+	struct sha1_array *ref = info->ref;
+	unsigned int i, nr;
+	int *shallow, nr_shallow = 0;
+	struct paint_info pi;
+
+	trace_printf_key(TRACE_KEY, "shallow: assign_shallow_commits_to_refs\n");
+	shallow = xmalloc(sizeof(*shallow) * (info->nr_ours + info->nr_theirs));
+	for (i = 0; i < info->nr_ours; i++)
+		shallow[nr_shallow++] = info->ours[i];
+	for (i = 0; i < info->nr_theirs; i++)
+		shallow[nr_shallow++] = info->theirs[i];
+
+	/*
+	 * Prepare the commit graph to track what refs can reach what
+	 * (new) shallow commits.
+	 */
+	nr = get_max_object_index();
+	for (i = 0; i < nr; i++) {
+		struct object *o = get_indexed_object(i);
+		if (!o || o->type != OBJ_COMMIT)
+			continue;
+
+		o->flags &= ~(UNINTERESTING | BOTTOM | SEEN);
+	}
+
+	memset(&pi, 0, sizeof(pi));
+	init_ref_bitmap(&pi.ref_bitmap);
+	pi.nr_bits = ref->nr;
+
+	/*
+	 * "--not --all" to cut short the traversal if new refs
+	 * connect to old refs. If not (e.g. force ref updates) it'll
+	 * have to go down to the current shallow commits.
+	 */
+	head_ref(mark_uninteresting, NULL);
+	for_each_ref(mark_uninteresting, NULL);
+
+	/* Mark potential bottoms so we won't go out of bound */
+	for (i = 0; i < nr_shallow; i++) {
+		struct commit *c = lookup_commit(sha1[shallow[i]]);
+		c->object.flags |= BOTTOM;
+	}
+
+	for (i = 0; i < ref->nr; i++)
+		paint_down(&pi, ref->sha1[i], i);
+
+	if (used) {
+		int bitmap_size = ((pi.nr_bits + 31) / 32) * sizeof(uint32_t);
+		memset(used, 0, sizeof(*used) * info->shallow->nr);
+		for (i = 0; i < nr_shallow; i++) {
+			const struct commit *c = lookup_commit(sha1[shallow[i]]);
+			uint32_t **map = ref_bitmap_at(&pi.ref_bitmap, c);
+			if (*map)
+				used[shallow[i]] = xmemdupz(*map, bitmap_size);
+		}
+		/*
+		 * unreachable shallow commits are not removed from
+		 * "ours" and "theirs". The user is supposed to run
+		 * step 7 on every ref separately and not trust "ours"
+		 * and "theirs" any more.
+		 */
+	} else
+		post_assign_shallow(info, &pi.ref_bitmap, ref_status);
+
+	clear_ref_bitmap(&pi.ref_bitmap);
+	for (i = 0; i < pi.slab_count; i++)
+		free(pi.slab[i]);
+	free(pi.slab);
+	free(shallow);
+}
+
+struct commit_array {
+	struct commit **commits;
+	int nr, alloc;
+};
+
+static int add_ref(const char *refname,
+		   const unsigned char *sha1, int flags, void *cb_data)
+{
+	struct commit_array *ca = cb_data;
+	ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc);
+	ca->commits[ca->nr] = lookup_commit_reference_gently(sha1, 1);
+	if (ca->commits[ca->nr])
+		ca->nr++;
+	return 0;
+}
+
+static void update_refstatus(int *ref_status, int nr, uint32_t *bitmap)
+{
+	int i;
+	if (!ref_status)
+		return;
+	for (i = 0; i < nr; i++)
+		if (bitmap[i / 32] & (1 << (i % 32)))
+			ref_status[i]++;
+}
+
+/*
+ * Step 7, reachability test on "ours" at commit level
+ */
+static void post_assign_shallow(struct shallow_info *info,
+				struct ref_bitmap *ref_bitmap,
+				int *ref_status)
+{
+	unsigned char (*sha1)[20] = info->shallow->sha1;
+	struct commit *c;
+	uint32_t **bitmap;
+	int dst, i, j;
+	int bitmap_nr = (info->ref->nr + 31) / 32;
+	struct commit_array ca;
+
+	trace_printf_key(TRACE_KEY, "shallow: post_assign_shallow\n");
+	if (ref_status)
+		memset(ref_status, 0, sizeof(*ref_status) * info->ref->nr);
+
+	/* Remove unreachable shallow commits from "theirs" */
+	for (i = dst = 0; i < info->nr_theirs; i++) {
+		if (i != dst)
+			info->theirs[dst] = info->theirs[i];
+		c = lookup_commit(sha1[info->theirs[i]]);
+		bitmap = ref_bitmap_at(ref_bitmap, c);
+		if (!*bitmap)
+			continue;
+		for (j = 0; j < bitmap_nr; j++)
+			if (bitmap[0][j]) {
+				update_refstatus(ref_status, info->ref->nr, *bitmap);
+				dst++;
+				break;
+			}
+	}
+	info->nr_theirs = dst;
+
+	memset(&ca, 0, sizeof(ca));
+	head_ref(add_ref, &ca);
+	for_each_ref(add_ref, &ca);
+
+	/* Remove unreachable shallow commits from "ours" */
+	for (i = dst = 0; i < info->nr_ours; i++) {
+		if (i != dst)
+			info->ours[dst] = info->ours[i];
+		c = lookup_commit(sha1[info->ours[i]]);
+		bitmap = ref_bitmap_at(ref_bitmap, c);
+		if (!*bitmap)
+			continue;
+		for (j = 0; j < bitmap_nr; j++)
+			if (bitmap[0][j] &&
+			    /* Step 7, reachability test at commit level */
+			    !in_merge_bases_many(c, ca.nr, ca.commits)) {
+				update_refstatus(ref_status, info->ref->nr, *bitmap);
+				dst++;
+				break;
+			}
+	}
+	info->nr_ours = dst;
+
+	free(ca.commits);
+}
+
+/* (Delayed) step 7, reachability test at commit level */
+int delayed_reachability_test(struct shallow_info *si, int c)
+{
+	if (si->need_reachability_test[c]) {
+		struct commit *commit = lookup_commit(si->shallow->sha1[c]);
+
+		if (!si->commits) {
+			struct commit_array ca;
+			memset(&ca, 0, sizeof(ca));
+			head_ref(add_ref, &ca);
+			for_each_ref(add_ref, &ca);
+			si->commits = ca.commits;
+			si->nr_commits = ca.nr;
+		}
+
+		si->reachable[c] = in_merge_bases_many(commit,
+						       si->nr_commits,
+						       si->commits);
+		si->need_reachability_test[c] = 0;
+	}
+	return si->reachable[c];
+}
diff --git a/shell.c b/shell.c
index 66350b2..5c0d47a 100644
--- a/shell.c
+++ b/shell.c
@@ -15,7 +15,7 @@
 	setup_path();
 	if (!arg || !(arg = sq_dequote(arg)))
 		die("bad argument");
-	if (prefixcmp(me, "git-"))
+	if (!starts_with(me, "git-"))
 		die("bad command");
 
 	my_argv[0] = me + 4;
diff --git a/strbuf.c b/strbuf.c
index 1170d01..83caf4a 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,6 +1,15 @@
 #include "cache.h"
 #include "refs.h"
 
+int starts_with(const char *str, const char *prefix)
+{
+	for (; ; str++, prefix++)
+		if (!*prefix)
+			return 1;
+		else if (*str != *prefix)
+			return 0;
+}
+
 int prefixcmp(const char *str, const char *prefix)
 {
 	for (; ; str++, prefix++)
@@ -10,6 +19,15 @@
 			return (unsigned char)*prefix - (unsigned char)*str;
 }
 
+int ends_with(const char *str, const char *suffix)
+{
+	int len = strlen(str), suflen = strlen(suffix);
+	if (len < suflen)
+		return 0;
+	else
+		return !strcmp(str + len - suflen, suffix);
+}
+
 int suffixcmp(const char *str, const char *suffix)
 {
 	int len = strlen(str), suflen = strlen(suffix);
diff --git a/streaming.c b/streaming.c
index debe904..d7c9f32 100644
--- a/streaming.c
+++ b/streaming.c
@@ -113,7 +113,7 @@
 
 	oi->typep = type;
 	oi->sizep = &size;
-	status = sha1_object_info_extended(sha1, oi);
+	status = sha1_object_info_extended(sha1, oi, 0);
 	if (status < 0)
 		return stream_error;
 
@@ -538,7 +538,7 @@
 			goto close_and_exit;
 	}
 	if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
-		     write(fd, "", 1) != 1))
+		     xwrite(fd, "", 1) != 1))
 		goto close_and_exit;
 	result = 0;
 
diff --git a/submodule.c b/submodule.c
index c0f93c2..613857e 100644
--- a/submodule.c
+++ b/submodule.c
@@ -10,6 +10,7 @@
 #include "string-list.h"
 #include "sha1-array.h"
 #include "argv-array.h"
+#include "blob.h"
 
 static struct string_list config_name_for_path;
 static struct string_list config_fetch_recurse_submodules_for_name;
@@ -30,6 +31,118 @@
  */
 static int gitmodules_is_unmerged;
 
+/*
+ * This flag is set if the .gitmodules file had unstaged modifications on
+ * startup. This must be checked before allowing modifications to the
+ * .gitmodules file with the intention to stage them later, because when
+ * continuing we would stage the modifications the user didn't stage herself
+ * too. That might change in a future version when we learn to stage the
+ * changes we do ourselves without staging any previous modifications.
+ */
+static int gitmodules_is_modified;
+
+
+int is_staging_gitmodules_ok(void)
+{
+	return !gitmodules_is_modified;
+}
+
+/*
+ * Try to update the "path" entry in the "submodule.<name>" section of the
+ * .gitmodules file. Return 0 only if a .gitmodules file was found, a section
+ * with the correct path=<oldpath> setting was found and we could update it.
+ */
+int update_path_in_gitmodules(const char *oldpath, const char *newpath)
+{
+	struct strbuf entry = STRBUF_INIT;
+	struct string_list_item *path_option;
+
+	if (!file_exists(".gitmodules")) /* Do nothing without .gitmodules */
+		return -1;
+
+	if (gitmodules_is_unmerged)
+		die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
+
+	path_option = unsorted_string_list_lookup(&config_name_for_path, oldpath);
+	if (!path_option) {
+		warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
+		return -1;
+	}
+	strbuf_addstr(&entry, "submodule.");
+	strbuf_addstr(&entry, path_option->util);
+	strbuf_addstr(&entry, ".path");
+	if (git_config_set_in_file(".gitmodules", entry.buf, newpath) < 0) {
+		/* Maybe the user already did that, don't error out here */
+		warning(_("Could not update .gitmodules entry %s"), entry.buf);
+		strbuf_release(&entry);
+		return -1;
+	}
+	strbuf_release(&entry);
+	return 0;
+}
+
+/*
+ * Try to remove the "submodule.<name>" section from .gitmodules where the given
+ * path is configured. Return 0 only if a .gitmodules file was found, a section
+ * with the correct path=<path> setting was found and we could remove it.
+ */
+int remove_path_from_gitmodules(const char *path)
+{
+	struct strbuf sect = STRBUF_INIT;
+	struct string_list_item *path_option;
+
+	if (!file_exists(".gitmodules")) /* Do nothing without .gitmodules */
+		return -1;
+
+	if (gitmodules_is_unmerged)
+		die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
+
+	path_option = unsorted_string_list_lookup(&config_name_for_path, path);
+	if (!path_option) {
+		warning(_("Could not find section in .gitmodules where path=%s"), path);
+		return -1;
+	}
+	strbuf_addstr(&sect, "submodule.");
+	strbuf_addstr(&sect, path_option->util);
+	if (git_config_rename_section_in_file(".gitmodules", sect.buf, NULL) < 0) {
+		/* Maybe the user already did that, don't error out here */
+		warning(_("Could not remove .gitmodules entry for %s"), path);
+		strbuf_release(&sect);
+		return -1;
+	}
+	strbuf_release(&sect);
+	return 0;
+}
+
+void stage_updated_gitmodules(void)
+{
+	struct strbuf buf = STRBUF_INIT;
+	struct stat st;
+	int pos;
+	struct cache_entry *ce;
+	int namelen = strlen(".gitmodules");
+
+	pos = cache_name_pos(".gitmodules", namelen);
+	if (pos < 0) {
+		warning(_("could not find .gitmodules in index"));
+		return;
+	}
+	ce = active_cache[pos];
+	ce->ce_flags = namelen;
+	if (strbuf_read_file(&buf, ".gitmodules", 0) < 0)
+		die(_("reading updated .gitmodules failed"));
+	if (lstat(".gitmodules", &st) < 0)
+		die_errno(_("unable to stat updated .gitmodules"));
+	fill_stat_cache_info(ce, &st);
+	ce->ce_mode = ce_mode_from_stat(ce, st.st_mode);
+	if (remove_cache_entry_at(pos) < 0)
+		die(_("unable to remove .gitmodules from index"));
+	if (write_sha1_file(buf.buf, buf.len, blob_type, ce->sha1))
+		die(_("adding updated .gitmodules failed"));
+	if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
+		die(_("staging updated .gitmodules failed"));
+}
+
 static int add_submodule_odb(const char *path)
 {
 	struct strbuf objects_directory = STRBUF_INIT;
@@ -88,7 +201,7 @@
 
 int submodule_config(const char *var, const char *value, void *cb)
 {
-	if (!prefixcmp(var, "submodule."))
+	if (starts_with(var, "submodule."))
 		return parse_submodule_config_option(var, value);
 	else if (!strcmp(var, "fetch.recursesubmodules")) {
 		config_fetch_recurse_submodules = parse_fetch_recurse_submodules_arg(var, value);
@@ -116,6 +229,11 @@
 				    !memcmp(ce->name, ".gitmodules", 11))
 					gitmodules_is_unmerged = 1;
 			}
+		} else if (pos < active_nr) {
+			struct stat st;
+			if (lstat(".gitmodules", &st) == 0 &&
+			    ce_match_stat(active_cache[pos], &st, 0) & DATA_CHANGED)
+				gitmodules_is_modified = 1;
 		}
 
 		if (!gitmodules_is_unmerged)
@@ -1010,3 +1128,34 @@
 	free(merges.objects);
 	return 0;
 }
+
+/* Update gitfile and core.worktree setting to connect work tree and git dir */
+void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
+{
+	struct strbuf file_name = STRBUF_INIT;
+	struct strbuf rel_path = STRBUF_INIT;
+	const char *real_work_tree = xstrdup(real_path(work_tree));
+	FILE *fp;
+
+	/* Update gitfile */
+	strbuf_addf(&file_name, "%s/.git", work_tree);
+	fp = fopen(file_name.buf, "w");
+	if (!fp)
+		die(_("Could not create git link %s"), file_name.buf);
+	fprintf(fp, "gitdir: %s\n", relative_path(git_dir, real_work_tree,
+						  &rel_path));
+	fclose(fp);
+
+	/* Update core.worktree setting */
+	strbuf_reset(&file_name);
+	strbuf_addf(&file_name, "%s/config", git_dir);
+	if (git_config_set_in_file(file_name.buf, "core.worktree",
+				   relative_path(real_work_tree, git_dir,
+						 &rel_path)))
+		die(_("Could not set core.worktree in %s"),
+		    file_name.buf);
+
+	strbuf_release(&file_name);
+	strbuf_release(&rel_path);
+	free((void *)real_work_tree);
+}
diff --git a/submodule.h b/submodule.h
index c7ffc7c..7beec48 100644
--- a/submodule.h
+++ b/submodule.h
@@ -11,6 +11,10 @@
 	RECURSE_SUBMODULES_ON = 2
 };
 
+int is_staging_gitmodules_ok(void);
+int update_path_in_gitmodules(const char *oldpath, const char *newpath);
+int remove_path_from_gitmodules(const char *path);
+void stage_updated_gitmodules(void);
 void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
 		const char *path);
 int submodule_config(const char *var, const char *value, void *cb);
@@ -36,5 +40,6 @@
 int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name,
 		struct string_list *needs_pushing);
 int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name);
+void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir);
 
 #endif
diff --git a/t/.gitattributes b/t/.gitattributes
index 1b97c54..2d44088 100644
--- a/t/.gitattributes
+++ b/t/.gitattributes
@@ -1 +1,2 @@
 t[0-9][0-9][0-9][0-9]/* -whitespace
+t0110/url-* binary
diff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t
old mode 100644
new mode 100755
diff --git a/t/Git-SVN/Utils/add_path_to_url.t b/t/Git-SVN/Utils/add_path_to_url.t
old mode 100644
new mode 100755
diff --git a/t/Git-SVN/Utils/can_compress.t b/t/Git-SVN/Utils/can_compress.t
old mode 100644
new mode 100755
diff --git a/t/Git-SVN/Utils/canonicalize_url.t b/t/Git-SVN/Utils/canonicalize_url.t
old mode 100644
new mode 100755
diff --git a/t/Git-SVN/Utils/collapse_dotdot.t b/t/Git-SVN/Utils/collapse_dotdot.t
old mode 100644
new mode 100755
diff --git a/t/Git-SVN/Utils/fatal.t b/t/Git-SVN/Utils/fatal.t
old mode 100644
new mode 100755
diff --git a/t/Git-SVN/Utils/join_paths.t b/t/Git-SVN/Utils/join_paths.t
old mode 100644
new mode 100755
diff --git a/t/README b/t/README
index 0a939eb..caeeb9d 100644
--- a/t/README
+++ b/t/README
@@ -340,7 +340,11 @@
  - use perl without spelling it as "$PERL_PATH". This is to help our
    friends on Windows where the platform Perl often adds CR before
    the end of line, and they bundle Git with a version of Perl that
-   does not do so, whose path is specified with $PERL_PATH.
+   does not do so, whose path is specified with $PERL_PATH. Note that we
+   provide a "perl" function which uses $PERL_PATH under the hood, so
+   you do not need to worry when simply running perl in the test scripts
+   (but you do, for example, on a shebang line or in a sub script
+   created via "write_script").
 
  - use sh without spelling it as "$SHELL_PATH", when the script can
    be misinterpreted by broken platform shell (e.g. Solaris).
@@ -387,7 +391,7 @@
 below), e.g.:
 
     test_expect_success PERL 'I need Perl' '
-        "$PERL_PATH" -e "hlagh() if unf_unf()"
+        perl -e "hlagh() if unf_unf()"
     '
 
 The advantage of skipping tests like this is that platforms that don't
@@ -520,7 +524,7 @@
 
 	test_external \
 	    'GitwebCache::*FileCache*' \
-	    "$PERL_PATH" "$TEST_DIRECTORY"/t9503/test_cache_interface.pl
+	    perl "$TEST_DIRECTORY"/t9503/test_cache_interface.pl
 
    If the test is outputting its own TAP you should set the
    test_external_has_tap variable somewhere before calling the first
@@ -536,7 +540,7 @@
 
 	test_external_without_stderr \
 	    'Perl API' \
-	    "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl
+	    perl "$TEST_DIRECTORY"/t9700/test.pl
 
  - test_expect_code <exit-code> <command>
 
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
index d4e7f47..304c7b7 100644
--- a/t/annotate-tests.sh
+++ b/t/annotate-tests.sh
@@ -92,7 +92,7 @@
 '
 
 test_expect_success 'merge branch1 & branch2' '
-	git pull . branch1
+	git merge branch1
 '
 
 test_expect_success 'blame 2 authors + 2 merged-in authors' '
@@ -116,6 +116,27 @@
 	check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1
 '
 
+test_expect_success 'blame huge graft' '
+	test_when_finished "git checkout branch2" &&
+	test_when_finished "rm -f .git/info/grafts" &&
+	graft= &&
+	for i in 0 1 2
+	do
+		for j in 0 1 2 3 4 5 6 7 8 9
+		do
+			git checkout --orphan "$i$j" &&
+			printf "%s\n" "$i" "$j" >file &&
+			test_tick &&
+			GIT_AUTHOR_NAME=$i$j GIT_AUTHOR_EMAIL=$i$j@test.git \
+			git commit -a -m "$i$j" &&
+			commit=$(git rev-parse --verify HEAD) &&
+			graft="$graft$commit "
+		done
+	done &&
+	printf "%s " $graft >.git/info/grafts &&
+	check_count -h 00 01 1 10 1
+'
+
 test_expect_success 'setup incomplete line' '
 	echo "incomplete" | tr -d "\\012" >>file &&
 	GIT_AUTHOR_NAME="C" GIT_AUTHOR_EMAIL="C@test.git" \
@@ -185,6 +206,26 @@
 	check_count -L6,3 B 1 B1 1 B2 1 D 1
 '
 
+test_expect_success 'blame -L -X' '
+	test_must_fail $PROG -L-1 file
+'
+
+test_expect_success 'blame -L 0' '
+	test_must_fail $PROG -L0 file
+'
+
+test_expect_success 'blame -L ,0' '
+	test_must_fail $PROG -L,0 file
+'
+
+test_expect_success 'blame -L ,+0' '
+	test_must_fail $PROG -L,+0 file
+'
+
+test_expect_success 'blame -L X,+0' '
+	test_must_fail $PROG -L1,+0 file
+'
+
 test_expect_success 'blame -L X,+1' '
 	check_count -L3,+1 B2 1
 '
@@ -193,6 +234,14 @@
 	check_count -L3,+4 B 1 B1 1 B2 1 D 1
 '
 
+test_expect_success 'blame -L ,-0' '
+	test_must_fail $PROG -L,-0 file
+'
+
+test_expect_success 'blame -L X,-0' '
+	test_must_fail $PROG -L1,-0 file
+'
+
 test_expect_success 'blame -L X,-1' '
 	check_count -L3,-1 B2 1
 '
@@ -225,14 +274,105 @@
 	check_count -L/99/,-3 B 1 B2 1 D 1
 '
 
+# 'file' ends with an incomplete line, so 'wc' reports one fewer lines than
+# git-blame sees, hence the last line is actually $(wc...)+1.
+test_expect_success 'blame -L X (X == nlines)' '
+	n=$(expr $(wc -l <file) + 1) &&
+	check_count -L$n C 1
+'
+
+test_expect_success 'blame -L X (X == nlines + 1)' '
+	n=$(expr $(wc -l <file) + 2) &&
+	test_must_fail $PROG -L$n file
+'
+
 test_expect_success 'blame -L X (X > nlines)' '
 	test_must_fail $PROG -L12345 file
 '
 
+test_expect_success 'blame -L ,Y (Y == nlines)' '
+	n=$(expr $(wc -l <file) + 1) &&
+	check_count -L,$n A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
+'
+
+test_expect_success 'blame -L ,Y (Y == nlines + 1)' '
+	n=$(expr $(wc -l <file) + 2) &&
+	test_must_fail $PROG -L,$n file
+'
+
 test_expect_success 'blame -L ,Y (Y > nlines)' '
 	test_must_fail $PROG -L,12345 file
 '
 
+test_expect_success 'blame -L multiple (disjoint)' '
+	check_count -L2,3 -L6,7 A 1 B1 1 B2 1 "A U Thor" 1
+'
+
+test_expect_success 'blame -L multiple (disjoint: unordered)' '
+	check_count -L6,7 -L2,3 A 1 B1 1 B2 1 "A U Thor" 1
+'
+
+test_expect_success 'blame -L multiple (adjacent)' '
+	check_count -L2,3 -L4,5 A 1 B 1 B2 1 D 1
+'
+
+test_expect_success 'blame -L multiple (adjacent: unordered)' '
+	check_count -L4,5 -L2,3 A 1 B 1 B2 1 D 1
+'
+
+test_expect_success 'blame -L multiple (overlapping)' '
+	check_count -L2,4 -L3,5 A 1 B 1 B2 1 D 1
+'
+
+test_expect_success 'blame -L multiple (overlapping: unordered)' '
+	check_count -L3,5 -L2,4 A 1 B 1 B2 1 D 1
+'
+
+test_expect_success 'blame -L multiple (superset/subset)' '
+	check_count -L2,8 -L3,5 A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
+'
+
+test_expect_success 'blame -L multiple (superset/subset: unordered)' '
+	check_count -L3,5 -L2,8 A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
+'
+
+test_expect_success 'blame -L /RE/ (relative)' '
+	check_count -L3,3 -L/fox/ B1 1 B2 1 C 1 D 1 "A U Thor" 1
+'
+
+test_expect_success 'blame -L /RE/ (relative: no preceding range)' '
+	check_count -L/dog/ A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
+'
+
+test_expect_success 'blame -L /RE/ (relative: adjacent)' '
+	check_count -L1,1 -L/dog/,+1 A 1 E 1
+'
+
+test_expect_success 'blame -L /RE/ (relative: not found)' '
+	test_must_fail $PROG -L4,4 -L/dog/ file
+'
+
+test_expect_success 'blame -L /RE/ (relative: end-of-file)' '
+	test_must_fail $PROG -L, -L/$/ file
+'
+
+test_expect_success 'blame -L ^/RE/ (absolute)' '
+	check_count -L3,3 -L^/dog/,+2 A 1 B2 1
+'
+
+test_expect_success 'blame -L ^/RE/ (absolute: no preceding range)' '
+	check_count -L^/dog/,+2 A 1 B2 1
+'
+
+test_expect_success 'blame -L ^/RE/ (absolute: not found)' '
+	test_must_fail $PROG -L4,4 -L^/tambourine/ file
+'
+
+test_expect_success 'blame -L ^/RE/ (absolute: end-of-file)' '
+	n=$(expr $(wc -l <file) + 1) &&
+	check_count -L$n -L^/$/,+2 A 1 C 1 E 1
+'
+
 test_expect_success 'setup -L :regex' '
 	tr Q "\\t" >hello.c <<-\EOF &&
 	int main(int argc, const char *argv[])
@@ -275,12 +415,139 @@
 	test_must_fail $PROG -L:nomatch hello.c
 '
 
-test_expect_success 'blame -L bogus' '
-	test_must_fail $PROG -L file &&
-	test_must_fail $PROG -L1,+ file &&
-	test_must_fail $PROG -L1,- file &&
-	test_must_fail $PROG -LX file &&
-	test_must_fail $PROG -L1,X file &&
-	test_must_fail $PROG -L1,+N file &&
+test_expect_success 'blame -L :RE (relative)' '
+	check_count -f hello.c -L3,3 -L:ma.. F 1 H 4
+'
+
+test_expect_success 'blame -L :RE (relative: no preceding range)' '
+	check_count -f hello.c -L:ma.. F 4 G 1
+'
+
+test_expect_success 'blame -L :RE (relative: not found)' '
+	test_must_fail $PROG -L3,3 -L:tambourine hello.c
+'
+
+test_expect_success 'blame -L :RE (relative: end-of-file)' '
+	test_must_fail $PROG -L, -L:main hello.c
+'
+
+test_expect_success 'blame -L ^:RE (absolute)' '
+	check_count -f hello.c -L3,3 -L^:ma.. F 4 G 1
+'
+
+test_expect_success 'blame -L ^:RE (absolute: no preceding range)' '
+	check_count -f hello.c -L^:ma.. F 4 G 1
+'
+
+test_expect_success 'blame -L ^:RE (absolute: not found)' '
+	test_must_fail $PROG -L4,4 -L^:tambourine hello.c
+'
+
+test_expect_success 'blame -L ^:RE (absolute: end-of-file)' '
+	n=$(printf "%d" $(wc -l <hello.c)) &&
+	check_count -f hello.c -L$n -L^:ma.. F 4 G 1 H 1
+'
+
+test_expect_success 'setup incremental' '
+	(
+	GIT_AUTHOR_NAME=I &&
+	export GIT_AUTHOR_NAME &&
+	GIT_AUTHOR_EMAIL=I@test.git &&
+	export GIT_AUTHOR_EMAIL &&
+	>incremental &&
+	git add incremental &&
+	git commit -m "step 0" &&
+	printf "partial" >>incremental &&
+	git commit -a -m "step 0.5" &&
+	echo >>incremental &&
+	git commit -a -m "step 1"
+	)
+'
+
+test_expect_success 'blame empty' '
+	check_count -h HEAD^^ -f incremental
+'
+
+test_expect_success 'blame -L 0 empty' '
+	test_must_fail $PROG -L0 incremental HEAD^^
+'
+
+test_expect_success 'blame -L 1 empty' '
+	test_must_fail $PROG -L1 incremental HEAD^^
+'
+
+test_expect_success 'blame -L 2 empty' '
+	test_must_fail $PROG -L2 incremental HEAD^^
+'
+
+test_expect_success 'blame half' '
+	check_count -h HEAD^ -f incremental I 1
+'
+
+test_expect_success 'blame -L 0 half' '
+	test_must_fail $PROG -L0 incremental HEAD^
+'
+
+test_expect_success 'blame -L 1 half' '
+	check_count -h HEAD^ -f incremental -L1 I 1
+'
+
+test_expect_success 'blame -L 2 half' '
+	test_must_fail $PROG -L2 incremental HEAD^
+'
+
+test_expect_success 'blame -L 3 half' '
+	test_must_fail $PROG -L3 incremental HEAD^
+'
+
+test_expect_success 'blame full' '
+	check_count -f incremental I 1
+'
+
+test_expect_success 'blame -L 0 full' '
+	test_must_fail $PROG -L0 incremental
+'
+
+test_expect_success 'blame -L 1 full' '
+	check_count -f incremental -L1 I 1
+'
+
+test_expect_success 'blame -L 2 full' '
+	test_must_fail $PROG -L2 incremental
+'
+
+test_expect_success 'blame -L 3 full' '
+	test_must_fail $PROG -L3 incremental
+'
+
+test_expect_success 'blame -L' '
+	test_must_fail $PROG -L file
+'
+
+test_expect_success 'blame -L X,+' '
+	test_must_fail $PROG -L1,+ file
+'
+
+test_expect_success 'blame -L X,-' '
+	test_must_fail $PROG -L1,- file
+'
+
+test_expect_success 'blame -L X (non-numeric X)' '
+	test_must_fail $PROG -LX file
+'
+
+test_expect_success 'blame -L X,Y (non-numeric Y)' '
+	test_must_fail $PROG -L1,Y file
+'
+
+test_expect_success 'blame -L X,+N (non-numeric N)' '
+	test_must_fail $PROG -L1,+N file
+'
+
+test_expect_success 'blame -L X,-N (non-numeric N)' '
 	test_must_fail $PROG -L1,-N file
 '
+
+test_expect_success 'blame -L ,^/RE/' '
+	test_must_fail $PROG -L1,^/99/ file
+'
diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh
index 9e381e0..d5dab5a 100644
--- a/t/gitweb-lib.sh
+++ b/t/gitweb-lib.sh
@@ -1,4 +1,5 @@
-#!/bin/sh
+# Initialization and helpers for Gitweb tests, which source this
+# shell library instead of test-lib.sh.
 #
 # Copyright (c) 2007 Jakub Narebski
 #
@@ -69,7 +70,7 @@
 	# written to web server logs, so we are not interested in that:
 	# we are interested only in properly formatted errors/warnings
 	rm -f gitweb.log &&
-	"$PERL_PATH" -- "$SCRIPT_NAME" \
+	perl -- "$SCRIPT_NAME" \
 		>gitweb.output 2>gitweb.log &&
 	perl -w -e '
 		open O, ">gitweb.headers";
diff --git a/t/lib-bash.sh b/t/lib-bash.sh
index 11397f7..2be955f 100644
--- a/t/lib-bash.sh
+++ b/t/lib-bash.sh
@@ -1,7 +1,6 @@
-#!/bin/sh
-#
-# Ensures that tests are run under Bash; primarily intended for running tests
-# of the completion script.
+# Shell library sourced instead of ./test-lib.sh by tests that need
+# to run under Bash; primarily intended for tests of the completion
+# script.
 
 if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then
 	# we are in full-on bash mode
diff --git a/t/lib-credential.sh b/t/lib-credential.sh
index 3c43ff1..957ae93 100755
--- a/t/lib-credential.sh
+++ b/t/lib-credential.sh
@@ -18,10 +18,6 @@
 		cat stderr &&
 		false
 	fi &&
-	if test_have_prereq MINGW
-	then
-		dos2unix -q stderr
-	fi &&
 	test_cmp expect-stdout stdout &&
 	test_cmp expect-stderr stderr
 }
diff --git a/t/lib-cvs.sh b/t/lib-cvs.sh
index 44263ad..5076718 100644
--- a/t/lib-cvs.sh
+++ b/t/lib-cvs.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+# Shell library sourced instead of ./test-lib.sh by cvsimport tests.
 
 . ./test-lib.sh
 
diff --git a/t/lib-diff-alternative.sh b/t/lib-diff-alternative.sh
index 75ffd91..8b4dbf2 100644
--- a/t/lib-diff-alternative.sh
+++ b/t/lib-diff-alternative.sh
@@ -1,4 +1,5 @@
-#!/bin/sh
+# Helpers shared by the test scripts for diff algorithms (patience,
+# histogram, etc).
 
 test_diff_frobnitz() {
 	cat >file1 <<\EOF
diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index ae8883a..eec757f 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -1,4 +1,5 @@
-#!/bin/sh
+# Initialization and Icelandic locale for basic git i18n tests,
+# which source this scriptlet instead of ./test-lib.sh.
 #
 # Copyright (c) 2010 Ævar Arnfjörð Bjarmason
 #
diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
index 87f0ad8..394b06b 100644
--- a/t/lib-git-daemon.sh
+++ b/t/lib-git-daemon.sh
@@ -1,4 +1,20 @@
-#!/bin/sh
+# Shell library to run git-daemon in tests.  Ends the test early if
+# GIT_TEST_GIT_DAEMON is not set.
+#
+# Usage:
+#
+#	. ./test-lib.sh
+#	. "$TEST_DIRECTORY"/lib-git-daemon.sh
+#	start_git_daemon
+#
+#	test_expect_success '...' '
+#		...
+#	'
+#
+#	test_expect_success ...
+#
+#	stop_git_daemon
+#	test_done
 
 if test -z "$GIT_TEST_GIT_DAEMON"
 then
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index 2098b9b..5aa8adc 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -47,14 +47,22 @@
 
 P4PORT=localhost:$P4DPORT
 P4CLIENT=client
-P4EDITOR=:
-export P4PORT P4CLIENT P4EDITOR
+P4USER=author
+P4EDITOR=true
+unset P4CHARSET
+export P4PORT P4CLIENT P4USER P4EDITOR P4CHARSET
 
 db="$TRASH_DIRECTORY/db"
 cli="$TRASH_DIRECTORY/cli"
 git="$TRASH_DIRECTORY/git"
 pidfile="$TRASH_DIRECTORY/p4d.pid"
 
+# git p4 submit generates a temp file, which will
+# not get cleaned up if the submission fails.  Don't
+# clutter up /tmp on the test machine.
+TMPDIR="$TRASH_DIRECTORY"
+export TMPDIR
+
 start_p4d() {
 	mkdir -p "$db" "$cli" "$git" &&
 	rm -f "$pidfile" &&
@@ -95,12 +103,24 @@
 		return 1
 	fi
 
+	# build a p4 user so author@example.com has an entry
+	p4_add_user author
+
 	# build a client
 	client_view "//depot/... //client/..." &&
 
 	return 0
 }
 
+p4_add_user() {
+	name=$1 &&
+	p4 user -f -i <<-EOF
+	User: $name
+	Email: $name@example.com
+	FullName: Dr. $name
+	EOF
+}
+
 kill_p4d() {
 	pid=$(cat "$pidfile")
 	# it had better exist for the first kill
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index c5e55b1..b0ec12f 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -29,7 +29,7 @@
 svnconf=$PWD/svnconf
 export svnconf
 
-"$PERL_PATH" -w -e "
+perl -w -e "
 use SVN::Core;
 use SVN::Repos;
 \$SVN::Core::VERSION gt '1.1.0' or exit(42);
@@ -146,7 +146,7 @@
 }
 
 convert_to_rev_db () {
-	"$PERL_PATH" -w -- - "$@" <<\EOF
+	perl -w -- - "$@" <<\EOF
 use strict;
 @ARGV == 2 or die "usage: convert_to_rev_db <input> <output>";
 open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]";
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 7059cc6..bfdff2a 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -1,4 +1,31 @@
-#!/bin/sh
+# Shell library to run an HTTP server for use in tests.
+# Ends the test early if httpd tests should not be run,
+# for example because the user has not enabled them.
+#
+# Usage:
+#
+#	. ./test-lib.sh
+#	. "$TEST_DIRECTORY"/lib-httpd.sh
+#	start_httpd
+#
+#	test_expect_success '...' '
+#		...
+#	'
+#
+#	test_expect_success ...
+#
+#	stop_httpd
+#	test_done
+#
+# Can be configured using the following variables.
+#
+#    GIT_TEST_HTTPD              enable HTTPD tests
+#    LIB_HTTPD_PATH              web server path
+#    LIB_HTTPD_MODULE_PATH       web server modules path
+#    LIB_HTTPD_PORT              listening port
+#    LIB_HTTPD_DAV               enable DAV
+#    LIB_HTTPD_SVN               enable SVN
+#    LIB_HTTPD_SSL               enable SSL
 #
 # Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at>
 #
@@ -102,7 +129,7 @@
 	HTTPD_DEST=127.0.0.1:$LIB_HTTPD_PORT
 	HTTPD_URL=$HTTPD_PROTO://$HTTPD_DEST
 	HTTPD_URL_USER=$HTTPD_PROTO://user%40host@$HTTPD_DEST
-	HTTPD_URL_USER_PASS=$HTTPD_PROTO://user%40host:user%40host@$HTTPD_DEST
+	HTTPD_URL_USER_PASS=$HTTPD_PROTO://user%40host:pass%40host@$HTTPD_DEST
 
 	if test -n "$LIB_HTTPD_DAV" -o -n "$LIB_HTTPD_SVN"
 	then
@@ -141,10 +168,11 @@
 		-f "$TEST_PATH/apache.conf" $HTTPD_PARA -k stop
 }
 
-test_http_push_nonff() {
+test_http_push_nonff () {
 	REMOTE_REPO=$1
 	LOCAL_REPO=$2
 	BRANCH=$3
+	EXPECT_CAS_RESULT=${4-failure}
 
 	test_expect_success 'non-fast-forward push fails' '
 		cd "$REMOTE_REPO" &&
@@ -167,13 +195,37 @@
 	test_expect_success 'non-fast-forward push shows help message' '
 		test_i18ngrep "Updates were rejected because" output
 	'
+
+	test_expect_${EXPECT_CAS_RESULT} 'force with lease aka cas' '
+		HEAD=$(	cd "$REMOTE_REPO" && git rev-parse --verify HEAD ) &&
+		test_when_finished '\''
+			(cd "$REMOTE_REPO" && git update-ref HEAD "$HEAD")
+		'\'' &&
+		(
+			cd "$LOCAL_REPO" &&
+			git push -v --force-with-lease=$BRANCH:$HEAD origin
+		) &&
+		git rev-parse --verify "$BRANCH" >expect &&
+		(
+			cd "$REMOTE_REPO" && git rev-parse --verify HEAD
+		) >actual &&
+		test_cmp expect actual
+	'
 }
 
 setup_askpass_helper() {
 	test_expect_success 'setup askpass helper' '
 		write_script "$TRASH_DIRECTORY/askpass" <<-\EOF &&
 		echo >>"$TRASH_DIRECTORY/askpass-query" "askpass: $*" &&
-		cat "$TRASH_DIRECTORY/askpass-response"
+		case "$*" in
+		*Username*)
+			what=user
+			;;
+		*Password*)
+			what=pass
+			;;
+		esac &&
+		cat "$TRASH_DIRECTORY/askpass-$what"
 		EOF
 		GIT_ASKPASS="$TRASH_DIRECTORY/askpass" &&
 		export GIT_ASKPASS &&
@@ -183,7 +235,8 @@
 
 set_askpass() {
 	>"$TRASH_DIRECTORY/askpass-query" &&
-	echo "$*" >"$TRASH_DIRECTORY/askpass-response"
+	echo "$1" >"$TRASH_DIRECTORY/askpass-user" &&
+	echo "$2" >"$TRASH_DIRECTORY/askpass-pass"
 }
 
 expect_askpass() {
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 4a261f1..3a03e82 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -22,6 +22,9 @@
 <IfModule !mod_version.c>
 	LoadModule version_module modules/mod_version.so
 </IfModule>
+<IfModule !mod_headers.c>
+	LoadModule headers_module modules/mod_headers.so
+</IfModule>
 
 <IfVersion < 2.4>
 LockFile accept.lock
@@ -87,6 +90,11 @@
 	SetEnv GIT_HTTP_EXPORT_ALL
 	SetEnv GIT_NAMESPACE ns
 </LocationMatch>
+<LocationMatch /smart_cookies/>
+	SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+	SetEnv GIT_HTTP_EXPORT_ALL
+	Header set Set-Cookie name=value
+</LocationMatch>
 ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
 ScriptAlias /broken_smart/ broken-smart-http.sh/
 <Directory ${GIT_EXEC_PATH}>
diff --git a/t/lib-httpd/passwd b/t/lib-httpd/passwd
index f2fbcad..99a34d6 100644
--- a/t/lib-httpd/passwd
+++ b/t/lib-httpd/passwd
@@ -1 +1 @@
-user@host:nKpa8pZUHx/ic
+user@host:xb4E8pqD81KQs
diff --git a/t/lib-pack.sh b/t/lib-pack.sh
new file mode 100644
index 0000000..7509846
--- /dev/null
+++ b/t/lib-pack.sh
@@ -0,0 +1,98 @@
+# Support routines for hand-crafting weird or malicious packs.
+#
+# You can make a complete pack like:
+#
+#   pack_header 2 >foo.pack &&
+#   pack_obj e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 >>foo.pack &&
+#   pack_obj e68fe8129b546b101aee9510c5328e7f21ca1d18 >>foo.pack &&
+#   pack_trailer foo.pack
+
+# Print the big-endian 4-byte octal representation of $1
+uint32_octal () {
+	n=$1
+	printf '\\%o' $(($n / 16777216)); n=$((n % 16777216))
+	printf '\\%o' $(($n /    65536)); n=$((n %    65536))
+	printf '\\%o' $(($n /      256)); n=$((n %      256))
+	printf '\\%o' $(($n           ));
+}
+
+# Print the big-endian 4-byte binary representation of $1
+uint32_binary () {
+	printf "$(uint32_octal "$1")"
+}
+
+# Print a pack header, version 2, for a pack with $1 objects
+pack_header () {
+	printf 'PACK' &&
+	printf '\0\0\0\2' &&
+	uint32_binary "$1"
+}
+
+# Print the pack data for object $1, as a delta against object $2 (or as a full
+# object if $2 is missing or empty). The output is suitable for including
+# directly in the packfile, and represents the entirety of the object entry.
+# Doing this on the fly (especially picking your deltas) is quite tricky, so we
+# have hardcoded some well-known objects. See the case statements below for the
+# complete list.
+pack_obj () {
+	case "$1" in
+	# empty blob
+	e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)
+		case "$2" in
+		'')
+			printf '\060\170\234\003\0\0\0\0\1'
+			return
+			;;
+		esac
+		;;
+
+	# blob containing "\7\76"
+	e68fe8129b546b101aee9510c5328e7f21ca1d18)
+		case "$2" in
+		'')
+			printf '\062\170\234\143\267\3\0\0\116\0\106'
+			return
+			;;
+		01d7713666f4de822776c7622c10f1b07de280dc)
+			printf '\165\1\327\161\66\146\364\336\202\47\166' &&
+			printf '\307\142\54\20\361\260\175\342\200\334\170' &&
+			printf '\234\143\142\142\142\267\003\0\0\151\0\114'
+			return
+			;;
+		esac
+		;;
+
+	# blob containing "\7\0"
+	01d7713666f4de822776c7622c10f1b07de280dc)
+		case "$2" in
+		'')
+			printf '\062\170\234\143\147\0\0\0\20\0\10'
+			return
+			;;
+		e68fe8129b546b101aee9510c5328e7f21ca1d18)
+			printf '\165\346\217\350\22\233\124\153\20\32\356' &&
+			printf '\225\20\305\62\216\177\41\312\35\30\170\234' &&
+			printf '\143\142\142\142\147\0\0\0\53\0\16'
+			return
+			;;
+		esac
+		;;
+	esac
+
+	echo >&2 "BUG: don't know how to print $1${2:+ (from $2)}"
+	return 1
+}
+
+# Compute and append pack trailer to "$1"
+pack_trailer () {
+	test-sha1 -b <"$1" >trailer.tmp &&
+	cat trailer.tmp >>"$1" &&
+	rm -f trailer.tmp
+}
+
+# Remove any existing packs to make sure that
+# whatever we index next will be the pack that we
+# actually use.
+clear_packs () {
+	rm -f .git/objects/pack/*
+}
diff --git a/t/lib-pager.sh b/t/lib-pager.sh
index ba03eab..3aa7a3f 100644
--- a/t/lib-pager.sh
+++ b/t/lib-pager.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+# Helpers for tests of git's choice of pager.
 
 test_expect_success 'determine default pager' '
 	test_might_fail git config --unset core.pager &&
diff --git a/t/lib-prereq-FILEMODE.sh b/t/lib-prereq-FILEMODE.sh
deleted file mode 100644
index bce5a4c..0000000
--- a/t/lib-prereq-FILEMODE.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010 Ævar Arnfjörð Bjarmason
-#
-
-if test "$(git config --bool core.filemode)" = false
-then
-	say 'filemode disabled on the filesystem'
-else
-	test_set_prereq FILEMODE
-fi
diff --git a/t/lib-read-tree.sh b/t/lib-read-tree.sh
index abc2c6f..b95f485 100644
--- a/t/lib-read-tree.sh
+++ b/t/lib-read-tree.sh
@@ -1,43 +1,41 @@
-#!/bin/sh
-#
 # Helper functions to check if read-tree would succeed/fail as expected with
 # and without the dry-run option. They also test that the dry-run does not
 # write the index and that together with -u it doesn't touch the work tree.
 #
 read_tree_must_succeed () {
-    git ls-files -s >pre-dry-run &&
-    git read-tree -n "$@" &&
-    git ls-files -s >post-dry-run &&
-    test_cmp pre-dry-run post-dry-run &&
-    git read-tree "$@"
+	git ls-files -s >pre-dry-run &&
+	git read-tree -n "$@" &&
+	git ls-files -s >post-dry-run &&
+	test_cmp pre-dry-run post-dry-run &&
+	git read-tree "$@"
 }
 
 read_tree_must_fail () {
-    git ls-files -s >pre-dry-run &&
-    test_must_fail git read-tree -n "$@" &&
-    git ls-files -s >post-dry-run &&
-    test_cmp pre-dry-run post-dry-run &&
-    test_must_fail git read-tree "$@"
+	git ls-files -s >pre-dry-run &&
+	test_must_fail git read-tree -n "$@" &&
+	git ls-files -s >post-dry-run &&
+	test_cmp pre-dry-run post-dry-run &&
+	test_must_fail git read-tree "$@"
 }
 
 read_tree_u_must_succeed () {
-    git ls-files -s >pre-dry-run &&
-    git diff-files -p >pre-dry-run-wt &&
-    git read-tree -n "$@" &&
-    git ls-files -s >post-dry-run &&
-    git diff-files -p >post-dry-run-wt &&
-    test_cmp pre-dry-run post-dry-run &&
-    test_cmp pre-dry-run-wt post-dry-run-wt &&
-    git read-tree "$@"
+	git ls-files -s >pre-dry-run &&
+	git diff-files -p >pre-dry-run-wt &&
+	git read-tree -n "$@" &&
+	git ls-files -s >post-dry-run &&
+	git diff-files -p >post-dry-run-wt &&
+	test_cmp pre-dry-run post-dry-run &&
+	test_cmp pre-dry-run-wt post-dry-run-wt &&
+	git read-tree "$@"
 }
 
 read_tree_u_must_fail () {
-    git ls-files -s >pre-dry-run &&
-    git diff-files -p >pre-dry-run-wt &&
-    test_must_fail git read-tree -n "$@" &&
-    git ls-files -s >post-dry-run &&
-    git diff-files -p >post-dry-run-wt &&
-    test_cmp pre-dry-run post-dry-run &&
-    test_cmp pre-dry-run-wt post-dry-run-wt &&
-    test_must_fail git read-tree "$@"
+	git ls-files -s >pre-dry-run &&
+	git diff-files -p >pre-dry-run-wt &&
+	test_must_fail git read-tree -n "$@" &&
+	git ls-files -s >post-dry-run &&
+	git diff-files -p >post-dry-run-wt &&
+	test_cmp pre-dry-run post-dry-run &&
+	test_cmp pre-dry-run-wt post-dry-run-wt &&
+	test_must_fail git read-tree "$@"
 }
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 8ff87fb..6bd2522 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+# Helper functions used by interactive rebase tests.
 
 # After setting the fake editor with this function, you can
 #
diff --git a/t/lib-terminal.sh b/t/lib-terminal.sh
index 58d911d..9a2dca5 100644
--- a/t/lib-terminal.sh
+++ b/t/lib-terminal.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+# Helpers for terminal output tests.
 
 test_expect_success PERL 'set up terminal for tests' '
 	# Reading from the pty master seems to get stuck _sometimes_
@@ -19,7 +19,7 @@
 	then
 		:
 	elif
-		"$PERL_PATH" "$TEST_DIRECTORY"/test-terminal.perl \
+		perl "$TEST_DIRECTORY"/test-terminal.perl \
 			sh -c "test -t 1 && test -t 2"
 	then
 		test_set_prereq TTY &&
@@ -29,7 +29,7 @@
 				echo >&4 "test_terminal: need to declare TTY prerequisite"
 				return 127
 			fi
-			"$PERL_PATH" "$TEST_DIRECTORY"/test-terminal.perl "$@"
+			perl "$TEST_DIRECTORY"/test-terminal.perl "$@"
 		}
 	fi
 '
diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh
index 4f71a63..16359d5 100755
--- a/t/perf/p0001-rev-list.sh
+++ b/t/perf/p0001-rev-list.sh
@@ -14,4 +14,16 @@
 	git rev-list --all --objects >/dev/null
 '
 
+test_expect_success 'create new unreferenced commit' '
+	commit=$(git commit-tree HEAD^{tree} -p HEAD)
+'
+
+test_perf 'rev-list $commit --not --all' '
+	git rev-list $commit --not --all >/dev/null
+'
+
+test_perf 'rev-list --objects $commit --not --all' '
+	git rev-list --objects $commit --not --all >/dev/null
+'
+
 test_done
diff --git a/t/perf/p4001-diff-no-index.sh b/t/perf/p4001-diff-no-index.sh
new file mode 100755
index 0000000..683be69
--- /dev/null
+++ b/t/perf/p4001-diff-no-index.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+test_description="Test diff --no-index performance"
+
+. ./perf-lib.sh
+
+test_perf_large_repo
+test_checkout_worktree
+
+file1=$(git ls-files | tail -n 2 | head -1)
+file2=$(git ls-files | tail -n 1 | head -1)
+
+test_expect_success "empty files, so they take no time to diff" "
+	echo >$file1 &&
+	echo >$file2
+"
+
+test_perf "diff --no-index" "
+	git diff --no-index $file1 $file2 >/dev/null
+"
+
+test_done
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index f4eecaa..a8c9574 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -1,4 +1,6 @@
-#!/bin/sh
+# Performance testing framework.  Each perf script starts much like
+# a normal test script, except it sources this library instead of
+# test-lib.sh.  See t/perf/README for documentation.
 #
 # Copyright (c) 2011 Thomas Rast
 #
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 10be52b..a2bb63c 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -41,20 +41,17 @@
 test_expect_success 'success is reported like this' '
 	:
 '
-test_expect_failure 'pretend we have a known breakage' '
-	false
-'
 
 run_sub_test_lib_test () {
 	name="$1" descr="$2" # stdin is the body of the test code
 	shift 2
 	mkdir "$name" &&
 	(
-		# Pretend we're a test harness.  This prevents
-		# test-lib from writing the counts to a file that will
-		# later be summarized, showing spurious "failed" tests
-		HARNESS_ACTIVE=t &&
-		export HARNESS_ACTIVE &&
+		# Pretend we're not running under a test harness, whether we
+		# are or not. The test-lib output depends on the setting of
+		# this variable, so we need a stable setting under which to run
+		# the sub-test.
+		sane_unset HARNESS_ACTIVE &&
 		cd "$name" &&
 		cat >"$name.sh" <<-EOF &&
 		#!$SHELL_PATH
@@ -71,6 +68,8 @@
 		cat >>"$name.sh" &&
 		chmod +x "$name.sh" &&
 		export TEST_DIRECTORY &&
+		TEST_OUTPUT_DIRECTORY=$(pwd) &&
+		export TEST_OUTPUT_DIRECTORY &&
 		./"$name.sh" "$@" >out 2>err
 	)
 }
@@ -233,16 +232,13 @@
 	grep -v "^Initialized empty" test-verbose/out+ >test-verbose/out &&
 	check_sub_test_lib_test test-verbose <<-\EOF
 	> expecting success: true
-	> Z
 	> ok 1 - passing test
 	> Z
 	> expecting success: echo foo
 	> foo
-	> Z
 	> ok 2 - test with output
 	> Z
 	> expecting success: false
-	> Z
 	> not ok 3 - failing test
 	> #	false
 	> Z
@@ -265,7 +261,6 @@
 	> Z
 	> expecting success: echo foo
 	> foo
-	> Z
 	> ok 2 - test with output
 	> Z
 	> not ok 3 - failing test
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
index cb14425..37e9396 100755
--- a/t/t0002-gitfile.sh
+++ b/t/t0002-gitfile.sh
@@ -7,7 +7,7 @@
 . ./test-lib.sh
 
 objpath() {
-    echo "$1" | sed -e 's|\(..\)|\1/|'
+	echo "$1" | sed -e 's|\(..\)|\1/|'
 }
 
 objck() {
@@ -19,7 +19,6 @@
 	fi
 }
 
-
 test_expect_success 'initial setup' '
 	REAL="$(pwd)/.real" &&
 	mv .git "$REAL"
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 0b98b6f..b9d7947 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -13,7 +13,6 @@
 	test_line_count = 0 err
 }
 
-
 test_expect_success 'setup' '
 	mkdir -p a/b/d a/c b &&
 	(
diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh
index c29342d..b4d98e6 100755
--- a/t/t0008-ignores.sh
+++ b/t/t0008-ignores.sh
@@ -37,6 +37,14 @@
 	test_cmp "$HOME/expected-stderr" "$HOME/stderr"
 }
 
+broken_c_unquote () {
+	"$PERL_PATH" -pe 's/^"//; s/\\//; s/"$//; tr/\n/\0/' "$@"
+}
+
+broken_c_unquote_verbose () {
+	"$PERL_PATH" -pe 's/	"/	/; s/\\//; s/"$//; tr/:\t\n/\0/' "$@"
+}
+
 stderr_contains () {
 	regexp="$1"
 	if grep "$regexp" "$HOME/stderr"
@@ -66,11 +74,11 @@
 
 	init_vars &&
 	rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" &&
-	echo git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $args \
+	echo git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
 		>"$HOME/cmd" &&
 	echo "$expect_code" >"$HOME/expected-exit-code" &&
 	test_expect_code "$expect_code" \
-		git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $args \
+		git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
 		>"$HOME/stdout" 2>"$HOME/stderr" &&
 	test_cmp "$HOME/expected-stdout" "$HOME/stdout" &&
 	stderr_empty_on_success "$expect_code"
@@ -87,6 +95,9 @@
 # check-ignore --verbose output is the same as normal output except
 # for the extra first column.
 #
+# A parameter is used to determine if the tests are run with the
+# normal case (using the index), or with the --no-index option.
+#
 # Arguments:
 #   - (optional) prereqs for this test, e.g. 'SYMLINKS'
 #   - test name
@@ -94,19 +105,26 @@
 #     from the other verbosity modes is automatically inferred
 #     from this value)
 #   - code to run (should invoke test_check_ignore)
-test_expect_success_multi () {
+#   - index option: --index or --no-index
+test_expect_success_multiple () {
 	prereq=
-	if test $# -eq 4
+	if test $# -eq 5
 	then
 		prereq=$1
 		shift
 	fi
+	if test "$4" = "--index"
+	then
+		no_index_opt=
+	else
+		no_index_opt=$4
+	fi
 	testname="$1" expect_all="$2" code="$3"
 
 	expect_verbose=$( echo "$expect_all" | grep -v '^::	' )
 	expect=$( echo "$expect_verbose" | sed -e 's/.*	//' )
 
-	test_expect_success $prereq "$testname" '
+	test_expect_success $prereq "$testname${no_index_opt:+ with $no_index_opt}" '
 		expect "$expect" &&
 		eval "$code"
 	'
@@ -116,7 +134,8 @@
 	then
 		for quiet_opt in '-q' '--quiet'
 		do
-			test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" "
+			opts="${no_index_opt:+$no_index_opt }$quiet_opt"
+			test_expect_success $prereq "$testname${opts:+ with $opts}" "
 			expect '' &&
 			$code
 		"
@@ -126,7 +145,7 @@
 
 	for verbose_opt in '-v' '--verbose'
 	do
-		for non_matching_opt in '' ' -n' ' --non-matching'
+		for non_matching_opt in '' '-n' '--non-matching'
 		do
 			if test -n "$non_matching_opt"
 			then
@@ -139,12 +158,21 @@
 				expect '$my_expect' &&
 				$code
 			"
-			opts="$verbose_opt$non_matching_opt"
+			opts="${no_index_opt:+$no_index_opt }$verbose_opt${non_matching_opt:+ $non_matching_opt}"
 			test_expect_success $prereq "$testname${opts:+ with $opts}" "$test_code"
 		done
 	done
 	verbose_opt=
 	non_matching_opt=
+	no_index_opt=
+}
+
+test_expect_success_multi () {
+	test_expect_success_multiple "$@" "--index"
+}
+
+test_expect_success_no_index_multi () {
+	test_expect_success_multiple "$@" "--no-index"
 }
 
 test_expect_success 'setup' '
@@ -288,7 +316,7 @@
 
 # First make sure that the presence of a file in the working tree
 # does not impact results, but that the presence of a file in the
-# index does.
+# index does unless the --no-index option is used.
 
 for subdir in '' 'a/'
 do
@@ -303,22 +331,42 @@
 		"::	${subdir}non-existent" \
 		"test_check_ignore '${subdir}non-existent' 1"
 
+	test_expect_success_no_index_multi "non-existent file $where not ignored" \
+		"::	${subdir}non-existent" \
+		"test_check_ignore '${subdir}non-existent' 1"
+
 	test_expect_success_multi "non-existent file $where ignored" \
 		".gitignore:1:one	${subdir}one" \
 		"test_check_ignore '${subdir}one'"
 
+	test_expect_success_no_index_multi "non-existent file $where ignored" \
+		".gitignore:1:one	${subdir}one" \
+		"test_check_ignore '${subdir}one'"
+
 	test_expect_success_multi "existing untracked file $where not ignored" \
 		"::	${subdir}not-ignored" \
 		"test_check_ignore '${subdir}not-ignored' 1"
 
+	test_expect_success_no_index_multi "existing untracked file $where not ignored" \
+		"::	${subdir}not-ignored" \
+		"test_check_ignore '${subdir}not-ignored' 1"
+
 	test_expect_success_multi "existing tracked file $where not ignored" \
 		"::	${subdir}ignored-but-in-index" \
 		"test_check_ignore '${subdir}ignored-but-in-index' 1"
 
+	test_expect_success_no_index_multi "existing tracked file $where shown as ignored" \
+		".gitignore:2:ignored-*	${subdir}ignored-but-in-index" \
+		"test_check_ignore '${subdir}ignored-but-in-index'"
+
 	test_expect_success_multi "existing untracked file $where ignored" \
 		".gitignore:2:ignored-*	${subdir}ignored-and-untracked" \
 		"test_check_ignore '${subdir}ignored-and-untracked'"
 
+	test_expect_success_no_index_multi "existing untracked file $where ignored" \
+		".gitignore:2:ignored-*	${subdir}ignored-and-untracked" \
+		"test_check_ignore '${subdir}ignored-and-untracked'"
+
 	test_expect_success_multi "mix of file types $where" \
 "::	${subdir}non-existent
 .gitignore:1:one	${subdir}one
@@ -332,6 +380,20 @@
 			${subdir}ignored-but-in-index
 			${subdir}ignored-and-untracked'
 		"
+
+	test_expect_success_no_index_multi "mix of file types $where" \
+"::	${subdir}non-existent
+.gitignore:1:one	${subdir}one
+::	${subdir}not-ignored
+.gitignore:2:ignored-*	${subdir}ignored-but-in-index
+.gitignore:2:ignored-*	${subdir}ignored-and-untracked" \
+		"test_check_ignore '
+			${subdir}non-existent
+			${subdir}one
+			${subdir}not-ignored
+			${subdir}ignored-but-in-index
+			${subdir}ignored-and-untracked'
+		"
 done
 
 # Having established the above, from now on we mostly test against
@@ -432,7 +494,7 @@
 
 test_expect_success_multi SYMLINKS 'beyond a symlink' '' '
 	test_check_ignore "a/symlink/foo" 128 &&
-	test_stderr "fatal: '\''a/symlink/foo'\'' is beyond a symbolic link"
+	test_stderr "fatal: pathspec '\''a/symlink/foo'\'' is beyond a symbolic link"
 '
 
 test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
@@ -440,7 +502,7 @@
 		cd a &&
 		test_check_ignore "symlink/foo" 128
 	) &&
-	test_stderr "fatal: '\''symlink/foo'\'' is beyond a symbolic link"
+	test_stderr "fatal: pathspec '\''symlink/foo'\'' is beyond a symbolic link"
 '
 
 ############################################################################
@@ -449,7 +511,7 @@
 
 test_expect_success_multi 'submodule' '' '
 	test_check_ignore "a/submodule/one" 128 &&
-	test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
+	test_stderr "fatal: Pathspec '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
 '
 
 test_expect_success_multi 'submodule from subdirectory' '' '
@@ -457,7 +519,7 @@
 		cd a &&
 		test_check_ignore "submodule/one" 128
 	) &&
-	test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
+	test_stderr "fatal: Pathspec '\''submodule/one'\'' is in submodule '\''a/submodule'\''"
 '
 
 ############################################################################
@@ -552,12 +614,11 @@
 	$global_excludes:2:!globaltwo	b/globaltwo
 EOF
 
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
-	tr "\n" "\0" >stdin0
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
-	tr "\n" "\0" >expected-default0
-sed -e 's/	"/	/' -e 's/\\//' -e 's/"$//' expected-verbose | \
-	tr ":\t\n" "\0" >expected-verbose0
+broken_c_unquote stdin >stdin0
+
+broken_c_unquote expected-default >expected-default0
+
+broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 test_expect_success '--stdin' '
 	expect_from_stdin <expected-default &&
@@ -638,12 +699,11 @@
 grep -v '^::	' expected-all >expected-verbose
 sed -e 's/.*	//' expected-verbose >expected-default
 
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
-	tr "\n" "\0" >stdin0
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
-	tr "\n" "\0" >expected-default0
-sed -e 's/	"/	/' -e 's/\\//' -e 's/"$//' expected-verbose | \
-	tr ":\t\n" "\0" >expected-verbose0
+broken_c_unquote stdin >stdin0
+
+broken_c_unquote expected-default >expected-default0
+
+broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 test_expect_success '--stdin from subdirectory' '
 	expect_from_stdin <expected-default &&
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 05d78d2..6b3cedc 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -91,6 +91,7 @@
 test_expect_success "setup unicode normalization tests" '
 	test_create_repo unicode &&
 	cd unicode &&
+	git config core.precomposeunicode false &&
 	touch "$aumlcdiar" &&
 	git add "$aumlcdiar" &&
 	git commit -m initial &&
diff --git a/t/t0056-git-C.sh b/t/t0056-git-C.sh
new file mode 100755
index 0000000..99c0377
--- /dev/null
+++ b/t/t0056-git-C.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+test_description='"-C <path>" option and its effects on other path-related options'
+
+. ./test-lib.sh
+
+test_expect_success '"git -C <path>" runs git from the directory <path>' '
+	test_create_repo dir1 &&
+	echo 1 >dir1/a.txt &&
+	msg="initial in dir1" &&
+	(cd dir1 && git add a.txt && git commit -m "$msg") &&
+	echo "$msg" >expected &&
+	git -C dir1 log --format=%s >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Multiple -C options: "-C dir1 -C dir2" is equivalent to "-C dir1/dir2"' '
+	test_create_repo dir1/dir2 &&
+	echo 1 >dir1/dir2/b.txt &&
+	git -C dir1/dir2 add b.txt &&
+	msg="initial in dir1/dir2" &&
+	echo "$msg" >expected &&
+	git -C dir1/dir2 commit -m "$msg" &&
+	git -C dir1 -C dir2 log --format=%s >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Effect on --git-dir option: "-C c --git-dir=a.git" is equivalent to "--git-dir c/a.git"' '
+	mkdir c &&
+	mkdir c/a &&
+	mkdir c/a.git &&
+	(cd c/a.git && git init --bare) &&
+	echo 1 >c/a/a.txt &&
+	git --git-dir c/a.git --work-tree=c/a add a.txt &&
+	git --git-dir c/a.git --work-tree=c/a commit -m "initial" &&
+	git --git-dir=c/a.git log -1 --format=%s >expected &&
+	git -C c --git-dir=a.git log -1 --format=%s >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Order should not matter: "--git-dir=a.git -C c" is equivalent to "-C c --git-dir=a.git"' '
+	git -C c --git-dir=a.git log -1 --format=%s >expected &&
+	git --git-dir=a.git -C c log -1 --format=%s >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Effect on --work-tree option: "-C c/a.git --work-tree=../a"  is equivalent to "--work-tree=c/a --git-dir=c/a.git"' '
+	rm c/a/a.txt &&
+	git --git-dir=c/a.git --work-tree=c/a status >expected &&
+	git -C c/a.git --work-tree=../a status >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Order should not matter: "--work-tree=../a -C c/a.git" is equivalent to "-C c/a.git --work-tree=../a"' '
+	git -C c/a.git --work-tree=../a status >expected &&
+	git --work-tree=../a -C c/a.git status >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Effect on --git-dir and --work-tree options - "-C c --git-dir=a.git --work-tree=a" is equivalent to "--git-dir=c/a.git --work-tree=c/a"' '
+	git --git-dir=c/a.git --work-tree=c/a status >expected &&
+	git -C c --git-dir=a.git --work-tree=a status >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Order should not matter: "-C c --git-dir=a.git --work-tree=a" is equivalent to "--git-dir=a.git -C c --work-tree=a"' '
+	git -C c --git-dir=a.git --work-tree=a status >expected &&
+	git --git-dir=a.git -C c --work-tree=a status >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Order should not matter: "-C c --git-dir=a.git --work-tree=a" is equivalent to "--git-dir=a.git --work-tree=a -C c"' '
+	git -C c --git-dir=a.git --work-tree=a status >expected &&
+	git --git-dir=a.git --work-tree=a -C c status >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Relative followed by fullpath: "-C ./here -C /there" is equivalent to "-C /there"' '
+	echo "initial in dir1/dir2" >expected &&
+	git -C dir1 -C "$(pwd)/dir1/dir2" log --format=%s >actual &&
+	test_cmp expected actual
+'
+
+test_done
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 3a48de2..07c10c8 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -8,13 +8,13 @@
 . ./test-lib.sh
 
 norm_path() {
-	expected=$(test-path-utils mingw_path "$2")
+	expected=$(test-path-utils print_path "$2")
 	test_expect_success $3 "normalize path: $1 => $2" \
 	"test \"\$(test-path-utils normalize_path_copy '$1')\" = '$expected'"
 }
 
 relative_path() {
-	expected=$(test-path-utils mingw_path "$3")
+	expected=$(test-path-utils print_path "$3")
 	test_expect_success $4 "relative path: $1 $2 => $3" \
 	"test \"\$(test-path-utils relative_path '$1' '$2')\" = '$expected'"
 }
@@ -190,33 +190,37 @@
 	test "$sym" = "$(test-path-utils real_path "$dir2/syml")"
 '
 
-relative_path /a/b/c/	/a/b/		c/
-relative_path /a/b/c/	/a/b		c/
-relative_path /a//b//c/	//a/b//		c/	POSIX
-relative_path /a/b	/a/b		./
-relative_path /a/b/	/a/b		./
-relative_path /a	/a/b		../
-relative_path /		/a/b/		../../
-relative_path /a/c	/a/b/		../c
-relative_path /a/c	/a/b		../c
-relative_path /x/y	/a/b/		../../x/y
-relative_path /a/b	"<empty>"	/a/b
-relative_path /a/b 	"<null>"	/a/b
-relative_path a/b/c/	a/b/		c/
-relative_path a/b/c/	a/b		c/
-relative_path a/b//c	a//b		c
-relative_path a/b/	a/b/		./
-relative_path a/b/	a/b		./
-relative_path a		a/b		../
-relative_path x/y	a/b		../../x/y
-relative_path a/c	a/b		../c
-relative_path a/b	"<empty>"	a/b
-relative_path a/b 	"<null>"	a/b
-relative_path "<empty>"	/a/b		./
-relative_path "<empty>"	"<empty>"	./
-relative_path "<empty>"	"<null>"	./
-relative_path "<null>"	"<empty>"	./
-relative_path "<null>"	"<null>"	./
-relative_path "<null>"	/a/b		./
+relative_path /foo/a/b/c/	/foo/a/b/	c/
+relative_path /foo/a/b/c/	/foo/a/b	c/
+relative_path /foo/a//b//c/	///foo/a/b//	c/		POSIX
+relative_path /foo/a/b		/foo/a/b	./
+relative_path /foo/a/b/		/foo/a/b	./
+relative_path /foo/a		/foo/a/b	../
+relative_path /			/foo/a/b/	../../../
+relative_path /foo/a/c		/foo/a/b/	../c
+relative_path /foo/a/c		/foo/a/b	../c
+relative_path /foo/x/y		/foo/a/b/	../../x/y
+relative_path /foo/a/b		"<empty>"	/foo/a/b
+relative_path /foo/a/b 		"<null>"	/foo/a/b
+relative_path foo/a/b/c/	foo/a/b/	c/
+relative_path foo/a/b/c/	foo/a/b		c/
+relative_path foo/a/b//c	foo/a//b	c
+relative_path foo/a/b/		foo/a/b/	./
+relative_path foo/a/b/		foo/a/b		./
+relative_path foo/a		foo/a/b		../
+relative_path foo/x/y		foo/a/b		../../x/y
+relative_path foo/a/c		foo/a/b		../c
+relative_path foo/a/b		/foo/x/y	foo/a/b
+relative_path /foo/a/b		foo/x/y		/foo/a/b
+relative_path d:/a/b		D:/a/c		../b		MINGW
+relative_path C:/a/b		D:/a/c		C:/a/b		MINGW
+relative_path foo/a/b		"<empty>"	foo/a/b
+relative_path foo/a/b 		"<null>"	foo/a/b
+relative_path "<empty>"		/foo/a/b	./
+relative_path "<empty>"		"<empty>"	./
+relative_path "<empty>"		"<null>"	./
+relative_path "<null>"		"<empty>"	./
+relative_path "<null>"		"<null>"	./
+relative_path "<null>"		/foo/a/b	./
 
 test_done
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
index 986b2a8..5ed69a6 100755
--- a/t/t0070-fundamental.sh
+++ b/t/t0070-fundamental.sh
@@ -25,6 +25,10 @@
 	grep "cannotwrite/test" err
 '
 
+test_expect_success 'git_mkstemps_mode does not fail if fd 0 is not open' '
+	git commit --allow-empty -m message <&-
+'
+
 test_expect_success 'check for a bug in the regex routines' '
 	# if this test fails, re-build git with NO_REGEX=1
 	test-regex
diff --git a/t/t0110-urlmatch-normalization.sh b/t/t0110-urlmatch-normalization.sh
new file mode 100755
index 0000000..8d6096d
--- /dev/null
+++ b/t/t0110-urlmatch-normalization.sh
@@ -0,0 +1,177 @@
+#!/bin/sh
+
+test_description='urlmatch URL normalization'
+. ./test-lib.sh
+
+# The base name of the test url files
+tu="$TEST_DIRECTORY/t0110/url"
+
+# Note that only file: URLs should be allowed without a host
+
+test_expect_success 'url scheme' '
+	! test-urlmatch-normalization "" &&
+	! test-urlmatch-normalization "_" &&
+	! test-urlmatch-normalization "scheme" &&
+	! test-urlmatch-normalization "scheme:" &&
+	! test-urlmatch-normalization "scheme:/" &&
+	! test-urlmatch-normalization "scheme://" &&
+	! test-urlmatch-normalization "file" &&
+	! test-urlmatch-normalization "file:" &&
+	! test-urlmatch-normalization "file:/" &&
+	test-urlmatch-normalization "file://" &&
+	! test-urlmatch-normalization "://acme.co" &&
+	! test-urlmatch-normalization "x_test://acme.co" &&
+	! test-urlmatch-normalization "-test://acme.co" &&
+	! test-urlmatch-normalization "0test://acme.co" &&
+	! test-urlmatch-normalization "+test://acme.co" &&
+	! test-urlmatch-normalization ".test://acme.co" &&
+	! test-urlmatch-normalization "schem%6e://" &&
+	test-urlmatch-normalization "x-Test+v1.0://acme.co" &&
+	test "$(test-urlmatch-normalization -p "AbCdeF://x.Y")" = "abcdef://x.y/"
+'
+
+test_expect_success 'url authority' '
+	! test-urlmatch-normalization "scheme://user:pass@" &&
+	! test-urlmatch-normalization "scheme://?" &&
+	! test-urlmatch-normalization "scheme://#" &&
+	! test-urlmatch-normalization "scheme:///" &&
+	! test-urlmatch-normalization "scheme://:" &&
+	! test-urlmatch-normalization "scheme://:555" &&
+	test-urlmatch-normalization "file://user:pass@" &&
+	test-urlmatch-normalization "file://?" &&
+	test-urlmatch-normalization "file://#" &&
+	test-urlmatch-normalization "file:///" &&
+	test-urlmatch-normalization "file://:" &&
+	! test-urlmatch-normalization "file://:555" &&
+	test-urlmatch-normalization "scheme://user:pass@host" &&
+	test-urlmatch-normalization "scheme://@host" &&
+	test-urlmatch-normalization "scheme://%00@host" &&
+	! test-urlmatch-normalization "scheme://%%@host" &&
+	! test-urlmatch-normalization "scheme://host_" &&
+	test-urlmatch-normalization "scheme://user:pass@host/" &&
+	test-urlmatch-normalization "scheme://@host/" &&
+	test-urlmatch-normalization "scheme://host/" &&
+	test-urlmatch-normalization "scheme://host?x" &&
+	test-urlmatch-normalization "scheme://host#x" &&
+	test-urlmatch-normalization "scheme://host/@" &&
+	test-urlmatch-normalization "scheme://host?@x" &&
+	test-urlmatch-normalization "scheme://host#@x" &&
+	test-urlmatch-normalization "scheme://[::1]" &&
+	test-urlmatch-normalization "scheme://[::1]/" &&
+	! test-urlmatch-normalization "scheme://hos%41/" &&
+	test-urlmatch-normalization "scheme://[invalid....:/" &&
+	test-urlmatch-normalization "scheme://invalid....:]/" &&
+	! test-urlmatch-normalization "scheme://invalid....:[/" &&
+	! test-urlmatch-normalization "scheme://invalid....:["
+'
+
+test_expect_success 'url port checks' '
+	test-urlmatch-normalization "xyz://q@some.host:" &&
+	test-urlmatch-normalization "xyz://q@some.host:456/" &&
+	! test-urlmatch-normalization "xyz://q@some.host:0" &&
+	! test-urlmatch-normalization "xyz://q@some.host:0000000" &&
+	test-urlmatch-normalization "xyz://q@some.host:0000001?" &&
+	test-urlmatch-normalization "xyz://q@some.host:065535#" &&
+	test-urlmatch-normalization "xyz://q@some.host:65535" &&
+	! test-urlmatch-normalization "xyz://q@some.host:65536" &&
+	! test-urlmatch-normalization "xyz://q@some.host:99999" &&
+	! test-urlmatch-normalization "xyz://q@some.host:100000" &&
+	! test-urlmatch-normalization "xyz://q@some.host:100001" &&
+	test-urlmatch-normalization "http://q@some.host:80" &&
+	test-urlmatch-normalization "https://q@some.host:443" &&
+	test-urlmatch-normalization "http://q@some.host:80/" &&
+	test-urlmatch-normalization "https://q@some.host:443?" &&
+	! test-urlmatch-normalization "http://q@:8008" &&
+	! test-urlmatch-normalization "http://:8080" &&
+	! test-urlmatch-normalization "http://:" &&
+	test-urlmatch-normalization "xyz://q@some.host:456/" &&
+	test-urlmatch-normalization "xyz://[::1]:456/" &&
+	test-urlmatch-normalization "xyz://[::1]:/" &&
+	! test-urlmatch-normalization "xyz://[::1]:000/" &&
+	! test-urlmatch-normalization "xyz://[::1]:0%300/" &&
+	! test-urlmatch-normalization "xyz://[::1]:0x80/" &&
+	! test-urlmatch-normalization "xyz://[::1]:4294967297/" &&
+	! test-urlmatch-normalization "xyz://[::1]:030f/"
+'
+
+test_expect_success 'url port normalization' '
+	test "$(test-urlmatch-normalization -p "http://x:800")" = "http://x:800/" &&
+	test "$(test-urlmatch-normalization -p "http://x:0800")" = "http://x:800/" &&
+	test "$(test-urlmatch-normalization -p "http://x:00000800")" = "http://x:800/" &&
+	test "$(test-urlmatch-normalization -p "http://x:065535")" = "http://x:65535/" &&
+	test "$(test-urlmatch-normalization -p "http://x:1")" = "http://x:1/" &&
+	test "$(test-urlmatch-normalization -p "http://x:80")" = "http://x/" &&
+	test "$(test-urlmatch-normalization -p "http://x:080")" = "http://x/" &&
+	test "$(test-urlmatch-normalization -p "http://x:000000080")" = "http://x/" &&
+	test "$(test-urlmatch-normalization -p "https://x:443")" = "https://x/" &&
+	test "$(test-urlmatch-normalization -p "https://x:0443")" = "https://x/" &&
+	test "$(test-urlmatch-normalization -p "https://x:000000443")" = "https://x/"
+'
+
+test_expect_success 'url general escapes' '
+	! test-urlmatch-normalization "http://x.y?%fg" &&
+	test "$(test-urlmatch-normalization -p "X://W/%7e%41^%3a")" = "x://w/~A%5E%3A" &&
+	test "$(test-urlmatch-normalization -p "X://W/:/?#[]@")" = "x://w/:/?#[]@" &&
+	test "$(test-urlmatch-normalization -p "X://W/$&()*+,;=")" = "x://w/$&()*+,;=" &&
+	test "$(test-urlmatch-normalization -p "X://W/'\''")" = "x://w/'\''" &&
+	test "$(test-urlmatch-normalization -p "X://W?'\!'")" = "x://w/?'\!'"
+'
+
+test_expect_success 'url high-bit escapes' '
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-1")")" = "x://q/%01%02%03%04%05%06%07%08%0E%0F%10%11%12" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-2")")" = "x://q/%13%14%15%16%17%18%19%1B%1C%1D%1E%1F%7F" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-3")")" = "x://q/%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-4")")" = "x://q/%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-5")")" = "x://q/%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-6")")" = "x://q/%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-7")")" = "x://q/%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-8")")" = "x://q/%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-9")")" = "x://q/%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-10")")" = "x://q/%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF" &&
+	test "$(test-urlmatch-normalization -p "$(cat "$tu-11")")" = "x://q/%C2%80%DF%BF%E0%A0%80%EF%BF%BD%F0%90%80%80%F0%AF%BF%BD"
+'
+
+test_expect_success 'url username/password escapes' '
+	test "$(test-urlmatch-normalization -p "x://%41%62(^):%70+d@foo")" = "x://Ab(%5E):p+d@foo/"
+'
+
+test_expect_success 'url normalized lengths' '
+	test "$(test-urlmatch-normalization -l "Http://%4d%65:%4d^%70@The.Host")" = 25 &&
+	test "$(test-urlmatch-normalization -l "http://%41:%42@x.y/%61/")" = 17 &&
+	test "$(test-urlmatch-normalization -l "http://@x.y/^")" = 15
+'
+
+test_expect_success 'url . and .. segments' '
+	test "$(test-urlmatch-normalization -p "x://y/.")" = "x://y/" &&
+	test "$(test-urlmatch-normalization -p "x://y/./")" = "x://y/" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/.")" = "x://y/a" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/./")" = "x://y/a/" &&
+	test "$(test-urlmatch-normalization -p "x://y/.?")" = "x://y/?" &&
+	test "$(test-urlmatch-normalization -p "x://y/./?")" = "x://y/?" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/.?")" = "x://y/a?" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/./?")" = "x://y/a/?" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/./b/.././../c")" = "x://y/c" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/./b/../.././c/")" = "x://y/c/" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/./b/.././../c/././.././.")" = "x://y/" &&
+	! test-urlmatch-normalization "x://y/a/./b/.././../c/././.././.." &&
+	test "$(test-urlmatch-normalization -p "x://y/a/./?/././..")" = "x://y/a/?/././.." &&
+	test "$(test-urlmatch-normalization -p "x://y/%2e/")" = "x://y/" &&
+	test "$(test-urlmatch-normalization -p "x://y/%2E/")" = "x://y/" &&
+	test "$(test-urlmatch-normalization -p "x://y/a/%2e./")" = "x://y/" &&
+	test "$(test-urlmatch-normalization -p "x://y/b/.%2E/")" = "x://y/" &&
+	test "$(test-urlmatch-normalization -p "x://y/c/%2e%2E/")" = "x://y/"
+'
+
+# http://@foo specifies an empty user name but does not specify a password
+# http://foo  specifies neither a user name nor a password
+# So they should not be equivalent
+test_expect_success 'url equivalents' '
+	test-urlmatch-normalization "httP://x" "Http://X/" &&
+	test-urlmatch-normalization "Http://%4d%65:%4d^%70@The.Host" "hTTP://Me:%4D^p@the.HOST:80/" &&
+	! test-urlmatch-normalization "https://@x.y/^" "httpS://x.y:443/^" &&
+	test-urlmatch-normalization "https://@x.y/^" "httpS://@x.y:0443/^" &&
+	test-urlmatch-normalization "https://@x.y/^/../abc" "httpS://@x.y:0443/abc" &&
+	test-urlmatch-normalization "https://@x.y/^/.." "httpS://@x.y:0443/"
+'
+
+test_done
diff --git a/t/t0110/README b/t/t0110/README
new file mode 100644
index 0000000..ad4a50e
--- /dev/null
+++ b/t/t0110/README
@@ -0,0 +1,9 @@
+The url data files in this directory contain URLs with characters
+in the range 0x01-0x1f and 0x7f-0xff to test the proper normalization
+of unprintable characters.
+
+A select few characters in the 0x01-0x1f range are skipped to help
+avoid problems running the test itself.
+
+The urls are in test files in this directory rather than being
+embedded in the test script for portability.
diff --git a/t/t0110/url-1 b/t/t0110/url-1
new file mode 100644
index 0000000..519019c
--- /dev/null
+++ b/t/t0110/url-1
@@ -0,0 +1 @@
+x://q/
diff --git a/t/t0110/url-10 b/t/t0110/url-10
new file mode 100644
index 0000000..b9965de
--- /dev/null
+++ b/t/t0110/url-10
@@ -0,0 +1 @@
+x://q/ðñòóôõö÷øùúûüýþÿ
diff --git a/t/t0110/url-11 b/t/t0110/url-11
new file mode 100644
index 0000000..f0a50f1
--- /dev/null
+++ b/t/t0110/url-11
@@ -0,0 +1 @@
+x://q/€߿ࠀ�𐀀𯿽
diff --git a/t/t0110/url-2 b/t/t0110/url-2
new file mode 100644
index 0000000..43334b0
--- /dev/null
+++ b/t/t0110/url-2
@@ -0,0 +1 @@
+x://q/
diff --git a/t/t0110/url-3 b/t/t0110/url-3
new file mode 100644
index 0000000..7378c7b
--- /dev/null
+++ b/t/t0110/url-3
@@ -0,0 +1 @@
+x://q/€‚ƒ„…†‡ˆ‰Š‹ŒŽ
diff --git a/t/t0110/url-4 b/t/t0110/url-4
new file mode 100644
index 0000000..220b198
--- /dev/null
+++ b/t/t0110/url-4
@@ -0,0 +1 @@
+x://q/‘’“”•–—˜™š›œžŸ
diff --git a/t/t0110/url-5 b/t/t0110/url-5
new file mode 100644
index 0000000..1ccd927
--- /dev/null
+++ b/t/t0110/url-5
@@ -0,0 +1 @@
+x://q/ ¡¢£¤¥¦§¨©ª«¬­®¯
diff --git a/t/t0110/url-6 b/t/t0110/url-6
new file mode 100644
index 0000000..e8283aa
--- /dev/null
+++ b/t/t0110/url-6
@@ -0,0 +1 @@
+x://q/°±²³´µ¶·¸¹º»¼½¾¿
diff --git a/t/t0110/url-7 b/t/t0110/url-7
new file mode 100644
index 0000000..fa7c10b
--- /dev/null
+++ b/t/t0110/url-7
@@ -0,0 +1 @@
+x://q/ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
diff --git a/t/t0110/url-8 b/t/t0110/url-8
new file mode 100644
index 0000000..79a0ba8
--- /dev/null
+++ b/t/t0110/url-8
@@ -0,0 +1 @@
+x://q/ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
diff --git a/t/t0110/url-9 b/t/t0110/url-9
new file mode 100644
index 0000000..8b44bec
--- /dev/null
+++ b/t/t0110/url-9
@@ -0,0 +1 @@
+x://q/àáâãäåæçèéêëìíîï
diff --git a/t/t0202-gettext-perl.sh b/t/t0202-gettext-perl.sh
index 428ebb0..a29d166 100755
--- a/t/t0202-gettext-perl.sh
+++ b/t/t0202-gettext-perl.sh
@@ -12,7 +12,7 @@
 	test_done
 fi
 
-"$PERL_PATH" -MTest::More -e 0 2>/dev/null || {
+perl -MTest::More -e 0 2>/dev/null || {
 	skip_all="Perl Test::More unavailable, skipping test"
 	test_done
 }
@@ -22,6 +22,6 @@
 
 test_external_without_stderr \
     'Perl Git::I18N API' \
-    "$PERL_PATH" "$TEST_DIRECTORY"/t0202/test.pl
+    perl "$TEST_DIRECTORY"/t0202/test.pl
 
 test_done
diff --git a/t/t0202/test.pl b/t/t0202/test.pl
old mode 100644
new mode 100755
diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh
index f53de79..0745685 100755
--- a/t/t1005-read-tree-reset.sh
+++ b/t/t1005-read-tree-reset.sh
@@ -8,84 +8,99 @@
 # two-tree test
 
 test_expect_success 'setup' '
-  git init &&
-  mkdir df &&
-  echo content >df/file &&
-  git add df/file &&
-  git commit -m one &&
-  git ls-files >expect &&
-  rm -rf df &&
-  echo content >df &&
-  git add df &&
-  echo content >new &&
-  git add new &&
-  git commit -m two
+	git init &&
+	mkdir df &&
+	echo content >df/file &&
+	git add df/file &&
+	git commit -m one &&
+	git ls-files >expect &&
+	rm -rf df &&
+	echo content >df &&
+	git add df &&
+	echo content >new &&
+	git add new &&
+	git commit -m two
 '
 
 test_expect_success 'reset should work' '
-  read_tree_u_must_succeed -u --reset HEAD^ &&
-  git ls-files >actual &&
-  test_cmp expect actual
+	read_tree_u_must_succeed -u --reset HEAD^ &&
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'reset should remove remnants from a failed merge' '
-  read_tree_u_must_succeed --reset -u HEAD &&
-  git ls-files -s >expect &&
-  sha1=$(git rev-parse :new) &&
-  (
-	echo "100644 $sha1 1	old"
-	echo "100644 $sha1 3	old"
-  ) | git update-index --index-info &&
-  >old &&
-  git ls-files -s &&
-  read_tree_u_must_succeed --reset -u HEAD &&
-  git ls-files -s >actual &&
-  ! test -f old
+	read_tree_u_must_succeed --reset -u HEAD &&
+	git ls-files -s >expect &&
+	sha1=$(git rev-parse :new) &&
+	(
+		echo "100644 $sha1 1	old"
+		echo "100644 $sha1 3	old"
+	) | git update-index --index-info &&
+	>old &&
+	git ls-files -s &&
+	read_tree_u_must_succeed --reset -u HEAD &&
+	git ls-files -s >actual &&
+	! test -f old
+'
+
+test_expect_success 'two-way reset should remove remnants too' '
+	read_tree_u_must_succeed --reset -u HEAD &&
+	git ls-files -s >expect &&
+	sha1=$(git rev-parse :new) &&
+	(
+		echo "100644 $sha1 1	old"
+		echo "100644 $sha1 3	old"
+	) | git update-index --index-info &&
+	>old &&
+	git ls-files -s &&
+	read_tree_u_must_succeed --reset -u HEAD HEAD &&
+	git ls-files -s >actual &&
+	! test -f old
 '
 
 test_expect_success 'Porcelain reset should remove remnants too' '
-  read_tree_u_must_succeed --reset -u HEAD &&
-  git ls-files -s >expect &&
-  sha1=$(git rev-parse :new) &&
-  (
-	echo "100644 $sha1 1	old"
-	echo "100644 $sha1 3	old"
-  ) | git update-index --index-info &&
-  >old &&
-  git ls-files -s &&
-  git reset --hard &&
-  git ls-files -s >actual &&
-  ! test -f old
+	read_tree_u_must_succeed --reset -u HEAD &&
+	git ls-files -s >expect &&
+	sha1=$(git rev-parse :new) &&
+	(
+		echo "100644 $sha1 1	old"
+		echo "100644 $sha1 3	old"
+	) | git update-index --index-info &&
+	>old &&
+	git ls-files -s &&
+	git reset --hard &&
+	git ls-files -s >actual &&
+	! test -f old
 '
 
 test_expect_success 'Porcelain checkout -f should remove remnants too' '
-  read_tree_u_must_succeed --reset -u HEAD &&
-  git ls-files -s >expect &&
-  sha1=$(git rev-parse :new) &&
-  (
-	echo "100644 $sha1 1	old"
-	echo "100644 $sha1 3	old"
-  ) | git update-index --index-info &&
-  >old &&
-  git ls-files -s &&
-  git checkout -f &&
-  git ls-files -s >actual &&
-  ! test -f old
+	read_tree_u_must_succeed --reset -u HEAD &&
+	git ls-files -s >expect &&
+	sha1=$(git rev-parse :new) &&
+	(
+		echo "100644 $sha1 1	old"
+		echo "100644 $sha1 3	old"
+	) | git update-index --index-info &&
+	>old &&
+	git ls-files -s &&
+	git checkout -f &&
+	git ls-files -s >actual &&
+	! test -f old
 '
 
 test_expect_success 'Porcelain checkout -f HEAD should remove remnants too' '
-  read_tree_u_must_succeed --reset -u HEAD &&
-  git ls-files -s >expect &&
-  sha1=$(git rev-parse :new) &&
-  (
-	echo "100644 $sha1 1	old"
-	echo "100644 $sha1 3	old"
-  ) | git update-index --index-info &&
-  >old &&
-  git ls-files -s &&
-  git checkout -f HEAD &&
-  git ls-files -s >actual &&
-  ! test -f old
+	read_tree_u_must_succeed --reset -u HEAD &&
+	git ls-files -s >expect &&
+	sha1=$(git rev-parse :new) &&
+	(
+		echo "100644 $sha1 1	old"
+		echo "100644 $sha1 3	old"
+	) | git update-index --index-info &&
+	>old &&
+	git ls-files -s &&
+	git checkout -f HEAD &&
+	git ls-files -s >actual &&
+	! test -f old
 '
 
 test_done
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 4e911fb..a72e700 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -78,6 +78,35 @@
 	echo $sha1 | git cat-file --batch-check="%(objecttype) %(objectname)" >actual &&
 	test_cmp expect actual
     '
+
+    test_expect_success '--batch-check with %(rest)' '
+	echo "$type this is some extra content" >expect &&
+	echo "$sha1    this is some extra content" |
+		git cat-file --batch-check="%(objecttype) %(rest)" >actual &&
+	test_cmp expect actual
+    '
+
+    test -z "$content" ||
+    test_expect_success "--batch without type ($type)" '
+	{
+		echo "$size" &&
+		maybe_remove_timestamp "$content" $no_ts
+	} >expect &&
+	echo $sha1 | git cat-file --batch="%(objectsize)" >actual.full &&
+	maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
+	test_cmp expect actual
+    '
+
+    test -z "$content" ||
+    test_expect_success "--batch without size ($type)" '
+	{
+		echo "$type" &&
+		maybe_remove_timestamp "$content" $no_ts
+	} >expect &&
+	echo $sha1 | git cat-file --batch="%(objecttype)" >actual.full &&
+	maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
+	test_cmp expect actual
+    '
 }
 
 hello_content="Hello World"
@@ -91,6 +120,14 @@
 
 run_tests 'blob' $hello_sha1 $hello_size "$hello_content" "$hello_content"
 
+test_expect_success '--batch-check without %(rest) considers whole line' '
+	echo "$hello_sha1 blob $hello_size" >expect &&
+	git update-index --add --cacheinfo 100644 $hello_sha1 "white space" &&
+	test_when_finished "git update-index --remove \"white space\"" &&
+	echo ":white space" | git cat-file --batch-check >actual &&
+	test_cmp expect actual
+'
+
 tree_sha1=$(git write-tree)
 tree_size=33
 tree_pretty_content="100644 blob $hello_sha1	hello"
@@ -179,6 +216,12 @@
     test " missing" = "$(echo | git cat-file --batch-check)"
 '
 
+test_expect_success 'empty --batch-check notices missing object' '
+	echo "$_z40 missing" >expect &&
+	echo "$_z40" | git cat-file --batch-check="" >actual &&
+	test_cmp expect actual
+'
+
 batch_input="$hello_sha1
 $commit_sha1
 $tag_sha1
@@ -219,4 +262,38 @@
     "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)"
 '
 
+test_expect_success 'setup blobs which are likely to delta' '
+	test-genrandom foo 10240 >foo &&
+	{ cat foo; echo plus; } >foo-plus &&
+	git add foo foo-plus &&
+	git commit -m foo &&
+	cat >blobs <<-\EOF
+	HEAD:foo
+	HEAD:foo-plus
+	EOF
+'
+
+test_expect_success 'confirm that neither loose blob is a delta' '
+	cat >expect <<-EOF
+	$_z40
+	$_z40
+	EOF
+	git cat-file --batch-check="%(deltabase)" <blobs >actual &&
+	test_cmp expect actual
+'
+
+# To avoid relying too much on the current delta heuristics,
+# we will check only that one of the two objects is a delta
+# against the other, but not the order. We can do so by just
+# asking for the base of both, and checking whether either
+# sha1 appears in the output.
+test_expect_success '%(deltabase) reports packed delta bases' '
+	git repack -ad &&
+	git cat-file --batch-check="%(deltabase)" <blobs >actual &&
+	{
+		grep "$(git rev-parse HEAD:foo)" actual ||
+		grep "$(git rev-parse HEAD:foo-plus)" actual
+	}
+'
+
 test_done
diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh
index df573c4..b946f87 100755
--- a/t/t1010-mktree.sh
+++ b/t/t1010-mktree.sh
@@ -42,13 +42,13 @@
 '
 
 test_expect_success 'ls-tree output in wrong order given to mktree (1)' '
-	"$PERL_PATH" -e "print reverse <>" <top |
+	perl -e "print reverse <>" <top |
 	git mktree >actual &&
 	test_cmp tree actual
 '
 
 test_expect_success 'ls-tree output in wrong order given to mktree (2)' '
-	"$PERL_PATH" -e "print reverse <>" <top.withsub |
+	perl -e "print reverse <>" <top.withsub |
 	git mktree >actual &&
 	test_cmp tree.withsub actual
 '
diff --git a/t/t1013-loose-object-format.sh b/t/t1013-loose-object-format.sh
deleted file mode 100755
index fbf5f2f..0000000
--- a/t/t1013-loose-object-format.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2011 Roberto Tyley
-#
-
-test_description='Correctly identify and parse loose object headers
-
-There are two file formats for loose objects - the original standard
-format, and the experimental format introduced with Git v1.4.3, later
-deprecated with v1.5.3. Although Git no longer writes the
-experimental format, objects in both formats must be read, with the
-format for a given file being determined by the header.
-
-Detecting file format based on header is not entirely trivial, not
-least because the first byte of a zlib-deflated stream will vary
-depending on how much memory was allocated for the deflation window
-buffer when the object was written out (for example 4KB on Android,
-rather that 32KB on a normal PC).
-
-The loose objects used as test vectors have been generated with the
-following Git versions:
-
-standard format: Git v1.7.4.1
-experimental format: Git v1.4.3 (legacyheaders=false)
-standard format, deflated with 4KB window size: Agit/JGit on Android
-'
-
-. ./test-lib.sh
-
-assert_blob_equals() {
-	printf "%s" "$2" >expected &&
-	git cat-file -p "$1" >actual &&
-	test_cmp expected actual
-}
-
-test_expect_success setup '
-	cp -R "$TEST_DIRECTORY/t1013/objects" .git/ &&
-	git --version
-'
-
-test_expect_success 'read standard-format loose objects' '
-	git cat-file tag 8d4e360d6c70fbd72411991c02a09c442cf7a9fa &&
-	git cat-file commit 6baee0540ea990d9761a3eb9ab183003a71c3696 &&
-	git ls-tree 7a37b887a73791d12d26c0d3e39568a8fb0fa6e8 &&
-	assert_blob_equals "257cc5642cb1a054f08cc83f2d943e56fd3ebe99" "foo$LF"
-'
-
-test_expect_success 'read experimental-format loose objects' '
-	git cat-file tag 76e7fa9941f4d5f97f64fea65a2cba436bc79cbb &&
-	git cat-file commit 7875c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 &&
-	git ls-tree 95b1625de3ba8b2214d1e0d0591138aea733f64f &&
-	assert_blob_equals "2e65efe2a145dda7ee51d1741299f848e5bf752e" "a" &&
-	assert_blob_equals "9ae9e86b7bd6cb1472d9373702d8249973da0832" "ab" &&
-	assert_blob_equals "85df50785d62d3b05ab03d9cbf7e4a0b49449730" "abcd" &&
-	assert_blob_equals "1656f9233d999f61ef23ef390b9c71d75399f435" "abcdefgh" &&
-	assert_blob_equals "1e72a6b2c4a577ab0338860fa9fe87f761fc9bbd" "abcdefghi" &&
-	assert_blob_equals "70e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd" "abcdefghijklmnop" &&
-	assert_blob_equals "bd15045f6ce8ff75747562173640456a394412c8" "abcdefghijklmnopqrstuvwx"
-'
-
-test_expect_success 'read standard-format objects deflated with smaller window buffer' '
-	git cat-file tag f816d5255855ac160652ee5253b06cd8ee14165a &&
-	git cat-file tag 149cedb5c46929d18e0f118e9fa31927487af3b6
-'
-
-test_done
diff --git a/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6 b/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6
deleted file mode 100644
index 472fd14..0000000
--- a/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435 b/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435
deleted file mode 100644
index c379d74..0000000
--- a/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd b/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd
deleted file mode 100644
index 9370630..0000000
--- a/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 b/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99
deleted file mode 100644
index bdcf704..0000000
--- a/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e b/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e
deleted file mode 100644
index ad62c43..0000000
--- a/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696 b/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696
deleted file mode 100644
index 3d2f033..0000000
--- a/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd b/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd
deleted file mode 100644
index b3f71a6..0000000
--- a/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb b/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb
deleted file mode 100644
index af4e9a7..0000000
--- a/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 b/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09
deleted file mode 100644
index 3dd28be..0000000
--- a/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8 b/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8
deleted file mode 100644
index 2b97b26..0000000
--- a/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730 b/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730
deleted file mode 100644
index 6dff746..0000000
--- a/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa b/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa
deleted file mode 100644
index cb41e92..0000000
--- a/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f b/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f
deleted file mode 100644
index 7ac46b4..0000000
--- a/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832 b/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832
deleted file mode 100644
index 9d8316d..0000000
--- a/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8 b/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8
deleted file mode 100644
index eebf239..0000000
--- a/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
deleted file mode 100644
index 134cf19..0000000
--- a/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
+++ /dev/null
Binary files differ
diff --git a/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a b/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a
deleted file mode 100644
index 26b75ae..0000000
--- a/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a
+++ /dev/null
Binary files differ
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index c4a7d84..9673593 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -652,16 +652,23 @@
 	test_cmp expect actual
 '
 
+test_expect_success '--int is at least 64 bits' '
+	git config giga.watts 121g &&
+	echo 129922760704 >expect &&
+	git config --int --get giga.watts >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'invalid unit' '
 	git config aninvalid.unit "1auto" &&
 	echo 1auto >expect &&
 	git config aninvalid.unit >actual &&
 	test_cmp expect actual &&
-	cat > expect <<-\EOF
-	fatal: bad config value for '\''aninvalid.unit'\'' in .git/config
+	cat >expect <<-\EOF
+	fatal: bad numeric config value '\''1auto'\'' for '\''aninvalid.unit'\'' in .git/config: invalid unit
 	EOF
 	test_must_fail git config --int --get aninvalid.unit 2>actual &&
-	test_cmp actual expect
+	test_i18ncmp expect actual
 '
 
 cat > expect << EOF
@@ -1087,6 +1094,31 @@
 	grep " line 3 " error
 '
 
+test_expect_success 'urlmatch' '
+	cat >.git/config <<-\EOF &&
+	[http]
+		sslVerify
+	[http "https://weak.example.com"]
+		sslVerify = false
+		cookieFile = /tmp/cookie.txt
+	EOF
+
+	echo true >expect &&
+	git config --bool --get-urlmatch http.SSLverify https://good.example.com >actual &&
+	test_cmp expect actual &&
+
+	echo false >expect &&
+	git config --bool --get-urlmatch http.sslverify https://weak.example.com >actual &&
+	test_cmp expect actual &&
+
+	{
+		echo http.cookiefile /tmp/cookie.txt &&
+		echo http.sslverify false
+	} >expect &&
+	git config --get-urlmatch HTTP https://weak.example.com >actual &&
+	test_cmp expect actual
+'
+
 # good section hygiene
 test_expect_failure 'unsetting the last key in a section removes header' '
 	cat >.git/config <<-\EOF &&
diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh
index 46103a1..3a2c819 100755
--- a/t/t1303-wacky-config.sh
+++ b/t/t1303-wacky-config.sh
@@ -3,17 +3,28 @@
 test_description='Test wacky input to git config'
 . ./test-lib.sh
 
+# Leaving off the newline is intentional!
 setup() {
 	(printf "[section]\n" &&
 	printf "  key = foo") >.git/config
 }
 
+# 'check section.key value' verifies that the entry for section.key is
+# 'value'
 check() {
 	echo "$2" >expected
 	git config --get "$1" >actual 2>&1
 	test_cmp actual expected
 }
 
+# 'check section.key regex value' verifies that the entry for
+# section.key *that matches 'regex'* is 'value'
+check_regex() {
+	echo "$3" >expected
+	git config --get "$1" "$2" >actual 2>&1
+	test_cmp actual expected
+}
+
 test_expect_success 'modify same key' '
 	setup &&
 	git config section.key bar &&
@@ -47,4 +58,57 @@
 	check section.key "$LONG_VALUE"
 '
 
+setup_many() {
+	setup &&
+	# This time we want the newline so that we can tack on more
+	# entries.
+	echo >>.git/config &&
+	# Semi-efficient way of concatenating 5^5 = 3125 lines. Note
+	# that because 'setup' already put one line, this means 3126
+	# entries for section.key in the config file.
+	cat >5to1 <<-\EOF &&
+	  key = foo
+	  key = foo
+	  key = foo
+	  key = foo
+	  key = foo
+	EOF
+	cat 5to1 5to1 5to1 5to1 5to1 >5to2 &&	   # 25
+	cat 5to2 5to2 5to2 5to2 5to2 >5to3 &&	   # 125
+	cat 5to3 5to3 5to3 5to3 5to3 >5to4 &&	   # 635
+	cat 5to4 5to4 5to4 5to4 5to4 >>.git/config # 3125
+}
+
+test_expect_success 'get many entries' '
+	setup_many &&
+	git config --get-all section.key >actual &&
+	test_line_count = 3126 actual
+'
+
+test_expect_success 'get many entries by regex' '
+	setup_many &&
+	git config --get-regexp "sec.*ke." >actual &&
+	test_line_count = 3126 actual
+'
+
+test_expect_success 'add and replace one of many entries' '
+	setup_many &&
+	git config --add section.key bar &&
+	check_regex section.key "b.*r" bar &&
+	git config section.key beer "b.*r" &&
+	check_regex section.key "b.*r" beer
+'
+
+test_expect_success 'replace many entries' '
+	setup_many &&
+	git config --replace-all section.key bar &&
+	check section.key bar
+'
+
+test_expect_success 'unset many entries' '
+	setup_many &&
+	git config --unset-all section.key &&
+	test_must_fail git config section.key
+'
+
 test_done
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index e415ee0..6ffd82f 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -302,4 +302,636 @@
 	'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER)' \
 	'test OTHER = $(git cat-file blob "master@{2005-05-26 23:42}:F")'
 
+a=refs/heads/a
+b=refs/heads/b
+c=refs/heads/c
+E='""'
+F='%s\0'
+pws='path with space'
+
+test_expect_success 'stdin test setup' '
+	echo "$pws" >"$pws" &&
+	git add -- "$pws" &&
+	git commit -m "$pws"
+'
+
+test_expect_success '-z fails without --stdin' '
+	test_must_fail git update-ref -z $m $m $m 2>err &&
+	grep "usage: git update-ref" err
+'
+
+test_expect_success 'stdin works with no input' '
+	>stdin &&
+	git update-ref --stdin <stdin &&
+	git rev-parse --verify -q $m
+'
+
+test_expect_success 'stdin fails on empty line' '
+	echo "" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: empty command in input" err
+'
+
+test_expect_success 'stdin fails on only whitespace' '
+	echo " " >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: whitespace before command:  " err
+'
+
+test_expect_success 'stdin fails on leading whitespace' '
+	echo " create $a $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: whitespace before command:  create $a $m" err
+'
+
+test_expect_success 'stdin fails on unknown command' '
+	echo "unknown $a" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: unknown command: unknown $a" err
+'
+
+test_expect_success 'stdin fails on badly quoted input' '
+	echo "create $a \"master" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: badly quoted argument: \\\"master" err
+'
+
+test_expect_success 'stdin fails on arguments not separated by space' '
+	echo "create \"$a\"master" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: expected SP but got: master" err
+'
+
+test_expect_success 'stdin fails create with no ref' '
+	echo "create " >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: create line missing <ref>" err
+'
+
+test_expect_success 'stdin fails create with bad ref name' '
+	echo "create ~a $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: invalid ref format: ~a" err
+'
+
+test_expect_success 'stdin fails create with no new value' '
+	echo "create $a" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: create $a missing <newvalue>" err
+'
+
+test_expect_success 'stdin fails create with too many arguments' '
+	echo "create $a $m $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: create $a has extra input:  $m" err
+'
+
+test_expect_success 'stdin fails update with no ref' '
+	echo "update " >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: update line missing <ref>" err
+'
+
+test_expect_success 'stdin fails update with bad ref name' '
+	echo "update ~a $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: invalid ref format: ~a" err
+'
+
+test_expect_success 'stdin fails update with no new value' '
+	echo "update $a" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: update $a missing <newvalue>" err
+'
+
+test_expect_success 'stdin fails update with too many arguments' '
+	echo "update $a $m $m $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: update $a has extra input:  $m" err
+'
+
+test_expect_success 'stdin fails delete with no ref' '
+	echo "delete " >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: delete line missing <ref>" err
+'
+
+test_expect_success 'stdin fails delete with bad ref name' '
+	echo "delete ~a $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: invalid ref format: ~a" err
+'
+
+test_expect_success 'stdin fails delete with too many arguments' '
+	echo "delete $a $m $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: delete $a has extra input:  $m" err
+'
+
+test_expect_success 'stdin fails verify with too many arguments' '
+	echo "verify $a $m $m" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: verify $a has extra input:  $m" err
+'
+
+test_expect_success 'stdin fails option with unknown name' '
+	echo "option unknown" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: option unknown: unknown" err
+'
+
+test_expect_success 'stdin fails with duplicate refs' '
+	cat >stdin <<-EOF &&
+	create $a $m
+	create $b $m
+	create $a $m
+	EOF
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: Multiple updates for ref '"'"'$a'"'"' not allowed." err
+'
+
+test_expect_success 'stdin create ref works' '
+	echo "create $a $m" >stdin &&
+	git update-ref --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin update ref creates with zero old value' '
+	echo "update $b $m $Z" >stdin &&
+	git update-ref --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	git update-ref -d $b
+'
+
+test_expect_success 'stdin update ref creates with empty old value' '
+	echo "update $b $m $E" >stdin &&
+	git update-ref --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin create ref works with path with space to blob' '
+	echo "create refs/blobs/pws \"$m:$pws\"" >stdin &&
+	git update-ref --stdin <stdin &&
+	git rev-parse "$m:$pws" >expect &&
+	git rev-parse refs/blobs/pws >actual &&
+	test_cmp expect actual &&
+	git update-ref -d refs/blobs/pws
+'
+
+test_expect_success 'stdin update ref fails with wrong old value' '
+	echo "update $c $m $m~1" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin update ref fails with bad old value' '
+	echo "update $c $m does-not-exist" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: invalid old value for ref $c: does-not-exist" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin create ref fails with bad new value' '
+	echo "create $c does-not-exist" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: invalid new value for ref $c: does-not-exist" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin create ref fails with zero new value' '
+	echo "create $c " >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: create $c given zero new value" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin update ref works with right old value' '
+	echo "update $b $m~1 $m" >stdin &&
+	git update-ref --stdin <stdin &&
+	git rev-parse $m~1 >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin delete ref fails with wrong old value' '
+	echo "delete $a $m~1" >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: Cannot lock the ref '"'"'$a'"'"'" err &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin delete ref fails with zero old value' '
+	echo "delete $a " >stdin &&
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: delete $a given zero old value" err &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin update symref works option no-deref' '
+	git symbolic-ref TESTSYMREF $b &&
+	cat >stdin <<-EOF &&
+	option no-deref
+	update TESTSYMREF $a $b
+	EOF
+	git update-ref --stdin <stdin &&
+	git rev-parse TESTSYMREF >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $m~1 >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin delete symref works option no-deref' '
+	git symbolic-ref TESTSYMREF $b &&
+	cat >stdin <<-EOF &&
+	option no-deref
+	delete TESTSYMREF $b
+	EOF
+	git update-ref --stdin <stdin &&
+	test_must_fail git rev-parse --verify -q TESTSYMREF &&
+	git rev-parse $m~1 >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin delete ref works with right old value' '
+	echo "delete $b $m~1" >stdin &&
+	git update-ref --stdin <stdin &&
+	test_must_fail git rev-parse --verify -q $b
+'
+
+test_expect_success 'stdin update/create/verify combination works' '
+	cat >stdin <<-EOF &&
+	update $a $m
+	create $b $m
+	verify $c
+	EOF
+	git update-ref --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin update refs works with identity updates' '
+	cat >stdin <<-EOF &&
+	update $a $m $m
+	update $b $m $m
+	update $c $Z $E
+	EOF
+	git update-ref --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin update refs fails with wrong old value' '
+	git update-ref $c $m &&
+	cat >stdin <<-EOF &&
+	update $a $m $m
+	update $b $m $m
+	update $c  ''
+	EOF
+	test_must_fail git update-ref --stdin <stdin 2>err &&
+	grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	git rev-parse $c >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin delete refs works with packed and loose refs' '
+	git pack-refs --all &&
+	git update-ref $c $m~1 &&
+	cat >stdin <<-EOF &&
+	delete $a $m
+	update $b $Z $m
+	update $c $E $m~1
+	EOF
+	git update-ref --stdin <stdin &&
+	test_must_fail git rev-parse --verify -q $a &&
+	test_must_fail git rev-parse --verify -q $b &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin -z works on empty input' '
+	>stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse --verify -q $m
+'
+
+test_expect_success 'stdin -z fails on empty line' '
+	echo "" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: whitespace before command: " err
+'
+
+test_expect_success 'stdin -z fails on empty command' '
+	printf $F "" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: empty command in input" err
+'
+
+test_expect_success 'stdin -z fails on only whitespace' '
+	printf $F " " >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: whitespace before command:  " err
+'
+
+test_expect_success 'stdin -z fails on leading whitespace' '
+	printf $F " create $a" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: whitespace before command:  create $a" err
+'
+
+test_expect_success 'stdin -z fails on unknown command' '
+	printf $F "unknown $a" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: unknown command: unknown $a" err
+'
+
+test_expect_success 'stdin -z fails create with no ref' '
+	printf $F "create " >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: create line missing <ref>" err
+'
+
+test_expect_success 'stdin -z fails create with bad ref name' '
+	printf $F "create ~a " "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: invalid ref format: ~a " err
+'
+
+test_expect_success 'stdin -z fails create with no new value' '
+	printf $F "create $a" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: create $a missing <newvalue>" err
+'
+
+test_expect_success 'stdin -z fails create with too many arguments' '
+	printf $F "create $a" "$m" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: unknown command: $m" err
+'
+
+test_expect_success 'stdin -z fails update with no ref' '
+	printf $F "update " >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: update line missing <ref>" err
+'
+
+test_expect_success 'stdin -z fails update with bad ref name' '
+	printf $F "update ~a" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: invalid ref format: ~a" err
+'
+
+test_expect_success 'stdin -z fails update with no new value' '
+	printf $F "update $a" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: update $a missing <newvalue>" err
+'
+
+test_expect_success 'stdin -z fails update with no old value' '
+	printf $F "update $a" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: update $a missing \\[<oldvalue>\\] NUL" err
+'
+
+test_expect_success 'stdin -z fails update with too many arguments' '
+	printf $F "update $a" "$m" "$m" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: unknown command: $m" err
+'
+
+test_expect_success 'stdin -z fails delete with no ref' '
+	printf $F "delete " >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: delete line missing <ref>" err
+'
+
+test_expect_success 'stdin -z fails delete with bad ref name' '
+	printf $F "delete ~a" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: invalid ref format: ~a" err
+'
+
+test_expect_success 'stdin -z fails delete with no old value' '
+	printf $F "delete $a" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: delete $a missing \\[<oldvalue>\\] NUL" err
+'
+
+test_expect_success 'stdin -z fails delete with too many arguments' '
+	printf $F "delete $a" "$m" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: unknown command: $m" err
+'
+
+test_expect_success 'stdin -z fails verify with too many arguments' '
+	printf $F "verify $a" "$m" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: unknown command: $m" err
+'
+
+test_expect_success 'stdin -z fails verify with no old value' '
+	printf $F "verify $a" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: verify $a missing \\[<oldvalue>\\] NUL" err
+'
+
+test_expect_success 'stdin -z fails option with unknown name' '
+	printf $F "option unknown" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: option unknown: unknown" err
+'
+
+test_expect_success 'stdin -z fails with duplicate refs' '
+	printf $F "create $a" "$m" "create $b" "$m" "create $a" "$m" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: Multiple updates for ref '"'"'$a'"'"' not allowed." err
+'
+
+test_expect_success 'stdin -z create ref works' '
+	printf $F "create $a" "$m" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z update ref creates with zero old value' '
+	printf $F "update $b" "$m" "$Z" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	git update-ref -d $b
+'
+
+test_expect_success 'stdin -z update ref creates with empty old value' '
+	printf $F "update $b" "$m" "" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z create ref works with path with space to blob' '
+	printf $F "create refs/blobs/pws" "$m:$pws" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse "$m:$pws" >expect &&
+	git rev-parse refs/blobs/pws >actual &&
+	test_cmp expect actual &&
+	git update-ref -d refs/blobs/pws
+'
+
+test_expect_success 'stdin -z update ref fails with wrong old value' '
+	printf $F "update $c" "$m" "$m~1" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin -z update ref fails with bad old value' '
+	printf $F "update $c" "$m" "does-not-exist" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: invalid old value for ref $c: does-not-exist" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin -z create ref fails with bad new value' '
+	printf $F "create $c" "does-not-exist" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: invalid new value for ref $c: does-not-exist" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin -z create ref fails with zero new value' '
+	printf $F "create $c" "" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: create $c given zero new value" err &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin -z update ref works with right old value' '
+	printf $F "update $b" "$m~1" "$m" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse $m~1 >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z delete ref fails with wrong old value' '
+	printf $F "delete $a" "$m~1" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: Cannot lock the ref '"'"'$a'"'"'" err &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z delete ref fails with zero old value' '
+	printf $F "delete $a" "$Z" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: delete $a given zero old value" err &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z update symref works option no-deref' '
+	git symbolic-ref TESTSYMREF $b &&
+	printf $F "option no-deref" "update TESTSYMREF" "$a" "$b" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse TESTSYMREF >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $m~1 >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z delete symref works option no-deref' '
+	git symbolic-ref TESTSYMREF $b &&
+	printf $F "option no-deref" "delete TESTSYMREF" "$b" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	test_must_fail git rev-parse --verify -q TESTSYMREF &&
+	git rev-parse $m~1 >expect &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z delete ref works with right old value' '
+	printf $F "delete $b" "$m~1" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	test_must_fail git rev-parse --verify -q $b
+'
+
+test_expect_success 'stdin -z update/create/verify combination works' '
+	printf $F "update $a" "$m" "" "create $b" "$m" "verify $c" "" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin -z update refs works with identity updates' '
+	printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$Z" "" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
+test_expect_success 'stdin -z update refs fails with wrong old value' '
+	git update-ref $c $m &&
+	printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "" "$Z" >stdin &&
+	test_must_fail git update-ref -z --stdin <stdin 2>err &&
+	grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err &&
+	git rev-parse $m >expect &&
+	git rev-parse $a >actual &&
+	test_cmp expect actual &&
+	git rev-parse $b >actual &&
+	test_cmp expect actual &&
+	git rev-parse $c >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin -z delete refs works with packed and loose refs' '
+	git pack-refs --all &&
+	git update-ref $c $m~1 &&
+	printf $F "delete $a" "$m" "update $b" "$Z" "$m" "update $c" "" "$m~1" >stdin &&
+	git update-ref -z --stdin <stdin &&
+	test_must_fail git rev-parse --verify -q $a &&
+	test_must_fail git rev-parse --verify -q $b &&
+	test_must_fail git rev-parse --verify -q $c
+'
+
 test_done
diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh
index 13c88c9..83b1300 100755
--- a/t/t1502-rev-parse-parseopt.sh
+++ b/t/t1502-rev-parse-parseopt.sh
@@ -12,9 +12,11 @@
     -h, --help            show the help
     --foo                 some nifty option --foo
     --bar ...             some cool option --bar with an argument
+    -b, --baz             a short and long option
 
 An option group Header
     -C[...]               option C with an optional argument
+    -d, --data[=...]      short and long option with an optional argument
 
 Extras
     --extra1              line above used to cause a segfault but no longer does
@@ -31,9 +33,11 @@
 
 foo       some nifty option --foo
 bar=      some cool option --bar with an argument
+b,baz     a short and long option
 
  An option group Header
 C?        option C with an optional argument
+d,data?   short and long option with an optional argument
 
 Extras
 extra1    line above used to cause a segfault but no longer does
@@ -45,16 +49,16 @@
 '
 
 cat > expect <<EOF
-set -- --foo --bar 'ham' -- 'arg'
+set -- --foo --bar 'ham' -b -- 'arg'
 EOF
 
 test_expect_success 'test --parseopt' '
-	git rev-parse --parseopt -- --foo --bar=ham arg < optionspec > output &&
+	git rev-parse --parseopt -- --foo --bar=ham --baz arg < optionspec > output &&
 	test_cmp expect output
 '
 
 test_expect_success 'test --parseopt with mixed options and arguments' '
-	git rev-parse --parseopt -- --foo arg --bar=ham < optionspec > output &&
+	git rev-parse --parseopt -- --foo arg --bar=ham --baz < optionspec > output &&
 	test_cmp expect output
 '
 
@@ -99,4 +103,36 @@
 	test_cmp expect output
 '
 
+cat > expect <<EOF
+set -- --foo --bar='z' --baz -C'Z' --data='A' -- 'arg'
+EOF
+
+test_expect_success 'test --parseopt --stuck-long' '
+	git rev-parse --parseopt --stuck-long -- --foo --bar=z -b arg -CZ -dA <optionspec >output &&
+	test_cmp expect output
+'
+
+cat > expect <<EOF
+set -- --data='' -C --baz -- 'arg'
+EOF
+
+test_expect_success 'test --parseopt --stuck-long and empty optional argument' '
+	git rev-parse --parseopt --stuck-long -- --data= arg -C -b <optionspec >output &&
+	test_cmp expect output
+'
+
+cat > expect <<EOF
+set -- --data --baz -- 'arg'
+EOF
+
+test_expect_success 'test --parseopt --stuck-long and long option with unset optional argument' '
+	git rev-parse --parseopt --stuck-long -- --data arg -b <optionspec >output &&
+	test_cmp expect output
+'
+
+test_expect_success 'test --parseopt --stuck-long and short option with unset optional argument' '
+	git rev-parse --parseopt --stuck-long -- -d arg -b <optionspec >output &&
+	test_cmp expect output
+'
+
 test_done
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index f950c10..613d9bf 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -196,4 +196,28 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'arg before dashdash must be a revision (missing)' '
+	test_must_fail git rev-parse foobar -- 2>stderr &&
+	test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (file)' '
+	>foobar &&
+	test_must_fail git rev-parse foobar -- 2>stderr &&
+	test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
+	>foobar &&
+	git update-ref refs/heads/foobar HEAD &&
+	{
+		# we do not want to use rev-parse here, because
+		# we are testing it
+		cat .git/refs/heads/foobar &&
+		printf "%s\n" --
+	} >expect &&
+	git rev-parse foobar -- >actual &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh
index 2a19e79..178694e 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -17,6 +17,9 @@
 	 test_commit 4 &&
 	 git branch --track my-side origin/side &&
 	 git branch --track local-master master &&
+	 git branch --track fun@ny origin/side &&
+	 git branch --track @funny origin/side &&
+	 git branch --track funny@ origin/side &&
 	 git remote add -t master master-only .. &&
 	 git fetch master-only &&
 	 git branch bad-upstream &&
@@ -54,6 +57,24 @@
 	test refs/remotes/origin/side = "$(full_name my-side@{u})"
 '
 
+test_expect_success 'upstream of branch with @ in middle' '
+	full_name fun@ny@{u} >actual &&
+	echo refs/remotes/origin/side >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'upstream of branch with @ at start' '
+	full_name @funny@{u} >actual &&
+	echo refs/remotes/origin/side >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'upstream of branch with @ at end' '
+	full_name funny@@{u} >actual &&
+	echo refs/remotes/origin/side >expect &&
+	test_cmp expect actual
+'
+
 test_expect_success 'refs/heads/my-side@{upstream} does not resolve to my-side{upstream}' '
 	test_must_fail full_name refs/heads/my-side@{upstream}
 '
@@ -210,4 +231,20 @@
 	test_cmp expect actual
 '
 
+test_expect_success '@{reflog}-parsing does not look beyond colon' '
+	echo content >@{yesterday} &&
+	git add @{yesterday} &&
+	git commit -m "funny reflog file" &&
+	git hash-object @{yesterday} >expect &&
+	git rev-parse HEAD:@{yesterday} >actual
+'
+
+test_expect_success '@{upstream}-parsing does not look beyond colon' '
+	echo content >@{upstream} &&
+	git add @{upstream} &&
+	git commit -m "funny upstream file" &&
+	git hash-object @{upstream} >expect &&
+	git rev-parse HEAD:@{upstream} >actual
+'
+
 test_done
diff --git a/t/t1508-at-combinations.sh b/t/t1508-at-combinations.sh
index e5aea3b..078e119 100755
--- a/t/t1508-at-combinations.sh
+++ b/t/t1508-at-combinations.sh
@@ -9,8 +9,11 @@
 		if test '$2' = 'commit'
 		then
 			git log -1 --format=%s '$1' >actual
-		else
+		elif test '$2' = 'ref'
+		then
 			git rev-parse --symbolic-full-name '$1' >actual
+		else
+			git cat-file -p '$1' >actual
 		fi &&
 		test_cmp expect actual
 	"
@@ -32,6 +35,9 @@
 	git checkout -b upstream-branch &&
 	test_commit upstream-one &&
 	test_commit upstream-two &&
+	git checkout -b @/at-test &&
+	git checkout -b @@/at-test &&
+	git checkout -b @at-test &&
 	git checkout -b old-branch &&
 	test_commit old-one &&
 	test_commit old-two &&
@@ -55,6 +61,11 @@
 check "@{u}@{1}" commit upstream-one
 check "@{-1}@{u}" ref refs/heads/master
 check "@{-1}@{u}@{1}" commit master-one
+check "@" commit new-two
+check "@@{u}" ref refs/heads/upstream-branch
+check "@@/at-test" ref refs/heads/@@/at-test
+check "@/at-test" ref refs/heads/@/at-test
+check "@at-test" ref refs/heads/@at-test
 nonsense "@{u}@{-1}"
 nonsense "@{0}@{0}"
 nonsense "@{1}@{u}"
@@ -74,4 +85,14 @@
 check "HEAD@{1}" commit new-two
 check "@{1}" commit old-one
 
+test_expect_success 'create path with @' '
+	echo content >normal &&
+	echo content >fun@ny &&
+	git add normal fun@ny &&
+	git commit -m "funny path"
+'
+
+check "@:normal" blob content
+check "@:fun@ny" blob content
+
 test_done
diff --git a/t/t1511-rev-parse-caret.sh b/t/t1511-rev-parse-caret.sh
index eaefc77..15973f2 100755
--- a/t/t1511-rev-parse-caret.sh
+++ b/t/t1511-rev-parse-caret.sh
@@ -54,6 +54,13 @@
 	test_must_fail git rev-parse blob-tag^{tree}
 '
 
+test_expect_success 'ref^{tag}' '
+	test_must_fail git rev-parse HEAD^{tag} &&
+	git rev-parse commit-tag >expected &&
+	git rev-parse commit-tag^{tag} >actual &&
+	test_cmp expected actual
+'
+
 test_expect_success 'ref^{/.}' '
 	git rev-parse master >expected &&
 	git rev-parse master^{/.} >actual &&
diff --git a/t/t2008-checkout-subdir.sh b/t/t2008-checkout-subdir.sh
index 3e098ab..eadb943 100755
--- a/t/t2008-checkout-subdir.sh
+++ b/t/t2008-checkout-subdir.sh
@@ -58,13 +58,13 @@
 
 '
 
-# This is not expected to work as ls-files was not designed
-# to deal with such.  Enable it when ls-files is updated.
-: test_expect_success 'checkout with complex relative path' '
-
-	rm file1 &&
-	git checkout HEAD -- ../dir1/../dir1/file1 && test -f ./file1
-
+test_expect_success 'checkout with complex relative path' '
+	(
+		cd dir1 &&
+		rm file1 &&
+		git checkout HEAD -- ../dir1/../dir1/file1 &&
+		test "hello" = "$(cat file1)"
+	)
 '
 
 test_expect_success 'relative path outside tree should fail' \
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index f0421c0..b2798fe 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -115,7 +115,7 @@
 
 git config core.excludesFile excludes-file
 
-git status | grep "^#	" > output
+git -c status.displayCommentPrefix=true status | grep "^#	" > output
 
 cat > expect << EOF
 #	.gitignore
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 55c9ab0..fcdb867 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -14,10 +14,11 @@
 	echo World >>A &&
 	git update-index --add A &&
 	git commit -m "Second commit." &&
-	HEAD=$(git rev-parse --verify HEAD)'
+	HEAD=$(git rev-parse --verify HEAD)
+'
 
 test_expect_success 'git branch --help should not have created a bogus branch' '
-	test_might_fail git branch --help </dev/null >/dev/null 2>/dev/null &&
+	test_might_fail git branch --man --help </dev/null >/dev/null 2>&1 &&
 	test_path_is_missing .git/refs/heads/--help
 '
 
@@ -351,7 +352,7 @@
 test_expect_success 'no tracking without .fetch entries' '
 	git config branch.autosetupmerge true &&
 	git branch my6 s &&
-	git config branch.automsetupmerge false &&
+	git config branch.autosetupmerge false &&
 	test -z "$(git config branch.my6.remote)" &&
 	test -z "$(git config branch.my6.merge)"
 '
@@ -425,14 +426,14 @@
 test_expect_success 'use --set-upstream-to modify HEAD' '
 	test_config branch.master.remote foo &&
 	test_config branch.master.merge foo &&
-	git branch my12
+	git branch my12 &&
 	git branch --set-upstream-to my12 &&
 	test "$(git config branch.master.remote)" = "." &&
 	test "$(git config branch.master.merge)" = "refs/heads/my12"
 '
 
 test_expect_success 'use --set-upstream-to modify a particular branch' '
-	git branch my13
+	git branch my13 &&
 	git branch --set-upstream-to master my13 &&
 	test "$(git config branch.my13.remote)" = "." &&
 	test "$(git config branch.my13.merge)" = "refs/heads/master"
@@ -443,7 +444,7 @@
 '
 
 test_expect_success 'test --unset-upstream on HEAD' '
-	git branch my14
+	git branch my14 &&
 	test_config branch.master.remote foo &&
 	test_config branch.master.merge foo &&
 	git branch --set-upstream-to my14 &&
@@ -465,7 +466,7 @@
 '
 
 test_expect_success 'test --unset-upstream on a particular branch' '
-	git branch my15
+	git branch my15 &&
 	git branch --set-upstream-to master my14 &&
 	git branch --unset-upstream my14 &&
 	test_must_fail git config branch.my14.remote &&
diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh
index 7480d6e..9a146f1 100755
--- a/t/t3300-funny-names.sh
+++ b/t/t3300-funny-names.sh
@@ -69,7 +69,7 @@
 	tabs	," (dq) and spaces
 	EOF
 	git ls-files -z >ls-files.z &&
-	"$PERL_PATH" -pe "y/\000/\012/" <ls-files.z >current &&
+	perl -pe "y/\000/\012/" <ls-files.z >current &&
 	test_cmp expected current
 '
 
@@ -106,7 +106,7 @@
 	tabs	," (dq) and spaces
 	EOF
 	git diff-index -z --name-status $t0 >diff-index.z &&
-	"$PERL_PATH" -pe "y/\000/\012/" <diff-index.z >current &&
+	perl -pe "y/\000/\012/" <diff-index.z >current &&
 	test_cmp expected current
 '
 
@@ -116,7 +116,7 @@
 	tabs	," (dq) and spaces
 	EOF
 	git diff-tree -z --name-status $t0 $t1 >diff-tree.z &&
-	"$PERL_PATH" -pe y/\\000/\\012/ <diff-tree.z >current &&
+	perl -pe y/\\000/\\012/ <diff-tree.z >current &&
 	test_cmp expected current
 '
 
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index ebf93b0..6d94b1f 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -134,12 +134,22 @@
 	test_must_fail git rebase
 '
 
-test_expect_success 'default to @{upstream} when upstream arg is missing' '
+test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' '
+	git checkout -b default-base master &&
 	git checkout -b default topic &&
 	git config branch.default.remote . &&
-	git config branch.default.merge refs/heads/master &&
+	git config branch.default.merge refs/heads/default-base &&
 	git rebase &&
-	test "$(git rev-parse default~1)" = "$(git rev-parse master)"
+	git rev-parse --verify default-base >expect &&
+	git rev-parse default~1 >actual &&
+	test_cmp expect actual &&
+	git checkout default-base &&
+	git reset --hard HEAD^ &&
+	git checkout default &&
+	git rebase &&
+	git rev-parse --verify default-base >expect &&
+	git rev-parse default~1 >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'rebase -q is quiet' '
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 6f489e2..51f3bbb 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -100,7 +100,7 @@
 
 '
 
-test_expect_success 'chery-pick on unborn branch' '
+test_expect_success 'cherry-pick on unborn branch' '
 	git checkout --orphan unborn &&
 	git rm --cached -r . &&
 	rm -rf * &&
@@ -109,4 +109,36 @@
 	! test_cmp_rev initial HEAD
 '
 
+test_expect_success 'cherry-pick "-" to pick from previous branch' '
+	git checkout unborn &&
+	test_commit to-pick actual content &&
+	git checkout master &&
+	git cherry-pick - &&
+	echo content >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'cherry-pick "-" is meaningless without checkout' '
+	test_create_repo afresh &&
+	(
+		cd afresh &&
+		test_commit one &&
+		test_commit two &&
+		test_commit three &&
+		test_must_fail git cherry-pick -
+	)
+'
+
+test_expect_success 'cherry-pick "-" works with arguments' '
+	git checkout -b side-branch &&
+	test_commit change actual change &&
+	git checkout master &&
+	git cherry-pick -s - &&
+	echo "Signed-off-by: C O Mitter <committer@example.com>" >expect &&
+	git cat-file commit HEAD | grep ^Signed-off-by: >signoff &&
+	test_cmp expect signoff &&
+	echo change >expect &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index 373aad6..fb889ac 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -105,7 +105,7 @@
 	test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
 '
 
-test_expect_success 'chery-pick --ff on unborn branch' '
+test_expect_success 'cherry-pick --ff on unborn branch' '
 	git checkout --orphan unborn &&
 	git rm --cached -r . &&
 	rm -rf * &&
diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh
index a5b6a5f..1e5b394 100755
--- a/t/t3509-cherry-pick-merge-df.sh
+++ b/t/t3509-cherry-pick-merge-df.sh
@@ -74,7 +74,7 @@
 	echo content > sub/file &&
 	echo foo > othersub/whatever &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	git rm -rf othersub &&
 	git mv sub/file othersub &&
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 5c87b55..3d30581 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -240,18 +240,15 @@
 
 test_expect_success 'choking "git rm" should not let it die with cruft' '
 	git reset -q --hard &&
+	test_when_finished "rm -f .git/index.lock && git reset -q --hard" &&
 	i=0 &&
 	while test $i -lt 12000
 	do
-	    echo "100644 $_z40 0	some-file-$i"
+	    echo "100644 1234567890123456789012345678901234567890 0	some-file-$i"
 	    i=$(( $i + 1 ))
 	done | git update-index --index-info &&
-	git rm -n "some-file-*" | :;
-	test -f .git/index.lock
-	status=$?
-	rm -f .git/index.lock
-	git reset -q --hard
-	test "$status" != 0
+	git rm -n "some-file-*" | : &&
+	test_path_is_missing .git/index.lock
 '
 
 test_expect_success 'rm removes subdirectories recursively' '
@@ -263,6 +260,7 @@
 '
 
 cat >expect <<EOF
+M  .gitmodules
 D  submod
 EOF
 
@@ -270,6 +268,15 @@
  M submod
 EOF
 
+cat >expect.cached <<EOF
+D  submod
+EOF
+
+cat >expect.both_deleted<<EOF
+D  .gitmodules
+D  submod
+EOF
+
 test_expect_success 'rm removes empty submodules from work tree' '
 	mkdir submod &&
 	git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) submod &&
@@ -281,16 +288,20 @@
 	git rm submod &&
 	test ! -e submod &&
 	git status -s -uno --ignore-submodules=none > actual &&
-	test_cmp expect actual
+	test_cmp expect actual &&
+	test_must_fail git config -f .gitmodules submodule.sub.url &&
+	test_must_fail git config -f .gitmodules submodule.sub.path
 '
 
-test_expect_success 'rm removes removed submodule from index' '
+test_expect_success 'rm removes removed submodule from index and .gitmodules' '
 	git reset --hard &&
 	git submodule update &&
 	rm -rf submod &&
 	git rm submod &&
 	git status -s -uno --ignore-submodules=none > actual &&
-	test_cmp expect actual
+	test_cmp expect actual &&
+	test_must_fail git config -f .gitmodules submodule.sub.url &&
+	test_must_fail git config -f .gitmodules submodule.sub.path
 '
 
 test_expect_success 'rm removes work tree of unmodified submodules' '
@@ -299,7 +310,9 @@
 	git rm submod &&
 	test ! -d submod &&
 	git status -s -uno --ignore-submodules=none > actual &&
-	test_cmp expect actual
+	test_cmp expect actual &&
+	test_must_fail git config -f .gitmodules submodule.sub.url &&
+	test_must_fail git config -f .gitmodules submodule.sub.path
 '
 
 test_expect_success 'rm removes a submodule with a trailing /' '
@@ -333,6 +346,72 @@
 	git rm -f submod &&
 	test ! -d submod &&
 	git status -s -uno --ignore-submodules=none > actual &&
+	test_cmp expect actual &&
+	test_must_fail git config -f .gitmodules submodule.sub.url &&
+	test_must_fail git config -f .gitmodules submodule.sub.path
+'
+
+test_expect_success 'rm --cached leaves work tree of populated submodules and .gitmodules alone' '
+	git reset --hard &&
+	git submodule update &&
+	git rm --cached submod &&
+	test -d submod &&
+	test -f submod/.git &&
+	git status -s -uno >actual &&
+	test_cmp expect.cached actual &&
+	git config -f .gitmodules submodule.sub.url &&
+	git config -f .gitmodules submodule.sub.path
+'
+
+test_expect_success 'rm --dry-run does not touch the submodule or .gitmodules' '
+	git reset --hard &&
+	git submodule update &&
+	git rm -n submod &&
+	test -f submod/.git &&
+	git diff-index --exit-code HEAD
+'
+
+test_expect_success 'rm does not complain when no .gitmodules file is found' '
+	git reset --hard &&
+	git submodule update &&
+	git rm .gitmodules &&
+	git rm submod >actual 2>actual.err &&
+	! test -s actual.err &&
+	! test -d submod &&
+	! test -f submod/.git &&
+	git status -s -uno >actual &&
+	test_cmp expect.both_deleted actual
+'
+
+test_expect_success 'rm will error out on a modified .gitmodules file unless staged' '
+	git reset --hard &&
+	git submodule update &&
+	git config -f .gitmodules foo.bar true &&
+	test_must_fail git rm submod >actual 2>actual.err &&
+	test -s actual.err &&
+	test -d submod &&
+	test -f submod/.git &&
+	git diff-files --quiet -- submod &&
+	git add .gitmodules &&
+	git rm submod >actual 2>actual.err &&
+	! test -s actual.err &&
+	! test -d submod &&
+	! test -f submod/.git &&
+	git status -s -uno >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'rm issues a warning when section is not found in .gitmodules' '
+	git reset --hard &&
+	git submodule update &&
+	git config -f .gitmodules --remove-section submodule.sub &&
+	git add .gitmodules &&
+	echo "warning: Could not find section in .gitmodules where path=submod" >expect.err &&
+	git rm submod >actual 2>actual.err &&
+	test_i18ncmp expect.err actual.err &&
+	! test -d submod &&
+	! test -f submod/.git &&
+	git status -s -uno >actual &&
 	test_cmp expect actual
 '
 
@@ -427,7 +506,9 @@
 	git rm -f submod &&
 	test ! -d submod &&
 	git status -s -uno --ignore-submodules=none > actual &&
-	test_cmp expect actual
+	test_cmp expect actual &&
+	test_must_fail git config -f .gitmodules submodule.sub.url &&
+	test_must_fail git config -f .gitmodules submodule.sub.path
 '
 
 test_expect_success 'rm of a conflicted populated submodule with modifications fails unless forced' '
@@ -446,7 +527,9 @@
 	git rm -f submod &&
 	test ! -d submod &&
 	git status -s -uno --ignore-submodules=none > actual &&
-	test_cmp expect actual
+	test_cmp expect actual &&
+	test_must_fail git config -f .gitmodules submodule.sub.url &&
+	test_must_fail git config -f .gitmodules submodule.sub.path
 '
 
 test_expect_success 'rm of a conflicted populated submodule with untracked files fails unless forced' '
@@ -622,6 +705,22 @@
 	rm -rf submod
 '
 
+test_expect_success 'checking out a commit after submodule removal needs manual updates' '
+	git commit -m "submodule removal" submod &&
+	git checkout HEAD^ &&
+	git submodule update &&
+	git checkout -q HEAD^ 2>actual &&
+	git checkout -q master 2>actual &&
+	echo "warning: unable to rmdir submod: Directory not empty" >expected &&
+	test_i18ncmp expected actual &&
+	git status -s submod >actual &&
+	echo "?? submod/" >expected &&
+	test_cmp expected actual &&
+	rm -rf submod &&
+	git status -s -uno --ignore-submodules=none > actual &&
+	! test -s actual
+'
+
 test_expect_success 'rm of d/f when d has become a non-directory' '
 	rm -rf d &&
 	mkdir d &&
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index aab86e8..fe274e2 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -272,6 +272,25 @@
 	! (git ls-files | grep "non-existent")
 '
 
+test_expect_success 'git add -A on empty repo does not error out' '
+	rm -fr empty &&
+	git init empty &&
+	(
+		cd empty &&
+		git add -A . &&
+		git add -A
+	)
+'
+
+test_expect_success '"git add ." in empty repo' '
+	rm -fr empty &&
+	git init empty &&
+	(
+		cd empty &&
+		git add .
+	)
+'
+
 test_expect_success 'git add --dry-run of existing changed file' "
 	echo new >>track-this &&
 	git add --dry-run track-this >actual 2>&1 &&
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 9fab25c..24ddd8a 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -2,20 +2,25 @@
 
 test_description='add -i basic tests'
 . ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh
 
-test_expect_success PERL 'setup (initial)' '
+if ! test_have_prereq PERL
+then
+	skip_all='skipping add -i tests, perl not available'
+	test_done
+fi
+
+test_expect_success 'setup (initial)' '
 	echo content >file &&
 	git add file &&
 	echo more >>file &&
 	echo lines >>file
 '
-test_expect_success PERL 'status works (initial)' '
+test_expect_success 'status works (initial)' '
 	git add -i </dev/null >output &&
 	grep "+1/-0 *+2/-0 file" output
 '
 
-test_expect_success PERL 'setup expected' '
+test_expect_success 'setup expected' '
 cat >expected <<EOF
 new file mode 100644
 index 0000000..d95f3ad
@@ -26,19 +31,19 @@
 EOF
 '
 
-test_expect_success PERL 'diff works (initial)' '
+test_expect_success 'diff works (initial)' '
 	(echo d; echo 1) | git add -i >output &&
 	sed -ne "/new file/,/content/p" <output >diff &&
 	test_cmp expected diff
 '
-test_expect_success PERL 'revert works (initial)' '
+test_expect_success 'revert works (initial)' '
 	git add file &&
 	(echo r; echo 1) | git add -i &&
 	git ls-files >output &&
 	! grep . output
 '
 
-test_expect_success PERL 'setup (commit)' '
+test_expect_success 'setup (commit)' '
 	echo baseline >file &&
 	git add file &&
 	git commit -m commit &&
@@ -47,12 +52,12 @@
 	echo more >>file &&
 	echo lines >>file
 '
-test_expect_success PERL 'status works (commit)' '
+test_expect_success 'status works (commit)' '
 	git add -i </dev/null >output &&
 	grep "+1/-0 *+2/-0 file" output
 '
 
-test_expect_success PERL 'setup expected' '
+test_expect_success 'setup expected' '
 cat >expected <<EOF
 index 180b47c..b6f2c08 100644
 --- a/file
@@ -63,12 +68,12 @@
 EOF
 '
 
-test_expect_success PERL 'diff works (commit)' '
+test_expect_success 'diff works (commit)' '
 	(echo d; echo 1) | git add -i >output &&
 	sed -ne "/^index/,/content/p" <output >diff &&
 	test_cmp expected diff
 '
-test_expect_success PERL 'revert works (commit)' '
+test_expect_success 'revert works (commit)' '
 	git add file &&
 	(echo r; echo 1) | git add -i &&
 	git add -i </dev/null >output &&
@@ -76,24 +81,24 @@
 '
 
 
-test_expect_success PERL 'setup expected' '
+test_expect_success 'setup expected' '
 cat >expected <<EOF
 EOF
 '
 
-test_expect_success PERL 'setup fake editor' '
+test_expect_success 'setup fake editor' '
 	>fake_editor.sh &&
 	chmod a+x fake_editor.sh &&
 	test_set_editor "$(pwd)/fake_editor.sh"
 '
 
-test_expect_success PERL 'dummy edit works' '
+test_expect_success 'dummy edit works' '
 	(echo e; echo a) | git add -p &&
 	git diff > diff &&
 	test_cmp expected diff
 '
 
-test_expect_success PERL 'setup patch' '
+test_expect_success 'setup patch' '
 cat >patch <<EOF
 @@ -1,1 +1,4 @@
  this
@@ -103,7 +108,7 @@
 EOF
 '
 
-test_expect_success PERL 'setup fake editor' '
+test_expect_success 'setup fake editor' '
 	echo "#!$SHELL_PATH" >fake_editor.sh &&
 	cat >>fake_editor.sh <<\EOF &&
 mv -f "$1" oldpatch &&
@@ -113,26 +118,26 @@
 	test_set_editor "$(pwd)/fake_editor.sh"
 '
 
-test_expect_success PERL 'bad edit rejected' '
+test_expect_success 'bad edit rejected' '
 	git reset &&
 	(echo e; echo n; echo d) | git add -p >output &&
 	grep "hunk does not apply" output
 '
 
-test_expect_success PERL 'setup patch' '
+test_expect_success 'setup patch' '
 cat >patch <<EOF
 this patch
 is garbage
 EOF
 '
 
-test_expect_success PERL 'garbage edit rejected' '
+test_expect_success 'garbage edit rejected' '
 	git reset &&
 	(echo e; echo n; echo d) | git add -p >output &&
 	grep "hunk does not apply" output
 '
 
-test_expect_success PERL 'setup patch' '
+test_expect_success 'setup patch' '
 cat >patch <<EOF
 @@ -1,0 +1,0 @@
  baseline
@@ -142,7 +147,7 @@
 EOF
 '
 
-test_expect_success PERL 'setup expected' '
+test_expect_success 'setup expected' '
 cat >expected <<EOF
 diff --git a/file b/file
 index b5dd6c9..f910ae9 100644
@@ -157,13 +162,13 @@
 EOF
 '
 
-test_expect_success PERL 'real edit works' '
+test_expect_success 'real edit works' '
 	(echo e; echo n; echo d) | git add -p &&
 	git diff >output &&
 	test_cmp expected output
 '
 
-test_expect_success PERL 'skip files similarly as commit -a' '
+test_expect_success 'skip files similarly as commit -a' '
 	git reset &&
 	echo file >.gitignore &&
 	echo changed >file &&
@@ -177,7 +182,7 @@
 '
 rm -f .gitignore
 
-test_expect_success PERL,FILEMODE 'patch does not affect mode' '
+test_expect_success FILEMODE 'patch does not affect mode' '
 	git reset --hard &&
 	echo content >>file &&
 	chmod +x file &&
@@ -186,7 +191,7 @@
 	git diff file | grep "new mode"
 '
 
-test_expect_success PERL,FILEMODE 'stage mode but not hunk' '
+test_expect_success FILEMODE 'stage mode but not hunk' '
 	git reset --hard &&
 	echo content >>file &&
 	chmod +x file &&
@@ -196,7 +201,7 @@
 '
 
 
-test_expect_success PERL,FILEMODE 'stage mode and hunk' '
+test_expect_success FILEMODE 'stage mode and hunk' '
 	git reset --hard &&
 	echo content >>file &&
 	chmod +x file &&
@@ -208,14 +213,14 @@
 
 # end of tests disabled when filemode is not usable
 
-test_expect_success PERL 'setup again' '
+test_expect_success 'setup again' '
 	git reset --hard &&
 	test_chmod +x file &&
 	echo content >>file
 '
 
 # Write the patch file with a new line at the top and bottom
-test_expect_success PERL 'setup patch' '
+test_expect_success 'setup patch' '
 cat >patch <<EOF
 index 180b47c..b6f2c08 100644
 --- a/file
@@ -229,7 +234,7 @@
 '
 
 # Expected output, similar to the patch but w/ diff at the top
-test_expect_success PERL 'setup expected' '
+test_expect_success 'setup expected' '
 cat >expected <<EOF
 diff --git a/file b/file
 index b6f2c08..61b9053 100755
@@ -244,7 +249,7 @@
 '
 
 # Test splitting the first patch, then adding both
-test_expect_success PERL 'add first line works' '
+test_expect_success 'add first line works' '
 	git commit -am "clear local changes" &&
 	git apply patch &&
 	(echo s; echo y; echo y) | git add -p file &&
@@ -252,7 +257,7 @@
 	test_cmp expected diff
 '
 
-test_expect_success PERL 'setup expected' '
+test_expect_success 'setup expected' '
 cat >expected <<EOF
 diff --git a/non-empty b/non-empty
 deleted file mode 100644
@@ -264,7 +269,7 @@
 EOF
 '
 
-test_expect_success PERL 'deleting a non-empty file' '
+test_expect_success 'deleting a non-empty file' '
 	git reset --hard &&
 	echo content >non-empty &&
 	git add non-empty &&
@@ -275,7 +280,7 @@
 	test_cmp expected diff
 '
 
-test_expect_success PERL 'setup expected' '
+test_expect_success 'setup expected' '
 cat >expected <<EOF
 diff --git a/empty b/empty
 deleted file mode 100644
@@ -283,7 +288,7 @@
 EOF
 '
 
-test_expect_success PERL 'deleting an empty file' '
+test_expect_success 'deleting an empty file' '
 	git reset --hard &&
 	> empty &&
 	git add empty &&
@@ -294,7 +299,7 @@
 	test_cmp expected diff
 '
 
-test_expect_success PERL 'split hunk setup' '
+test_expect_success 'split hunk setup' '
 	git reset --hard &&
 	for i in 10 20 30 40 50 60
 	do
@@ -310,7 +315,7 @@
 	done >test
 '
 
-test_expect_success PERL 'split hunk "add -p (edit)"' '
+test_expect_success 'split hunk "add -p (edit)"' '
 	# Split, say Edit and do nothing.  Then:
 	#
 	# 1. Broken version results in a patch that does not apply and
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index debda7a..5b79b21 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -673,4 +673,16 @@
 	grep quux bazzy
 '
 
+test_expect_success 'handle stash specification with spaces' '
+	git stash clear &&
+	echo pig >file &&
+	git stash &&
+	stamp=$(git log -g --format="%cd" -1 refs/stash) &&
+	test_tick &&
+	echo cow >file &&
+	git stash &&
+	git stash apply "stash@{$stamp}" &&
+	grep pig file
+'
+
 test_done
diff --git a/t/t3910-mac-os-precompose.sh b/t/t3910-mac-os-precompose.sh
index 5fe57c5..e4ba601 100755
--- a/t/t3910-mac-os-precompose.sh
+++ b/t/t3910-mac-os-precompose.sh
@@ -36,7 +36,7 @@
 
 test_expect_success "detect if nfd needed" '
 	precomposeunicode=`git config core.precomposeunicode` &&
-	test "$precomposeunicode" = false &&
+	test "$precomposeunicode" = true &&
 	git config core.precomposeunicode true
 '
 test_expect_success "setup" '
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index 589bc6b..9f5659f 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -110,6 +110,23 @@
 	test_cmp expected result
 '
 
+test_expect_success 'setup submodules' '
+	test_tick &&
+	git init submod &&
+	( cd submod && test_commit first; ) &&
+	git add submod &&
+	git commit -m first &&
+	( cd submod && test_commit second; ) &&
+	git add submod &&
+	git commit -m second
+'
+
+test_expect_success 'diff-tree ignores trailing slash on submodule path' '
+	git diff --name-only HEAD^ HEAD submod >expect &&
+	git diff --name-only HEAD^ HEAD submod/ >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'diff multiple wildcard pathspecs' '
 	mkdir path2 &&
 	echo rezrov >path2/file1 &&
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 8f272bc..73194b2 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -293,7 +293,7 @@
 	(git format-patch --stdout "$@"; echo $? > status.out) |
 	# Prints everything between the Message-ID and In-Reply-To,
 	# and replaces all Message-ID-lookalikes by a sequence number
-	"$PERL_PATH" -ne '
+	perl -ne '
 		if (/^(message-id|references|in-reply-to)/i) {
 			$printing = 1;
 		} elsif (/^\S/) {
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index 3fb4b97..604a838 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -145,7 +145,7 @@
 test_expect_success 'ignore-blank-lines: only new lines' '
 	test_seq 5 >x &&
 	git update-index x &&
-	test_seq 5 | sed "/3/i \\
+	test_seq 5 | sed "/3/i\\
 " >x &&
 	git diff --ignore-blank-lines >out &&
 	>expect &&
@@ -155,7 +155,8 @@
 test_expect_success 'ignore-blank-lines: only new lines with space' '
 	test_seq 5 >x &&
 	git update-index x &&
-	test_seq 5 | sed "/3/i \ " >x &&
+	test_seq 5 | sed "/3/i\\
+ " >x &&
 	git diff -w --ignore-blank-lines >out &&
 	>expect &&
 	test_cmp out expect
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index 2e7d73f..bcae35a 100755
--- a/t/t4020-diff-external.sh
+++ b/t/t4020-diff-external.sh
@@ -177,7 +177,7 @@
 	git diff | grep Binary
 '
 
-echo NULZbetweenZwords | "$PERL_PATH" -pe 'y/Z/\000/' > file
+echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file
 
 test_expect_success 'force diff with "diff"' '
 	echo >.gitattributes "file diff" &&
@@ -193,6 +193,19 @@
 	GIT_EXTERNAL_DIFF=echo git diff
 '
 
+test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' '
+	write_script external-diff.sh <<-\EOF &&
+	echo $GIT_DIFF_PATH_COUNTER of $GIT_DIFF_PATH_TOTAL >>counter.txt
+	EOF
+	>counter.txt &&
+	cat >expect <<-\EOF &&
+	1 of 2
+	2 of 2
+	EOF
+	GIT_EXTERNAL_DIFF=./external-diff.sh git diff &&
+	test_cmp expect counter.txt
+'
+
 test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' '
 	touch file.ext &&
 	git add file.ext &&
diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh
index 36e2f07..3ccc237 100755
--- a/t/t4029-diff-trailing-space.sh
+++ b/t/t4029-diff-trailing-space.sh
@@ -27,7 +27,7 @@
      git config --bool diff.suppressBlankEmpty true &&
      git diff f > actual &&
      test_cmp exp actual &&
-     "$PERL_PATH" -i.bak -p -e "s/^\$/ /" exp &&
+     perl -i.bak -p -e "s/^\$/ /" exp &&
      git config --bool diff.suppressBlankEmpty false &&
      git diff f > actual &&
      test_cmp exp actual &&
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index f75f46f..aad6c7f 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -58,6 +58,12 @@
 	test_cmp expect.text actual
 '
 
+test_expect_success 'show commit produces text' '
+	git show HEAD >diff &&
+	find_diff <diff >actual &&
+	test_cmp expect.text actual
+'
+
 test_expect_success 'diff-tree produces binary' '
 	git diff-tree -p HEAD^ HEAD >diff &&
 	find_diff <diff >actual &&
@@ -84,6 +90,24 @@
 	git reset --soft HEAD@{1}
 '
 
+test_expect_success 'show blob produces binary' '
+	git show HEAD:file >actual &&
+	printf "\\0\\n\\01\\n" >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'show --textconv blob produces text' '
+	git show --textconv HEAD:file >actual &&
+	printf "0\\n1\\n" >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'show --no-textconv blob produces binary' '
+	git show --no-textconv HEAD:file >actual &&
+	printf "\\0\\n\\01\\n" >expect &&
+	test_cmp expect actual
+'
+
 test_expect_success 'grep-diff (-G) operates on textconv data (add)' '
 	echo one >expect &&
 	git log --root --format=%s -G0 >actual &&
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
index 979e983..2ab3c48 100755
--- a/t/t4053-diff-no-index.sh
+++ b/t/t4053-diff-no-index.sh
@@ -29,4 +29,30 @@
 	)
 '
 
+test_expect_success 'git diff --no-index with broken index' '
+	(
+		cd repo &&
+		echo broken >.git/index &&
+		git diff --no-index a ../non/git/a
+	)
+'
+
+test_expect_success 'git diff outside repo with broken index' '
+	(
+		cd repo &&
+		git diff ../non/git/a ../non/git/b
+	)
+'
+
+test_expect_success 'git diff --no-index executed outside repo gives correct error message' '
+	(
+		GIT_CEILING_DIRECTORIES=$TRASH_DIRECTORY/non &&
+		export GIT_CEILING_DIRECTORIES &&
+		cd non/git &&
+		test_must_fail git diff --no-index a 2>actual.err &&
+		echo "usage: git diff --no-index <path> <path>" >expect.err &&
+		test_cmp expect.err actual.err
+	)
+'
+
 test_done
diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh
index 97172b4..cd04543 100755
--- a/t/t4055-diff-context.sh
+++ b/t/t4055-diff-context.sh
@@ -73,7 +73,7 @@
 test_expect_success 'non-integer config parsing' '
 	git config diff.context no &&
 	test_must_fail git diff 2>output &&
-	test_i18ngrep "bad config value" output
+	test_i18ngrep "bad numeric config value" output
 '
 
 test_expect_success 'negative integer config parsing' '
diff --git a/t/t4056-diff-order.sh b/t/t4056-diff-order.sh
new file mode 100755
index 0000000..9e2b29e
--- /dev/null
+++ b/t/t4056-diff-order.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+test_description='diff order'
+
+. ./test-lib.sh
+
+create_files () {
+	echo "$1" >a.h &&
+	echo "$1" >b.c &&
+	echo "$1" >c/Makefile &&
+	echo "$1" >d.txt &&
+	git add a.h b.c c/Makefile d.txt &&
+	git commit -m"$1"
+}
+
+test_expect_success 'setup' '
+	mkdir c &&
+	create_files 1 &&
+	create_files 2 &&
+
+	cat >order_file_1 <<-\EOF &&
+	*Makefile
+	*.txt
+	*.h
+	EOF
+
+	cat >order_file_2 <<-\EOF &&
+	*Makefile
+	*.h
+	*.c
+	EOF
+
+	cat >expect_none <<-\EOF &&
+	a.h
+	b.c
+	c/Makefile
+	d.txt
+	EOF
+
+	cat >expect_1 <<-\EOF &&
+	c/Makefile
+	d.txt
+	a.h
+	b.c
+	EOF
+
+	cat >expect_2 <<-\EOF
+	c/Makefile
+	a.h
+	b.c
+	d.txt
+	EOF
+'
+
+test_expect_success "no order (=tree object order)" '
+	git diff --name-only HEAD^..HEAD >actual &&
+	test_cmp expect_none actual
+'
+
+test_expect_success 'missing orderfile' '
+	rm -f bogus_file &&
+	test_must_fail git diff -Obogus_file --name-only HEAD^..HEAD
+'
+
+test_expect_success POSIXPERM,SANITY 'unreadable orderfile' '
+	>unreadable_file &&
+	chmod -r unreadable_file &&
+	test_must_fail git diff -Ounreadable_file --name-only HEAD^..HEAD
+'
+
+for i in 1 2
+do
+	test_expect_success "orderfile using option ($i)" '
+		git diff -Oorder_file_$i --name-only HEAD^..HEAD >actual &&
+		test_cmp expect_$i actual
+	'
+
+	test_expect_success PIPE "orderfile is fifo ($i)" '
+		rm -f order_fifo &&
+		mkfifo order_fifo &&
+		{
+			cat order_file_$i >order_fifo &
+		} &&
+		git diff -O order_fifo --name-only HEAD^..HEAD >actual &&
+		wait &&
+		test_cmp expect_$i actual
+	'
+
+	test_expect_success "orderfile using config ($i)" '
+		git -c diff.orderfile=order_file_$i diff --name-only HEAD^..HEAD >actual &&
+		test_cmp expect_$i actual
+	'
+
+	test_expect_success "cancelling configured orderfile ($i)" '
+		git -c diff.orderfile=order_file_$i diff -O/dev/null --name-only HEAD^..HEAD >actual &&
+		test_cmp expect_none actual
+	'
+done
+
+test_done
diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh
index e3ea3d5..49e2d6c 100755
--- a/t/t4102-apply-rename.sh
+++ b/t/t4102-apply-rename.sh
@@ -7,7 +7,6 @@
 
 '
 . ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh
 
 # setup
 
diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh
index b1b906b..1b420e3 100755
--- a/t/t4103-apply-binary.sh
+++ b/t/t4103-apply-binary.sh
@@ -23,10 +23,10 @@
 	git commit -m "Initial Version" 2>/dev/null &&
 
 	git checkout -b binary &&
-	"$PERL_PATH" -pe "y/x/\000/" <file1 >file3 &&
+	perl -pe "y/x/\000/" <file1 >file3 &&
 	cat file3 >file4 &&
 	git add file2 &&
-	"$PERL_PATH" -pe "y/\000/v/" <file3 >file1 &&
+	perl -pe "y/\000/v/" <file3 >file1 &&
 	rm -f file2 &&
 	git update-index --add --remove file1 file2 file3 file4 &&
 	git commit -m "Second Version" &&
diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh
index fca8153..1e4d438 100755
--- a/t/t4116-apply-reverse.sh
+++ b/t/t4116-apply-reverse.sh
@@ -12,14 +12,14 @@
 test_expect_success setup '
 
 	for i in a b c d e f g h i j k l m n; do echo $i; done >file1 &&
-	"$PERL_PATH" -pe "y/ijk/\\000\\001\\002/" <file1 >file2 &&
+	perl -pe "y/ijk/\\000\\001\\002/" <file1 >file2 &&
 
 	git add file1 file2 &&
 	git commit -m initial &&
 	git tag initial &&
 
 	for i in a b c g h i J K L m o n p q; do echo $i; done >file1 &&
-	"$PERL_PATH" -pe "y/mon/\\000\\001\\002/" <file1 >file2 &&
+	perl -pe "y/mon/\\000\\001\\002/" <file1 >file2 &&
 
 	git commit -a -m second &&
 	git tag second &&
@@ -48,12 +48,12 @@
 
 test_expect_success 'setup separate repository lacking postimage' '
 
-	git tar-tree initial initial | $TAR xf - &&
+	git archive --format=tar --prefix=initial/ initial | $TAR xf - &&
 	(
 		cd initial && git init && git add .
 	) &&
 
-	git tar-tree second second | $TAR xf - &&
+	git archive --format=tar --prefix=second/ second | $TAR xf - &&
 	(
 		cd second && git init && git add .
 	)
diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh
index c5fecdf..497b628 100755
--- a/t/t4120-apply-popt.sh
+++ b/t/t4120-apply-popt.sh
@@ -6,7 +6,6 @@
 test_description='git apply -p handling.'
 
 . ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh
 
 test_expect_success setup '
 	mkdir sub &&
diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh
index 0d36ebd..c268298 100755
--- a/t/t4129-apply-samemode.sh
+++ b/t/t4129-apply-samemode.sh
@@ -3,7 +3,6 @@
 test_description='applying patch with mode bits'
 
 . ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh
 
 test_expect_success setup '
 	echo original >file &&
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index 7f6666f..ed9c91e 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -78,7 +78,7 @@
 	test_might_fail git config --unset rerere.enabled &&
 	test_must_fail git merge first &&
 
-	sha1=$("$PERL_PATH" -pe "s/	.*//" .git/MERGE_RR) &&
+	sha1=$(perl -pe "s/	.*//" .git/MERGE_RR) &&
 	rr=.git/rr-cache/$sha1 &&
 	grep "^=======\$" $rr/preimage &&
 	! test -f $rr/postimage &&
@@ -91,7 +91,7 @@
 	git reset --hard &&
 	test_must_fail git merge first &&
 
-	sha1=$("$PERL_PATH" -pe "s/	.*//" .git/MERGE_RR) &&
+	sha1=$(perl -pe "s/	.*//" .git/MERGE_RR) &&
 	rr=.git/rr-cache/$sha1 &&
 	grep ^=======$ $rr/preimage
 '
@@ -101,7 +101,7 @@
 	git config rerere.enabled true &&
 	git reset --hard &&
 	test_must_fail git merge first &&
-	sha1=$("$PERL_PATH" -pe "s/	.*//" .git/MERGE_RR) &&
+	sha1=$(perl -pe "s/	.*//" .git/MERGE_RR) &&
 	rr=.git/rr-cache/$sha1
 '
 
@@ -172,7 +172,7 @@
 	git show second^:a1 | sed "s/To die: t/To die! T/" >a1 &&
 	git commit -q -a -m third &&
 
-	test_must_fail git pull . first &&
+	test_must_fail git merge first &&
 	# rerere kicked in
 	! grep "^=======\$" a1 &&
 	test_cmp expect a1
@@ -185,7 +185,7 @@
 
 test_expect_success 'rerere clear' '
 	rm $rr/postimage &&
-	echo "$sha1	a1" | "$PERL_PATH" -pe "y/\012/\000/" >.git/MERGE_RR &&
+	echo "$sha1	a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR &&
 	git rerere clear &&
 	! test -d $rr
 '
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index fb00041..2a6278b 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -310,4 +310,19 @@
 	test_cmp expected actual
 '
 
+test_expect_success 'log decoration properly follows tag chain' '
+	git tag -a tag1 -m tag1 &&
+	git tag -a tag2 -m tag2 tag1 &&
+	git tag -d tag1 &&
+	git commit --amend -m shorter &&
+	git log --no-walk --tags --pretty="%H %d" --decorate=full >actual &&
+	cat <<EOF >expected &&
+6a908c10688b2503073c39c9ba26322c73902bb5  (tag: refs/tags/tag2)
+9f716384d92283fb915a4eee5073f030638e05f9  (tag: refs/tags/message-one)
+b87e4cccdb77336ea79d89224737be7ea8e95367  (tag: refs/tags/message-two)
+EOF
+	sort actual >actual1 &&
+	test_cmp expected actual1
+'
+
 test_done
diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh
index 72300b5..d8f23f4 100755
--- a/t/t4208-log-magic-pathspec.sh
+++ b/t/t4208-log-magic-pathspec.sh
@@ -46,4 +46,19 @@
 	test_cmp expected actual
 '
 
+test_expect_success 'command line pathspec parsing for "git log"' '
+	git reset --hard &&
+	>a &&
+	git add a &&
+	git commit -m "add an empty a" --allow-empty &&
+	echo 1 >a &&
+	git commit -a -m "update a to 1" &&
+	git checkout HEAD^ &&
+	echo 2 >a &&
+	git commit -a -m "update a to 2" &&
+	test_must_fail git merge master &&
+	git add a &&
+	git log --merge -- a
+'
+
 test_done
diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh
index 7665d67..7369d3c 100755
--- a/t/t4211-line-log.sh
+++ b/t/t4211-line-log.sh
@@ -48,7 +48,7 @@
 canned_test "-M -L ':f:b.c' parallel-change" parallel-change-f-to-main
 
 canned_test "-L 4,12:a.c -L :main:a.c simple" multiple
-canned_test "-L 4,18:a.c -L :main:a.c simple" multiple-overlapping
+canned_test "-L 4,18:a.c -L ^:main:a.c simple" multiple-overlapping
 canned_test "-L :main:a.c -L 4,18:a.c simple" multiple-overlapping
 canned_test "-L 4:a.c -L 8,12:a.c simple" multiple-superset
 canned_test "-L 8,12:a.c -L 4:a.c simple" multiple-superset
@@ -64,17 +64,34 @@
 test_bad_opts "-L :b.c" "argument.*not of the form"
 test_bad_opts "-L :foo:b.c" "no match"
 
-# There is a separate bug when an empty -L range is the first -L encountered,
-# thus to demonstrate this particular bug, the empty -L range must follow a
-# non-empty -L range.
-test_expect_success '-L {empty-range} (any -L)' '
-	n=$(expr $(wc -l <b.c) + 1) &&
-	git log -L1,1:b.c -L$n:b.c
+test_expect_success '-L X (X == nlines)' '
+	n=$(wc -l <b.c) &&
+	git log -L $n:b.c
 '
 
-test_expect_success '-L {empty-range} (first -L)' '
+test_expect_success '-L X (X == nlines + 1)' '
 	n=$(expr $(wc -l <b.c) + 1) &&
-	git log -L$n:b.c
+	test_must_fail git log -L $n:b.c
+'
+
+test_expect_success '-L X (X == nlines + 2)' '
+	n=$(expr $(wc -l <b.c) + 2) &&
+	test_must_fail git log -L $n:b.c
+'
+
+test_expect_success '-L ,Y (Y == nlines)' '
+	n=$(printf "%d" $(wc -l <b.c)) &&
+	git log -L ,$n:b.c
+'
+
+test_expect_success '-L ,Y (Y == nlines + 1)' '
+	n=$(expr $(wc -l <b.c) + 1) &&
+	test_must_fail git log -L ,$n:b.c
+'
+
+test_expect_success '-L ,Y (Y == nlines + 2)' '
+	n=$(expr $(wc -l <b.c) + 2) &&
+	test_must_fail git log -L ,$n:b.c
 '
 
 test_done
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index c2023b1..05f011d 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -3,7 +3,7 @@
 # Copyright (C) 2005 Rene Scharfe
 #
 
-test_description='git tar-tree and git get-tar-commit-id test
+test_description='git archive and git get-tar-commit-id test
 
 This test covers the topics of file contents, commit date handling and
 commit id embedding:
@@ -13,11 +13,11 @@
   binary file (/bin/sh).  Only paths shorter than 99 characters are
   used.
 
-  git tar-tree applies the commit date to every file in the archive it
+  git archive applies the commit date to every file in the archive it
   creates.  The test sets the commit date to a specific value and checks
   if the tar archive contains that value.
 
-  When giving git tar-tree a commit id (in contrast to a tree id) it
+  When giving git archive a commit id (in contrast to a tree id) it
   embeds this commit id into the tar archive as a comment.  The test
   checks the ability of git get-tar-commit-id to figure it out from the
   tar file.
@@ -25,8 +25,6 @@
 '
 
 . ./test-lib.sh
-GZIP=${GZIP:-gzip}
-GUNZIP=${GUNZIP:-gzip -d}
 
 SUBSTFORMAT=%H%n
 
@@ -39,6 +37,8 @@
 	)
 '
 
+test_lazy_prereq GZIP 'gzip --version'
+
 get_pax_header() {
 	file=$1
 	header=$2=
@@ -196,16 +196,6 @@
     'git get-tar-commit-id <b.tar >b.commitid &&
      test_cmp .git/$(git symbolic-ref HEAD) b.commitid'
 
-test_expect_success 'git tar-tree' '
-	git tar-tree HEAD >tar-tree.tar &&
-	test_cmp b.tar tar-tree.tar
-'
-
-test_expect_success 'git tar-tree with prefix' '
-	git tar-tree HEAD prefix >tar-tree_with_prefix.tar &&
-	test_cmp with_prefix.tar tar-tree_with_prefix.tar
-'
-
 test_expect_success 'git archive with --output, override inferred format' '
 	git archive --format=tar --output=d4.zip HEAD &&
 	test_cmp b.tar d4.zip
@@ -275,12 +265,6 @@
 	test_cmp remote.bar config.bar
 '
 
-if $GZIP --version >/dev/null 2>&1; then
-	test_set_prereq GZIP
-else
-	say "Skipping some tar.gz tests because gzip not found"
-fi
-
 test_expect_success GZIP 'git archive --format=tgz' '
 	git archive --format=tgz HEAD >j.tgz
 '
@@ -300,14 +284,8 @@
 	test_cmp j.tgz j3.tar.gz
 '
 
-if $GUNZIP --version >/dev/null 2>&1; then
-	test_set_prereq GUNZIP
-else
-	say "Skipping some tar.gz tests because gunzip was not found"
-fi
-
-test_expect_success GZIP,GUNZIP 'extract tgz file' '
-	$GUNZIP -c <j.tgz >j.tar &&
+test_expect_success GZIP 'extract tgz file' '
+	gzip -d -c <j.tgz >j.tar &&
 	test_cmp b.tar j.tar
 '
 
diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh
index f47d871..51dedab 100755
--- a/t/t5001-archive-attr.sh
+++ b/t/t5001-archive-attr.sh
@@ -87,14 +87,4 @@
 	test_cmp substfile2 archive/substfile2
 '
 
-test_expect_success 'git tar-tree vs. git archive with worktree attributes' '
-	git tar-tree HEAD >tar-tree.tar &&
-	test_cmp worktree.tar tar-tree.tar
-'
-
-test_expect_success 'git tar-tree vs. git archive with worktree attrs, bare' '
-	(cd bare && git tar-tree HEAD) >bare-tar-tree.tar &&
-	test_cmp bare-worktree.tar bare-tar-tree.tar
-'
-
 test_done
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index a07c871..20c1961 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -13,9 +13,9 @@
 test_expect_success \
     'setup' \
     'rm -f .git/index* &&
-     "$PERL_PATH" -e "print \"a\" x 4096;" > a &&
-     "$PERL_PATH" -e "print \"b\" x 4096;" > b &&
-     "$PERL_PATH" -e "print \"c\" x 4096;" > c &&
+     perl -e "print \"a\" x 4096;" > a &&
+     perl -e "print \"b\" x 4096;" > b &&
+     perl -e "print \"c\" x 4096;" > c &&
      test-genrandom "seed a" 2097152 > a_big &&
      test-genrandom "seed b" 2097152 > b_big &&
      git update-index --add a a_big b b_big c &&
@@ -129,7 +129,7 @@
 cd "$TRASH"
 
 test_expect_success 'compare delta flavors' '
-	"$PERL_PATH" -e '\''
+	perl -e '\''
 		defined($_ = -s $_) or die for @ARGV;
 		exit 1 if $ARGV[0] <= $ARGV[1];
 	'\'' test-2-$packname_2.pack test-3-$packname_3.pack
@@ -151,7 +151,7 @@
 	    git cat-file $t $object || return 1
 	 done <obj-list
     } >current &&
-    test_cmp expect current'
+    cmp expect current'
 
 test_expect_success \
     'use packed deltified (REF_DELTA) objects' \
@@ -166,7 +166,7 @@
 	    git cat-file $t $object || return 1
 	 done <obj-list
     } >current &&
-    test_cmp expect current'
+    cmp expect current'
 
 test_expect_success \
     'use packed deltified (OFS_DELTA) objects' \
@@ -181,7 +181,7 @@
 	    git cat-file $t $object || return 1
 	 done <obj-list
     } >current &&
-    test_cmp expect current'
+    cmp expect current'
 
 unset GIT_OBJECT_DIRECTORY
 
@@ -195,9 +195,9 @@
 		rm -fr $GOP &&
 		git index-pack --stdin --keep=test <../test-3-${packname_3}.pack &&
 		test -f $GOP/pack-${packname_3}.pack &&
-		test_cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack &&
+		cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack &&
 		test -f $GOP/pack-${packname_3}.idx &&
-		test_cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx &&
+		cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx &&
 		test -f $GOP/pack-${packname_3}.keep
 	)
 '
diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh
index fe82025..4bbb718 100755
--- a/t/t5302-pack-index.sh
+++ b/t/t5302-pack-index.sh
@@ -174,11 +174,11 @@
 test_expect_success \
     '[index v1] 5) pack-objects happily reuses corrupted data' \
     'pack4=$(git pack-objects test-4 <obj-list) &&
-     test -f "test-4-${pack1}.pack"'
+     test -f "test-4-${pack4}.pack"'
 
 test_expect_success \
     '[index v1] 6) newly created pack is BAD !' \
-    'test_must_fail git verify-pack -v "test-4-${pack1}.pack"'
+    'test_must_fail git verify-pack -v "test-4-${pack4}.pack"'
 
 test_expect_success \
     '[index v2] 1) stream pack to repository' \
diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh
index 35926de..663b02b 100755
--- a/t/t5303-pack-corruption-resilience.sh
+++ b/t/t5303-pack-corruption-resilience.sh
@@ -98,7 +98,7 @@
     'create_new_pack &&
      git prune-packed &&
      chmod +w ${pack}.pack &&
-     "$PERL_PATH" -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
+     perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
      test_must_fail git cat-file blob $blob_1 > /dev/null &&
      test_must_fail git cat-file blob $blob_2 > /dev/null &&
      test_must_fail git cat-file blob $blob_3 > /dev/null'
@@ -155,7 +155,7 @@
     'create_new_pack &&
      git prune-packed &&
      chmod +w ${pack}.pack &&
-     "$PERL_PATH" -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
+     perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
      git cat-file blob $blob_1 > /dev/null &&
      test_must_fail git cat-file blob $blob_2 > /dev/null &&
      test_must_fail git cat-file blob $blob_3 > /dev/null'
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index e4bb3a1..66c9a41 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -221,4 +221,14 @@
 	test_cmp expected actual
 '
 
+test_expect_success 'prune .git/shallow' '
+	SHA1=`echo hi|git commit-tree HEAD^{tree}` &&
+	echo $SHA1 >.git/shallow &&
+	git prune --dry-run >out &&
+	grep $SHA1 .git/shallow &&
+	grep $SHA1 out &&
+	git prune &&
+	! test -f .git/shallow
+'
+
 test_done
diff --git a/t/t5308-pack-detect-duplicates.sh b/t/t5308-pack-detect-duplicates.sh
new file mode 100755
index 0000000..9c5a876
--- /dev/null
+++ b/t/t5308-pack-detect-duplicates.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+test_description='handling of duplicate objects in incoming packfiles'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-pack.sh
+
+# The sha1s we have in our pack. It's important that these have the same
+# starting byte, so that they end up in the same fanout section of the index.
+# That lets us make sure we are exercising the binary search with both sets.
+LO_SHA1=e68fe8129b546b101aee9510c5328e7f21ca1d18
+HI_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+
+# And here's a "missing sha1" which will produce failed lookups. It must also
+# be in the same fanout section, and should be between the two (so that during
+# our binary search, we are sure to end up looking at one or the other of the
+# duplicate runs).
+MISSING_SHA1='e69d000000000000000000000000000000000000'
+
+# git will never intentionally create packfiles with
+# duplicate objects, so we have to construct them by hand.
+#
+# $1 is the name of the packfile to create
+#
+# $2 is the number of times to duplicate each object
+create_pack () {
+	pack_header "$((2 * $2))" >"$1" &&
+	for i in $(test_seq 1 "$2"); do
+		pack_obj $LO_SHA1 &&
+		pack_obj $HI_SHA1
+	done >>"$1" &&
+	pack_trailer "$1"
+}
+
+# double-check that create_pack actually works
+test_expect_success 'pack with no duplicates' '
+	create_pack no-dups.pack 1 &&
+	git index-pack --stdin <no-dups.pack
+'
+
+test_expect_success 'index-pack will allow duplicate objects by default' '
+	clear_packs &&
+	create_pack dups.pack 100 &&
+	git index-pack --stdin <dups.pack
+'
+
+test_expect_success 'create batch-check test vectors' '
+	cat >input <<-EOF &&
+	$LO_SHA1
+	$HI_SHA1
+	$MISSING_SHA1
+	EOF
+	cat >expect <<-EOF
+	$LO_SHA1 blob 2
+	$HI_SHA1 blob 0
+	$MISSING_SHA1 missing
+	EOF
+'
+
+test_expect_success 'lookup in duplicated pack (binary search)' '
+	git cat-file --batch-check <input >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'lookup in duplicated pack (GIT_USE_LOOKUP)' '
+	(
+		GIT_USE_LOOKUP=1 &&
+		export GIT_USE_LOOKUP &&
+		git cat-file --batch-check <input >actual
+	) &&
+	test_cmp expect actual
+'
+
+test_expect_success 'index-pack can reject packs with duplicates' '
+	clear_packs &&
+	create_pack dups.pack 2 &&
+	test_must_fail git index-pack --strict --stdin <dups.pack &&
+	test_expect_code 1 git cat-file -e $LO_SHA1
+'
+
+test_done
diff --git a/t/t5309-pack-delta-cycles.sh b/t/t5309-pack-delta-cycles.sh
new file mode 100755
index 0000000..3e7861b
--- /dev/null
+++ b/t/t5309-pack-delta-cycles.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+test_description='test index-pack handling of delta cycles in packfiles'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-pack.sh
+
+# Two similar-ish objects that we have computed deltas between.
+A=01d7713666f4de822776c7622c10f1b07de280dc
+B=e68fe8129b546b101aee9510c5328e7f21ca1d18
+
+# double-check our hand-constucted packs
+test_expect_success 'index-pack works with a single delta (A->B)' '
+	clear_packs &&
+	{
+		pack_header 2 &&
+		pack_obj $A $B &&
+		pack_obj $B
+	} >ab.pack &&
+	pack_trailer ab.pack &&
+	git index-pack --stdin <ab.pack &&
+	git cat-file -t $A &&
+	git cat-file -t $B
+'
+
+test_expect_success 'index-pack works with a single delta (B->A)' '
+	clear_packs &&
+	{
+		pack_header 2 &&
+		pack_obj $A &&
+		pack_obj $B $A
+	} >ba.pack &&
+	pack_trailer ba.pack &&
+	git index-pack --stdin <ba.pack &&
+	git cat-file -t $A &&
+	git cat-file -t $B
+'
+
+test_expect_success 'index-pack detects missing base objects' '
+	clear_packs &&
+	{
+		pack_header 1 &&
+		pack_obj $A $B
+	} >missing.pack &&
+	pack_trailer missing.pack &&
+	test_must_fail git index-pack --fix-thin --stdin <missing.pack
+'
+
+test_expect_success 'index-pack detects REF_DELTA cycles' '
+	clear_packs &&
+	{
+		pack_header 2 &&
+		pack_obj $A $B &&
+		pack_obj $B $A
+	} >cycle.pack &&
+	pack_trailer cycle.pack &&
+	test_must_fail git index-pack --fix-thin --stdin <cycle.pack
+'
+
+test_expect_failure 'failover to an object in another pack' '
+	clear_packs &&
+	git index-pack --stdin <ab.pack &&
+	git index-pack --stdin --fix-thin <cycle.pack
+'
+
+test_expect_failure 'failover to a duplicate object in the same pack' '
+	clear_packs &&
+	{
+		pack_header 3 &&
+		pack_obj $A $B &&
+		pack_obj $B $A &&
+		pack_obj $A
+	} >recoverable.pack &&
+	pack_trailer recoverable.pack &&
+	git index-pack --fix-thin --stdin <recoverable.pack
+'
+
+test_done
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index d87ddf7..5b2b1c2 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -531,5 +531,92 @@
 		git fsck
 	)
 '
+check_prot_path () {
+	cat >expected <<-EOF &&
+	Diag: url=$1
+	Diag: protocol=$2
+	Diag: path=$3
+	EOF
+	git fetch-pack --diag-url "$1" | grep -v hostandport= >actual &&
+	test_cmp expected actual
+}
+
+check_prot_host_path () {
+	cat >expected <<-EOF &&
+	Diag: url=$1
+	Diag: protocol=$2
+	Diag: hostandport=$3
+	Diag: path=$4
+	EOF
+	git fetch-pack --diag-url "$1" >actual &&
+	test_cmp expected actual
+}
+
+for r in repo re:po re/po
+do
+	# git or ssh with scheme
+	for p in "ssh+git" "git+ssh" git ssh
+	do
+		for h in host host:12 [::1] [::1]:23
+		do
+			case "$p" in
+			*ssh*)
+				pp=ssh
+				;;
+			*)
+				pp=$p
+			;;
+			esac
+			test_expect_success "fetch-pack --diag-url $p://$h/$r" '
+				check_prot_host_path $p://$h/$r $pp "$h" "/$r"
+			'
+			# "/~" -> "~" conversion
+			test_expect_success "fetch-pack --diag-url $p://$h/~$r" '
+				check_prot_host_path $p://$h/~$r $pp "$h" "~$r"
+			'
+		done
+	done
+	# file with scheme
+	for p in file
+	do
+		test_expect_success "fetch-pack --diag-url $p://$h/$r" '
+			check_prot_path $p://$h/$r $p "/$r"
+		'
+		# No "/~" -> "~" conversion for file
+		test_expect_success "fetch-pack --diag-url $p://$h/~$r" '
+			check_prot_path $p://$h/~$r $p "/~$r"
+		'
+	done
+	# file without scheme
+	for h in nohost nohost:12 [::1] [::1]:23 [ [:aa
+	do
+		test_expect_success "fetch-pack --diag-url ./$h:$r" '
+			check_prot_path ./$h:$r $p "./$h:$r"
+		'
+		# No "/~" -> "~" conversion for file
+		test_expect_success "fetch-pack --diag-url ./$p:$h/~$r" '
+		check_prot_path ./$p:$h/~$r $p "./$p:$h/~$r"
+		'
+	done
+	#ssh without scheme
+	p=ssh
+	for h in host [::1]
+	do
+		test_expect_success "fetch-pack --diag-url $h:$r" '
+			check_prot_path $h:$r $p "$r"
+		'
+		# Do "/~" -> "~" conversion
+		test_expect_success "fetch-pack --diag-url $h:/~$r" '
+			check_prot_host_path $h:/~$r $p "$h" "~$r"
+		'
+	done
+done
+
+test_expect_success MINGW 'fetch-pack --diag-url file://c:/repo' '
+	check_prot_path file://c:/repo file c:/repo
+'
+test_expect_success MINGW 'fetch-pack --diag-url c:repo' '
+	check_prot_path c:repo file c:repo
+'
 
 test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index fde6891..ab28594 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -88,7 +88,7 @@
 	cd "$D" &&
 	git clone . prune &&
 	cd prune &&
-	git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+	git update-ref refs/remotes/origin/extrabranch master &&
 
 	git fetch --prune origin &&
 	test_must_fail git rev-parse origin/extrabranch
@@ -98,7 +98,7 @@
 	cd "$D" &&
 	git clone . prune-branch &&
 	cd prune-branch &&
-	git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+	git update-ref refs/remotes/origin/extrabranch master &&
 
 	git fetch --prune origin master &&
 	git rev-parse origin/extrabranch
@@ -113,25 +113,45 @@
 	git rev-parse origin/master
 '
 
-test_expect_success 'fetch --prune --tags does not delete the remote-tracking branches' '
+test_expect_success 'fetch --prune --tags prunes branches but not tags' '
 	cd "$D" &&
 	git clone . prune-tags &&
 	cd prune-tags &&
-	git fetch origin refs/heads/master:refs/tags/sometag &&
+	git tag sometag master &&
+	# Create what looks like a remote-tracking branch from an earlier
+	# fetch that has since been deleted from the remote:
+	git update-ref refs/remotes/origin/fake-remote master &&
 
 	git fetch --prune --tags origin &&
 	git rev-parse origin/master &&
-	test_must_fail git rev-parse somebranch
+	test_must_fail git rev-parse origin/fake-remote &&
+	git rev-parse sometag
 '
 
-test_expect_success 'fetch --prune --tags with branch does not delete other remote-tracking branches' '
+test_expect_success 'fetch --prune --tags with branch does not prune other things' '
 	cd "$D" &&
 	git clone . prune-tags-branch &&
 	cd prune-tags-branch &&
-	git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+	git tag sometag master &&
+	git update-ref refs/remotes/origin/extrabranch master &&
 
 	git fetch --prune --tags origin master &&
-	git rev-parse origin/extrabranch
+	git rev-parse origin/extrabranch &&
+	git rev-parse sometag
+'
+
+test_expect_success 'fetch --prune --tags with refspec prunes based on refspec' '
+	cd "$D" &&
+	git clone . prune-tags-refspec &&
+	cd prune-tags-refspec &&
+	git tag sometag master &&
+	git update-ref refs/remotes/origin/foo/otherbranch master &&
+	git update-ref refs/remotes/origin/extrabranch master &&
+
+	git fetch --prune --tags origin refs/heads/foo/*:refs/remotes/origin/foo/* &&
+	test_must_fail git rev-parse refs/remotes/origin/foo/otherbranch &&
+	git rev-parse origin/extrabranch &&
+	git rev-parse sometag
 '
 
 test_expect_success 'fetch tags when there is no tags' '
@@ -497,6 +517,88 @@
 	)
 '
 
+# configured prune tests
+
+set_config_tristate () {
+	# var=$1 val=$2
+	case "$2" in
+	unset)  test_unconfig "$1" ;;
+	*)	git config "$1" "$2" ;;
+	esac
+}
+
+test_configured_prune () {
+	fetch_prune=$1 remote_origin_prune=$2 cmdline=$3 expected=$4
+
+	test_expect_success "prune fetch.prune=$1 remote.origin.prune=$2${3:+ $3}; $4" '
+		# make sure a newbranch is there in . and also in one
+		git branch -f newbranch &&
+		(
+			cd one &&
+			test_unconfig fetch.prune &&
+			test_unconfig remote.origin.prune &&
+			git fetch &&
+			git rev-parse --verify refs/remotes/origin/newbranch
+		)
+
+		# now remove it
+		git branch -d newbranch &&
+
+		# then test
+		(
+			cd one &&
+			set_config_tristate fetch.prune $fetch_prune &&
+			set_config_tristate remote.origin.prune $remote_origin_prune &&
+
+			git fetch $cmdline &&
+			case "$expected" in
+			pruned)
+				test_must_fail git rev-parse --verify refs/remotes/origin/newbranch
+				;;
+			kept)
+				git rev-parse --verify refs/remotes/origin/newbranch
+				;;
+			esac
+		)
+	'
+}
+
+test_configured_prune unset unset ""		kept
+test_configured_prune unset unset "--no-prune"	kept
+test_configured_prune unset unset "--prune"	pruned
+
+test_configured_prune false unset ""		kept
+test_configured_prune false unset "--no-prune"	kept
+test_configured_prune false unset "--prune"	pruned
+
+test_configured_prune true  unset ""		pruned
+test_configured_prune true  unset "--prune"	pruned
+test_configured_prune true  unset "--no-prune"	kept
+
+test_configured_prune unset false ""		kept
+test_configured_prune unset false "--no-prune"	kept
+test_configured_prune unset false "--prune"	pruned
+
+test_configured_prune false false ""		kept
+test_configured_prune false false "--no-prune"	kept
+test_configured_prune false false "--prune"	pruned
+
+test_configured_prune true  false ""		kept
+test_configured_prune true  false "--prune"	pruned
+test_configured_prune true  false "--no-prune"	kept
+
+test_configured_prune unset true  ""		pruned
+test_configured_prune unset true  "--no-prune"	kept
+test_configured_prune unset true  "--prune"	pruned
+
+test_configured_prune false true  ""		pruned
+test_configured_prune false true  "--no-prune"	kept
+test_configured_prune false true  "--prune"	pruned
+
+test_configured_prune true  true  ""		pruned
+test_configured_prune true  true  "--prune"	pruned
+test_configured_prune true  true  "--no-prune"	kept
+
 test_expect_success 'all boundary commits are excluded' '
 	test_commit base &&
 	test_commit oneside &&
@@ -512,4 +614,41 @@
 	test_bundle_object_count .git/objects/pack/pack-${pack##pack	}.pack 3
 '
 
+test_expect_success 'fetch --prune prints the remotes url' '
+	git branch goodbye &&
+	git clone . only-prunes &&
+	git branch -D goodbye &&
+	(
+		cd only-prunes &&
+		git fetch --prune origin 2>&1 | head -n1 >../actual
+	) &&
+	echo "From ${D}/." >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'branchname D/F conflict resolved by --prune' '
+	git branch dir/file &&
+	git clone . prune-df-conflict &&
+	git branch -D dir/file &&
+	git branch dir &&
+	(
+		cd prune-df-conflict &&
+		git fetch --prune &&
+		git rev-parse origin/dir >../actual
+	) &&
+	git rev-parse dir >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'fetching a one-level ref works' '
+	test_commit extra &&
+	git reset --hard HEAD^ &&
+	git update-ref refs/foo extra &&
+	git init one-level &&
+	(
+		cd one-level &&
+		git fetch .. HEAD refs/foo
+	)
+'
+
 test_done
diff --git a/t/t5515/fetch.br-unconfig_--tags_.._.git b/t/t5515/fetch.br-unconfig_--tags_.._.git
index 1669cc4..0f70f66 100644
--- a/t/t5515/fetch.br-unconfig_--tags_.._.git
+++ b/t/t5515/fetch.br-unconfig_--tags_.._.git
@@ -1,4 +1,5 @@
 # br-unconfig --tags ../.git
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b		../
 6c9dec2b923228c9ff994c6cfe4ae16c12408dc5	not-for-merge	tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689	not-for-merge	tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba	not-for-merge	tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.master_--tags_.._.git b/t/t5515/fetch.master_--tags_.._.git
index 8a74935..ab473a6 100644
--- a/t/t5515/fetch.master_--tags_.._.git
+++ b/t/t5515/fetch.master_--tags_.._.git
@@ -1,4 +1,5 @@
 # master --tags ../.git
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b		../
 6c9dec2b923228c9ff994c6cfe4ae16c12408dc5	not-for-merge	tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689	not-for-merge	tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba	not-for-merge	tag 'tag-one-tree' of ../
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 4691d51..926e7f6 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1126,6 +1126,81 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
+	mk_test testrepo heads/master &&
+	rm -fr src dst &&
+	git init src &&
+	git init --bare dst &&
+	(
+		cd src &&
+		git pull ../testrepo master &&
+		git branch next &&
+		git config remote.dst.url ../dst &&
+		git config remote.dst.push "+refs/heads/*:refs/remotes/src/*" &&
+		git push dst master &&
+		git show-ref refs/heads/master |
+		sed -e "s|refs/heads/|refs/remotes/src/|" >../dst/expect
+	) &&
+	(
+		cd dst &&
+		test_must_fail git show-ref refs/heads/next &&
+		test_must_fail git show-ref refs/heads/master &&
+		git show-ref refs/remotes/src/master >actual
+	) &&
+	test_cmp dst/expect dst/actual
+'
+
+test_expect_success 'with no remote.$name.push, it is not used as refmap' '
+	mk_test testrepo heads/master &&
+	rm -fr src dst &&
+	git init src &&
+	git init --bare dst &&
+	(
+		cd src &&
+		git pull ../testrepo master &&
+		git branch next &&
+		git config remote.dst.url ../dst &&
+		git config push.default matching &&
+		git push dst master &&
+		git show-ref refs/heads/master >../dst/expect
+	) &&
+	(
+		cd dst &&
+		test_must_fail git show-ref refs/heads/next &&
+		git show-ref refs/heads/master >actual
+	) &&
+	test_cmp dst/expect dst/actual
+'
+
+test_expect_success 'with no remote.$name.push, upstream mapping is used' '
+	mk_test testrepo heads/master &&
+	rm -fr src dst &&
+	git init src &&
+	git init --bare dst &&
+	(
+		cd src &&
+		git pull ../testrepo master &&
+		git branch next &&
+		git config remote.dst.url ../dst &&
+		git config remote.dst.fetch "+refs/heads/*:refs/remotes/dst/*" &&
+		git config push.default upstream &&
+
+		git config branch.master.merge refs/heads/trunk &&
+		git config branch.master.remote dst &&
+
+		git push dst master &&
+		git show-ref refs/heads/master |
+		sed -e "s|refs/heads/master|refs/heads/trunk|" >../dst/expect
+	) &&
+	(
+		cd dst &&
+		test_must_fail git show-ref refs/heads/master &&
+		test_must_fail git show-ref refs/heads/next &&
+		git show-ref refs/heads/trunk >actual
+	) &&
+	test_cmp dst/expect dst/actual
+'
+
 test_expect_success 'push does not follow tags by default' '
 	mk_test testrepo heads/master &&
 	rm -fr src dst &&
@@ -1172,4 +1247,21 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'push --no-thin must produce non-thin pack' '
+	cat >>path1 <<\EOF &&
+keep base version of path1 big enough, compared to the new changes
+later, in order to pass size heuristics in
+builtin/pack-objects.c:try_delta()
+EOF
+	git commit -am initial &&
+	git init no-thin &&
+	git --git-dir=no-thin/.git config receive.unpacklimit 0 &&
+	git push no-thin/.git refs/heads/master:refs/heads/foo &&
+	echo modified >> path1 &&
+	git commit -am modified &&
+	git repack -adf &&
+	rcvpck="git receive-pack --reject-thin-pack-for-testing" &&
+	git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/master:refs/heads/foo
+'
+
 test_done
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index ed4d9c8..227d293 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -148,6 +148,95 @@
 	test new = $(git show HEAD:file2)
 '
 
+# add a feature branch, keep-merge, that is merged into master, so the
+# test can try preserving the merge commit (or not) with various
+# --rebase flags/pull.rebase settings.
+test_expect_success 'preserve merge setup' '
+	git reset --hard before-rebase &&
+	git checkout -b keep-merge second^ &&
+	test_commit file3 &&
+	git checkout to-rebase &&
+	git merge keep-merge &&
+	git tag before-preserve-rebase
+'
+
+test_expect_success 'pull.rebase=false create a new merge commit' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase false &&
+	git pull . copy &&
+	test $(git rev-parse HEAD^1) = $(git rev-parse before-preserve-rebase) &&
+	test $(git rev-parse HEAD^2) = $(git rev-parse copy) &&
+	test file3 = $(git show HEAD:file3.t)
+'
+
+test_expect_success 'pull.rebase=true flattens keep-merge' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase true &&
+	git pull . copy &&
+	test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
+	test file3 = $(git show HEAD:file3.t)
+'
+
+test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase 1 &&
+	git pull . copy &&
+	test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
+	test file3 = $(git show HEAD:file3.t)
+'
+
+test_expect_success 'pull.rebase=preserve rebases and merges keep-merge' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase preserve &&
+	git pull . copy &&
+	test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
+	test $(git rev-parse HEAD^2) = $(git rev-parse keep-merge)
+'
+
+test_expect_success 'pull.rebase=invalid fails' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase invalid &&
+	! git pull . copy
+'
+
+test_expect_success '--rebase=false create a new merge commit' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase true &&
+	git pull --rebase=false . copy &&
+	test $(git rev-parse HEAD^1) = $(git rev-parse before-preserve-rebase) &&
+	test $(git rev-parse HEAD^2) = $(git rev-parse copy) &&
+	test file3 = $(git show HEAD:file3.t)
+'
+
+test_expect_success '--rebase=true rebases and flattens keep-merge' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase preserve &&
+	git pull --rebase=true . copy &&
+	test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
+	test file3 = $(git show HEAD:file3.t)
+'
+
+test_expect_success '--rebase=preserve rebases and merges keep-merge' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase true &&
+	git pull --rebase=preserve . copy &&
+	test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
+	test $(git rev-parse HEAD^2) = $(git rev-parse keep-merge)
+'
+
+test_expect_success '--rebase=invalid fails' '
+	git reset --hard before-preserve-rebase &&
+	! git pull --rebase=invalid . copy
+'
+
+test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '
+	git reset --hard before-preserve-rebase &&
+	test_config pull.rebase preserve &&
+	git pull --rebase . copy &&
+	test $(git rev-parse HEAD^^) = $(git rev-parse copy) &&
+	test file3 = $(git show HEAD:file3.t)
+'
+
 test_expect_success '--rebase with rebased upstream' '
 
 	git remote add -f me . &&
diff --git a/t/t5525-fetch-tagopt.sh b/t/t5525-fetch-tagopt.sh
index 4fbf7a1..45815f7 100755
--- a/t/t5525-fetch-tagopt.sh
+++ b/t/t5525-fetch-tagopt.sh
@@ -8,7 +8,8 @@
 	git clone --mirror . $1 &&
 	git remote add remote_$1 $1 &&
 	(cd $1 &&
-	git tag tag_$1)
+	git tag tag_$1 &&
+	git branch branch_$1)
 }
 
 test_expect_success setup '
@@ -21,21 +22,33 @@
 
 test_expect_success "fetch with tagopt=--no-tags does not get tag" '
 	git fetch remote_one &&
-	test_must_fail git show-ref tag_one
+	test_must_fail git show-ref tag_one &&
+	git show-ref remote_one/branch_one
 	'
 
 test_expect_success "fetch --tags with tagopt=--no-tags gets tag" '
+	(
+		cd one &&
+		git branch second_branch_one
+	) &&
 	git fetch --tags remote_one &&
-	git show-ref tag_one
+	git show-ref tag_one &&
+	git show-ref remote_one/second_branch_one
 	'
 
 test_expect_success "fetch --no-tags with tagopt=--tags does not get tag" '
 	git fetch --no-tags remote_two &&
-	test_must_fail git show-ref tag_two
+	test_must_fail git show-ref tag_two &&
+	git show-ref remote_two/branch_two
 	'
 
 test_expect_success "fetch with tagopt=--tags gets tag" '
+	(
+		cd two &&
+		git branch second_branch_two
+	) &&
 	git fetch remote_two &&
-	git show-ref tag_two
+	git show-ref tag_two &&
+	git show-ref remote_two/second_branch_two
 	'
 test_done
diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index 8c16e04..445bb5f 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -12,6 +12,7 @@
 	(
 		cd work &&
 		git init &&
+		git config push.default matching &&
 		mkdir -p gar/bage &&
 		(
 			cd gar/bage &&
diff --git a/t/t5533-push-cas.sh b/t/t5533-push-cas.sh
new file mode 100755
index 0000000..ba20d83
--- /dev/null
+++ b/t/t5533-push-cas.sh
@@ -0,0 +1,189 @@
+#!/bin/sh
+
+test_description='compare & swap push force/delete safety'
+
+. ./test-lib.sh
+
+setup_srcdst_basic () {
+	rm -fr src dst &&
+	git clone --no-local . src &&
+	git clone --no-local src dst &&
+	(
+		cd src && git checkout HEAD^0
+	)
+}
+
+test_expect_success setup '
+	: create template repository
+	test_commit A &&
+	test_commit B &&
+	test_commit C
+'
+
+test_expect_success 'push to update (protected)' '
+	setup_srcdst_basic &&
+	(
+		cd dst &&
+		test_commit D &&
+		test_must_fail git push --force-with-lease=master:master origin master
+	) &&
+	git ls-remote . refs/heads/master >expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to update (protected, forced)' '
+	setup_srcdst_basic &&
+	(
+		cd dst &&
+		test_commit D &&
+		git push --force --force-with-lease=master:master origin master
+	) &&
+	git ls-remote dst refs/heads/master >expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to update (protected, tracking)' '
+	setup_srcdst_basic &&
+	(
+		cd src &&
+		git checkout master &&
+		test_commit D &&
+		git checkout HEAD^0
+	) &&
+	git ls-remote src refs/heads/master >expect &&
+	(
+		cd dst &&
+		test_commit E &&
+		git ls-remote . refs/remotes/origin/master >expect &&
+		test_must_fail git push --force-with-lease=master origin master &&
+		git ls-remote . refs/remotes/origin/master >actual &&
+		test_cmp expect actual
+	) &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to update (protected, tracking, forced)' '
+	setup_srcdst_basic &&
+	(
+		cd src &&
+		git checkout master &&
+		test_commit D &&
+		git checkout HEAD^0
+	) &&
+	(
+		cd dst &&
+		test_commit E &&
+		git ls-remote . refs/remotes/origin/master >expect &&
+		git push --force --force-with-lease=master origin master
+	) &&
+	git ls-remote dst refs/heads/master >expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to update (allowed)' '
+	setup_srcdst_basic &&
+	(
+		cd dst &&
+		test_commit D &&
+		git push --force-with-lease=master:master^ origin master
+	) &&
+	git ls-remote dst refs/heads/master >expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to update (allowed, tracking)' '
+	setup_srcdst_basic &&
+	(
+		cd dst &&
+		test_commit D &&
+		git push --force-with-lease=master origin master
+	) &&
+	git ls-remote dst refs/heads/master >expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to update (allowed even though no-ff)' '
+	setup_srcdst_basic &&
+	(
+		cd dst &&
+		git reset --hard HEAD^ &&
+		test_commit D &&
+		git push --force-with-lease=master origin master
+	) &&
+	git ls-remote dst refs/heads/master >expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to delete (protected)' '
+	setup_srcdst_basic &&
+	git ls-remote src refs/heads/master >expect &&
+	(
+		cd dst &&
+		test_must_fail git push --force-with-lease=master:master^ origin :master
+	) &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to delete (protected, forced)' '
+	setup_srcdst_basic &&
+	(
+		cd dst &&
+		git push --force --force-with-lease=master:master^ origin :master
+	) &&
+	>expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'push to delete (allowed)' '
+	setup_srcdst_basic &&
+	(
+		cd dst &&
+		git push --force-with-lease=master origin :master
+	) &&
+	>expect &&
+	git ls-remote src refs/heads/master >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'cover everything with default force-with-lease (protected)' '
+	setup_srcdst_basic &&
+	(
+		cd src &&
+		git branch naster master^
+	)
+	git ls-remote src refs/heads/\* >expect &&
+	(
+		cd dst &&
+		test_must_fail git push --force-with-lease origin master master:naster
+	) &&
+	git ls-remote src refs/heads/\* >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'cover everything with default force-with-lease (allowed)' '
+	setup_srcdst_basic &&
+	(
+		cd src &&
+		git branch naster master^
+	)
+	(
+		cd dst &&
+		git fetch &&
+		git push --force-with-lease origin master master:naster
+	) &&
+	git ls-remote dst refs/heads/master |
+	sed -e "s/master/naster/" >expect &&
+	git ls-remote src refs/heads/naster >actual &&
+	test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5536-fetch-conflicts.sh b/t/t5536-fetch-conflicts.sh
new file mode 100755
index 0000000..6c5d3a4
--- /dev/null
+++ b/t/t5536-fetch-conflicts.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+test_description='fetch handles conflicting refspecs correctly'
+
+. ./test-lib.sh
+
+D=$(pwd)
+
+setup_repository () {
+	git init "$1" && (
+		cd "$1" &&
+		git config remote.origin.url "$D" &&
+		shift &&
+		for refspec in "$@"
+		do
+			git config --add remote.origin.fetch "$refspec"
+		done
+	)
+}
+
+verify_stderr () {
+	cat >expected &&
+	# We're not interested in the error
+	# "fatal: The remote end hung up unexpectedly":
+	grep -E '^(fatal|warning):' <error | grep -v 'hung up' >actual | sort &&
+	test_cmp expected actual
+}
+
+test_expect_success 'setup' '
+	git commit --allow-empty -m "Initial" &&
+	git branch branch1 &&
+	git tag tag1 &&
+	git commit --allow-empty -m "First" &&
+	git branch branch2 &&
+	git tag tag2
+'
+
+test_expect_success 'fetch with no conflict' '
+	setup_repository ok "+refs/heads/*:refs/remotes/origin/*" && (
+		cd ok &&
+		git fetch origin
+	)
+'
+
+test_expect_success 'fetch conflict: config vs. config' '
+	setup_repository ccc \
+		"+refs/heads/branch1:refs/remotes/origin/branch1" \
+		"+refs/heads/branch2:refs/remotes/origin/branch1" && (
+		cd ccc &&
+		test_must_fail git fetch origin 2>error &&
+		verify_stderr <<-\EOF
+		fatal: Cannot fetch both refs/heads/branch1 and refs/heads/branch2 to refs/remotes/origin/branch1
+		EOF
+	)
+'
+
+test_expect_success 'fetch duplicate: config vs. config' '
+	setup_repository dcc \
+		"+refs/heads/*:refs/remotes/origin/*" \
+		"+refs/heads/branch1:refs/remotes/origin/branch1" && (
+		cd dcc &&
+		git fetch origin
+	)
+'
+
+test_expect_success 'fetch conflict: arg overrides config' '
+	setup_repository aoc \
+		"+refs/heads/*:refs/remotes/origin/*" && (
+		cd aoc &&
+		git fetch origin refs/heads/branch2:refs/remotes/origin/branch1
+	)
+'
+
+test_expect_success 'fetch conflict: arg vs. arg' '
+	setup_repository caa && (
+		cd caa &&
+		test_must_fail git fetch origin \
+			refs/heads/*:refs/remotes/origin/* \
+			refs/heads/branch2:refs/remotes/origin/branch1 2>error &&
+		verify_stderr <<-\EOF
+		fatal: Cannot fetch both refs/heads/branch1 and refs/heads/branch2 to refs/remotes/origin/branch1
+		EOF
+	)
+'
+
+test_expect_success 'fetch conflict: criss-cross args' '
+	setup_repository xaa \
+		"+refs/heads/*:refs/remotes/origin/*" && (
+		cd xaa &&
+		git fetch origin \
+			refs/heads/branch1:refs/remotes/origin/branch2 \
+			refs/heads/branch2:refs/remotes/origin/branch1 2>error &&
+		verify_stderr <<-\EOF
+		warning: refs/remotes/origin/branch1 usually tracks refs/heads/branch1, not refs/heads/branch2
+		warning: refs/remotes/origin/branch2 usually tracks refs/heads/branch2, not refs/heads/branch1
+		EOF
+	)
+'
+
+test_done
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
new file mode 100755
index 0000000..b0fa738
--- /dev/null
+++ b/t/t5537-fetch-shallow.sh
@@ -0,0 +1,204 @@
+#!/bin/sh
+
+test_description='fetch/clone from a shallow clone'
+
+. ./test-lib.sh
+
+commit() {
+	echo "$1" >tracked &&
+	git add tracked &&
+	git commit -m "$1"
+}
+
+test_expect_success 'setup' '
+	commit 1 &&
+	commit 2 &&
+	commit 3 &&
+	commit 4 &&
+	git config --global transfer.fsckObjects true
+'
+
+test_expect_success 'setup shallow clone' '
+	git clone --no-local --depth=2 .git shallow &&
+	git --git-dir=shallow/.git log --format=%s >actual &&
+	cat <<EOF >expect &&
+4
+3
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'clone from shallow clone' '
+	git clone --no-local shallow shallow2 &&
+	(
+	cd shallow2 &&
+	git fsck &&
+	git log --format=%s >actual &&
+	cat <<EOF >expect &&
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch from shallow clone' '
+	(
+	cd shallow &&
+	commit 5
+	) &&
+	(
+	cd shallow2 &&
+	git fetch &&
+	git fsck &&
+	git log --format=%s origin/master >actual &&
+	cat <<EOF >expect &&
+5
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch --depth from shallow clone' '
+	(
+	cd shallow &&
+	commit 6
+	) &&
+	(
+	cd shallow2 &&
+	git fetch --depth=2 &&
+	git fsck &&
+	git log --format=%s origin/master >actual &&
+	cat <<EOF >expect &&
+6
+5
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch --unshallow from shallow clone' '
+	(
+	cd shallow2 &&
+	git fetch --unshallow &&
+	git fsck &&
+	git log --format=%s origin/master >actual &&
+	cat <<EOF >expect &&
+6
+5
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch something upstream has but hidden by clients shallow boundaries' '
+	# the blob "1" is available in .git but hidden by the
+	# shallow2/.git/shallow and it should be resent
+	! git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` >/dev/null &&
+	echo 1 >1.t &&
+	git add 1.t &&
+	git commit -m add-1-back &&
+	(
+	cd shallow2 &&
+	git fetch ../.git +refs/heads/master:refs/remotes/top/master &&
+	git fsck &&
+	git log --format=%s top/master >actual &&
+	cat <<EOF >expect &&
+add-1-back
+4
+3
+EOF
+	test_cmp expect actual
+	) &&
+	git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` >/dev/null
+
+'
+
+test_expect_success 'fetch that requires changes in .git/shallow is filtered' '
+	(
+	cd shallow &&
+	git checkout --orphan no-shallow &&
+	commit no-shallow
+	) &&
+	git init notshallow &&
+	(
+	cd notshallow &&
+	git fetch ../shallow/.git refs/heads/*:refs/remotes/shallow/*&&
+	git for-each-ref --format="%(refname)" >actual.refs &&
+	cat <<EOF >expect.refs &&
+refs/remotes/shallow/no-shallow
+EOF
+	test_cmp expect.refs actual.refs &&
+	git log --format=%s shallow/no-shallow >actual &&
+	cat <<EOF >expect &&
+no-shallow
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch --update-shallow' '
+	(
+	cd shallow &&
+	git checkout master &&
+	commit 7 &&
+	git tag -m foo heavy-tag HEAD^ &&
+	git tag light-tag HEAD^:tracked
+	) &&
+	(
+	cd notshallow &&
+	git fetch --update-shallow ../shallow/.git refs/heads/*:refs/remotes/shallow/* &&
+	git fsck &&
+	git for-each-ref --sort=refname --format="%(refname)" >actual.refs &&
+	cat <<EOF >expect.refs &&
+refs/remotes/shallow/master
+refs/remotes/shallow/no-shallow
+refs/tags/heavy-tag
+refs/tags/light-tag
+EOF
+	test_cmp expect.refs actual.refs &&
+	git log --format=%s shallow/master >actual &&
+	cat <<EOF >expect &&
+7
+6
+5
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
+	say 'skipping remaining tests, git built without http support'
+	test_done
+fi
+
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5537'}
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'clone http repository' '
+	git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	git clone $HTTPD_URL/smart/repo.git clone &&
+	(
+	cd clone &&
+	git fsck &&
+	git log --format=%s origin/master >actual &&
+	cat <<EOF >expect &&
+7
+6
+5
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+stop_httpd
+test_done
diff --git a/t/t5538-push-shallow.sh b/t/t5538-push-shallow.sh
new file mode 100755
index 0000000..0a6e40f
--- /dev/null
+++ b/t/t5538-push-shallow.sh
@@ -0,0 +1,183 @@
+#!/bin/sh
+
+test_description='push from/to a shallow clone'
+
+. ./test-lib.sh
+
+commit() {
+	echo "$1" >tracked &&
+	git add tracked &&
+	git commit -m "$1"
+}
+
+test_expect_success 'setup' '
+	git config --global transfer.fsckObjects true &&
+	commit 1 &&
+	commit 2 &&
+	commit 3 &&
+	commit 4 &&
+	git clone . full &&
+	(
+	git init full-abc &&
+	cd full-abc &&
+	commit a &&
+	commit b &&
+	commit c
+	) &&
+	git clone --no-local --depth=2 .git shallow &&
+	git --git-dir=shallow/.git log --format=%s >actual &&
+	cat <<EOF >expect &&
+4
+3
+EOF
+	test_cmp expect actual &&
+	git clone --no-local --depth=2 full-abc/.git shallow2 &&
+	git --git-dir=shallow2/.git log --format=%s >actual &&
+	cat <<EOF >expect &&
+c
+b
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'push from shallow clone' '
+	(
+	cd shallow &&
+	commit 5 &&
+	git push ../.git +master:refs/remotes/shallow/master
+	) &&
+	git log --format=%s shallow/master >actual &&
+	git fsck &&
+	cat <<EOF >expect &&
+5
+4
+3
+2
+1
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'push from shallow clone, with grafted roots' '
+	(
+	cd shallow2 &&
+	test_must_fail git push ../.git +master:refs/remotes/shallow2/master 2>err &&
+	grep "shallow2/master.*shallow update not allowed" err
+	) &&
+	test_must_fail git rev-parse shallow2/master &&
+	git fsck
+'
+
+test_expect_success 'add new shallow root with receive.updateshallow on' '
+	test_config receive.shallowupdate true &&
+	(
+	cd shallow2 &&
+	git push ../.git +master:refs/remotes/shallow2/master
+	) &&
+	git log --format=%s shallow2/master >actual &&
+	git fsck &&
+	cat <<EOF >expect &&
+c
+b
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'push from shallow to shallow' '
+	(
+	cd shallow &&
+	git --git-dir=../shallow2/.git config receive.shallowupdate true &&
+	git push ../shallow2/.git +master:refs/remotes/shallow/master &&
+	git --git-dir=../shallow2/.git config receive.shallowupdate false
+	) &&
+	(
+	cd shallow2 &&
+	git log --format=%s shallow/master >actual &&
+	git fsck &&
+	cat <<EOF >expect &&
+5
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'push from full to shallow' '
+	! git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` &&
+	commit 1 &&
+	git push shallow2/.git +master:refs/remotes/top/master &&
+	(
+	cd shallow2 &&
+	git log --format=%s top/master >actual &&
+	git fsck &&
+	cat <<EOF >expect &&
+1
+4
+3
+EOF
+	test_cmp expect actual &&
+	git cat-file blob `echo 1|git hash-object --stdin` >/dev/null
+	)
+'
+
+if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
+	say 'skipping remaining tests, git built without http support'
+	test_done
+fi
+
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5537'}
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'push to shallow repo via http' '
+	git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	(
+	cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	git config http.receivepack true
+	) &&
+	(
+	cd full &&
+	commit 9 &&
+	git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master
+	) &&
+	(
+	cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	git fsck &&
+	git log --format=%s top/master >actual &&
+	cat <<EOF >expect &&
+9
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'push from shallow repo via http' '
+	mv "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" shallow-upstream.git &&
+	git clone --bare --no-local full "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	(
+	cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	git config http.receivepack true
+	) &&
+	commit 10 &&
+	git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master &&
+	(
+	cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	git fsck &&
+	git log --format=%s top/master >actual &&
+	cat <<EOF >expect &&
+10
+1
+4
+3
+2
+1
+EOF
+	test_cmp expect actual
+	)
+'
+
+stop_httpd
+test_done
diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh
index 01d0d95..5b0198c 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push.sh
@@ -154,7 +154,7 @@
 
 test_expect_success 'push to password-protected repository (user in URL)' '
 	test_commit pw-user &&
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git push "$HTTPD_URL_USER/auth/dumb/test_repo.git" HEAD &&
 	git rev-parse --verify HEAD >expect &&
 	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \
@@ -168,7 +168,7 @@
 
 test_expect_failure 'push to password-protected repository (no user in URL)' '
 	test_commit pw-nouser &&
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git push "$HTTPD_URL/auth/dumb/test_repo.git" HEAD &&
 	expect_askpass both user@host
 	git rev-parse --verify HEAD >expect &&
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh
index beb00be..bfd241e 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push.sh
@@ -153,7 +153,7 @@
 '
 
 test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
-	"$ROOT_PATH"/test_repo_clone master
+	"$ROOT_PATH"/test_repo_clone master 		success
 
 test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper' '
 	# create a dissimilarly-named remote ref so that git is unable to match the
@@ -274,7 +274,7 @@
 	cd "$ROOT_PATH/test_repo_clone" &&
 	echo push-auth-test >expect &&
 	test_commit push-auth-test &&
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git push "$HTTPD_URL"/auth/smart/test_repo.git &&
 	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
 		log -1 --format=%s >actual &&
@@ -286,7 +286,7 @@
 	cd "$ROOT_PATH/test_repo_clone" &&
 	echo push-half-auth >expect &&
 	test_commit push-half-auth &&
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git push "$HTTPD_URL"/auth-push/smart/test_repo.git &&
 	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
 		log -1 --format=%s >actual &&
@@ -316,7 +316,7 @@
 	cd "$ROOT_PATH/half-auth-clone" &&
 	echo two >expect &&
 	test_commit two &&
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" &&
 	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \
 		log -1 --format=%s >actual &&
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
index f7d0f14..8392624 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch.sh
@@ -62,13 +62,13 @@
 '
 
 test_expect_success 'http auth can use just user in URL' '
-	set_askpass user@host &&
+	set_askpass wrong pass@host &&
 	git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-pass &&
 	expect_askpass pass user@host
 '
 
 test_expect_success 'http auth can request both user and pass' '
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-both &&
 	expect_askpass both user@host
 '
@@ -77,7 +77,7 @@
 	test_config_global credential.helper "!f() {
 		cat >/dev/null
 		echo username=user@host
-		echo password=user@host
+		echo password=pass@host
 	}; f" &&
 	set_askpass wrong &&
 	git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-helper &&
@@ -86,14 +86,14 @@
 
 test_expect_success 'http auth can get username from config' '
 	test_config_global "credential.$HTTPD_URL.username" user@host &&
-	set_askpass user@host &&
+	set_askpass wrong pass@host &&
 	git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-user &&
 	expect_askpass pass user@host
 '
 
 test_expect_success 'configured username does not override URL' '
 	test_config_global "credential.$HTTPD_URL.username" wrong &&
-	set_askpass user@host &&
+	set_askpass wrong pass@host &&
 	git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-user2 &&
 	expect_askpass pass user@host
 '
diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh
index 1b71bb5..a124efe 100755
--- a/t/t5551-http-fetch.sh
+++ b/t/t5551-http-fetch.sh
@@ -119,7 +119,7 @@
 
 test_expect_success 'clone from password-protected repository' '
 	echo two >expect &&
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git clone --bare "$HTTPD_URL/auth/smart/repo.git" smart-auth &&
 	expect_askpass both user@host &&
 	git --git-dir=smart-auth log -1 --format=%s >actual &&
@@ -137,7 +137,7 @@
 
 test_expect_success 'clone from auth-only-for-objects repository' '
 	echo two >expect &&
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth &&
 	expect_askpass both user@host &&
 	git --git-dir=half-auth log -1 --format=%s >actual &&
@@ -151,7 +151,7 @@
 '
 
 test_expect_success 'redirects send auth to new location' '
-	set_askpass user@host &&
+	set_askpass user@host pass@host &&
 	git -c credential.useHttpPath=true \
 	  clone $HTTPD_URL/smart-redir-auth/repo.git repo-redir-auth &&
 	expect_askpass both user@host auth/smart/repo.git
@@ -198,6 +198,22 @@
 	test_cmp expect actual
 '
 
+cat >cookies.txt <<EOF
+127.0.0.1	FALSE	/smart_cookies/	FALSE	0	othername	othervalue
+EOF
+cat >expect_cookies.txt <<EOF
+
+127.0.0.1	FALSE	/smart_cookies/	FALSE	0	othername	othervalue
+127.0.0.1	FALSE	/smart_cookies/repo.git/info/	FALSE	0	name	value
+EOF
+test_expect_success 'cookies stored in http.cookiefile when http.savecookies set' '
+	git config http.cookiefile cookies.txt &&
+	git config http.savecookies true &&
+	git ls-remote $HTTPD_URL/smart_cookies/repo.git master &&
+	tail -3 cookies.txt > cookies_tail.txt
+	test_cmp expect_cookies.txt cookies_tail.txt
+'
+
 test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
 
 test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '
@@ -219,7 +235,7 @@
 	done | git fast-import --export-marks=marks &&
 
 	# now assign tags to all the dangling commits we created above
-	tag=$("$PERL_PATH" -e "print \"bla\" x 30") &&
+	tag=$(perl -e "print \"bla\" x 30") &&
 	sed -e "s|^:\([^ ]*\) \(.*\)$|\2 refs/tags/$tag-\1|" <marks >>packed-refs
 	)
 '
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index f8e5a9a..5e67035 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -280,9 +280,143 @@
 	test_cmp fetch.expected fetch.actual
 '
 
+setup_ssh_wrapper () {
+	test_expect_success 'setup ssh wrapper' '
+		write_script "$TRASH_DIRECTORY/ssh-wrapper" <<-\EOF &&
+		echo >>"$TRASH_DIRECTORY/ssh-output" "ssh: $*" &&
+		# throw away all but the last argument, which should be the
+		# command
+		while test $# -gt 1; do shift; done
+		eval "$1"
+		EOF
+		GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper" &&
+		export GIT_SSH &&
+		export TRASH_DIRECTORY &&
+		>"$TRASH_DIRECTORY"/ssh-output
+	'
+}
+
+expect_ssh () {
+	test_when_finished '
+		(cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output)
+	' &&
+	{
+		case "$1" in
+		none)
+			;;
+		*)
+			echo "ssh: $1 git-upload-pack '$2'"
+		esac
+	} >"$TRASH_DIRECTORY/ssh-expect" &&
+	(cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output)
+}
+
+setup_ssh_wrapper
+
+test_expect_success 'clone myhost:src uses ssh' '
+	git clone myhost:src ssh-clone &&
+	expect_ssh myhost src
+'
+
 test_expect_success NOT_MINGW,NOT_CYGWIN 'clone local path foo:bar' '
 	cp -R src "foo:bar" &&
-	git clone "./foo:bar" foobar
+	git clone "foo:bar" foobar &&
+	expect_ssh none
+'
+
+test_expect_success 'bracketed hostnames are still ssh' '
+	git clone "[myhost:123]:src" ssh-bracket-clone &&
+	expect_ssh myhost:123 src
+'
+
+counter=0
+# $1 url
+# $2 none|host
+# $3 path
+test_clone_url () {
+	counter=$(($counter + 1))
+	test_might_fail git clone "$1" tmp$counter &&
+	expect_ssh "$2" "$3"
+}
+
+test_expect_success NOT_MINGW 'clone c:temp is ssl' '
+	test_clone_url c:temp c temp
+'
+
+test_expect_success MINGW 'clone c:temp is dos drive' '
+	test_clone_url c:temp none
+'
+
+#ip v4
+for repo in rep rep/home/project 123
+do
+	test_expect_success "clone host:$repo" '
+		test_clone_url host:$repo host $repo
+	'
+done
+
+#ipv6
+for repo in rep rep/home/project 123
+do
+	test_expect_success "clone [::1]:$repo" '
+		test_clone_url [::1]:$repo ::1 $repo
+	'
+done
+#home directory
+test_expect_success "clone host:/~repo" '
+	test_clone_url host:/~repo host "~repo"
+'
+
+test_expect_success "clone [::1]:/~repo" '
+	test_clone_url [::1]:/~repo ::1 "~repo"
+'
+
+# Corner cases
+for url in foo/bar:baz [foo]bar/baz:qux [foo/bar]:baz
+do
+	test_expect_success "clone $url is not ssh" '
+		test_clone_url $url none
+	'
+done
+
+#with ssh:// scheme
+test_expect_success 'clone ssh://host.xz/home/user/repo' '
+	test_clone_url "ssh://host.xz/home/user/repo" host.xz "/home/user/repo"
+'
+
+# from home directory
+test_expect_success 'clone ssh://host.xz/~repo' '
+	test_clone_url "ssh://host.xz/~repo" host.xz "~repo"
+'
+
+# with port number
+test_expect_success 'clone ssh://host.xz:22/home/user/repo' '
+	test_clone_url "ssh://host.xz:22/home/user/repo" "-p 22 host.xz" "/home/user/repo"
+'
+
+# from home directory with port number
+test_expect_success 'clone ssh://host.xz:22/~repo' '
+	test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo"
+'
+
+#IPv6
+test_expect_success 'clone ssh://[::1]/home/user/repo' '
+	test_clone_url "ssh://[::1]/home/user/repo" "::1" "/home/user/repo"
+'
+
+#IPv6 from home directory
+test_expect_success 'clone ssh://[::1]/~repo' '
+	test_clone_url "ssh://[::1]/~repo" "::1" "~repo"
+'
+
+#IPv6 with port number
+test_expect_success 'clone ssh://[::1]:22/home/user/repo' '
+	test_clone_url "ssh://[::1]:22/home/user/repo" "-p 22 ::1" "/home/user/repo"
+'
+
+#IPv6 from home directory with port number
+test_expect_success 'clone ssh://[::1]:22/~repo' '
+	test_clone_url "ssh://[::1]:22/~repo" "-p 22 ::1" "~repo"
 '
 
 test_expect_success 'clone from a repository with two identical branches' '
@@ -296,4 +430,11 @@
 
 '
 
+test_expect_success 'shallow clone locally' '
+	git clone --depth=1 --no-local src ssrrcc &&
+	git clone ssrrcc ddsstt &&
+	test_cmp ssrrcc/.git/shallow ddsstt/.git/shallow &&
+	( cd ddsstt && git fsck )
+'
+
 test_done
diff --git a/t/t5800-remote-testpy.sh b/t/t5800-remote-testpy.sh
deleted file mode 100755
index 1e683d4..0000000
--- a/t/t5800-remote-testpy.sh
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010 Sverre Rabbelier
-#
-
-test_description='Test python remote-helper framework'
-
-. ./test-lib.sh
-
-if ! test_have_prereq PYTHON ; then
-	skip_all='skipping python remote-helper tests, python not available'
-	test_done
-fi
-
-"$PYTHON_PATH" -c '
-import sys
-if sys.hexversion < 0x02040000:
-    sys.exit(1)
-' || {
-	skip_all='skipping python remote-helper tests, python version < 2.4'
-	test_done
-}
-
-compare_refs() {
-	git --git-dir="$1/.git" rev-parse --verify $2 >expect &&
-	git --git-dir="$3/.git" rev-parse --verify $4 >actual &&
-	test_cmp expect actual
-}
-
-test_expect_success 'setup repository' '
-	git init --bare server/.git &&
-	git clone server public &&
-	(cd public &&
-	 echo content >file &&
-	 git add file &&
-	 git commit -m one &&
-	 git push origin master)
-'
-
-test_expect_success 'cloning from local repo' '
-	git clone "testpy::${PWD}/server" localclone &&
-	test_cmp public/file localclone/file
-'
-
-test_expect_success 'cloning from remote repo' '
-	git clone "testpy::file://${PWD}/server" clone &&
-	test_cmp public/file clone/file
-'
-
-test_expect_success 'create new commit on remote' '
-	(cd public &&
-	 echo content >>file &&
-	 git commit -a -m two &&
-	 git push)
-'
-
-test_expect_success 'pulling from local repo' '
-	(cd localclone && git pull) &&
-	test_cmp public/file localclone/file
-'
-
-test_expect_success 'pulling from remote remote' '
-	(cd clone && git pull) &&
-	test_cmp public/file clone/file
-'
-
-test_expect_success 'pushing to local repo' '
-	(cd localclone &&
-	echo content >>file &&
-	git commit -a -m three &&
-	git push) &&
-	compare_refs localclone HEAD server HEAD
-'
-
-# Generally, skip this test.  It demonstrates a now-fixed race in
-# git-remote-testpy, but is too slow to leave in for general use.
-: test_expect_success 'racily pushing to local repo' '
-	test_when_finished "rm -rf server2 localclone2" &&
-	cp -R server server2 &&
-	git clone "testpy::${PWD}/server2" localclone2 &&
-	(cd localclone2 &&
-	echo content >>file &&
-	git commit -a -m three &&
-	GIT_REMOTE_TESTGIT_SLEEPY=2 git push) &&
-	compare_refs localclone2 HEAD server2 HEAD
-'
-
-test_expect_success 'synch with changes from localclone' '
-	(cd clone &&
-	 git pull)
-'
-
-test_expect_success 'pushing remote local repo' '
-	(cd clone &&
-	echo content >>file &&
-	git commit -a -m four &&
-	git push) &&
-	compare_refs clone HEAD server HEAD
-'
-
-test_expect_success 'fetch new branch' '
-	(cd public &&
-	 git checkout -b new &&
-	 echo content >>file &&
-	 git commit -a -m five &&
-	 git push origin new
-	) &&
-	(cd localclone &&
-	 git fetch origin new
-	) &&
-	compare_refs public HEAD localclone FETCH_HEAD
-'
-
-test_expect_success 'fetch multiple branches' '
-	(cd localclone &&
-	 git fetch
-	) &&
-	compare_refs server master localclone refs/remotes/origin/master &&
-	compare_refs server new localclone refs/remotes/origin/new
-'
-
-test_expect_success 'push when remote has extra refs' '
-	(cd clone &&
-	 echo content >>file &&
-	 git commit -a -m six &&
-	 git push
-	) &&
-	compare_refs clone master server master
-'
-
-test_expect_success 'push new branch by name' '
-	(cd clone &&
-	 git checkout -b new-name  &&
-	 echo content >>file &&
-	 git commit -a -m seven &&
-	 git push origin new-name
-	) &&
-	compare_refs clone HEAD server refs/heads/new-name
-'
-
-test_expect_failure 'push new branch with old:new refspec' '
-	(cd clone &&
-	 git push origin new-name:new-refspec
-	) &&
-	compare_refs clone HEAD server refs/heads/new-refspec
-'
-
-test_expect_success 'proper failure checks for fetching' '
-	(GIT_REMOTE_TESTGIT_FAILURE=1 &&
-	export GIT_REMOTE_TESTGIT_FAILURE &&
-	cd localclone &&
-	test_must_fail git fetch 2>&1 | \
-		grep "Error while running fast-import"
-	)
-'
-
-# We sleep to give fast-export a chance to catch the SIGPIPE
-test_expect_failure 'proper failure checks for pushing' '
-	(GIT_REMOTE_TESTGIT_FAILURE=1 &&
-	export GIT_REMOTE_TESTGIT_FAILURE &&
-	GIT_REMOTE_TESTGIT_SLEEPY=1 &&
-	export GIT_REMOTE_TESTGIT_SLEEPY &&
-	cd localclone &&
-	test_must_fail git push --all 2>&1 | \
-		grep "Error while running fast-export"
-	)
-'
-
-test_done
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 8c4c539..613f69a 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -182,6 +182,17 @@
 	)
 '
 
+test_expect_success 'push update refs disabled by no-private-update' '
+	(cd local &&
+	echo more-update >>file &&
+	git commit -a -m more-update &&
+	git rev-parse --verify testgit/origin/heads/update >expect &&
+	GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE=t git push origin update &&
+	git rev-parse --verify testgit/origin/heads/update >actual &&
+	test_cmp expect actual
+	)
+'
+
 test_expect_success 'push update refs failure' '
 	(cd local &&
 	git checkout update &&
diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh
index 15e3d64..3794e4c 100755
--- a/t/t6000-rev-list-misc.sh
+++ b/t/t6000-rev-list-misc.sh
@@ -56,4 +56,21 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'propagate uninteresting flag down correctly' '
+	git rev-list --objects ^HEAD^{tree} HEAD^{tree} >actual &&
+	>expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'symleft flag bit is propagated down from tag' '
+	git log --format="%m %s" --left-right v1.0...master >actual &&
+	cat >expect <<-\EOF &&
+	> two
+	> one
+	< another
+	< that
+	EOF
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh
index f80bba8..39b3238 100755
--- a/t/t6010-merge-base.sh
+++ b/t/t6010-merge-base.sh
@@ -230,4 +230,71 @@
 	test_cmp expected.sorted actual.sorted
 '
 
+test_expect_success 'using reflog to find the fork point' '
+	git reset --hard &&
+	git checkout -b base $E &&
+
+	(
+		for count in 1 2 3
+		do
+			git commit --allow-empty -m "Base commit #$count" &&
+			git rev-parse HEAD >expect$count &&
+			git checkout -B derived &&
+			git commit --allow-empty -m "Derived #$count" &&
+			git rev-parse HEAD >derived$count &&
+			git checkout -B base $E || exit 1
+		done
+
+		for count in 1 2 3
+		do
+			git merge-base --fork-point base $(cat derived$count) >actual &&
+			test_cmp expect$count actual || exit 1
+		done
+
+	) &&
+	# check that we correctly default to HEAD
+	git checkout derived &&
+	git merge-base --fork-point base >actual &&
+	test_cmp expect3 actual
+'
+
+test_expect_success 'merge-base --octopus --all for complex tree' '
+	# Best common ancestor for JE, JAA and JDD is JC
+	#             JE
+	#            / |
+	#           /  |
+	#          /   |
+	#  JAA    /    |
+	#   |\   /     |
+	#   | \  | JDD |
+	#   |  \ |/ |  |
+	#   |   JC JD  |
+	#   |    | /|  |
+	#   |    |/ |  |
+	#  JA    |  |  |
+	#   |\  /|  |  |
+	#   X JB |  X  X
+	#   \  \ | /   /
+	#    \__\|/___/
+	#        J
+	test_commit J &&
+	test_commit JB &&
+	git reset --hard J &&
+	test_commit JC &&
+	git reset --hard J &&
+	test_commit JTEMP1 &&
+	test_merge JA JB &&
+	test_merge JAA JC &&
+	git reset --hard J &&
+	test_commit JTEMP2 &&
+	test_merge JD JB &&
+	test_merge JDD JC &&
+	git reset --hard J &&
+	test_commit JTEMP3 &&
+	test_merge JE JC &&
+	git rev-parse JC >expected &&
+	git merge-base --all --octopus JAA JDD JE >actual &&
+	test_cmp expected actual
+'
+
 test_done
diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh
index bbb0581..e51eb41 100755
--- a/t/t6011-rev-list-with-bad-commit.sh
+++ b/t/t6011-rev-list-with-bad-commit.sh
@@ -37,7 +37,7 @@
 
 test_expect_success 'corrupt second commit object' \
    '
-   "$PERL_PATH" -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack &&
+   perl -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack &&
    test_must_fail git fsck --full
    '
 
diff --git a/t/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh
index 892a537..59fc2f0 100755
--- a/t/t6013-rev-list-reverse-parents.sh
+++ b/t/t6013-rev-list-reverse-parents.sh
@@ -25,7 +25,7 @@
 
 test_expect_success '--reverse --parents --full-history combines correctly' '
 	git rev-list --parents --full-history master -- foo |
-		"$PERL_PATH" -e "print reverse <>" > expected &&
+		perl -e "print reverse <>" > expected &&
 	git rev-list --reverse --parents --full-history master -- foo \
 		> actual &&
 	test_cmp actual expected
@@ -33,7 +33,7 @@
 
 test_expect_success '--boundary does too' '
 	git rev-list --boundary --parents --full-history master ^root -- foo |
-		"$PERL_PATH" -e "print reverse <>" > expected &&
+		perl -e "print reverse <>" > expected &&
 	git rev-list --boundary --reverse --parents --full-history \
 		master ^root -- foo > actual &&
 	test_cmp actual expected
diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh
index f00cebf..d00f7db 100755
--- a/t/t6018-rev-list-glob.sh
+++ b/t/t6018-rev-list-glob.sh
@@ -129,6 +129,18 @@
 
 '
 
+test_expect_success 'rev-parse --exclude with --branches' '
+	compare rev-parse "--exclude=*/* --branches" "master someref subspace-x"
+'
+
+test_expect_success 'rev-parse --exclude with --all' '
+	compare rev-parse "--exclude=refs/remotes/* --all" "--branches --tags"
+'
+
+test_expect_success 'rev-parse accumulates multiple --exclude' '
+	compare rev-parse "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches
+'
+
 test_expect_success 'rev-list --glob=refs/heads/subspace/*' '
 
 	compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*"
@@ -231,6 +243,48 @@
 
 '
 
+test_expect_success 'rev-list --exclude with --branches' '
+	compare rev-list "--exclude=*/* --branches" "master someref subspace-x"
+'
+
+test_expect_success 'rev-list --exclude with --all' '
+	compare rev-list "--exclude=refs/remotes/* --all" "--branches --tags"
+'
+
+test_expect_success 'rev-list accumulates multiple --exclude' '
+	compare rev-list "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches
+'
+
+
+# "git rev-list<ENTER>" is likely to be a bug in the calling script and may
+# deserve an error message, but do cases where set of refs programatically
+# given using globbing and/or --stdin need to fail with the same error, or
+# are we better off reporting a success with no output?  The following few
+# tests document the current behaviour to remind us that we might want to
+# think about this issue.
+
+test_expect_failure 'rev-list may want to succeed with empty output on no input (1)' '
+	>expect &&
+	git rev-list --stdin <expect >actual &&
+	test_cmp expect actual
+'
+
+test_expect_failure 'rev-list may want to succeed with empty output on no input (2)' '
+	>expect &&
+	git rev-list --exclude=* --all >actual &&
+	test_cmp expect actual
+'
+
+test_expect_failure 'rev-list may want to succeed with empty output on no input (3)' '
+	(
+		test_create_repo empty &&
+		cd empty &&
+		>expect &&
+		git rev-list --all >actual &&
+		test_cmp expect actual
+	)
+'
+
 test_expect_success 'shortlog accepts --glob/--tags/--remotes' '
 
 	compare shortlog "subspace/one subspace/two" --branches=subspace &&
diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh
index c680f78..a89dfbe 100755
--- a/t/t6022-merge-rename.sh
+++ b/t/t6022-merge-rename.sh
@@ -259,7 +259,7 @@
 	printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file &&
 	echo foo >dir/file-in-the-way &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	echo 11 >>sub/file &&
 	echo more >>dir/file-in-the-way &&
@@ -439,7 +439,7 @@
 	mkdir one &&
 	echo stuff >one/file &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	git mv one/file destdir &&
 	git commit -m "Renamed to destdir" &&
@@ -479,7 +479,7 @@
 	echo stuff >one/file &&
 	echo other >two/file &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	git rm -rf one &&
 	git mv two/file one &&
@@ -539,7 +539,7 @@
 
 	echo stuff >original &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	mkdir two &&
 	>two/file &&
@@ -583,7 +583,7 @@
 	mkdir one two &&
 	touch one/file two/file &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	git rm -rf one &&
 	git mv original one &&
@@ -618,7 +618,7 @@
 
 	printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >original &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	git mv original rename &&
 	echo 11 >>rename &&
@@ -649,7 +649,7 @@
 	mkdir df &&
 	printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >df/file &&
 	git add -A &&
-	git commit -m "Common commmit" &&
+	git commit -m "Common commit" &&
 
 	git mv df/file temp &&
 	rm -rf df &&
diff --git a/t/t6031-merge-recursive.sh b/t/t6031-merge-recursive.sh
index 1cd649e..a953f1b 100755
--- a/t/t6031-merge-recursive.sh
+++ b/t/t6031-merge-recursive.sh
@@ -2,7 +2,6 @@
 
 test_description='merge-recursive: handle file mode'
 . ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh
 
 test_expect_success 'mode change in one branch: keep changed version' '
 	: >file1 &&
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index ec2b516..7ac8fd0 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -28,18 +28,25 @@
 		git reset --hard HEAD^ &&
 		git checkout -b b4 origin &&
 		advance e &&
-		advance f
+		advance f &&
+		git checkout -b brokenbase origin &&
+		git checkout -b b5 --track brokenbase &&
+		advance g &&
+		git branch -d brokenbase &&
+		git checkout -b b6 origin
 	) &&
 	git checkout -b follower --track master &&
-	advance g
+	advance h
 '
 
-script='s/^..\(b.\)[	 0-9a-f]*\[\([^]]*\)\].*/\1 \2/p'
+script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p'
 cat >expect <<\EOF
-b1 ahead 1, behind 1
-b2 ahead 1, behind 1
-b3 behind 1
-b4 ahead 2
+b1 [ahead 1, behind 1] d
+b2 [ahead 1, behind 1] d
+b3 [behind 1] b
+b4 [ahead 2] f
+b5 g
+b6 c
 EOF
 
 test_expect_success 'branch -v' '
@@ -52,10 +59,12 @@
 '
 
 cat >expect <<\EOF
-b1 origin/master: ahead 1, behind 1
-b2 origin/master: ahead 1, behind 1
-b3 origin/master: behind 1
-b4 origin/master: ahead 2
+b1 [origin/master: ahead 1, behind 1] d
+b2 [origin/master: ahead 1, behind 1] d
+b3 [origin/master: behind 1] b
+b4 [origin/master: ahead 2] f
+b5 [brokenbase: gone] g
+b6 [origin/master] c
 EOF
 
 test_expect_success 'branch -vv' '
@@ -67,7 +76,7 @@
 	test_i18ncmp expect actual
 '
 
-test_expect_success 'checkout' '
+test_expect_success 'checkout (diverged from upstream)' '
 	(
 		cd test && git checkout b1
 	) >actual &&
@@ -80,7 +89,22 @@
 	test_i18ngrep "is ahead of" actual
 '
 
-test_expect_success 'status' '
+test_expect_success 'checkout (upstream is gone)' '
+	(
+		cd test &&
+		git checkout b5
+	) >actual &&
+	test_i18ngrep "is based on .*, but the upstream is gone." actual
+'
+
+test_expect_success 'checkout (up-to-date with upstream)' '
+	(
+		cd test && git checkout b6
+	) >actual &&
+	test_i18ngrep "Your branch is up-to-date with .origin/master" actual
+'
+
+test_expect_success 'status (diverged from upstream)' '
 	(
 		cd test &&
 		git checkout b1 >/dev/null &&
@@ -90,6 +114,65 @@
 	test_i18ngrep "have 1 and 1 different" actual
 '
 
+test_expect_success 'status (upstream is gone)' '
+	(
+		cd test &&
+		git checkout b5 >/dev/null &&
+		# reports nothing to commit
+		test_must_fail git commit --dry-run
+	) >actual &&
+	test_i18ngrep "is based on .*, but the upstream is gone." actual
+'
+
+test_expect_success 'status (up-to-date with upstream)' '
+	(
+		cd test &&
+		git checkout b6 >/dev/null &&
+		# reports nothing to commit
+		test_must_fail git commit --dry-run
+	) >actual &&
+	test_i18ngrep "Your branch is up-to-date with .origin/master" actual
+'
+
+cat >expect <<\EOF
+## b1...origin/master [ahead 1, behind 1]
+EOF
+
+test_expect_success 'status -s -b (diverged from upstream)' '
+	(
+		cd test &&
+		git checkout b1 >/dev/null &&
+		git status -s -b | head -1
+	) >actual &&
+	test_i18ncmp expect actual
+'
+
+cat >expect <<\EOF
+## b5...brokenbase [gone]
+EOF
+
+test_expect_success 'status -s -b (upstream is gone)' '
+	(
+		cd test &&
+		git checkout b5 >/dev/null &&
+		git status -s -b | head -1
+	) >actual &&
+	test_i18ncmp expect actual
+'
+
+cat >expect <<\EOF
+## b6...origin/master
+EOF
+
+test_expect_success 'status -s -b (up-to-date with upstream)' '
+	(
+		cd test &&
+		git checkout b6 >/dev/null &&
+		git status -s -b | head -1
+	) >actual &&
+	test_i18ncmp expect actual
+'
+
 test_expect_success 'fail to track lightweight tags' '
 	git checkout master &&
 	git tag light &&
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index decdc33..719a116 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -122,9 +122,9 @@
      test "$HASH2" = "$(git replace -l)" &&
      test "$HASH2" = "$(git replace)" &&
      aa=${HASH2%??????????????????????????????????????} &&
-     test "$HASH2" = "$(git replace -l "$aa*")" &&
+     test "$HASH2" = "$(git replace --list "$aa*")" &&
      test_must_fail git replace -d $R &&
-     test_must_fail git replace -d &&
+     test_must_fail git replace --delete &&
      test_must_fail git replace -l -d $HASH2 &&
      git replace -d $HASH2 &&
      git show $HASH2 | grep "A U Thor" &&
@@ -147,7 +147,7 @@
      git show $HASH2 | grep "O Thor" &&
      test_must_fail git replace $HASH2 $R &&
      git replace -f $HASH2 $R &&
-     test_must_fail git replace -f &&
+     test_must_fail git replace --force &&
      test "$HASH2" = "$(git replace)"
 '
 
@@ -263,4 +263,65 @@
 	test_cmp file.replaced file
 '
 
+test_expect_success 'replaced and replacement objects must be of the same type' '
+	test_must_fail git replace mytag $HASH1 &&
+	test_must_fail git replace HEAD^{tree} HEAD~1 &&
+	BLOB=$(git rev-parse :file) &&
+	test_must_fail git replace HEAD^ $BLOB
+'
+
+test_expect_success '-f option bypasses the type check' '
+	git replace -f mytag $HASH1 &&
+	git replace --force HEAD^{tree} HEAD~1 &&
+	git replace -f HEAD^ $BLOB
+'
+
+test_expect_success 'git cat-file --batch works on replace objects' '
+	git replace | grep $PARA3 &&
+	echo $PARA3 | git cat-file --batch
+'
+
+test_expect_success 'test --format bogus' '
+	test_must_fail git replace --format bogus >/dev/null 2>&1
+'
+
+test_expect_success 'test --format short' '
+	git replace --format=short >actual &&
+	git replace >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'test --format medium' '
+	H1=$(git --no-replace-objects rev-parse HEAD~1) &&
+	HT=$(git --no-replace-objects rev-parse HEAD^{tree}) &&
+	MYTAG=$(git --no-replace-objects rev-parse mytag) &&
+	{
+		echo "$H1 -> $BLOB" &&
+		echo "$BLOB -> $REPLACED" &&
+		echo "$HT -> $H1" &&
+		echo "$PARA3 -> $S" &&
+		echo "$MYTAG -> $HASH1"
+	} | sort >expected &&
+	git replace -l --format medium | sort > actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'test --format long' '
+	{
+		echo "$H1 (commit) -> $BLOB (blob)" &&
+		echo "$BLOB (blob) -> $REPLACED (blob)" &&
+		echo "$HT (tree) -> $H1 (commit)" &&
+		echo "$PARA3 (commit) -> $S (commit)" &&
+		echo "$MYTAG (tag) -> $HASH1 (commit)"
+	} | sort >expected &&
+	git replace --format=long | sort > actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'replace ref cleanup' '
+	test -n "$(git replace)" &&
+	git replace -d $(git replace) &&
+	test -z "$(git replace)"
+'
+
 test_done
diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh
index e673c25..10b1452 100755
--- a/t/t6101-rev-parse-parents.sh
+++ b/t/t6101-rev-parse-parents.sh
@@ -6,39 +6,100 @@
 test_description='Test git rev-parse with different parent options'
 
 . ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions
 
-date >path0
-git update-index --add path0
-save_tag tree git write-tree
-hide_error save_tag start unique_commit "start" tree
-save_tag second unique_commit "second" tree -p start
-hide_error save_tag start2 unique_commit "start2" tree
-save_tag two_parents unique_commit "next" tree -p second -p start2
-save_tag final unique_commit "final" tree -p two_parents
+test_cmp_rev_output () {
+	git rev-parse --verify "$1" >expect &&
+	eval "$2" >actual &&
+	test_cmp expect actual
+}
 
-test_expect_success 'start is valid' 'git rev-parse start | grep "^[0-9a-f]\{40\}$"'
-test_expect_success 'start^0' "test $(cat .git/refs/tags/start) = $(git rev-parse start^0)"
-test_expect_success 'start^1 not valid' "if git rev-parse --verify start^1; then false; else :; fi"
-test_expect_success 'second^1 = second^' "test $(git rev-parse second^1) = $(git rev-parse second^)"
-test_expect_success 'final^1^1^1' "test $(git rev-parse start) = $(git rev-parse final^1^1^1)"
-test_expect_success 'final^1^1^1 = final^^^' "test $(git rev-parse final^1^1^1) = $(git rev-parse final^^^)"
-test_expect_success 'final^1^2' "test $(git rev-parse start2) = $(git rev-parse final^1^2)"
-test_expect_success 'final^1^2 != final^1^1' "test $(git rev-parse final^1^2) != $(git rev-parse final^1^1)"
-test_expect_success 'final^1^3 not valid' "if git rev-parse --verify final^1^3; then false; else :; fi"
-test_expect_success '--verify start2^1' 'test_must_fail git rev-parse --verify start2^1'
-test_expect_success '--verify start2^0' 'git rev-parse --verify start2^0'
-test_expect_success 'final^1^@ = final^1^1 final^1^2' "test \"$(git rev-parse final^1^@)\" = \"$(git rev-parse final^1^1 final^1^2)\""
-test_expect_success 'final^1^! = final^1 ^final^1^1 ^final^1^2' "test \"$(git rev-parse final^1^\!)\" = \"$(git rev-parse final^1 ^final^1^1 ^final^1^2)\""
+test_expect_success 'setup' '
+	test_commit start &&
+	test_commit second &&
+	git checkout --orphan tmp &&
+	test_commit start2 &&
+	git checkout master &&
+	git merge -m next start2 &&
+	test_commit final &&
 
-test_expect_success 'repack for next test' 'git repack -a -d'
+	test_seq 40 |
+	while read i
+	do
+		git checkout --orphan "b$i" &&
+		test_tick &&
+		git commit --allow-empty -m "$i" &&
+		commit=$(git rev-parse --verify HEAD) &&
+		printf "$commit " >>.git/info/grafts
+	done
+'
+
+test_expect_success 'start is valid' '
+	git rev-parse start | grep "^[0-9a-f]\{40\}$"
+'
+
+test_expect_success 'start^0' '
+	test_cmp_rev_output tags/start "git rev-parse start^0"
+'
+
+test_expect_success 'start^1 not valid' '
+	test_must_fail git rev-parse --verify start^1
+'
+
+test_expect_success 'second^1 = second^' '
+	test_cmp_rev_output second^ "git rev-parse second^1"
+'
+
+test_expect_success 'final^1^1^1' '
+	test_cmp_rev_output start "git rev-parse final^1^1^1"
+'
+
+test_expect_success 'final^1^1^1 = final^^^' '
+	test_cmp_rev_output final^^^ "git rev-parse final^1^1^1"
+'
+
+test_expect_success 'final^1^2' '
+	test_cmp_rev_output start2 "git rev-parse final^1^2"
+'
+
+test_expect_success 'final^1^2 != final^1^1' '
+	test $(git rev-parse final^1^2) != $(git rev-parse final^1^1)
+'
+
+test_expect_success 'final^1^3 not valid' '
+	test_must_fail git rev-parse --verify final^1^3
+'
+
+test_expect_success '--verify start2^1' '
+	test_must_fail git rev-parse --verify start2^1
+'
+
+test_expect_success '--verify start2^0' '
+	git rev-parse --verify start2^0
+'
+
+test_expect_success 'final^1^@ = final^1^1 final^1^2' '
+	git rev-parse final^1^1 final^1^2 >expect &&
+	git rev-parse final^1^@ >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'final^1^! = final^1 ^final^1^1 ^final^1^2' '
+	git rev-parse final^1 ^final^1^1 ^final^1^2 >expect &&
+	git rev-parse final^1^! >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'large graft octopus' '
+	test_cmp_rev_output b31 "git rev-parse --verify b1^30"
+'
+
+test_expect_success 'repack for next test' '
+	git repack -a -d
+'
+
 test_expect_success 'short SHA-1 works' '
-	start=`git rev-parse --verify start` &&
-	echo $start &&
-	abbrv=`echo $start | sed s/.\$//` &&
-	echo $abbrv &&
-	abbrv=`git rev-parse --verify $abbrv` &&
-	echo $abbrv &&
-	test $start = $abbrv'
+	start=$(git rev-parse --verify start) &&
+	test_cmp_rev_output start "git rev-parse ${start%?}"
+'
 
 test_done
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
index 39ef619..6583532 100755
--- a/t/t6130-pathspec-noglob.sh
+++ b/t/t6130-pathspec-noglob.sh
@@ -32,6 +32,16 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'star pathspec globs' '
+	cat >expect <<-\EOF &&
+	bracket
+	star
+	vanilla
+	EOF
+	git log --format=%s -- ":(glob)f*" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'bracket pathspec globs and matches literal brackets' '
 	cat >expect <<-\EOF &&
 	bracket
@@ -41,28 +51,112 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'bracket pathspec globs and matches literal brackets' '
+	cat >expect <<-\EOF &&
+	bracket
+	vanilla
+	EOF
+	git log --format=%s -- ":(glob)f[o][o]" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'no-glob option matches literally (vanilla)' '
 	echo vanilla >expect &&
 	git --literal-pathspecs log --format=%s -- foo >actual &&
 	test_cmp expect actual
 '
 
+test_expect_success 'no-glob option matches literally (vanilla)' '
+	echo vanilla >expect &&
+	git log --format=%s -- ":(literal)foo" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'no-glob option matches literally (star)' '
 	echo star >expect &&
 	git --literal-pathspecs log --format=%s -- "f*" >actual &&
 	test_cmp expect actual
 '
 
+test_expect_success 'no-glob option matches literally (star)' '
+	echo star >expect &&
+	git log --format=%s -- ":(literal)f*" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'no-glob option matches literally (bracket)' '
 	echo bracket >expect &&
 	git --literal-pathspecs log --format=%s -- "f[o][o]" >actual &&
 	test_cmp expect actual
 '
 
+test_expect_success 'no-glob option matches literally (bracket)' '
+	echo bracket >expect &&
+	git log --format=%s -- ":(literal)f[o][o]" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'no-glob option disables :(literal)' '
+	: >expect &&
+	git --literal-pathspecs log --format=%s -- ":(literal)foo" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'no-glob environment variable works' '
 	echo star >expect &&
 	GIT_LITERAL_PATHSPECS=1 git log --format=%s -- "f*" >actual &&
 	test_cmp expect actual
 '
 
+test_expect_success 'blame takes global pathspec flags' '
+	git --literal-pathspecs blame -- foo &&
+	git --icase-pathspecs   blame -- foo &&
+	git --glob-pathspecs    blame -- foo &&
+	git --noglob-pathspecs  blame -- foo
+'
+
+test_expect_success 'setup xxx/bar' '
+	mkdir xxx &&
+	test_commit xxx xxx/bar
+'
+
+test_expect_success '**/ works with :(glob)' '
+	cat >expect <<-\EOF &&
+	xxx
+	unrelated
+	EOF
+	git log --format=%s -- ":(glob)**/bar" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '**/ does not work with --noglob-pathspecs' '
+	: >expect &&
+	git --noglob-pathspecs log --format=%s -- "**/bar" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '**/ works with :(glob) and --noglob-pathspecs' '
+	cat >expect <<-\EOF &&
+	xxx
+	unrelated
+	EOF
+	git --noglob-pathspecs log --format=%s -- ":(glob)**/bar" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '**/ works with --glob-pathspecs' '
+	cat >expect <<-\EOF &&
+	xxx
+	unrelated
+	EOF
+	git --glob-pathspecs log --format=%s -- "**/bar" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '**/ does not work with :(literal) and --glob-pathspecs' '
+	: >expect &&
+	git --glob-pathspecs log --format=%s -- ":(literal)**/bar" >actual &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t6131-pathspec-icase.sh b/t/t6131-pathspec-icase.sh
new file mode 100755
index 0000000..a7c7ff5
--- /dev/null
+++ b/t/t6131-pathspec-icase.sh
@@ -0,0 +1,109 @@
+#!/bin/sh
+
+test_description='test case insensitive pathspec limiting'
+. ./test-lib.sh
+
+if test_have_prereq CASE_INSENSITIVE_FS
+then
+	skip_all='skipping case sensitive tests - case insensitive file system'
+	test_done
+fi
+
+test_expect_success 'create commits with glob characters' '
+	test_commit bar bar &&
+	test_commit bAr bAr &&
+	test_commit BAR BAR &&
+	mkdir foo &&
+	test_commit foo/bar foo/bar &&
+	test_commit foo/bAr foo/bAr &&
+	test_commit foo/BAR foo/BAR &&
+	mkdir fOo &&
+	test_commit fOo/bar fOo/bar &&
+	test_commit fOo/bAr fOo/bAr &&
+	test_commit fOo/BAR fOo/BAR &&
+	mkdir FOO &&
+	test_commit FOO/bar FOO/bar &&
+	test_commit FOO/bAr FOO/bAr &&
+	test_commit FOO/BAR FOO/BAR
+'
+
+test_expect_success 'tree_entry_interesting matches bar' '
+	echo bar >expect &&
+	git log --format=%s -- "bar" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'tree_entry_interesting matches :(icase)bar' '
+	cat <<-EOF >expect &&
+	BAR
+	bAr
+	bar
+	EOF
+	git log --format=%s -- ":(icase)bar" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'tree_entry_interesting matches :(icase)bar with prefix' '
+	cat <<-EOF >expect &&
+	fOo/BAR
+	fOo/bAr
+	fOo/bar
+	EOF
+	( cd fOo && git log --format=%s -- ":(icase)bar" ) >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'tree_entry_interesting matches :(icase)bar with empty prefix' '
+	cat <<-EOF >expect &&
+	FOO/BAR
+	FOO/bAr
+	FOO/bar
+	fOo/BAR
+	fOo/bAr
+	fOo/bar
+	foo/BAR
+	foo/bAr
+	foo/bar
+	EOF
+	( cd fOo && git log --format=%s -- ":(icase)../foo/bar" ) >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'match_pathspec_depth matches :(icase)bar' '
+	cat <<-EOF >expect &&
+	BAR
+	bAr
+	bar
+	EOF
+	git ls-files ":(icase)bar" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'match_pathspec_depth matches :(icase)bar with prefix' '
+	cat <<-EOF >expect &&
+	fOo/BAR
+	fOo/bAr
+	fOo/bar
+	EOF
+	( cd fOo && git ls-files --full-name ":(icase)bar" ) >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'match_pathspec_depth matches :(icase)bar with empty prefix' '
+	cat <<-EOF >expect &&
+	bar
+	fOo/BAR
+	fOo/bAr
+	fOo/bar
+	EOF
+	( cd fOo && git ls-files --full-name ":(icase)bar" ../bar ) >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '"git diff" can take magic :(icase) pathspec' '
+	echo FOO/BAR >expect &&
+	git diff --name-only HEAD^ HEAD -- ":(icase)foo/bar" >actual &&
+	test_cmp expect actual
+'
+
+test_done
diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh
new file mode 100755
index 0000000..62049be
--- /dev/null
+++ b/t/t6132-pathspec-exclude.sh
@@ -0,0 +1,184 @@
+#!/bin/sh
+
+test_description='test case exclude pathspec'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	for p in file sub/file sub/sub/file sub/file2 sub/sub/sub/file sub2/file; do
+		if echo $p | grep /; then
+			mkdir -p `dirname $p`
+		fi &&
+		: >$p &&
+		git add $p &&
+		git commit -m $p
+	done &&
+	git log --oneline --format=%s >actual &&
+	cat <<EOF >expect &&
+sub2/file
+sub/sub/sub/file
+sub/file2
+sub/sub/file
+sub/file
+file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'exclude only should error out' '
+	test_must_fail git log --oneline --format=%s -- ":(exclude)sub"
+'
+
+test_expect_success 't_e_i() exclude sub' '
+	git log --oneline --format=%s -- . ":(exclude)sub" >actual
+	cat <<EOF >expect &&
+sub2/file
+file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 't_e_i() exclude sub/sub/file' '
+	git log --oneline --format=%s -- . ":(exclude)sub/sub/file" >actual
+	cat <<EOF >expect &&
+sub2/file
+sub/sub/sub/file
+sub/file2
+sub/file
+file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 't_e_i() exclude sub using mnemonic' '
+	git log --oneline --format=%s -- . ":!sub" >actual
+	cat <<EOF >expect &&
+sub2/file
+file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 't_e_i() exclude :(icase)SUB' '
+	git log --oneline --format=%s -- . ":(exclude,icase)SUB" >actual
+	cat <<EOF >expect &&
+sub2/file
+file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 't_e_i() exclude sub2 from sub' '
+	(
+	cd sub &&
+	git log --oneline --format=%s -- :/ ":/!sub2" >actual
+	cat <<EOF >expect &&
+sub/sub/sub/file
+sub/file2
+sub/sub/file
+sub/file
+file
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 't_e_i() exclude sub/*file' '
+	git log --oneline --format=%s -- . ":(exclude)sub/*file" >actual
+	cat <<EOF >expect &&
+sub2/file
+sub/file2
+file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 't_e_i() exclude :(glob)sub/*/file' '
+	git log --oneline --format=%s -- . ":(exclude,glob)sub/*/file" >actual
+	cat <<EOF >expect &&
+sub2/file
+sub/sub/sub/file
+sub/file2
+sub/file
+file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'm_p_d() exclude sub' '
+	git ls-files -- . ":(exclude)sub" >actual
+	cat <<EOF >expect &&
+file
+sub2/file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'm_p_d() exclude sub/sub/file' '
+	git ls-files -- . ":(exclude)sub/sub/file" >actual
+	cat <<EOF >expect &&
+file
+sub/file
+sub/file2
+sub/sub/sub/file
+sub2/file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'm_p_d() exclude sub using mnemonic' '
+	git ls-files -- . ":!sub" >actual
+	cat <<EOF >expect &&
+file
+sub2/file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'm_p_d() exclude :(icase)SUB' '
+	git ls-files -- . ":(exclude,icase)SUB" >actual
+	cat <<EOF >expect &&
+file
+sub2/file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'm_p_d() exclude sub2 from sub' '
+	(
+	cd sub &&
+	git ls-files -- :/ ":/!sub2" >actual
+	cat <<EOF >expect &&
+../file
+file
+file2
+sub/file
+sub/sub/file
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'm_p_d() exclude sub/*file' '
+	git ls-files -- . ":(exclude)sub/*file" >actual
+	cat <<EOF >expect &&
+file
+sub/file2
+sub2/file
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'm_p_d() exclude :(glob)sub/*/file' '
+	git ls-files -- . ":(exclude,glob)sub/*/file" >actual
+	cat <<EOF >expect &&
+file
+sub/file
+sub/file2
+sub/sub/sub/file
+sub2/file
+EOF
+	test_cmp expect actual
+'
+
+test_done
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 752f5cb..bda354c 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -18,16 +18,13 @@
     export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
 }
 
-test_expect_success 'Create sample commit with known timestamp' '
+test_expect_success setup '
 	setdate_and_increment &&
 	echo "Using $datestamp" > one &&
 	git add one &&
 	git commit -m "Initial" &&
 	setdate_and_increment &&
-	git tag -a -m "Tagging at $datestamp" testtag
-'
-
-test_expect_success 'Create upstream config' '
+	git tag -a -m "Tagging at $datestamp" testtag &&
 	git update-ref refs/remotes/origin/master master &&
 	git remote add origin nowhere &&
 	git config branch.master.remote origin &&
@@ -52,12 +49,14 @@
 test_atom head upstream refs/remotes/origin/master
 test_atom head objecttype commit
 test_atom head objectsize 171
-test_atom head objectname 67a36f10722846e891fbada1ba48ed035de75581
-test_atom head tree 0e51c00fcb93dffc755546f27593d511e1bdb46f
+test_atom head objectname $(git rev-parse refs/heads/master)
+test_atom head tree $(git rev-parse refs/heads/master^{tree})
 test_atom head parent ''
 test_atom head numparent 0
 test_atom head object ''
 test_atom head type ''
+test_atom head '*objectname' ''
+test_atom head '*objecttype' ''
 test_atom head author 'A U Thor <author@example.com> 1151939924 +0200'
 test_atom head authorname 'A U Thor'
 test_atom head authoremail '<author@example.com>'
@@ -80,17 +79,20 @@
 test_atom head contents:signature ''
 test_atom head contents 'Initial
 '
+test_atom head HEAD '*'
 
 test_atom tag refname refs/tags/testtag
 test_atom tag upstream ''
 test_atom tag objecttype tag
 test_atom tag objectsize 154
-test_atom tag objectname 98b46b1d36e5b07909de1b3886224e3e81e87322
+test_atom tag objectname $(git rev-parse refs/tags/testtag)
 test_atom tag tree ''
 test_atom tag parent ''
 test_atom tag numparent ''
-test_atom tag object '67a36f10722846e891fbada1ba48ed035de75581'
+test_atom tag object $(git rev-parse refs/tags/testtag^0)
 test_atom tag type 'commit'
+test_atom tag '*objectname' '67a36f10722846e891fbada1ba48ed035de75581'
+test_atom tag '*objecttype' 'commit'
 test_atom tag author ''
 test_atom tag authorname ''
 test_atom tag authoremail ''
@@ -113,6 +115,7 @@
 test_atom tag contents:signature ''
 test_atom tag contents 'Tagging at 1151939927
 '
+test_atom tag HEAD ' '
 
 test_expect_success 'Check invalid atoms names are errors' '
 	test_must_fail git for-each-ref --format="%(INVALID)" refs/heads
@@ -304,8 +307,35 @@
 	test_cmp expected actual
 '
 
+test_expect_success 'setup for upstream:track[short]' '
+	test_commit two
+'
+
 cat >expected <<EOF
-67a36f1
+[ahead 1]
+EOF
+
+test_expect_success 'Check upstream:track format' '
+	git for-each-ref --format="%(upstream:track)" refs/heads >actual &&
+	test_cmp expected actual
+'
+
+cat >expected <<EOF
+>
+EOF
+
+test_expect_success 'Check upstream:trackshort format' '
+	git for-each-ref --format="%(upstream:trackshort)" refs/heads >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'Check that :track[short] cannot be used with other atoms' '
+	test_must_fail git for-each-ref --format="%(refname:track)" 2>/dev/null &&
+	test_must_fail git for-each-ref --format="%(refname:trackshort)" 2>/dev/null
+'
+
+cat >expected <<EOF
+$(git rev-parse --short HEAD)
 EOF
 
 test_expect_success 'Check short objectname format' '
@@ -317,6 +347,23 @@
 	test_must_fail git for-each-ref --format="%(refname:INVALID)"
 '
 
+get_color ()
+{
+	git config --get-color no.such.slot "$1"
+}
+
+cat >expected <<EOF
+$(git rev-parse --short refs/heads/master) $(get_color green)master$(get_color reset)
+$(git rev-parse --short refs/remotes/origin/master) $(get_color green)origin/master$(get_color reset)
+$(git rev-parse --short refs/tags/testtag) $(get_color green)testtag$(get_color reset)
+$(git rev-parse --short refs/tags/two) $(get_color green)two$(get_color reset)
+EOF
+
+test_expect_success 'Check %(color:...) ' '
+	git for-each-ref --format="%(objectname:short) %(color:green)%(refname:short)" >actual &&
+	test_cmp expected actual
+'
+
 cat >expected <<\EOF
 heads/master
 tags/master
@@ -456,9 +503,9 @@
 body contents
 $sig"
 
-cat >expected <<\EOF
-408fe76d02a785a006c2e9c669b7be5589ede96d <committer@example.com> refs/tags/master
-90b5ebede4899eda64893bc2a4c8f1d6fb6dfc40 <committer@example.com> refs/tags/bogo
+cat >expected <<EOF
+$(git rev-parse refs/tags/master) <committer@example.com> refs/tags/master
+$(git rev-parse refs/tags/bogo) <committer@example.com> refs/tags/bogo
 EOF
 
 test_expect_success 'Verify sort with multiple keys' '
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index b1a6365..63194d8 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -9,6 +9,11 @@
 	git gc
 '
 
+test_expect_success 'gc does not leave behind pid file' '
+	git gc &&
+	test_path_is_missing .git/gc.pid
+'
+
 test_expect_success 'gc --gobbledegook' '
 	test_expect_code 129 git gc --nonsense 2>err &&
 	test_i18ngrep "[Uu]sage: git gc" err
diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh
index 101816e..e3c8c2c 100755
--- a/t/t7001-mv.sh
+++ b/t/t7001-mv.sh
@@ -70,6 +70,35 @@
 rm -f idontexist untracked1 untracked2 \
      path0/idontexist path0/untracked1 path0/untracked2 \
      .git/index.lock
+rmdir path1
+
+test_expect_success \
+    'moving to absent target with trailing slash' \
+    'test_must_fail git mv path0/COPYING no-such-dir/ &&
+     test_must_fail git mv path0/COPYING no-such-dir// &&
+     git mv path0/ no-such-dir/ &&
+     test_path_is_dir no-such-dir'
+
+test_expect_success \
+    'clean up' \
+    'git reset --hard'
+
+test_expect_success \
+    'moving to existing untracked target with trailing slash' \
+    'mkdir path1 &&
+     git mv path0/ path1/ &&
+     test_path_is_dir path1/path0/'
+
+test_expect_success \
+    'moving to existing tracked target with trailing slash' \
+    'mkdir path2 &&
+     >path2/file && git add path2/file &&
+     git mv path1/path0/ path2/ &&
+     test_path_is_dir path2/path0/'
+
+test_expect_success \
+    'clean up' \
+    'git reset --hard'
 
 test_expect_success \
     'adding another file' \
@@ -259,4 +288,179 @@
 
 rm -f moved symlink
 
+test_expect_success 'setup submodule' '
+	git commit -m initial &&
+	git reset --hard &&
+	git submodule add ./. sub &&
+	echo content >file &&
+	git add file &&
+	git commit -m "added sub and file"
+'
+
+test_expect_success 'git mv cannot move a submodule in a file' '
+	test_must_fail git mv sub file
+'
+
+test_expect_success 'git mv moves a submodule with a .git directory and no .gitmodules' '
+	entry="$(git ls-files --stage sub | cut -f 1)" &&
+	git rm .gitmodules &&
+	(
+		cd sub &&
+		rm -f .git &&
+		cp -a ../.git/modules/sub .git &&
+		GIT_WORK_TREE=. git config --unset core.worktree
+	) &&
+	mkdir mod &&
+	git mv sub mod/sub &&
+	! test -e sub &&
+	[ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
+	(
+		cd mod/sub &&
+		git status
+	) &&
+	git update-index --refresh &&
+	git diff-files --quiet
+'
+
+test_expect_success 'git mv moves a submodule with a .git directory and .gitmodules' '
+	rm -rf mod &&
+	git reset --hard &&
+	git submodule update &&
+	entry="$(git ls-files --stage sub | cut -f 1)" &&
+	(
+		cd sub &&
+		rm -f .git &&
+		cp -a ../.git/modules/sub .git &&
+		GIT_WORK_TREE=. git config --unset core.worktree
+	) &&
+	mkdir mod &&
+	git mv sub mod/sub &&
+	! test -e sub &&
+	[ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
+	(
+		cd mod/sub &&
+		git status
+	) &&
+	echo mod/sub >expected &&
+	git config -f .gitmodules submodule.sub.path >actual &&
+	test_cmp expected actual &&
+	git update-index --refresh &&
+	git diff-files --quiet
+'
+
+test_expect_success 'git mv moves a submodule with gitfile' '
+	rm -rf mod/sub &&
+	git reset --hard &&
+	git submodule update &&
+	entry="$(git ls-files --stage sub | cut -f 1)" &&
+	(
+		cd mod &&
+		git mv ../sub/ .
+	) &&
+	! test -e sub &&
+	[ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
+	(
+		cd mod/sub &&
+		git status
+	) &&
+	echo mod/sub >expected &&
+	git config -f .gitmodules submodule.sub.path >actual &&
+	test_cmp expected actual &&
+	git update-index --refresh &&
+	git diff-files --quiet
+'
+
+test_expect_success 'mv does not complain when no .gitmodules file is found' '
+	rm -rf mod/sub &&
+	git reset --hard &&
+	git submodule update &&
+	git rm .gitmodules &&
+	entry="$(git ls-files --stage sub | cut -f 1)" &&
+	git mv sub mod/sub 2>actual.err &&
+	! test -s actual.err &&
+	! test -e sub &&
+	[ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
+	(
+		cd mod/sub &&
+		git status
+	) &&
+	git update-index --refresh &&
+	git diff-files --quiet
+'
+
+test_expect_success 'mv will error out on a modified .gitmodules file unless staged' '
+	rm -rf mod/sub &&
+	git reset --hard &&
+	git submodule update &&
+	git config -f .gitmodules foo.bar true &&
+	entry="$(git ls-files --stage sub | cut -f 1)" &&
+	test_must_fail git mv sub mod/sub 2>actual.err &&
+	test -s actual.err &&
+	test -e sub &&
+	git diff-files --quiet -- sub &&
+	git add .gitmodules &&
+	git mv sub mod/sub 2>actual.err &&
+	! test -s actual.err &&
+	! test -e sub &&
+	[ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
+	(
+		cd mod/sub &&
+		git status
+	) &&
+	git update-index --refresh &&
+	git diff-files --quiet
+'
+
+test_expect_success 'mv issues a warning when section is not found in .gitmodules' '
+	rm -rf mod/sub &&
+	git reset --hard &&
+	git submodule update &&
+	git config -f .gitmodules --remove-section submodule.sub &&
+	git add .gitmodules &&
+	entry="$(git ls-files --stage sub | cut -f 1)" &&
+	echo "warning: Could not find section in .gitmodules where path=sub" >expect.err &&
+	git mv sub mod/sub 2>actual.err &&
+	test_i18ncmp expect.err actual.err &&
+	! test -e sub &&
+	[ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
+	(
+		cd mod/sub &&
+		git status
+	) &&
+	git update-index --refresh &&
+	git diff-files --quiet
+'
+
+test_expect_success 'mv --dry-run does not touch the submodule or .gitmodules' '
+	rm -rf mod/sub &&
+	git reset --hard &&
+	git submodule update &&
+	git mv -n sub mod/sub 2>actual.err &&
+	test -f sub/.git &&
+	git diff-index --exit-code HEAD &&
+	git update-index --refresh &&
+	git diff-files --quiet -- sub .gitmodules
+'
+
+test_expect_success 'checking out a commit before submodule moved needs manual updates' '
+	git mv sub sub2 &&
+	git commit -m "moved sub to sub2" &&
+	git checkout -q HEAD^ 2>actual &&
+	echo "warning: unable to rmdir sub2: Directory not empty" >expected &&
+	test_i18ncmp expected actual &&
+	git status -s sub2 >actual &&
+	echo "?? sub2/" >expected &&
+	test_cmp expected actual &&
+	! test -f sub/.git &&
+	test -f sub2/.git &&
+	git submodule update &&
+	test -f sub/.git &&
+	rm -rf sub2 &&
+	git diff-index --exit-code HEAD &&
+	git update-index --refresh &&
+	git diff-files --quiet -- sub .gitmodules &&
+	git status -s sub2 >actual &&
+	! test -s actual
+'
+
 test_done
diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh
index ff25908..7fe3367 100755
--- a/t/t7006-pager.sh
+++ b/t/t7006-pager.sh
@@ -37,6 +37,18 @@
 	test_cmp expected actual
 '
 
+test_expect_success TTY 'LESS and LV envvars are set for pagination' '
+	(
+		sane_unset LESS LV &&
+		PAGER="env >pager-env.out" &&
+		export PAGER &&
+
+		test_terminal git log
+	) &&
+	grep ^LESS= pager-env.out &&
+	grep ^LV= pager-env.out
+'
+
 test_expect_success TTY 'some commands do not use a pager' '
 	rm -f paginated.out &&
 	test_terminal git rev-list HEAD &&
diff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh
index 26f8319..b146406 100755
--- a/t/t7008-grep-binary.sh
+++ b/t/t7008-grep-binary.sh
@@ -145,4 +145,35 @@
 	test_cmp expect actual
 '
 
+cat >nul_to_q_textconv <<'EOF'
+#!/bin/sh
+"$PERL_PATH" -pe 'y/\000/Q/' < "$1"
+EOF
+chmod +x nul_to_q_textconv
+
+test_expect_success 'setup textconv filters' '
+	echo a diff=foo >.gitattributes &&
+	git config diff.foo.textconv "\"$(pwd)\""/nul_to_q_textconv
+'
+
+test_expect_success 'grep does not honor textconv' '
+	test_must_fail git grep Qfile
+'
+
+test_expect_success 'grep --textconv honors textconv' '
+	echo "a:binaryQfile" >expect &&
+	git grep --textconv Qfile >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'grep --no-textconv does not honor textconv' '
+	test_must_fail git grep --no-textconv Qfile
+'
+
+test_expect_success 'grep --textconv blob honors textconv' '
+	echo "HEAD:a:binaryQfile" >expect &&
+	git grep --textconv Qfile HEAD:a >actual &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t7009-filter-branch-null-sha1.sh b/t/t7009-filter-branch-null-sha1.sh
new file mode 100755
index 0000000..a997f7a
--- /dev/null
+++ b/t/t7009-filter-branch-null-sha1.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='filter-branch removal of trees with null sha1'
+. ./test-lib.sh
+
+test_expect_success 'setup: base commits' '
+	test_commit one &&
+	test_commit two &&
+	test_commit three
+'
+
+test_expect_success 'setup: a commit with a bogus null sha1 in the tree' '
+	{
+		git ls-tree HEAD &&
+		printf "160000 commit $_z40\\tbroken\\n"
+	} >broken-tree
+	echo "add broken entry" >msg &&
+
+	tree=$(git mktree <broken-tree) &&
+	test_tick &&
+	commit=$(git commit-tree $tree -p HEAD <msg) &&
+	git update-ref HEAD "$commit"
+'
+
+# we have to make one more commit on top removing the broken
+# entry, since otherwise our index does not match HEAD (and filter-branch will
+# complain). We could make the index match HEAD, but doing so would involve
+# writing a null sha1 into the index.
+test_expect_success 'setup: bring HEAD and index in sync' '
+	test_tick &&
+	git commit -a -m "back to normal"
+'
+
+test_expect_success 'filter commands are still checked' '
+	test_must_fail git filter-branch \
+		--force --prune-empty \
+		--index-filter "git rm --cached --ignore-unmatch three.t"
+'
+
+test_expect_success 'removing the broken entry works' '
+	echo three >expect &&
+	git filter-branch \
+		--force --prune-empty \
+		--index-filter "git rm --cached --ignore-unmatch broken" &&
+	git log -1 --format=%s >actual &&
+	test_cmp expect actual
+'
+
+test_done
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index 52ef06b..7d467c0 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -29,20 +29,19 @@
 	test_cmp expect actual
 '
 
-cat >expect <<EOF
-# On branch side
-# You have unmerged paths.
-#   (fix conflicts and run "git commit")
-#
-# Unmerged paths:
-#   (use "git add/rm <file>..." as appropriate to mark resolution)
-#
-#	deleted by us:      foo
-#
+test_expect_success 'M/D conflict does not segfault' '
+	cat >expect <<EOF &&
+On branch side
+You have unmerged paths.
+  (fix conflicts and run "git commit")
+
+Unmerged paths:
+  (use "git add/rm <file>..." as appropriate to mark resolution)
+
+	deleted by us:      foo
+
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
-
-test_expect_success 'M/D conflict does not segfault' '
 	mkdir mdconflict &&
 	(
 		cd mdconflict &&
@@ -135,19 +134,19 @@
 	test_commit on_second main.txt on_second &&
 	test_commit master conflict.txt master &&
 	test_must_fail git merge second_branch &&
-	cat >expected <<-\EOF &&
-	# On branch master
-	# You have unmerged paths.
-	#   (fix conflicts and run "git commit")
-	#
-	# Unmerged paths:
-	#   (use "git add/rm <file>..." as appropriate to mark resolution)
-	#
-	#	both added:         conflict.txt
-	#	deleted by them:    main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<\EOF &&
+On branch master
+You have unmerged paths.
+  (fix conflicts and run "git commit")
+
+Unmerged paths:
+  (use "git add/rm <file>..." as appropriate to mark resolution)
+
+	both added:         conflict.txt
+	deleted by them:    main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -168,20 +167,20 @@
 
 test_expect_success 'status when conflicts with add and rm advice (both deleted)' '
 	test_must_fail git merge conflict &&
-	cat >expected <<-\EOF &&
-	# On branch conflict_second
-	# You have unmerged paths.
-	#   (fix conflicts and run "git commit")
-	#
-	# Unmerged paths:
-	#   (use "git add/rm <file>..." as appropriate to mark resolution)
-	#
-	#	both deleted:       main.txt
-	#	added by them:      sub_master.txt
-	#	added by us:        sub_second.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<\EOF &&
+On branch conflict_second
+You have unmerged paths.
+  (fix conflicts and run "git commit")
+
+Unmerged paths:
+  (use "git add/rm <file>..." as appropriate to mark resolution)
+
+	both deleted:       main.txt
+	added by them:      sub_master.txt
+	added by us:        sub_second.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -192,22 +191,22 @@
 	test_must_fail git merge conflict &&
 	git add sub_master.txt &&
 	git add sub_second.txt &&
-	cat >expected <<-\EOF &&
-	# On branch conflict_second
-	# You have unmerged paths.
-	#   (fix conflicts and run "git commit")
-	#
-	# Changes to be committed:
-	#
-	#	new file:   sub_master.txt
-	#
-	# Unmerged paths:
-	#   (use "git rm <file>..." to mark resolution)
-	#
-	#	both deleted:       main.txt
-	#
-	# Untracked files not listed (use -u option to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+On branch conflict_second
+You have unmerged paths.
+  (fix conflicts and run "git commit")
+
+Changes to be committed:
+
+	new file:   sub_master.txt
+
+Unmerged paths:
+  (use "git rm <file>..." to mark resolution)
+
+	both deleted:       main.txt
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual &&
 	git reset --hard &&
diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh
index 95fab20..98b7d7b 100755
--- a/t/t7105-reset-patch.sh
+++ b/t/t7105-reset-patch.sh
@@ -25,15 +25,17 @@
 '
 
 test_expect_success PERL 'git reset -p' '
-	(echo n; echo y) | git reset -p &&
+	(echo n; echo y) | git reset -p >output &&
 	verify_state dir/foo work head &&
-	verify_saved_state bar
+	verify_saved_state bar &&
+	test_i18ngrep "Unstage" output
 '
 
 test_expect_success PERL 'git reset -p HEAD^' '
-	(echo n; echo y) | git reset -p HEAD^ &&
+	(echo n; echo y) | git reset -p HEAD^ >output &&
 	verify_state dir/foo work parent &&
-	verify_saved_state bar
+	verify_saved_state bar &&
+	test_i18ngrep "Apply" output
 '
 
 # The idea in the rest is that bar sorts first, so we always say 'y'
diff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh
index 8062cf5..0f95f00 100755
--- a/t/t7106-reset-unborn-branch.sh
+++ b/t/t7106-reset-unborn-branch.sh
@@ -11,7 +11,10 @@
 test_expect_success 'reset' '
 	git add a b &&
 	git reset &&
-	test "$(git ls-files)" = ""
+
+	>expect &&
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'reset HEAD' '
@@ -24,28 +27,43 @@
 	rm .git/index &&
 	git add a b &&
 	git reset a &&
-	test "$(git ls-files)" = "b"
+
+	echo b >expect &&
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
-test_expect_success 'reset -p' '
+test_expect_success PERL 'reset -p' '
 	rm .git/index &&
 	git add a &&
-	echo y | git reset -p &&
-	test "$(git ls-files)" = ""
+	echo y >yes &&
+	git reset -p <yes >output &&
+
+	>expect &&
+	git ls-files >actual &&
+	test_cmp expect actual &&
+	test_i18ngrep "Unstage" output
 '
 
 test_expect_success 'reset --soft is a no-op' '
 	rm .git/index &&
 	git add a &&
-	git reset --soft
-	test "$(git ls-files)" = "a"
+	git reset --soft &&
+
+	echo a >expect &&
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'reset --hard' '
 	rm .git/index &&
 	git add a &&
+	test_when_finished "echo a >a" &&
 	git reset --hard &&
-	test "$(git ls-files)" = "" &&
+
+	>expect &&
+	git ls-files >actual &&
+	test_cmp expect actual &&
 	test_path_is_missing a
 '
 
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index a39d074..c28e8d8 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -481,7 +481,7 @@
 
 '
 
-test_expect_success 'gracefully add submodule with a trailing slash' '
+test_expect_success 'gracefully add/reset submodule with a trailing slash' '
 
 	git reset --hard &&
 	git commit -m "commit subproject" init &&
@@ -495,7 +495,9 @@
 	git add init/ &&
 	test_must_fail git diff --exit-code --cached init &&
 	test $commit = $(git ls-files --stage |
-		sed -n "s/^160000 \([^ ]*\).*/\1/p")
+		sed -n "s/^160000 \([^ ]*\).*/\1/p") &&
+	git reset init/ &&
+	git diff --exit-code --cached init
 
 '
 
@@ -783,13 +785,11 @@
 			test_cmp expect .git
 		) &&
 		echo "repo" >expect &&
-		git config -f .gitmodules submodule.repo.path >actual &&
-		test_cmp expect actual &&
+		test_must_fail git config -f .gitmodules submodule.repo.path &&
 		git config -f .gitmodules submodule.repo_new.path >actual &&
 		test_cmp expect actual&&
 		echo "$submodurl/repo" >expect &&
-		git config -f .gitmodules submodule.repo.url >actual &&
-		test_cmp expect actual &&
+		test_must_fail git config -f .gitmodules submodule.repo.url &&
 		echo "$submodurl/bare.git" >expect &&
 		git config -f .gitmodules submodule.repo_new.url >actual &&
 		test_cmp expect actual &&
@@ -809,12 +809,8 @@
 		git rm repo &&
 		test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
 		test ! -d repo &&
-		echo "repo" >expect &&
-		git config -f .gitmodules submodule.repo_new.path >actual &&
-		test_cmp expect actual&&
-		echo "$submodurl/bare.git" >expect &&
-		git config -f .gitmodules submodule.repo_new.url >actual &&
-		test_cmp expect actual &&
+		test_must_fail git config -f .gitmodules submodule.repo_new.path &&
+		test_must_fail git config -f .gitmodules submodule.repo_new.url &&
 		echo "$submodurl/bare.git" >expect &&
 		git config submodule.repo_new.url >actual &&
 		test_cmp expect actual &&
@@ -968,7 +964,6 @@
 		git add sub &&
 		git commit -m "init sub"
 	) &&
-	test_config core.precomposeunicode true &&
 	git submodule add ./"$svname" &&
 	git submodule >&2 &&
 	test -n "$(git submodule | grep "$svname")"
diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh
index ac2434c..366746f 100755
--- a/t/t7401-submodule-summary.sh
+++ b/t/t7401-submodule-summary.sh
@@ -104,6 +104,24 @@
 	test_cmp expected actual
 "
 
+test_expect_success 'no ignore=all setting has any effect' "
+	git config -f .gitmodules submodule.sm1.path sm1 &&
+	git config -f .gitmodules submodule.sm1.ignore all &&
+	git config submodule.sm1.ignore all &&
+	git config diff.ignoreSubmodules all &&
+	git submodule summary >actual &&
+	cat >expected <<-EOF &&
+* sm1 $head1...$head2 (1):
+  > Add foo3
+
+EOF
+	test_cmp expected actual &&
+	git config --unset diff.ignoreSubmodules &&
+	git config --remove-section submodule.sm1 &&
+	git config -f .gitmodules --remove-section submodule.sm1
+"
+
+
 commit_file sm1 &&
 head3=$(
 	cd sm1 &&
@@ -265,13 +283,11 @@
 test_expect_success '--for-status' "
 	git submodule summary --for-status HEAD^ >actual &&
 	test_i18ncmp actual - <<EOF
-# Submodule changes to be committed:
-#
-# * sm1 $head6...0000000:
-#
-# * sm2 0000000...$head7 (2):
-#   > Add foo9
-#
+* sm1 $head6...0000000:
+
+* sm2 0000000...$head7 (2):
+  > Add foo9
+
 EOF
 "
 
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 0825a92..0246e80 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -762,6 +762,17 @@
 	 (cd submodule &&
 	  test 1 = $(git log --oneline | wc -l)
 	 )
+)
+'
+
+test_expect_success 'submodule update --recursive drops module name before recursing' '
+	(cd super2 &&
+	 (cd deeper/submodule/subsubmodule &&
+	  git checkout HEAD^
+	 ) &&
+	 git submodule update --recursive deeper/submodule >actual &&
+	 test_i18ngrep "Submodule path .deeper/submodule/subsubmodule.: checked out" actual
 	)
 '
+
 test_done
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index be93f10..7ca10b8 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -254,10 +254,6 @@
 		) &&
 		git submodule status --cached --recursive -- nested1 > ../actual
 	) &&
-	if test_have_prereq MINGW
-	then
-		dos2unix actual
-	fi &&
 	test_cmp expect actual
 '
 
@@ -329,4 +325,13 @@
 	test_cmp expected actual
 '
 
+test_expect_success 'multi-argument command passed to foreach is not shell-evaluated twice' '
+	(
+		cd super &&
+		git submodule foreach "echo \\\"quoted\\\"" > ../expected &&
+		git submodule foreach echo \"quoted\" > ../actual
+	) &&
+	test_cmp expected actual
+'
+
 test_done
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index 99ce36f..94eec83 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -53,10 +53,11 @@
 '
 
 test_expect_success 'using invalid commit with -C' '
-	test_must_fail git commit -C bogus
+	test_must_fail git commit --allow-empty -C bogus
 '
 
 test_expect_success 'nothing to commit' '
+	git reset --hard &&
 	test_must_fail git commit -m initial
 '
 
diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh
index da5bd3b..2ddf28c 100755
--- a/t/t7507-commit-verbose.sh
+++ b/t/t7507-commit-verbose.sh
@@ -65,9 +65,35 @@
 	check_message diff
 '
 
-test_expect_failure 'diff in message is retained with -v' '
+test_expect_success 'diff in message is retained with -v' '
 	git commit --amend -F diff -v &&
 	check_message diff
 '
 
+test_expect_success 'submodule log is stripped out too with -v' '
+	git config diff.submodule log &&
+	git submodule add ./. sub &&
+	git commit -m "sub added" &&
+	(
+		cd sub &&
+		echo "more" >>file &&
+		git commit -a -m "submodule commit"
+	) &&
+	(
+		GIT_EDITOR=cat &&
+		export GIT_EDITOR &&
+		test_must_fail git commit -a -v 2>err
+	) &&
+	test_i18ngrep "Aborting commit due to empty commit message." err
+'
+
+test_expect_success 'verbose diff is stripped out with set core.commentChar' '
+	(
+		GIT_EDITOR=cat &&
+		export GIT_EDITOR &&
+		test_must_fail git -c core.commentchar=";" commit -a -v 2>err
+	) &&
+	test_i18ngrep "Aborting commit due to empty commit message." err
+'
+
 test_done
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index ac3d0fe..c987b5e 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -60,8 +60,13 @@
 	test_i18ngrep "use \"git rm --cached <file>\.\.\.\" to unstage" output
 '
 
+strip_comments () {
+	tab='	'
+	sed "s/^\# //; s/^\#$//; s/^#$tab/$tab/" <"$1" >"$1".tmp &&
+	rm "$1" && mv "$1".tmp "$1"
+}
+
 test_expect_success 'status --column' '
-	COLUMNS=50 git status --column="column dense" >output &&
 	cat >expect <<\EOF &&
 # On branch master
 # Changes to be committed:
@@ -78,9 +83,17 @@
 # Untracked files:
 #   (use "git add <file>..." to include in what will be committed)
 #
-#	dir1/untracked dir2/untracked untracked
-#	dir2/modified  output
+#	dir1/untracked dir2/untracked output
+#	dir2/modified  expect         untracked
+#
 EOF
+	COLUMNS=50 git -c status.displayCommentPrefix=true status --column="column dense" >output &&
+	test_i18ncmp expect output
+'
+
+test_expect_success 'status --column status.displayCommentPrefix=false' '
+	strip_comments expect &&
+	COLUMNS=49 git -c status.displayCommentPrefix=false status --column="column dense" >output &&
 	test_i18ncmp expect output
 '
 
@@ -106,28 +119,58 @@
 #	expect
 #	output
 #	untracked
+#
 EOF
 
-test_expect_success 'status (2)' '
-	git status >output &&
+test_expect_success 'status with status.displayCommentPrefix=true' '
+	git -c status.displayCommentPrefix=true status >output &&
 	test_i18ncmp expect output
 '
 
+test_expect_success 'status with status.displayCommentPrefix=false' '
+	strip_comments expect &&
+	git -c status.displayCommentPrefix=false status >output &&
+	test_i18ncmp expect output
+'
+
+test_expect_success 'setup fake editor' '
+	cat >.git/editor <<-\EOF &&
+	#! /bin/sh
+	cp "$1" output
+EOF
+	chmod 755 .git/editor
+'
+
+commit_template_commented () {
+	(
+		EDITOR=.git/editor &&
+		export EDITOR &&
+		# Fails due to empty message
+		test_must_fail git commit
+	) &&
+	! grep '^[^#]' output
+}
+
+test_expect_success 'commit ignores status.displayCommentPrefix=false in COMMIT_EDITMSG' '
+	commit_template_commented
+'
+
 cat >expect <<\EOF
-# On branch master
-# Changes to be committed:
-#	new file:   dir2/added
-#
-# Changes not staged for commit:
-#	modified:   dir1/modified
-#
-# Untracked files:
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
+On branch master
+Changes to be committed:
+	new file:   dir2/added
+
+Changes not staged for commit:
+	modified:   dir1/modified
+
+Untracked files:
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
 EOF
 
 test_expect_success 'status (advice.statusHints false)' '
@@ -185,33 +228,35 @@
 	git status -s --ignored >output &&
 	test_cmp expect output &&
 
-	cat >expect <<-\EOF &&
-	# On branch master
-	# Changes to be committed:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#
-	#	new file:   dir2/added
-	#
-	# Changes not staged for commit:
-	#   (use "git add <file>..." to update what will be committed)
-	#   (use "git checkout -- <file>..." to discard changes in working directory)
-	#
-	#	modified:   dir1/modified
-	#
-	# Untracked files:
-	#   (use "git add <file>..." to include in what will be committed)
-	#
-	#	dir2/modified
-	# Ignored files:
-	#   (use "git add -f <file>..." to include in what will be committed)
-	#
-	#	.gitignore
-	#	dir1/untracked
-	#	dir2/untracked
-	#	expect
-	#	output
-	#	untracked
-	EOF
+	cat >expect <<\EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   dir2/added
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir2/modified
+
+Ignored files:
+  (use "git add -f <file>..." to include in what will be committed)
+
+	.gitignore
+	dir1/untracked
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	git status --ignored >output &&
 	test_i18ncmp expect output
 '
@@ -246,30 +291,31 @@
 	git status -s --ignored >output &&
 	test_cmp expect output &&
 
-	cat >expect <<-\EOF &&
-	# On branch master
-	# Changes to be committed:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#
-	#	new file:   dir2/added
-	#
-	# Changes not staged for commit:
-	#   (use "git add <file>..." to update what will be committed)
-	#   (use "git checkout -- <file>..." to discard changes in working directory)
-	#
-	#	modified:   dir1/modified
-	#
-	# Ignored files:
-	#   (use "git add -f <file>..." to include in what will be committed)
-	#
-	#	.gitignore
-	#	dir1/untracked
-	#	dir2/modified
-	#	dir2/untracked
-	#	expect
-	#	output
-	#	untracked
-	EOF
+	cat >expect <<\EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   dir2/added
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Ignored files:
+  (use "git add -f <file>..." to include in what will be committed)
+
+	.gitignore
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	git status --ignored >output &&
 	test_i18ncmp expect output
 '
@@ -310,22 +356,22 @@
 	: >dir3/untracked2
 '
 
-cat >expect <<EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	new file:   dir2/added
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Untracked files not listed (use -u option to show untracked files)
-EOF
 test_expect_success 'status -uno' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   dir2/added
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
 	git status -uno >output &&
 	test_i18ncmp expect output
 '
@@ -336,17 +382,17 @@
 	test_i18ncmp expect output
 '
 
-cat >expect <<EOF
-# On branch master
-# Changes to be committed:
-#	new file:   dir2/added
-#
-# Changes not staged for commit:
-#	modified:   dir1/modified
-#
-# Untracked files not listed
-EOF
 test_expect_success 'status -uno (advice.statusHints false)' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+	new file:   dir2/added
+
+Changes not staged for commit:
+	modified:   dir1/modified
+
+Untracked files not listed
+EOF
 	test_config advice.statusHints false &&
 	git status -uno >output &&
 	test_i18ncmp expect output
@@ -367,31 +413,32 @@
 	test_cmp expect output
 '
 
-cat >expect <<EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	new file:   dir2/added
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	dir3/
-#	expect
-#	output
-#	untracked
-EOF
 test_expect_success 'status -unormal' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   dir2/added
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	dir3/
+	expect
+	output
+	untracked
+
+EOF
 	git status -unormal >output &&
 	test_i18ncmp expect output
 '
@@ -424,32 +471,33 @@
 	test_cmp expect output
 '
 
-cat >expect <<EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	new file:   dir2/added
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	dir3/untracked1
-#	dir3/untracked2
-#	expect
-#	output
-#	untracked
-EOF
 test_expect_success 'status -uall' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   dir2/added
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	dir3/untracked1
+	dir3/untracked2
+	expect
+	output
+	untracked
+
+EOF
 	git status -uall >output &&
 	test_i18ncmp expect output
 '
@@ -486,31 +534,31 @@
 	test_cmp expect output
 '
 
-cat >expect <<\EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	new file:   ../dir2/added
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	untracked
-#	../dir2/modified
-#	../dir2/untracked
-#	../expect
-#	../output
-#	../untracked
-EOF
-
 test_expect_success 'status with relative paths' '
+	cat >expect <<\EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   ../dir2/added
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	untracked
+	../dir2/modified
+	../dir2/untracked
+	../expect
+	../output
+	../untracked
+
+EOF
 	(cd dir1 && git status) >output &&
 	test_i18ncmp expect output
 '
@@ -557,31 +605,31 @@
 
 '
 
-cat >expect <<\EOF
-# On branch <GREEN>master<RESET>
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	<GREEN>new file:   dir2/added<RESET>
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	<RED>modified:   dir1/modified<RESET>
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	<BLUE>dir1/untracked<RESET>
-#	<BLUE>dir2/modified<RESET>
-#	<BLUE>dir2/untracked<RESET>
-#	<BLUE>expect<RESET>
-#	<BLUE>output<RESET>
-#	<BLUE>untracked<RESET>
-EOF
-
 test_expect_success 'status with color.ui' '
+	cat >expect <<\EOF &&
+On branch <GREEN>master<RESET>
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	<GREEN>new file:   dir2/added<RESET>
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	<RED>modified:   dir1/modified<RESET>
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	<BLUE>dir1/untracked<RESET>
+	<BLUE>dir2/modified<RESET>
+	<BLUE>dir2/untracked<RESET>
+	<BLUE>expect<RESET>
+	<BLUE>output<RESET>
+	<BLUE>untracked<RESET>
+
+EOF
 	test_config color.ui always &&
 	git status | test_decode_color >output &&
 	test_i18ncmp expect output
@@ -685,33 +733,33 @@
 
 '
 
-cat >expect <<\EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	new file:   dir2/added
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
-EOF
 
 
 test_expect_success 'status without relative paths' '
+	cat >expect <<\EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
 
+	new file:   dir2/added
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	test_config status.relativePaths false &&
 	(cd dir1 && git status) >output &&
 	test_i18ncmp expect output
@@ -737,23 +785,24 @@
 
 '
 
-cat <<EOF >expect
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	modified:   dir1/modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/
-#	expect
-#	output
-#	untracked
-EOF
 test_expect_success 'dry-run of partial commit excluding new file in index' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/
+	expect
+	output
+	untracked
+
+EOF
 	git commit --dry-run dir1/modified >output &&
 	test_i18ncmp expect output
 '
@@ -778,31 +827,32 @@
 	git add sm
 '
 
-cat >expect <<EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	new file:   dir2/added
-#	new file:   sm
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
-EOF
 test_expect_success 'status submodule summary is disabled by default' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   dir2/added
+	new file:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	git status >output &&
 	test_i18ncmp expect output
 '
@@ -837,41 +887,52 @@
 
 head=$(cd sm && git rev-parse --short=7 --verify HEAD)
 
-cat >expect <<EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	new file:   dir2/added
-#	new file:   sm
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Submodule changes to be committed:
-#
-# * sm 0000000...$head (1):
-#   > Add foo
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
-EOF
 test_expect_success 'status submodule summary' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	new file:   dir2/added
+	new file:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Submodule changes to be committed:
+
+* sm 0000000...$head (1):
+  > Add foo
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	git config status.submodulesummary 10 &&
 	git status >output &&
 	test_i18ncmp expect output
 '
 
+test_expect_success 'status submodule summary with status.displayCommentPrefix=false' '
+	strip_comments expect &&
+	git -c status.displayCommentPrefix=false status >output &&
+	test_i18ncmp expect output
+'
+
+test_expect_success 'commit with submodule summary ignores status.displayCommentPrefix' '
+	commit_template_commented
+'
+
 cat >expect <<EOF
  M dir1/modified
 A  dir2/added
@@ -888,26 +949,27 @@
 	test_cmp expect output
 '
 
-cat >expect <<EOF
-# On branch master
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
+test_expect_success 'status submodule summary (clean submodule): commit' '
+	cat >expect <<EOF &&
+On branch master
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
-test_expect_success 'status submodule summary (clean submodule): commit' '
 	git commit -m "commit submodule" &&
 	git config status.submodulesummary 10 &&
 	test_must_fail git commit --dry-run >output &&
@@ -932,41 +994,42 @@
 
 test_expect_success 'status -z implies porcelain' '
 	git status --porcelain |
-	"$PERL_PATH" -pe "s/\012/\000/g" >expect &&
+	perl -pe "s/\012/\000/g" >expect &&
 	git status -z >output &&
 	test_cmp expect output
 '
 
-cat >expect <<EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD^1 <file>..." to unstage)
-#
-#	new file:   dir2/added
-#	new file:   sm
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Submodule changes to be committed:
-#
-# * sm 0000000...$head (1):
-#   > Add foo
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
-EOF
 test_expect_success 'commit --dry-run submodule summary (--amend)' '
+	cat >expect <<EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD^1 <file>..." to unstage)
+
+	new file:   dir2/added
+	new file:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Submodule changes to be committed:
+
+* sm 0000000...$head (1):
+  > Add foo
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	git config status.submodulesummary 10 &&
 	git commit --dry-run --amend >output &&
 	test_i18ncmp expect output
@@ -991,37 +1054,37 @@
 new_head=$(cd sm && git rev-parse --short=7 --verify HEAD)
 touch .gitmodules
 
-cat > expect << EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	modified:   sm
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Submodule changes to be committed:
-#
-# * sm $head...$new_head (1):
-#   > Add bar
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	.gitmodules
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
-EOF
-
 test_expect_success '--ignore-submodules=untracked suppresses submodules with untracked content' '
+	cat > expect << EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	modified:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Submodule changes to be committed:
+
+* sm $head...$new_head (1):
+  > Add bar
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	.gitmodules
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	echo modified  sm/untracked &&
 	git status --ignore-submodules=untracked >output &&
 	test_i18ncmp expect output
@@ -1101,39 +1164,39 @@
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
-cat > expect << EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	modified:   sm
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#   (commit or discard the untracked or modified content in submodules)
-#
-#	modified:   dir1/modified
-#	modified:   sm (modified content)
-#
-# Submodule changes to be committed:
-#
-# * sm $head...$new_head (1):
-#   > Add bar
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	.gitmodules
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
-EOF
-
 test_expect_success "--ignore-submodules=untracked doesn't suppress submodules with modified content" '
+	cat > expect << EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	modified:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+  (commit or discard the untracked or modified content in submodules)
+
+	modified:   dir1/modified
+	modified:   sm (modified content)
+
+Submodule changes to be committed:
+
+* sm $head...$new_head (1):
+  > Add bar
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	.gitmodules
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	git status --ignore-submodules=untracked > output &&
 	test_i18ncmp expect output
 '
@@ -1159,43 +1222,43 @@
 
 head2=$(cd sm && git commit -q -m "2nd commit" foo && git rev-parse --short=7 --verify HEAD)
 
-cat > expect << EOF
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	modified:   sm
-#
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#	modified:   sm (new commits)
-#
-# Submodule changes to be committed:
-#
-# * sm $head...$new_head (1):
-#   > Add bar
-#
-# Submodules changed but not updated:
-#
-# * sm $new_head...$head2 (1):
-#   > 2nd commit
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	.gitmodules
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
-EOF
-
 test_expect_success "--ignore-submodules=untracked doesn't suppress submodule summary" '
+	cat > expect << EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	modified:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+	modified:   sm (new commits)
+
+Submodule changes to be committed:
+
+* sm $head...$new_head (1):
+  > Add bar
+
+Submodules changed but not updated:
+
+* sm $new_head...$head2 (1):
+  > 2nd commit
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	.gitmodules
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
+EOF
 	git status --ignore-submodules=untracked > output &&
 	test_i18ncmp expect output
 '
@@ -1276,47 +1339,48 @@
 ;	expect
 ;	output
 ;	untracked
+;
 EOF
 
 test_expect_success "status (core.commentchar with submodule summary)" '
 	test_config core.commentchar ";" &&
-	git status >output &&
+	git -c status.displayCommentPrefix=true status >output &&
 	test_i18ncmp expect output
 '
 
 test_expect_success "status (core.commentchar with two chars with submodule summary)" '
 	test_config core.commentchar ";;" &&
-	git status >output &&
+	git -c status.displayCommentPrefix=true status >output &&
 	test_i18ncmp expect output
 '
 
-cat > expect << EOF
-# On branch master
-# Changes not staged for commit:
-#   (use "git add <file>..." to update what will be committed)
-#   (use "git checkout -- <file>..." to discard changes in working directory)
-#
-#	modified:   dir1/modified
-#
-# Untracked files:
-#   (use "git add <file>..." to include in what will be committed)
-#
-#	.gitmodules
-#	dir1/untracked
-#	dir2/modified
-#	dir2/untracked
-#	expect
-#	output
-#	untracked
+test_expect_success "--ignore-submodules=all suppresses submodule summary" '
+	cat > expect << EOF &&
+On branch master
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+	.gitmodules
+	dir1/untracked
+	dir2/modified
+	dir2/untracked
+	expect
+	output
+	untracked
+
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
-
-test_expect_success "--ignore-submodules=all suppresses submodule summary" '
 	git status --ignore-submodules=all > output &&
 	test_i18ncmp expect output
 '
 
-test_expect_failure '.gitmodules ignore=all suppresses submodule summary' '
+test_expect_success '.gitmodules ignore=all suppresses submodule summary' '
 	git config --add -f .gitmodules submodule.subname.ignore all &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status > output &&
@@ -1324,7 +1388,7 @@
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
-test_expect_failure '.git/config ignore=all suppresses submodule summary' '
+test_expect_success '.git/config ignore=all suppresses submodule summary' '
 	git config --add -f .gitmodules submodule.subname.ignore none &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git config --add submodule.subname.ignore all &&
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index 31a798f..3cec57a 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -25,18 +25,18 @@
 
 test_expect_success 'status when conflicts unresolved' '
 	test_must_fail git merge master &&
-	cat >expected <<-\EOF &&
-	# On branch conflicts
-	# You have unmerged paths.
-	#   (fix conflicts and run "git commit")
-	#
-	# Unmerged paths:
-	#   (use "git add <file>..." to mark resolution)
-	#
-	#	both modified:      main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<\EOF &&
+On branch conflicts
+You have unmerged paths.
+  (fix conflicts and run "git commit")
+
+Unmerged paths:
+  (use "git add <file>..." to mark resolution)
+
+	both modified:      main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -47,17 +47,17 @@
 	test_must_fail git merge master &&
 	echo one >main.txt &&
 	git add main.txt &&
-	cat >expected <<-\EOF &&
-	# On branch conflicts
-	# All conflicts fixed but you are still merging.
-	#   (use "git commit" to conclude merge)
-	#
-	# Changes to be committed:
-	#
-	#	modified:   main.txt
-	#
-	# Untracked files not listed (use -u option to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+On branch conflicts
+All conflicts fixed but you are still merging.
+  (use "git commit" to conclude merge)
+
+Changes to be committed:
+
+	modified:   main.txt
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -76,21 +76,21 @@
 	test_when_finished "git rebase --abort" &&
 	ONTO=$(git rev-parse --short HEAD^^) &&
 	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
-	#   (fix conflicts and then run "git rebase --continue")
-	#   (use "git rebase --skip" to skip this patch)
-	#   (use "git rebase --abort" to check out the original branch)
-	#
-	# Unmerged paths:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#   (use "git add <file>..." to mark resolution)
-	#
-	#	both modified:      main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
+  (fix conflicts and then run "git rebase --continue")
+  (use "git rebase --skip" to skip this patch)
+  (use "git rebase --abort" to check out the original branch)
+
+Unmerged paths:
+  (use "git reset HEAD <file>..." to unstage)
+  (use "git add <file>..." to mark resolution)
+
+	both modified:      main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -103,18 +103,18 @@
 	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
 	echo three >main.txt &&
 	git add main.txt &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
-	#   (all conflicts fixed: run "git rebase --continue")
-	#
-	# Changes to be committed:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#
-	#	modified:   main.txt
-	#
-	# Untracked files not listed (use -u option to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
+  (all conflicts fixed: run "git rebase --continue")
+
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	modified:   main.txt
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -135,21 +135,21 @@
 	test_when_finished "git rebase --abort" &&
 	ONTO=$(git rev-parse --short rebase_i_conflicts) &&
 	test_must_fail git rebase -i rebase_i_conflicts &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
-	#   (fix conflicts and then run "git rebase --continue")
-	#   (use "git rebase --skip" to skip this patch)
-	#   (use "git rebase --abort" to check out the original branch)
-	#
-	# Unmerged paths:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#   (use "git add <file>..." to mark resolution)
-	#
-	#	both modified:      main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
+  (fix conflicts and then run "git rebase --continue")
+  (use "git rebase --skip" to skip this patch)
+  (use "git rebase --abort" to check out the original branch)
+
+Unmerged paths:
+  (use "git reset HEAD <file>..." to unstage)
+  (use "git add <file>..." to mark resolution)
+
+	both modified:      main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -161,18 +161,18 @@
 	ONTO=$(git rev-parse --short rebase_i_conflicts) &&
 	test_must_fail git rebase -i rebase_i_conflicts &&
 	git add main.txt &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
-	#   (all conflicts fixed: run "git rebase --continue")
-	#
-	# Changes to be committed:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#
-	#	modified:   main.txt
-	#
-	# Untracked files not listed (use -u option to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
+  (all conflicts fixed: run "git rebase --continue")
+
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	modified:   main.txt
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -189,14 +189,14 @@
 	test_when_finished "git rebase --abort" &&
 	ONTO=$(git rev-parse --short HEAD~2) &&
 	git rebase -i HEAD~2 &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -215,19 +215,19 @@
 	ONTO=$(git rev-parse --short HEAD~3) &&
 	git rebase -i HEAD~3 &&
 	git reset HEAD^ &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''$ONTO'\''.
-	#   (Once your working directory is clean, run "git rebase --continue")
-	#
-	# Changes not staged for commit:
-	#   (use "git add <file>..." to update what will be committed)
-	#   (use "git checkout -- <file>..." to discard changes in working directory)
-	#
-	#	modified:   main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''$ONTO'\''.
+  (Once your working directory is clean, run "git rebase --continue")
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -246,14 +246,14 @@
 	ONTO=$(git rev-parse --short HEAD~3) &&
 	git rebase -i HEAD~3 &&
 	git commit --amend -m "foo" &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -276,14 +276,14 @@
 	ONTO=$(git rev-parse --short HEAD~3) &&
 	git rebase -i HEAD~3 &&
 	git rebase --continue &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -298,19 +298,19 @@
 	git rebase -i HEAD~3 &&
 	git rebase --continue &&
 	git reset HEAD^ &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (Once your working directory is clean, run "git rebase --continue")
-	#
-	# Changes not staged for commit:
-	#   (use "git add <file>..." to update what will be committed)
-	#   (use "git checkout -- <file>..." to discard changes in working directory)
-	#
-	#	modified:   main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (Once your working directory is clean, run "git rebase --continue")
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -325,14 +325,14 @@
 	git rebase -i HEAD~3 &&
 	git rebase --continue &&
 	git commit --amend -m "foo" &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -347,14 +347,14 @@
 	git rebase -i HEAD~3 &&
 	git commit --amend -m "a" &&
 	git rebase --continue &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -370,19 +370,19 @@
 	git commit --amend -m "b" &&
 	git rebase --continue &&
 	git reset HEAD^ &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (Once your working directory is clean, run "git rebase --continue")
-	#
-	# Changes not staged for commit:
-	#   (use "git add <file>..." to update what will be committed)
-	#   (use "git checkout -- <file>..." to discard changes in working directory)
-	#
-	#	modified:   main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (Once your working directory is clean, run "git rebase --continue")
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -398,14 +398,14 @@
 	git commit --amend -m "c" &&
 	git rebase --continue &&
 	git commit --amend -m "d" &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -422,14 +422,14 @@
 	git add main.txt &&
 	git commit -m "e" &&
 	git rebase --continue &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -447,19 +447,19 @@
 	git commit --amend -m "f" &&
 	git rebase --continue &&
 	git reset HEAD^ &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (Once your working directory is clean, run "git rebase --continue")
-	#
-	# Changes not staged for commit:
-	#   (use "git add <file>..." to update what will be committed)
-	#   (use "git checkout -- <file>..." to discard changes in working directory)
-	#
-	#	modified:   main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (Once your working directory is clean, run "git rebase --continue")
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+	modified:   main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -477,14 +477,14 @@
 	git commit --amend -m "g" &&
 	git rebase --continue &&
 	git commit --amend -m "h" &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
-	#   (use "git commit --amend" to amend the current commit)
-	#   (use "git rebase --continue" once you are satisfied with your changes)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
+  (use "git commit --amend" to amend the current commit)
+  (use "git rebase --continue" once you are satisfied with your changes)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -504,15 +504,15 @@
 	test_when_finished "rm Maildir/* && git am --abort" &&
 	git format-patch -1 -oMaildir &&
 	test_must_fail git am Maildir/*.patch &&
-	cat >expected <<-\EOF &&
-	# On branch am_already_exists
-	# You are in the middle of an am session.
-	#   (fix conflicts and then run "git am --continue")
-	#   (use "git am --skip" to skip this patch)
-	#   (use "git am --abort" to restore the original branch)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+On branch am_already_exists
+You are in the middle of an am session.
+  (fix conflicts and then run "git am --continue")
+  (use "git am --skip" to skip this patch)
+  (use "git am --abort" to restore the original branch)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -526,15 +526,15 @@
 	test_when_finished "rm Maildir/* && git am --abort" &&
 	git format-patch -1 -oMaildir &&
 	test_must_fail git am Maildir/*.patch &&
-	cat >expected <<-\EOF &&
-	# On branch am_not_exists
-	# You are in the middle of an am session.
-	#   (fix conflicts and then run "git am --continue")
-	#   (use "git am --skip" to skip this patch)
-	#   (use "git am --abort" to restore the original branch)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+On branch am_not_exists
+You are in the middle of an am session.
+  (fix conflicts and then run "git am --continue")
+  (use "git am --skip" to skip this patch)
+  (use "git am --abort" to restore the original branch)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -549,15 +549,15 @@
 	git commit -m "delete all am_empty" &&
 	echo error >Maildir/0002-two_am.patch &&
 	test_must_fail git am Maildir/*.patch &&
-	cat >expected <<-\EOF &&
-	# On branch am_empty
-	# You are in the middle of an am session.
-	# The current patch is empty.
-	#   (use "git am --skip" to skip this patch)
-	#   (use "git am --abort" to restore the original branch)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+On branch am_empty
+You are in the middle of an am session.
+The current patch is empty.
+  (use "git am --skip" to skip this patch)
+  (use "git am --abort" to restore the original branch)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -574,13 +574,13 @@
 	git bisect bad &&
 	git bisect good one_bisect &&
 	TGT=$(git rev-parse --short two_bisect) &&
-	cat >expected <<-EOF &&
-	# HEAD detached at $TGT
-	# You are currently bisecting, started from branch '\''bisect'\''.
-	#   (use "git bisect reset" to get back to the original branch)
-	#
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+HEAD detached at $TGT
+You are currently bisecting, started from branch '\''bisect'\''.
+  (use "git bisect reset" to get back to the original branch)
+
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -597,15 +597,15 @@
 	test_when_finished "git rebase --abort" &&
 	ONTO=$(git rev-parse --short HEAD^^) &&
 	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
-	cat >expected <<-EOF &&
-	# rebase in progress; onto $ONTO
-	# You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''.
-	#
-	# Unmerged paths:
-	#	both modified:      main.txt
-	#
-	no changes added to commit
-	EOF
+	cat >expected <<EOF &&
+rebase in progress; onto $ONTO
+You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''.
+
+Unmerged paths:
+	both modified:      main.txt
+
+no changes added to commit
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -626,19 +626,20 @@
 test_expect_success 'status when cherry-picking before resolving conflicts' '
 	test_when_finished "git cherry-pick --abort" &&
 	test_must_fail git cherry-pick cherry_branch_second &&
-	cat >expected <<-\EOF &&
-	# On branch cherry_branch
-	# You are currently cherry-picking.
-	#   (fix conflicts and run "git cherry-pick --continue")
-	#   (use "git cherry-pick --abort" to cancel the cherry-pick operation)
-	#
-	# Unmerged paths:
-	#   (use "git add <file>..." to mark resolution)
-	#
-	#	both modified:      main.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	TO_CHERRY_PICK=$(git rev-parse --short CHERRY_PICK_HEAD) &&
+	cat >expected <<EOF &&
+On branch cherry_branch
+You are currently cherry-picking commit $TO_CHERRY_PICK.
+  (fix conflicts and run "git cherry-pick --continue")
+  (use "git cherry-pick --abort" to cancel the cherry-pick operation)
+
+Unmerged paths:
+  (use "git add <file>..." to mark resolution)
+
+	both modified:      main.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -648,20 +649,21 @@
 	git reset --hard cherry_branch &&
 	test_when_finished "git cherry-pick --abort" &&
 	test_must_fail git cherry-pick cherry_branch_second &&
+	TO_CHERRY_PICK=$(git rev-parse --short CHERRY_PICK_HEAD) &&
 	echo end >main.txt &&
 	git add main.txt &&
-	cat >expected <<-\EOF &&
-	# On branch cherry_branch
-	# You are currently cherry-picking.
-	#   (all conflicts fixed: run "git cherry-pick --continue")
-	#   (use "git cherry-pick --abort" to cancel the cherry-pick operation)
-	#
-	# Changes to be committed:
-	#
-	#	modified:   main.txt
-	#
-	# Untracked files not listed (use -u option to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+On branch cherry_branch
+You are currently cherry-picking commit $TO_CHERRY_PICK.
+  (all conflicts fixed: run "git cherry-pick --continue")
+  (use "git cherry-pick --abort" to cancel the cherry-pick operation)
+
+Changes to be committed:
+
+	modified:   main.txt
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -669,18 +671,18 @@
 test_expect_success 'status showing detached at and from a tag' '
 	test_commit atag tagging &&
 	git checkout atag &&
-	cat >expected <<-\EOF
-	# HEAD detached at atag
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+HEAD detached at atag
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual &&
 
 	git reset --hard HEAD^ &&
-	cat >expected <<-\EOF
-	# HEAD detached from atag
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+HEAD detached from atag
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -695,20 +697,20 @@
 	test_commit new to-revert.txt &&
 	TO_REVERT=$(git rev-parse --short HEAD^) &&
 	test_must_fail git revert $TO_REVERT &&
-	cat >expected <<-EOF
-	# On branch master
-	# You are currently reverting commit $TO_REVERT.
-	#   (fix conflicts and run "git revert --continue")
-	#   (use "git revert --abort" to cancel the revert operation)
-	#
-	# Unmerged paths:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#   (use "git add <file>..." to mark resolution)
-	#
-	#	both modified:      to-revert.txt
-	#
-	no changes added to commit (use "git add" and/or "git commit -a")
-	EOF
+	cat >expected <<EOF &&
+On branch master
+You are currently reverting commit $TO_REVERT.
+  (fix conflicts and run "git revert --continue")
+  (use "git revert --abort" to cancel the revert operation)
+
+Unmerged paths:
+  (use "git reset HEAD <file>..." to unstage)
+  (use "git add <file>..." to mark resolution)
+
+	both modified:      to-revert.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
@@ -716,29 +718,29 @@
 test_expect_success 'status while reverting commit (conflicts resolved)' '
 	echo reverted >to-revert.txt &&
 	git add to-revert.txt &&
-	cat >expected <<-EOF
-	# On branch master
-	# You are currently reverting commit $TO_REVERT.
-	#   (all conflicts fixed: run "git revert --continue")
-	#   (use "git revert --abort" to cancel the revert operation)
-	#
-	# Changes to be committed:
-	#   (use "git reset HEAD <file>..." to unstage)
-	#
-	#	modified:   to-revert.txt
-	#
-	# Untracked files not listed (use -u option to show untracked files)
-	EOF
+	cat >expected <<EOF &&
+On branch master
+You are currently reverting commit $TO_REVERT.
+  (all conflicts fixed: run "git revert --continue")
+  (use "git revert --abort" to cancel the revert operation)
+
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+	modified:   to-revert.txt
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
 
 test_expect_success 'status after reverting commit' '
 	git revert --continue &&
-	cat >expected <<-\EOF
-	# On branch master
-	nothing to commit (use -u to show untracked files)
-	EOF
+	cat >expected <<\EOF &&
+On branch master
+nothing to commit (use -u to show untracked files)
+EOF
 	git status --untracked-files=no >actual &&
 	test_i18ncmp expected actual
 '
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index d526b1d..05d9db0 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -253,7 +253,7 @@
     git checkout -b test6 branch1 &&
     git submodule update -N &&
     mv submod submod-movedaside &&
-    git rm submod &&
+    git rm --cached submod &&
     git commit -m "Submodule deleted from branch" &&
     git checkout -b test6.a test6 &&
     test_must_fail git merge master &&
@@ -322,7 +322,7 @@
     git checkout -b test7 branch1 &&
     git submodule update -N &&
     mv submod submod-movedaside &&
-    git rm submod &&
+    git rm --cached submod &&
     echo not a submodule >submod &&
     git add submod &&
     git commit -m "Submodule path becomes file" &&
@@ -453,7 +453,7 @@
 test_expect_success 'directory vs modified submodule' '
     git checkout -b test11 branch1 &&
     mv submod submod-movedaside &&
-    git rm submod &&
+    git rm --cached submod &&
     mkdir submod &&
     echo not a submodule >submod/file16 &&
     git add submod/file16 &&
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index d954b84..b45bd1e 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -17,7 +17,7 @@
 	# The second pack will contain the excluded object
 	packsha1=$(git rev-list --objects --all | grep file2 |
 		git pack-objects pack) &&
-	touch -r pack-$packsha1.pack pack-$packsha1.keep &&
+	>pack-$packsha1.keep &&
 	objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 |
 		sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") &&
 	mv pack-* .git/objects/pack/ &&
diff --git a/t/t8007-cat-file-textconv.sh b/t/t8007-cat-file-textconv.sh
index b95e102..eacd49a 100755
--- a/t/t8007-cat-file-textconv.sh
+++ b/t/t8007-cat-file-textconv.sh
@@ -20,11 +20,11 @@
 '
 
 cat >expected <<EOF
-fatal: git cat-file --textconv: unable to run textconv on :one.bin
+bin: test version 2
 EOF
 
 test_expect_success 'no filter specified' '
-	git cat-file --textconv :one.bin 2>result
+	git cat-file --textconv :one.bin >result &&
 	test_cmp expected result
 '
 
@@ -34,10 +34,6 @@
 	git config diff.test.cachetextconv false
 '
 
-cat >expected <<EOF
-bin: test version 2
-EOF
-
 test_expect_success 'cat-file without --textconv' '
 	git cat-file blob :one.bin >result &&
 	test_cmp expected result
@@ -71,25 +67,19 @@
 '
 
 test_expect_success 'cat-file without --textconv (symlink)' '
+	printf "%s" "one.bin" >expected &&
 	git cat-file blob :symlink.bin >result &&
-	printf "%s" "one.bin" >expected
 	test_cmp expected result
 '
 
 
 test_expect_success 'cat-file --textconv on index (symlink)' '
-	! git cat-file --textconv :symlink.bin 2>result &&
-	cat >expected <<\EOF &&
-fatal: git cat-file --textconv: unable to run textconv on :symlink.bin
-EOF
+	git cat-file --textconv :symlink.bin >result &&
 	test_cmp expected result
 '
 
 test_expect_success 'cat-file --textconv on HEAD (symlink)' '
-	! git cat-file --textconv HEAD:symlink.bin 2>result &&
-	cat >expected <<EOF &&
-fatal: git cat-file --textconv: unable to run textconv on HEAD:symlink.bin
-EOF
+	git cat-file --textconv HEAD:symlink.bin >result &&
 	test_cmp expected result
 '
 
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 2813aa9..3119c8c 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -23,7 +23,6 @@
       echo do
       echo "  echo \"!\$a!\""
       echo "done >commandline\$output"
-      test_have_prereq MINGW && echo "dos2unix commandline\$output"
       echo "cat > msgtxt\$output"
       ) >fake.sendmail &&
      chmod +x ./fake.sendmail &&
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index f524d2f..d33d714 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -62,7 +62,7 @@
 	echo friend > README &&
 	cat tmp >> README &&
 	git commit -a -m "friend" &&
-	git pull . merge
+	git merge merge
 	'
 
 test_debug 'gitk --all & sleep 1'
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
index b7ef9e2..69e9c0d 100755
--- a/t/t9117-git-svn-init-clone.sh
+++ b/t/t9117-git-svn-init-clone.sh
@@ -52,4 +52,71 @@
 	rm -rf target
 	'
 
+test_expect_success 'init without -s/-T/-b/-t does not warn' '
+	test ! -d trunk &&
+	git svn init "$svnrepo"/project/trunk trunk 2>warning &&
+	test_must_fail grep -q prefix warning &&
+	rm -rf trunk &&
+	rm -f warning
+	'
+
+test_expect_success 'clone without -s/-T/-b/-t does not warn' '
+	test ! -d trunk &&
+	git svn clone "$svnrepo"/project/trunk 2>warning &&
+	test_must_fail grep -q prefix warning &&
+	rm -rf trunk &&
+	rm -f warning
+	'
+
+test_svn_configured_prefix () {
+	prefix=$1 &&
+	cat >expect <<EOF &&
+project/trunk:refs/remotes/${prefix}trunk
+project/branches/*:refs/remotes/${prefix}*
+project/tags/*:refs/remotes/${prefix}tags/*
+EOF
+	test ! -f actual &&
+	git --git-dir=project/.git config svn-remote.svn.fetch >>actual &&
+	git --git-dir=project/.git config svn-remote.svn.branches >>actual &&
+	git --git-dir=project/.git config svn-remote.svn.tags >>actual &&
+	test_cmp expect actual &&
+	rm -f expect actual
+}
+
+test_expect_success 'init with -s/-T/-b/-t without --prefix warns' '
+	test ! -d project &&
+	git svn init -s "$svnrepo"/project project 2>warning &&
+	grep -q prefix warning &&
+	test_svn_configured_prefix "" &&
+	rm -rf project &&
+	rm -f warning
+	'
+
+test_expect_success 'clone with -s/-T/-b/-t without --prefix warns' '
+	test ! -d project &&
+	git svn clone -s "$svnrepo"/project 2>warning &&
+	grep -q prefix warning &&
+	test_svn_configured_prefix "" &&
+	rm -rf project &&
+	rm -f warning
+	'
+
+test_expect_success 'init with -s/-T/-b/-t and --prefix does not warn' '
+	test ! -d project &&
+	git svn init -s "$svnrepo"/project project --prefix="" 2>warning &&
+	test_must_fail grep -q prefix warning &&
+	test_svn_configured_prefix "" &&
+	rm -rf project &&
+	rm -f warning
+	'
+
+test_expect_success 'clone with -s/-T/-b/-t and --prefix does not warn' '
+	test ! -d project &&
+	git svn clone -s "$svnrepo"/project --prefix="" 2>warning &&
+	test_must_fail grep -q prefix warning &&
+	test_svn_configured_prefix "" &&
+	rm -rf project &&
+	rm -f warning
+	'
+
 test_done
diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh
index 9a40f1e..8cfdfe7 100755
--- a/t/t9129-git-svn-i18n-commitencoding.sh
+++ b/t/t9129-git-svn-i18n-commitencoding.sh
@@ -29,7 +29,7 @@
 compare_svn_head_with () {
 	# extract just the log message and strip out committer info.
 	# don't use --limit here since svn 1.1.x doesn't have it,
-	LC_ALL="$a_utf8_locale" svn log `git svn info --url` | "$PERL_PATH" -w -e '
+	LC_ALL="$a_utf8_locale" svn log `git svn info --url` | perl -w -e '
 		use bytes;
 		$/ = ("-"x72) . "\n";
 		my @x = <STDIN>;
diff --git a/t/t9137-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh
index c17aa31..d60da63 100755
--- a/t/t9137-git-svn-dcommit-clobber-series.sh
+++ b/t/t9137-git-svn-dcommit-clobber-series.sh
@@ -20,8 +20,8 @@
 	test x"`sed -n -e 61p < file`" = x61 &&
 	svn_cmd co "$svnrepo" tmp &&
 	(cd tmp &&
-		"$PERL_PATH" -i.bak -p -e "s/^58$/5588/" file &&
-		"$PERL_PATH" -i.bak -p -e "s/^61$/6611/" file &&
+		perl -i.bak -p -e "s/^58$/5588/" file &&
+		perl -i.bak -p -e "s/^61$/6611/" file &&
 		poke file &&
 		test x"`sed -n -e 58p < file`" = x5588 &&
 		test x"`sed -n -e 61p < file`" = x6611 &&
@@ -40,8 +40,8 @@
 test_expect_success 'change file but in unrelated area' "
 	test x\"\`sed -n -e 4p < file\`\" = x4 &&
 	test x\"\`sed -n -e 7p < file\`\" = x7 &&
-	"$PERL_PATH" -i.bak -p -e 's/^4\$/4444/' file &&
-	"$PERL_PATH" -i.bak -p -e 's/^7\$/7777/' file &&
+	perl -i.bak -p -e 's/^4\$/4444/' file &&
+	perl -i.bak -p -e 's/^7\$/7777/' file &&
 	test x\"\`sed -n -e 4p < file\`\" = x4444 &&
 	test x\"\`sed -n -e 7p < file\`\" = x7777 &&
 	git commit -m '4 => 4444, 7 => 7777' file &&
diff --git a/t/t9150/make-svk-dump b/t/t9150/make-svk-dump
old mode 100644
new mode 100755
diff --git a/t/t9151/make-svnmerge-dump b/t/t9151/make-svnmerge-dump
old mode 100644
new mode 100755
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 3fb3368..812c9cd 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -5,7 +5,6 @@
 test_description='Test export of commits to CVS'
 
 . ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh
 
 if ! test_have_prereq PERL; then
 	skip_all='skipping git cvsexportcommit tests, perl not available'
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index ac6f3b6..27263df 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -12,7 +12,7 @@
 # This could be written as "head -c $1", but IRIX "head" does not
 # support the -c option.
 head_c () {
-	"$PERL_PATH" -e '
+	perl -e '
 		my $len = $ARGV[1];
 		while ($len > 0) {
 			my $s;
@@ -1031,6 +1031,32 @@
 	 git diff-tree -M -r M3^ M3 >actual &&
 	 compare_diff_raw expect actual'
 
+cat >input <<INPUT_END
+commit refs/heads/M4
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+rename root
+COMMIT
+
+from refs/heads/M2^0
+R "" sub
+
+INPUT_END
+
+cat >expect <<EOF
+:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100	file2/oldf	sub/file2/oldf
+:100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 R100	file4	sub/file4
+:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100	i/am/new/to/you	sub/i/am/new/to/you
+:100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100	newdir/exec.sh	sub/newdir/exec.sh
+:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100	newdir/interesting	sub/newdir/interesting
+EOF
+test_expect_success \
+	'M: rename root to subdirectory' \
+	'git fast-import <input &&
+	 git diff-tree -M -r M4^ M4 >actual &&
+	 cat actual &&
+	 compare_diff_raw expect actual'
+
 ###
 ### series N
 ###
@@ -1228,6 +1254,29 @@
 	 compare_diff_raw expect actual'
 
 test_expect_success \
+	'N: copy root by path' \
+	'cat >expect <<-\EOF &&
+	:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100	file2/newf	oldroot/file2/newf
+	:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100	file2/oldf	oldroot/file2/oldf
+	:100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 C100	file4	oldroot/file4
+	:100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 C100	newdir/exec.sh	oldroot/newdir/exec.sh
+	:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100	newdir/interesting	oldroot/newdir/interesting
+	EOF
+	 cat >input <<-INPUT_END &&
+	commit refs/heads/N-copy-root-path
+	committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+	data <<COMMIT
+	copy root directory by (empty) path
+	COMMIT
+
+	from refs/heads/branch^0
+	C "" oldroot
+	INPUT_END
+	 git fast-import <input &&
+	 git diff-tree -C --find-copies-harder -r branch N-copy-root-path >actual &&
+	 compare_diff_raw expect actual'
+
+test_expect_success \
 	'N: delete directory by copying' \
 	'cat >expect <<-\EOF &&
 	OBJID
@@ -2815,14 +2864,14 @@
 '
 
 #
-# notemodify, mark in committish
+# notemodify, mark in commit-ish
 #
-test_expect_success 'S: notemodify with garbarge after mark committish must fail' '
+test_expect_success 'S: notemodify with garbarge after mark commit-ish must fail' '
 	test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
 	commit refs/heads/Snotes
 	committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 	data <<COMMIT
-	commit S note committish
+	commit S note commit-ish
 	COMMIT
 	N :202 :302x
 	EOF
@@ -2934,4 +2983,20 @@
 	test_i18ngrep "space after tree-ish" err
 '
 
+###
+### series T (ls)
+###
+# Setup is carried over from series S.
+
+test_expect_success 'T: ls root tree' '
+	sed -e "s/Z\$//" >expect <<-EOF &&
+	040000 tree $(git rev-parse S^{tree})	Z
+	EOF
+	sha1=$(git rev-parse --verify S) &&
+	git fast-import --import-marks=marks <<-EOF >actual &&
+	ls $sha1 ""
+	EOF
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 34c2d8f..2312dec 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -429,7 +429,7 @@
 		--cacheinfo 100644 $blob "path with \\backslash" \
 		--cacheinfo 100644 $blob "path with space" &&
 	 git commit -m addition &&
-	 git ls-files -z -s | "$PERL_PATH" -0pe "s{\\t}{$&subdir/}" >index &&
+	 git ls-files -z -s | perl -0pe "s{\\t}{$&subdir/}" >index &&
 	 git read-tree --empty &&
 	 git update-index -z --index-info <index &&
 	 git commit -m rename &&
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 0431386..3edc408 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -20,7 +20,7 @@
     skip_all='skipping git-cvsserver tests, cvs not found'
     test_done
 fi
-"$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
+perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
     skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable'
     test_done
 }
diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh
index 8c3db76..5a4ed28 100755
--- a/t/t9401-git-cvsserver-crlf.sh
+++ b/t/t9401-git-cvsserver-crlf.sh
@@ -68,7 +68,7 @@
     skip_all='skipping git-cvsserver tests, perl not available'
     test_done
 fi
-"$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
+perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
     skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable'
     test_done
 }
diff --git a/t/t9402-git-cvsserver-refs.sh b/t/t9402-git-cvsserver-refs.sh
index db69af2..1e266ef 100755
--- a/t/t9402-git-cvsserver-refs.sh
+++ b/t/t9402-git-cvsserver-refs.sh
@@ -76,7 +76,7 @@
 	skip_all='skipping git-cvsserver tests, perl not available'
 	test_done
 fi
-"$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
+perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
 	skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable'
 	test_done
 }
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 6fca193..e74b9ab 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -328,7 +328,7 @@
 	 git add b &&
 	 git commit -a -m "On branch" &&
 	 git checkout master &&
-	 git pull . b &&
+	 git merge b &&
 	 git tag merge_commit'
 
 test_expect_success \
@@ -683,9 +683,11 @@
 # syntax highlighting
 
 
-highlight --version >/dev/null 2>&1
+highlight_version=$(highlight --version </dev/null 2>/dev/null)
 if [ $? -eq 127 ]; then
-	say "Skipping syntax highlighting test, because 'highlight' was not found"
+	say "Skipping syntax highlighting tests: 'highlight' not found"
+elif test -z "$highlight_version"; then
+	say "Skipping syntax highlighting tests: incorrect 'highlight' found"
 else
 	test_set_prereq HIGHLIGHT
 	cat >>gitweb_config.perl <<-\EOF
diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh
index 435d896..102c133 100755
--- a/t/t9700-perl-git.sh
+++ b/t/t9700-perl-git.sh
@@ -11,7 +11,7 @@
 	test_done
 fi
 
-"$PERL_PATH" -MTest::More -e 0 2>/dev/null || {
+perl -MTest::More -e 0 2>/dev/null || {
 	skip_all="Perl Test::More unavailable, skipping test"
 	test_done
 }
@@ -55,6 +55,6 @@
 
 test_external_without_stderr \
     'Perl API' \
-    "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl
+    perl "$TEST_DIRECTORY"/t9700/test.pl
 
 test_done
diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh
index a82744b..66d3fc9 100755
--- a/t/t9802-git-p4-filetype.sh
+++ b/t/t9802-git-p4-filetype.sh
@@ -250,6 +250,89 @@
 	)
 '
 
+test_expect_success SYMLINKS 'create p4 symlink' '
+	cd "$cli" &&
+	ln -s symlink-target symlink &&
+	p4 add symlink &&
+	p4 submit -d "add symlink"
+'
+
+test_expect_success SYMLINKS 'ensure p4 symlink parsed correctly' '
+	test_when_finished cleanup_git &&
+	git p4 clone --dest="$git" //depot@all &&
+	(
+		cd "$git" &&
+		test -L symlink &&
+		test $(readlink symlink) = symlink-target
+	)
+'
+
+test_expect_success SYMLINKS 'empty symlink target' '
+	(
+		# first create the file as a file
+		cd "$cli" &&
+		>empty-symlink &&
+		p4 add empty-symlink &&
+		p4 submit -d "add empty-symlink as a file"
+	) &&
+	(
+		# now change it to be a symlink to "target1"
+		cd "$cli" &&
+		p4 edit empty-symlink &&
+		p4 reopen -t symlink empty-symlink &&
+		rm empty-symlink &&
+		ln -s target1 empty-symlink &&
+		p4 add empty-symlink &&
+		p4 submit -d "make empty-symlink point to target1"
+	) &&
+	(
+		# Hack the p4 depot to make the symlink point to nothing;
+		# this should not happen in reality, but shows up
+		# in p4 repos in the wild.
+		#
+		# The sed expression changes this:
+		#     @@
+		#     text
+		#     @target1
+		#     @
+		# to this:
+		#     @@
+		#     text
+		#     @@
+		#
+		cd "$db/depot" &&
+		sed "/@target1/{; s/target1/@/; n; d; }" \
+		    empty-symlink,v >empty-symlink,v.tmp &&
+		mv empty-symlink,v.tmp empty-symlink,v
+	) &&
+	(
+		# Make sure symlink really is empty.  Asking
+		# p4 to sync here will make it generate errors.
+		cd "$cli" &&
+		p4 print -q //depot/empty-symlink#2 >out &&
+		test ! -s out
+	) &&
+	test_when_finished cleanup_git &&
+
+	# make sure git p4 handles it without error
+	git p4 clone --dest="$git" //depot@all &&
+
+	# fix the symlink, make it point to "target2"
+	(
+		cd "$cli" &&
+		p4 open empty-symlink &&
+		rm empty-symlink &&
+		ln -s target2 empty-symlink &&
+		p4 submit -d "make empty-symlink point to target2"
+	) &&
+	cleanup_git &&
+	git p4 clone --dest="$git" //depot@all &&
+	(
+		cd "$git" &&
+		test $(readlink empty-symlink) = target2
+	)
+'
+
 test_expect_success 'kill p4d' '
 	kill_p4d
 '
diff --git a/t/t9805-git-p4-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh
index ff2cc79..8931188 100755
--- a/t/t9805-git-p4-skip-submit-edit.sh
+++ b/t/t9805-git-p4-skip-submit-edit.sh
@@ -17,7 +17,7 @@
 	)
 '
 
-# this works because EDITOR is set to :
+# this works because P4EDITOR is set to true
 test_expect_success 'no config, unedited, say yes' '
 	git p4 clone --dest="$git" //depot &&
 	test_when_finished cleanup_git &&
@@ -90,7 +90,9 @@
 		cd "$git" &&
 		echo line >>file1 &&
 		git commit -a -m "change 5" &&
-		P4EDITOR="" EDITOR="\"$TRASH_DIRECTORY/ed.sh\"" git p4 submit &&
+		P4EDITOR="$TRASH_DIRECTORY/ed.sh" &&
+		export P4EDITOR &&
+		git p4 submit &&
 		p4 changes //depot/... >wc &&
 		test_line_count = 5 wc
 	)
diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh
index 1fb7bc7..4caf36e 100755
--- a/t/t9807-git-p4-submit.sh
+++ b/t/t9807-git-p4-submit.sh
@@ -17,7 +17,7 @@
 	)
 '
 
-test_expect_failure 'is_cli_file_writeable function' '
+test_expect_success 'is_cli_file_writeable function' '
 	(
 		cd "$cli" &&
 		echo a >a &&
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 77f6349..23a827f 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -76,28 +76,28 @@
 '
 
 # double % for printf
-test_expect_success 'unsupported view wildcard %%n' '
+test_expect_success 'view wildcard %%n' '
 	client_view "//depot/%%%%1/sub/... //client/sub/%%%%1/..." &&
 	test_when_finished cleanup_git &&
-	test_must_fail git p4 clone --use-client-spec --dest="$git" //depot
+	git p4 clone --use-client-spec --dest="$git" //depot
 '
 
-test_expect_success 'unsupported view wildcard *' '
+test_expect_success 'view wildcard *' '
 	client_view "//depot/*/bar/... //client/*/bar/..." &&
 	test_when_finished cleanup_git &&
-	test_must_fail git p4 clone --use-client-spec --dest="$git" //depot
+	git p4 clone --use-client-spec --dest="$git" //depot
 '
 
-test_expect_success 'wildcard ... only supported at end of spec 1' '
+test_expect_success 'wildcard ... in the middle' '
 	client_view "//depot/.../file11 //client/.../file11" &&
 	test_when_finished cleanup_git &&
-	test_must_fail git p4 clone --use-client-spec --dest="$git" //depot
+	git p4 clone --use-client-spec --dest="$git" //depot
 '
 
-test_expect_success 'wildcard ... only supported at end of spec 2' '
+test_expect_success 'wildcard ... in the middle and at the end' '
 	client_view "//depot/.../a/... //client/.../a/..." &&
 	test_when_finished cleanup_git &&
-	test_must_fail git p4 clone --use-client-spec --dest="$git" //depot
+	git p4 clone --use-client-spec --dest="$git" //depot
 '
 
 test_expect_success 'basic map' '
diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh
index 34fbc90..8134ab4 100755
--- a/t/t9810-git-p4-rcs.sh
+++ b/t/t9810-git-p4-rcs.sh
@@ -263,7 +263,7 @@
 		git config git-p4.attemptRCSCleanup true &&
 		(cd "$cli" && p4_append_to_file kwfile1.c) &&
 		old_lines=$(wc -l <kwfile1.c) &&
-		"$PERL_PATH" -n -i -e "print unless m/Revision:/" kwfile1.c &&
+		perl -n -i -e "print unless m/Revision:/" kwfile1.c &&
 		new_lines=$(wc -l <kwfile1.c) &&
 		test $new_lines = $(($old_lines - 1)) &&
 
diff --git a/t/t9812-git-p4-wildcards.sh b/t/t9812-git-p4-wildcards.sh
index 6763325..c7472cb 100755
--- a/t/t9812-git-p4-wildcards.sh
+++ b/t/t9812-git-p4-wildcards.sh
@@ -161,6 +161,56 @@
 	)
 '
 
+test_expect_success 'p4 deleted a wildcard file' '
+	(
+		cd "$cli" &&
+		echo "wild delete test" >wild@delete &&
+		p4 add -f wild@delete &&
+		p4 submit -d "add wild@delete"
+	) &&
+	test_when_finished cleanup_git &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		test_path_is_file wild@delete
+	) &&
+	(
+		cd "$cli" &&
+		# must use its encoded name
+		p4 delete wild%40delete &&
+		p4 submit -d "delete wild@delete"
+	) &&
+	(
+		cd "$git" &&
+		git p4 sync &&
+		git merge --ff-only p4/master &&
+		test_path_is_missing wild@delete
+	)
+'
+
+test_expect_success 'wildcard files requiring keyword scrub' '
+	(
+		cd "$cli" &&
+		cat <<-\EOF >scrub@wild &&
+		$Id$
+		line2
+		EOF
+		p4 add -t text+k -f scrub@wild &&
+		p4 submit -d "scrub at wild"
+	) &&
+	test_when_finished cleanup_git &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		git config git-p4.skipSubmitEdit true &&
+		git config git-p4.attemptRCSCleanup true &&
+		sed "s/^line2/line2 edit/" <scrub@wild >scrub@wild.tmp &&
+		mv -f scrub@wild.tmp scrub@wild &&
+		git commit -m "scrub at wild line2 edit" scrub@wild &&
+		git p4 submit
+	)
+'
+
 test_expect_success 'kill p4d' '
 	kill_p4d
 '
diff --git a/t/t9813-git-p4-preserve-users.sh b/t/t9813-git-p4-preserve-users.sh
index f2e85e5..166b840 100755
--- a/t/t9813-git-p4-preserve-users.sh
+++ b/t/t9813-git-p4-preserve-users.sh
@@ -19,16 +19,6 @@
 	)
 '
 
-p4_add_user() {
-	name=$1 fullname=$2 &&
-	p4 user -f -i <<-EOF &&
-	User: $name
-	Email: $name@localhost
-	FullName: $fullname
-	EOF
-	p4 passwd -P secret $name
-}
-
 p4_grant_admin() {
 	name=$1 &&
 	{
@@ -51,8 +41,8 @@
 
 # Test username support, submitting as user 'alice'
 test_expect_success 'preserve users' '
-	p4_add_user alice Alice &&
-	p4_add_user bob Bob &&
+	p4_add_user alice &&
+	p4_add_user bob &&
 	p4_grant_admin alice &&
 	git p4 clone --dest="$git" //depot &&
 	test_when_finished cleanup_git &&
@@ -60,8 +50,8 @@
 		cd "$git" &&
 		echo "username: a change by alice" >>file1 &&
 		echo "username: a change by bob" >>file2 &&
-		git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 &&
-		git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 &&
+		git commit --author "Alice <alice@example.com>" -m "a change by alice" file1 &&
+		git commit --author "Bob <bob@example.com>" -m "a change by bob" file2 &&
 		git config git-p4.skipSubmitEditCheck true &&
 		P4EDITOR=touch P4USER=alice P4PASSWD=secret git p4 commit --preserve-user &&
 		p4_check_commit_author file1 alice &&
@@ -78,7 +68,7 @@
 		cd "$git" &&
 		git config git-p4.skipSubmitEditCheck true &&
 		echo "username-noperms: a change by alice" >>file1 &&
-		git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 &&
+		git commit --author "Alice <alice@example.com>" -m "perms: a change by alice" file1 &&
 		P4EDITOR=touch P4USER=bob P4PASSWD=secret &&
 		export P4EDITOR P4USER P4PASSWD &&
 		test_must_fail git p4 commit --preserve-user &&
@@ -94,9 +84,9 @@
 		cd "$git" &&
 		git config git-p4.skipSubmitEditCheck true &&
 		echo "username-bob: a change by bob" >>file1 &&
-		git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 &&
+		git commit --author "Bob <bob@example.com>" -m "preserve: a change by bob" file1 &&
 		echo "username-unknown: a change by charlie" >>file1 &&
-		git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 &&
+		git commit --author "Charlie <charlie@example.com>" -m "preserve: a change by charlie" file1 &&
 		P4EDITOR=touch P4USER=alice P4PASSWD=secret &&
 		export P4EDITOR P4USER P4PASSWD &&
 		test_must_fail git p4 commit --preserve-user &&
@@ -121,24 +111,24 @@
 	(
 		cd "$git" &&
 		git config git-p4.skipSubmitEditCheck true &&
-		p4_add_user derek Derek &&
+		p4_add_user derek &&
 
-		make_change_by_user usernamefile3 Derek derek@localhost &&
+		make_change_by_user usernamefile3 Derek derek@example.com &&
 		P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
 		export P4EDITOR P4USER P4PASSWD &&
 		git p4 commit |\
-		grep "git author derek@localhost does not match" &&
+		grep "git author derek@example.com does not match" &&
 
-		make_change_by_user usernamefile3 Charlie charlie@localhost &&
+		make_change_by_user usernamefile3 Charlie charlie@example.com &&
 		git p4 commit |\
-		grep "git author charlie@localhost does not match" &&
+		grep "git author charlie@example.com does not match" &&
 
-		make_change_by_user usernamefile3 alice alice@localhost &&
+		make_change_by_user usernamefile3 alice alice@example.com &&
 		git p4 commit |\
 		test_must_fail grep "git author.*does not match" &&
 
 		git config git-p4.skipUserNameCheck true &&
-		make_change_by_user usernamefile3 Charlie charlie@localhost &&
+		make_change_by_user usernamefile3 Charlie charlie@example.com &&
 		git p4 commit |\
 		test_must_fail grep "git author.*does not match" &&
 
diff --git a/t/t9816-git-p4-locked.sh b/t/t9816-git-p4-locked.sh
new file mode 100755
index 0000000..e71e543
--- /dev/null
+++ b/t/t9816-git-p4-locked.sh
@@ -0,0 +1,145 @@
+#!/bin/sh
+
+test_description='git p4 locked file behavior'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+	start_p4d
+'
+
+# See
+# http://www.perforce.com/perforce/doc.current/manuals/p4sag/03_superuser.html#1088563
+# for suggestions on how to configure "sitewide pessimistic locking"
+# where only one person can have a file open for edit at a time.
+test_expect_success 'init depot' '
+	(
+		cd "$cli" &&
+		echo "TypeMap: +l //depot/..." | p4 typemap -i &&
+		echo file1 >file1 &&
+		p4 add file1 &&
+		p4 submit -d "add file1"
+	)
+'
+
+test_expect_success 'edit with lock not taken' '
+	test_when_finished cleanup_git &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		echo line2 >>file1 &&
+		git add file1 &&
+		git commit -m "line2 in file1" &&
+		git config git-p4.skipSubmitEdit true &&
+		git p4 submit
+	)
+'
+
+test_expect_failure 'add with lock not taken' '
+	test_when_finished cleanup_git &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		echo line1 >>add-lock-not-taken &&
+		git add file2 &&
+		git commit -m "add add-lock-not-taken" &&
+		git config git-p4.skipSubmitEdit true &&
+		git p4 submit --verbose
+	)
+'
+
+lock_in_another_client() {
+	# build a different client
+	cli2="$TRASH_DIRECTORY/cli2" &&
+	mkdir -p "$cli2" &&
+	test_when_finished "p4 client -f -d client2 && rm -rf \"$cli2\"" &&
+	(
+		cd "$cli2" &&
+		P4CLIENT=client2 &&
+		cli="$cli2" &&
+		client_view "//depot/... //client2/..." &&
+		p4 sync &&
+		p4 open file1
+	)
+}
+
+test_expect_failure 'edit with lock taken' '
+	lock_in_another_client &&
+	test_when_finished cleanup_git &&
+	test_when_finished "cd \"$cli\" && p4 sync -f file1" &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		echo line3 >>file1 &&
+		git add file1 &&
+		git commit -m "line3 in file1" &&
+		git config git-p4.skipSubmitEdit true &&
+		git p4 submit --verbose
+	)
+'
+
+test_expect_failure 'delete with lock taken' '
+	lock_in_another_client &&
+	test_when_finished cleanup_git &&
+	test_when_finished "cd \"$cli\" && p4 sync -f file1" &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		git rm file1 &&
+		git commit -m "delete file1" &&
+		git config git-p4.skipSubmitEdit true &&
+		git p4 submit --verbose
+	)
+'
+
+test_expect_failure 'chmod with lock taken' '
+	lock_in_another_client &&
+	test_when_finished cleanup_git &&
+	test_when_finished "cd \"$cli\" && p4 sync -f file1" &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		chmod +x file1 &&
+		git add file1 &&
+		git commit -m "chmod +x file1" &&
+		git config git-p4.skipSubmitEdit true &&
+		git p4 submit --verbose
+	)
+'
+
+test_expect_failure 'copy with lock taken' '
+	lock_in_another_client &&
+	test_when_finished cleanup_git &&
+	test_when_finished "cd \"$cli\" && p4 revert file2 && rm -f file2" &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		cp file1 file2 &&
+		git add file2 &&
+		git commit -m "cp file1 to file2" &&
+		git config git-p4.skipSubmitEdit true &&
+		git config git-p4.detectCopies true &&
+		git p4 submit --verbose
+	)
+'
+
+test_expect_failure 'move with lock taken' '
+	lock_in_another_client &&
+	test_when_finished cleanup_git &&
+	test_when_finished "cd \"$cli\" && p4 sync file1 && rm -f file2" &&
+	git p4 clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		git mv file1 file2 &&
+		git commit -m "mv file1 to file2" &&
+		git config git-p4.skipSubmitEdit true &&
+		git config git-p4.detectRenames true &&
+		git p4 submit --verbose
+	)
+'
+
+test_expect_success 'kill p4d' '
+	kill_p4d
+'
+
+test_done
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index 3c3e4e8..59f875e 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -61,6 +61,29 @@
 	test_cmp expected "$actual"
 '
 
+repo_with_newline='repo
+with
+newline'
+
+if mkdir "$repo_with_newline" 2>/dev/null
+then
+	test_set_prereq FUNNYNAMES
+else
+	say 'Your filesystem does not allow newlines in filenames.'
+fi
+
+test_expect_success FUNNYNAMES 'prompt - with newline in path' '
+	printf " (master)" >expected &&
+	git init "$repo_with_newline" &&
+	test_when_finished "rm -rf \"$repo_with_newline\"" &&
+	mkdir "$repo_with_newline"/subdir &&
+	(
+		cd "$repo_with_newline/subdir" &&
+		__git_ps1 >"$actual"
+	) &&
+	test_cmp expected "$actual"
+'
+
 test_expect_success 'prompt - detached head' '
 	printf " ((%s...))" $(git log -1 --format="%h" --abbrev=13 b1^) >expected &&
 	test_config core.abbrev 13 &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index a7e9aac..aeae3ca 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1,4 +1,5 @@
-#!/bin/sh
+# Library of functions shared by all tests scripts, included by
+# test-lib.sh.
 #
 # Copyright (c) 2005 Junio C Hamano
 #
@@ -76,11 +77,11 @@
 }
 
 nul_to_q () {
-	"$PERL_PATH" -pe 'y/\000/Q/'
+	perl -pe 'y/\000/Q/'
 }
 
 q_to_nul () {
-	"$PERL_PATH" -pe 'y/Q/\000/'
+	perl -pe 'y/Q/\000/'
 }
 
 q_to_cr () {
@@ -648,7 +649,7 @@
 	2)	;;
 	*)	error "bug in the test script: not 1 or 2 parameters to test_seq" ;;
 	esac
-	"$PERL_PATH" -le 'print for $ARGV[0]..$ARGV[1]' -- "$@"
+	perl -le 'print for $ARGV[0]..$ARGV[1]' -- "$@"
 }
 
 # This function can be used to schedule some commands to be run
@@ -710,3 +711,73 @@
 		git update-index --add --cacheinfo 120000 $ln_s_obj "$2"
 	fi
 }
+
+perl () {
+	command "$PERL_PATH" "$@"
+}
+
+# The following mingw_* functions obey POSIX shell syntax, but are actually
+# bash scripts, and are meant to be used only with bash on Windows.
+
+# A test_cmp function that treats LF and CRLF equal and avoids to fork
+# diff when possible.
+mingw_test_cmp () {
+	# Read text into shell variables and compare them. If the results
+	# are different, use regular diff to report the difference.
+	local test_cmp_a= test_cmp_b=
+
+	# When text came from stdin (one argument is '-') we must feed it
+	# to diff.
+	local stdin_for_diff=
+
+	# Since it is difficult to detect the difference between an
+	# empty input file and a failure to read the files, we go straight
+	# to diff if one of the inputs is empty.
+	if test -s "$1" && test -s "$2"
+	then
+		# regular case: both files non-empty
+		mingw_read_file_strip_cr_ test_cmp_a <"$1"
+		mingw_read_file_strip_cr_ test_cmp_b <"$2"
+	elif test -s "$1" && test "$2" = -
+	then
+		# read 2nd file from stdin
+		mingw_read_file_strip_cr_ test_cmp_a <"$1"
+		mingw_read_file_strip_cr_ test_cmp_b
+		stdin_for_diff='<<<"$test_cmp_b"'
+	elif test "$1" = - && test -s "$2"
+	then
+		# read 1st file from stdin
+		mingw_read_file_strip_cr_ test_cmp_a
+		mingw_read_file_strip_cr_ test_cmp_b <"$2"
+		stdin_for_diff='<<<"$test_cmp_a"'
+	fi
+	test -n "$test_cmp_a" &&
+	test -n "$test_cmp_b" &&
+	test "$test_cmp_a" = "$test_cmp_b" ||
+	eval "diff -u \"\$@\" $stdin_for_diff"
+}
+
+# $1 is the name of the shell variable to fill in
+mingw_read_file_strip_cr_ () {
+	# Read line-wise using LF as the line separator
+	# and use IFS to strip CR.
+	local line
+	while :
+	do
+		if IFS=$'\r' read -r -d $'\n' line
+		then
+			# good
+			line=$line$'\n'
+		else
+			# we get here at EOF, but also if the last line
+			# was not terminated by LF; in the latter case,
+			# some text was read
+			if test -z "$line"
+			then
+				# EOF, really
+				break
+			fi
+		fi
+		eval "$1=\$$1\$line"
+	done
+}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index c5e914a..1531c24 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+# Test framework for git.  See t/README for usage.
 #
 # Copyright (c) 2005 Junio C Hamano
 #
@@ -26,6 +26,10 @@
 	# outside of t/, e.g. for running tests on the test library
 	# itself.
 	TEST_DIRECTORY=$(pwd)
+else
+	# ensure that TEST_DIRECTORY is an absolute path so that it
+	# is valid even if the current working directory is changed
+	TEST_DIRECTORY=$(cd "$TEST_DIRECTORY" && pwd) || exit 1
 fi
 if test -z "$TEST_OUTPUT_DIRECTORY"
 then
@@ -205,29 +209,17 @@
 	--valgrind-only=*)
 		valgrind_only=$(expr "z$1" : 'z[^=]*=\(.*\)')
 		shift ;;
-	--valgrind-parallel=*)
-		valgrind_parallel=$(expr "z$1" : 'z[^=]*=\(.*\)')
-		shift ;;
-	--valgrind-only-stride=*)
-		valgrind_only_stride=$(expr "z$1" : 'z[^=]*=\(.*\)')
-		shift ;;
-	--valgrind-only-offset=*)
-		valgrind_only_offset=$(expr "z$1" : 'z[^=]*=\(.*\)')
-		shift ;;
 	--tee)
 		shift ;; # was handled already
 	--root=*)
 		root=$(expr "z$1" : 'z[^=]*=\(.*\)')
 		shift ;;
-	--statusprefix=*)
-		statusprefix=$(expr "z$1" : 'z[^=]*=\(.*\)')
-		shift ;;
 	*)
 		echo "error: unknown test option '$1'" >&2; exit 1 ;;
 	esac
 done
 
-if test -n "$valgrind_only" || test -n "$valgrind_only_stride"
+if test -n "$valgrind_only"
 then
 	test -z "$valgrind" && valgrind=memcheck
 	test -z "$verbose" && verbose_only="$valgrind_only"
@@ -329,12 +321,12 @@
 
 test_ok_ () {
 	test_success=$(($test_success + 1))
-	say_color "" "${statusprefix}ok $test_count - $@"
+	say_color "" "ok $test_count - $@"
 }
 
 test_failure_ () {
 	test_failure=$(($test_failure + 1))
-	say_color error "${statusprefix}not ok $test_count - $1"
+	say_color error "not ok $test_count - $1"
 	shift
 	echo "$@" | sed -e 's/^/#	/'
 	test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
@@ -342,12 +334,12 @@
 
 test_known_broken_ok_ () {
 	test_fixed=$(($test_fixed+1))
-	say_color error "${statusprefix}ok $test_count - $@ # TODO known breakage vanished"
+	say_color error "ok $test_count - $@ # TODO known breakage vanished"
 }
 
 test_known_broken_failure_ () {
 	test_broken=$(($test_broken+1))
-	say_color warn "${statusprefix}not ok $test_count - $@ # TODO known breakage"
+	say_color warn "not ok $test_count - $@ # TODO known breakage"
 }
 
 test_debug () {
@@ -377,9 +369,7 @@
 last_verbose=t
 maybe_setup_verbose () {
 	test -z "$verbose_only" && return
-	if match_pattern_list $test_count $verbose_only ||
-		{ test -n "$valgrind_only_stride" &&
-		expr $test_count "%" $valgrind_only_stride - $valgrind_only_offset = 0 >/dev/null; }
+	if match_pattern_list $test_count $verbose_only
 	then
 		exec 4>&2 3>&1
 		# Emit a delimiting blank line when going from
@@ -403,7 +393,7 @@
 
 maybe_setup_valgrind () {
 	test -z "$GIT_VALGRIND" && return
-	if test -z "$valgrind_only" && test -z "$valgrind_only_stride"
+	if test -z "$valgrind_only"
 	then
 		GIT_VALGRIND_ENABLED=t
 		return
@@ -412,10 +402,6 @@
 	if match_pattern_list $test_count $valgrind_only
 	then
 		GIT_VALGRIND_ENABLED=t
-	elif test -n "$valgrind_only_stride" &&
-		expr $test_count "%" $valgrind_only_stride - $valgrind_only_offset = 0 >/dev/null
-	then
-		GIT_VALGRIND_ENABLED=t
 	fi
 }
 
@@ -477,8 +463,8 @@
 			of_prereq=" of $test_prereq"
 		fi
 
-		say_color skip >&3 "${statusprefix}skipping test: $@"
-		say_color skip "${statusprefix}ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
+		say_color skip >&3 "skipping test: $@"
+		say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
 		: true
 		;;
 	*)
@@ -495,8 +481,6 @@
 test_done () {
 	GIT_EXIT_OK=t
 
-	# Note: t0000 relies on $HARNESS_ACTIVE disabling the .counts
-	# output file
 	if test -z "$HARNESS_ACTIVE"
 	then
 		test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
@@ -516,11 +500,11 @@
 
 	if test "$test_fixed" != 0
 	then
-		say_color error "${statusprefix}# $test_fixed known breakage(s) vanished; please update test(s)"
+		say_color error "# $test_fixed known breakage(s) vanished; please update test(s)"
 	fi
 	if test "$test_broken" != 0
 	then
-		say_color warn "${statusprefix}# still have $test_broken known breakage(s)"
+		say_color warn "# still have $test_broken known breakage(s)"
 	fi
 	if test "$test_broken" != 0 || test "$test_fixed" != 0
 	then
@@ -543,9 +527,9 @@
 		then
 			if test $test_remaining -gt 0
 			then
-				say_color pass "${statusprefix}# passed all $msg"
+				say_color pass "# passed all $msg"
 			fi
-			say "${statusprefix}1..$test_count$skip_all"
+			say "1..$test_count$skip_all"
 		fi
 
 		test -d "$remove_trash" &&
@@ -559,8 +543,8 @@
 	*)
 		if test $test_external_has_tap -eq 0
 		then
-			say_color error "${statusprefix}# failed $test_failure among $msg"
-			say "${statusprefix}1..$test_count"
+			say_color error "# failed $test_failure among $msg"
+			say "1..$test_count"
 		fi
 
 		exit 1 ;;
@@ -568,9 +552,6 @@
 	esac
 }
 
-
-# Set up a directory that we can put in PATH which redirects all git
-# calls to 'valgrind git ...'.
 if test -n "$valgrind"
 then
 	make_symlink () {
@@ -594,11 +575,9 @@
 
 	make_valgrind_symlink () {
 		# handle only executables, unless they are shell libraries that
-		# need to be in the exec-path.  We will just use "#!" as a
-		# guess for a shell-script, since we have no idea what the user
-		# may have configured as the shell path.
+		# need to be in the exec-path.
 		test -x "$1" ||
-		test "#!" = "$(head -c 2 <"$1")" ||
+		test "# " = "$(head -c 2 <"$1")" ||
 		return;
 
 		base=$(basename "$1")
@@ -618,42 +597,33 @@
 		make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
 	}
 
-	# In the case of --valgrind-parallel, we only need to do the
-	# wrapping once, in the main script.  The worker children all
-	# have $valgrind_only_stride set, so we can skip based on that.
-	if test -z "$valgrind_only_stride"
-	then
-		# override all git executables in TEST_DIRECTORY/..
-		GIT_VALGRIND=$TEST_DIRECTORY/valgrind
-		mkdir -p "$GIT_VALGRIND"/bin
-		for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
+	# override all git executables in TEST_DIRECTORY/..
+	GIT_VALGRIND=$TEST_DIRECTORY/valgrind
+	mkdir -p "$GIT_VALGRIND"/bin
+	for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
+	do
+		make_valgrind_symlink $file
+	done
+	# special-case the mergetools loadables
+	make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
+	OLDIFS=$IFS
+	IFS=:
+	for path in $PATH
+	do
+		ls "$path"/git-* 2> /dev/null |
+		while read file
 		do
-			make_valgrind_symlink $file
+			make_valgrind_symlink "$file"
 		done
-		# special-case the mergetools loadables
-		make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
-		OLDIFS=$IFS
-		IFS=:
-		for path in $PATH
-		do
-			ls "$path"/git-* 2> /dev/null |
-			while read file
-			do
-				make_valgrind_symlink "$file"
-			done
-		done
-		IFS=$OLDIFS
-	fi
+	done
+	IFS=$OLDIFS
 	PATH=$GIT_VALGRIND/bin:$PATH
 	GIT_EXEC_PATH=$GIT_VALGRIND/bin
 	export GIT_VALGRIND
 	GIT_VALGRIND_MODE="$valgrind"
 	export GIT_VALGRIND_MODE
 	GIT_VALGRIND_ENABLED=t
-	if test -n "$valgrind_only" || test -n "$valgrind_only_stride"
-	then
-		GIT_VALGRIND_ENABLED=
-	fi
+	test -n "$valgrind_only" && GIT_VALGRIND_ENABLED=
 	export GIT_VALGRIND_ENABLED
 elif test -n "$GIT_TEST_INSTALLED"
 then
@@ -700,15 +670,6 @@
 	error "You haven't built things yet, have you?"
 }
 
-if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON"
-then
-	GITPYTHONLIB="$GIT_BUILD_DIR/git_remote_helpers/build/lib"
-	export GITPYTHONLIB
-	test -d "$GIT_BUILD_DIR"/git_remote_helpers/build || {
-		error "You haven't built git_remote_helpers yet, have you?"
-	}
-fi
-
 if ! test -x "$GIT_BUILD_DIR"/test-chmtime
 then
 	echo >&2 'You need to build test-chmtime:'
@@ -739,41 +700,6 @@
 else
 	mkdir -p "$TRASH_DIRECTORY"
 fi
-
-# Gross hack to spawn N sub-instances of the tests in parallel, and
-# summarize the results.  Note that if this is enabled, the script
-# terminates at the end of this 'if' block.
-if test -n "$valgrind_parallel"
-then
-	for i in $(test_seq 1 $valgrind_parallel)
-	do
-		root="$TRASH_DIRECTORY/vgparallel-$i"
-		mkdir "$root"
-		TEST_OUTPUT_DIRECTORY="$root" \
-			${SHELL_PATH} "$0" \
-			--root="$root" --statusprefix="[$i] " \
-			--valgrind="$valgrind" \
-			--valgrind-only-stride="$valgrind_parallel" \
-			--valgrind-only-offset="$i" &
-		pids="$pids $!"
-	done
-	trap "kill $pids" INT TERM HUP
-	wait $pids
-	trap - INT TERM HUP
-	for i in $(test_seq 1 $valgrind_parallel)
-	do
-		root="$TRASH_DIRECTORY/vgparallel-$i"
-		eval "$(cat "$root/test-results/$(basename "$0" .sh)"-*.counts |
-			sed 's/^\([a-z][a-z]*\) \([0-9][0-9]*\)/inner_\1=\2/')"
-		test_count=$(expr $test_count + $inner_total)
-		test_success=$(expr $test_success + $inner_success)
-		test_fixed=$(expr $test_fixed + $inner_fixed)
-		test_broken=$(expr $test_broken + $inner_broken)
-		test_failure=$(expr $test_failure + $inner_failed)
-	done
-	test_done
-fi
-
 # Use -P to resolve symlinks in our working directory so that the cwd
 # in subprocesses like git equals our $PWD (for pathname comparisons).
 cd -P "$TRASH_DIRECTORY" || exit 1
@@ -826,6 +752,7 @@
 	test_set_prereq NOT_CYGWIN
 	test_set_prereq SED_STRIPS_CR
 	test_set_prereq GREP_STRIPS_CR
+	GIT_TEST_CMP=mingw_test_cmp
 	;;
 *CYGWIN*)
 	test_set_prereq POSIXPERM
@@ -903,6 +830,10 @@
 	ln -s x y && test -h y
 '
 
+test_lazy_prereq FILEMODE '
+	test "$(git config --bool core.filemode)" = true
+'
+
 test_lazy_prereq CASE_INSENSITIVE_FS '
 	echo good >CamelCase &&
 	echo bad >camelcase &&
diff --git a/tag.c b/tag.c
index 78d272b..7b07921 100644
--- a/tag.c
+++ b/tag.c
@@ -86,7 +86,7 @@
 		return -1;
 	bufptr += 48; /* "object " + sha1 + "\n" */
 
-	if (prefixcmp(bufptr, "type "))
+	if (!starts_with(bufptr, "type "))
 		return -1;
 	bufptr += 5;
 	nl = memchr(bufptr, '\n', tail - bufptr);
@@ -109,7 +109,7 @@
 		item->tagged = NULL;
 	}
 
-	if (bufptr + 4 < tail && !prefixcmp(bufptr, "tag "))
+	if (bufptr + 4 < tail && starts_with(bufptr, "tag "))
 		; 		/* good */
 	else
 		return -1;
@@ -120,7 +120,7 @@
 	item->tag = xmemdupz(bufptr, nl - bufptr);
 	bufptr = nl + 1;
 
-	if (bufptr + 7 < tail && !prefixcmp(bufptr, "tagger "))
+	if (bufptr + 7 < tail && starts_with(bufptr, "tagger "))
 		item->date = parse_tag_date(bufptr, tail);
 	else
 		item->date = 0;
@@ -160,8 +160,8 @@
 {
 	char *eol;
 	size_t len = 0;
-	while (len < size && prefixcmp(buf + len, PGP_SIGNATURE) &&
-			prefixcmp(buf + len, PGP_MESSAGE)) {
+	while (len < size && !starts_with(buf + len, PGP_SIGNATURE) &&
+			!starts_with(buf + len, PGP_MESSAGE)) {
 		eol = memchr(buf + len, '\n', size - len);
 		len += eol ? eol - (buf + len) + 1 : size - len;
 	}
diff --git a/templates/hooks--pre-commit.sample b/templates/hooks--pre-commit.sample
index 586e3bf..68d62d5 100755
--- a/templates/hooks--pre-commit.sample
+++ b/templates/hooks--pre-commit.sample
@@ -16,7 +16,7 @@
 fi
 
 # If you want to allow non-ASCII filenames set this variable to true.
-allownonascii=$(git config hooks.allownonascii)
+allownonascii=$(git config --bool hooks.allownonascii)
 
 # Redirect output to stderr.
 exec 1>&2
diff --git a/test-line-buffer.c b/test-line-buffer.c
index ef1d7ba..1e58f04 100644
--- a/test-line-buffer.c
+++ b/test-line-buffer.c
@@ -19,7 +19,7 @@
 {
 	switch (*command) {
 	case 'b':
-		if (!prefixcmp(command, "binary ")) {
+		if (starts_with(command, "binary ")) {
 			struct strbuf sb = STRBUF_INIT;
 			strbuf_addch(&sb, '>');
 			buffer_read_binary(buf, &sb, strtouint32(arg));
@@ -28,12 +28,12 @@
 			return;
 		}
 	case 'c':
-		if (!prefixcmp(command, "copy ")) {
+		if (starts_with(command, "copy ")) {
 			buffer_copy_bytes(buf, strtouint32(arg));
 			return;
 		}
 	case 's':
-		if (!prefixcmp(command, "skip ")) {
+		if (starts_with(command, "skip ")) {
 			buffer_skip_bytes(buf, strtouint32(arg));
 			return;
 		}
diff --git a/test-match-trees.c b/test-match-trees.c
index a3c4688..2ef725e 100644
--- a/test-match-trees.c
+++ b/test-match-trees.c
@@ -12,10 +12,10 @@
 		die("cannot parse %s as an object name", av[2]);
 	one = parse_tree_indirect(hash1);
 	if (!one)
-		die("not a treeish %s", av[1]);
+		die("not a tree-ish %s", av[1]);
 	two = parse_tree_indirect(hash2);
 	if (!two)
-		die("not a treeish %s", av[2]);
+		die("not a tree-ish %s", av[2]);
 
 	shift_tree(one->object.sha1, two->object.sha1, shifted, -1);
 	printf("shifted: %s\n", sha1_to_hex(shifted));
diff --git a/test-path-utils.c b/test-path-utils.c
index bb975e4..3dd3744 100644
--- a/test-path-utils.c
+++ b/test-path-utils.c
@@ -116,7 +116,7 @@
 		return 0;
 	}
 
-	if (argc == 3 && !strcmp(argv[1], "mingw_path")) {
+	if (argc == 3 && !strcmp(argv[1], "print_path")) {
 		puts(argv[2]);
 		return 0;
 	}
diff --git a/test-sha1.c b/test-sha1.c
index 80daba9..e57eae1 100644
--- a/test-sha1.c
+++ b/test-sha1.c
@@ -5,10 +5,15 @@
 	git_SHA_CTX ctx;
 	unsigned char sha1[20];
 	unsigned bufsz = 8192;
+	int binary = 0;
 	char *buffer;
 
-	if (ac == 2)
-		bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024;
+	if (ac == 2) {
+		if (!strcmp(av[1], "-b"))
+			binary = 1;
+		else
+			bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024;
+	}
 
 	if (!bufsz)
 		bufsz = 8192;
@@ -42,6 +47,10 @@
 		git_SHA1_Update(&ctx, buffer, this_sz);
 	}
 	git_SHA1_Final(sha1, &ctx);
-	puts(sha1_to_hex(sha1));
+
+	if (binary)
+		fwrite(sha1, 1, 20, stdout);
+	else
+		puts(sha1_to_hex(sha1));
 	exit(0);
 }
diff --git a/test-string-list.c b/test-string-list.c
index 00ce6c9..14bdf9d 100644
--- a/test-string-list.c
+++ b/test-string-list.c
@@ -38,7 +38,7 @@
 static int prefix_cb(struct string_list_item *item, void *cb_data)
 {
 	const char *prefix = (const char *)cb_data;
-	return !prefixcmp(item->string, prefix);
+	return starts_with(item->string, prefix);
 }
 
 int main(int argc, char **argv)
diff --git a/test-urlmatch-normalization.c b/test-urlmatch-normalization.c
new file mode 100644
index 0000000..090bf21
--- /dev/null
+++ b/test-urlmatch-normalization.c
@@ -0,0 +1,50 @@
+#include "git-compat-util.h"
+#include "urlmatch.h"
+
+int main(int argc, char **argv)
+{
+	const char usage[] = "test-urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
+	char *url1, *url2;
+	int opt_p = 0, opt_l = 0;
+
+	/*
+	 * For one url, succeed if url_normalize succeeds on it, fail otherwise.
+	 * For two urls, succeed only if url_normalize succeeds on both and
+	 * the results compare equal with strcmp.  If -p is given (one url only)
+	 * and url_normalize succeeds, print the result followed by "\n".  If
+	 * -l is given (one url only) and url_normalize succeeds, print the
+	 * returned length in decimal followed by "\n".
+	 */
+
+	if (argc > 1 && !strcmp(argv[1], "-p")) {
+		opt_p = 1;
+		argc--;
+		argv++;
+	} else if (argc > 1 && !strcmp(argv[1], "-l")) {
+		opt_l = 1;
+		argc--;
+		argv++;
+	}
+
+	if (argc < 2 || argc > 3)
+		die("%s", usage);
+
+	if (argc == 2) {
+		struct url_info info;
+		url1 = url_normalize(argv[1], &info);
+		if (!url1)
+			return 1;
+		if (opt_p)
+			printf("%s\n", url1);
+		if (opt_l)
+			printf("%u\n", (unsigned)info.url_len);
+		return 0;
+	}
+
+	if (opt_p || opt_l)
+		die("%s", usage);
+
+	url1 = url_normalize(argv[1], NULL);
+	url2 = url_normalize(argv[2], NULL);
+	return (url1 && url2 && !strcmp(url1, url2)) ? 0 : 1;
+}
diff --git a/trace.c b/trace.c
index 3d744d1..08180a9 100644
--- a/trace.c
+++ b/trace.c
@@ -76,7 +76,7 @@
 }
 
 __attribute__((format (printf, 2, 3)))
-static void trace_printf_key(const char *key, const char *fmt, ...)
+void trace_printf_key(const char *key, const char *fmt, ...)
 {
 	va_list ap;
 	va_start(ap, fmt);
diff --git a/transport-helper.c b/transport-helper.c
index 63cabc3..ad72fbd 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -27,7 +27,9 @@
 		push : 1,
 		connect : 1,
 		signed_tags : 1,
-		no_disconnect_req : 1;
+		check_connectivity : 1,
+		no_disconnect_req : 1,
+		no_private_update : 1;
 	char *export_marks;
 	char *import_marks;
 	/* These go from remote name (as in "list") to private name */
@@ -186,7 +188,9 @@
 			data->bidi_import = 1;
 		else if (!strcmp(capname, "export"))
 			data->export = 1;
-		else if (!data->refspecs && !prefixcmp(capname, "refspec ")) {
+		else if (!strcmp(capname, "check-connectivity"))
+			data->check_connectivity = 1;
+		else if (!data->refspecs && starts_with(capname, "refspec ")) {
 			ALLOC_GROW(refspecs,
 				   refspec_nr + 1,
 				   refspec_alloc);
@@ -195,16 +199,18 @@
 			data->connect = 1;
 		} else if (!strcmp(capname, "signed-tags")) {
 			data->signed_tags = 1;
-		} else if (!prefixcmp(capname, "export-marks ")) {
+		} else if (starts_with(capname, "export-marks ")) {
 			struct strbuf arg = STRBUF_INIT;
 			strbuf_addstr(&arg, "--export-marks=");
 			strbuf_addstr(&arg, capname + strlen("export-marks "));
 			data->export_marks = strbuf_detach(&arg, NULL);
-		} else if (!prefixcmp(capname, "import-marks")) {
+		} else if (starts_with(capname, "import-marks")) {
 			struct strbuf arg = STRBUF_INIT;
 			strbuf_addstr(&arg, "--import-marks=");
 			strbuf_addstr(&arg, capname + strlen("import-marks "));
 			data->import_marks = strbuf_detach(&arg, NULL);
+		} else if (starts_with(capname, "no-private-update")) {
+			data->no_private_update = 1;
 		} else if (mandatory) {
 			die("Unknown mandatory capability %s. This remote "
 			    "helper probably needs newer version of Git.",
@@ -263,6 +269,7 @@
 	TRANS_OPT_THIN,
 	TRANS_OPT_KEEP
 	};
+
 static const char *boolean_options[] = {
 	TRANS_OPT_THIN,
 	TRANS_OPT_KEEP,
@@ -304,7 +311,7 @@
 
 	if (!strcmp(buf.buf, "ok"))
 		ret = 0;
-	else if (!prefixcmp(buf.buf, "error")) {
+	else if (starts_with(buf.buf, "error")) {
 		ret = -1;
 	} else if (!strcmp(buf.buf, "unsupported"))
 		ret = 1;
@@ -349,6 +356,15 @@
 	struct strbuf buf = STRBUF_INIT;
 
 	standard_options(transport);
+	if (data->check_connectivity &&
+	    data->transport_options.check_self_contained_and_connected)
+		set_helper_option(transport, "check-connectivity", "true");
+
+	if (transport->cloning)
+		set_helper_option(transport, "cloning", "true");
+
+	if (data->transport_options.update_shallow)
+		set_helper_option(transport, "update-shallow", "true");
 
 	for (i = 0; i < nr_heads; i++) {
 		const struct ref *posn = to_fetch[i];
@@ -365,13 +381,17 @@
 	while (1) {
 		recvline(data, &buf);
 
-		if (!prefixcmp(buf.buf, "lock ")) {
+		if (starts_with(buf.buf, "lock ")) {
 			const char *name = buf.buf + 5;
 			if (transport->pack_lockfile)
 				warning("%s also locked %s", data->name, name);
 			else
 				transport->pack_lockfile = xstrdup(name);
 		}
+		else if (data->check_connectivity &&
+			 data->transport_options.check_self_contained_and_connected &&
+			 !strcmp(buf.buf, "connectivity-ok"))
+			data->transport_options.self_contained_and_connected = 1;
 		else if (!buf.len)
 			break;
 		else
@@ -632,10 +652,10 @@
 	char *refname, *msg;
 	int status;
 
-	if (!prefixcmp(buf->buf, "ok ")) {
+	if (starts_with(buf->buf, "ok ")) {
 		status = REF_STATUS_OK;
 		refname = buf->buf + 3;
-	} else if (!prefixcmp(buf->buf, "error ")) {
+	} else if (starts_with(buf->buf, "error ")) {
 		status = REF_STATUS_REMOTE_REJECT;
 		refname = buf->buf + 6;
 	} else
@@ -683,6 +703,11 @@
 			free(msg);
 			msg = NULL;
 		}
+		else if (!strcmp(msg, "stale info")) {
+			status = REF_STATUS_REJECT_STALE;
+			free(msg);
+			msg = NULL;
+		}
 	}
 
 	if (*ref)
@@ -723,7 +748,7 @@
 		if (push_update_ref_status(&buf, &ref, remote_refs))
 			continue;
 
-		if (!data->refspecs)
+		if (!data->refspecs || data->no_private_update)
 			continue;
 
 		/* propagate back the update to the remote namespace */
@@ -737,13 +762,15 @@
 }
 
 static int push_refs_with_push(struct transport *transport,
-		struct ref *remote_refs, int flags)
+			       struct ref *remote_refs, int flags)
 {
 	int force_all = flags & TRANSPORT_PUSH_FORCE;
 	int mirror = flags & TRANSPORT_PUSH_MIRROR;
 	struct helper_data *data = transport->data;
 	struct strbuf buf = STRBUF_INIT;
 	struct ref *ref;
+	struct string_list cas_options = STRING_LIST_INIT_DUP;
+	struct string_list_item *cas_option;
 
 	get_helper(transport);
 	if (!data->push)
@@ -756,6 +783,7 @@
 		/* Check for statuses set by set_ref_status_for_push() */
 		switch (ref->status) {
 		case REF_STATUS_REJECT_NONFASTFORWARD:
+		case REF_STATUS_REJECT_STALE:
 		case REF_STATUS_REJECT_ALREADY_EXISTS:
 		case REF_STATUS_UPTODATE:
 			continue;
@@ -778,11 +806,29 @@
 		strbuf_addch(&buf, ':');
 		strbuf_addstr(&buf, ref->name);
 		strbuf_addch(&buf, '\n');
+
+		/*
+		 * The "--force-with-lease" options without explicit
+		 * values to expect have already been expanded into
+		 * the ref->old_sha1_expect[] field; we can ignore
+		 * transport->smart_options->cas altogether and instead
+		 * can enumerate them from the refs.
+		 */
+		if (ref->expect_old_sha1) {
+			struct strbuf cas = STRBUF_INIT;
+			strbuf_addf(&cas, "%s:%s",
+				    ref->name, sha1_to_hex(ref->old_sha1_expect));
+			string_list_append(&cas_options, strbuf_detach(&cas, NULL));
+		}
 	}
-	if (buf.len == 0)
+	if (buf.len == 0) {
+		string_list_clear(&cas_options, 0);
 		return 0;
+	}
 
 	standard_options(transport);
+	for_each_string_list_item(cas_option, &cas_options)
+		set_helper_option(transport, "cas", cas_option->string);
 
 	if (flags & TRANSPORT_PUSH_DRY_RUN) {
 		if (set_helper_option(transport, "dry-run", "true") != 0)
@@ -1089,9 +1135,8 @@
 		return 0;	/* Nothing to write. */
 
 	transfer_debug("%s is writable", t->dest_name);
-	bytes = write(t->dest, t->buf, t->bufuse);
-	if (bytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN &&
-		errno != EINTR) {
+	bytes = xwrite(t->dest, t->buf, t->bufuse);
+	if (bytes < 0 && errno != EWOULDBLOCK) {
 		error("write(%s) failed: %s", t->dest_name, strerror(errno));
 		return -1;
 	} else if (bytes > 0) {
diff --git a/transport.c b/transport.c
index de25588..ca7bb44 100644
--- a/transport.c
+++ b/transport.c
@@ -3,6 +3,8 @@
 #include "run-command.h"
 #include "pkt-line.h"
 #include "fetch-pack.h"
+#include "remote.h"
+#include "connect.h"
 #include "send-pack.h"
 #include "walker.h"
 #include "bundle.h"
@@ -12,6 +14,7 @@
 #include "url.h"
 #include "submodule.h"
 #include "string-list.h"
+#include "sha1-array.h"
 
 /* rsync support */
 
@@ -167,13 +170,13 @@
 		remotename = ref->name;
 		tmp = resolve_ref_unsafe(localname, sha, 1, &flag);
 		if (tmp && flag & REF_ISSYMREF &&
-			!prefixcmp(tmp, "refs/heads/"))
+			starts_with(tmp, "refs/heads/"))
 			localname = tmp;
 
 		/* Both source and destination must be local branches. */
-		if (!localname || prefixcmp(localname, "refs/heads/"))
+		if (!localname || !starts_with(localname, "refs/heads/"))
 			continue;
-		if (!remotename || prefixcmp(remotename, "refs/heads/"))
+		if (!remotename || !starts_with(remotename, "refs/heads/"))
 			continue;
 
 		if (!pretend)
@@ -189,7 +192,7 @@
 
 static const char *rsync_url(const char *url)
 {
-	return prefixcmp(url, "rsync://") ? skip_prefix(url, "rsync:") : url;
+	return !starts_with(url, "rsync://") ? skip_prefix(url, "rsync:") : url;
 }
 
 static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)
@@ -294,8 +297,8 @@
 	FILE *f;
 
 	/* when called via for_each_ref(), flags is non-zero */
-	if (flags && prefixcmp(name, "refs/heads/") &&
-			prefixcmp(name, "refs/tags/"))
+	if (flags && !starts_with(name, "refs/heads/") &&
+			!starts_with(name, "refs/tags/"))
 		return 0;
 
 	strbuf_addstr(buf, name);
@@ -452,7 +455,8 @@
 	struct child_process *conn;
 	int fd[2];
 	unsigned got_remote_heads : 1;
-	struct extra_have_objects extra_have;
+	struct sha1_array extra_have;
+	struct sha1_array shallow;
 };
 
 static int set_git_option(struct git_transport_options *opts,
@@ -473,6 +477,9 @@
 	} else if (!strcmp(name, TRANS_OPT_KEEP)) {
 		opts->keep = !!value;
 		return 0;
+	} else if (!strcmp(name, TRANS_OPT_UPDATE_SHALLOW)) {
+		opts->update_shallow = !!value;
+		return 0;
 	} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
 		if (!value)
 			opts->depth = 0;
@@ -509,7 +516,9 @@
 
 	connect_setup(transport, for_push, 0);
 	get_remote_heads(data->fd[0], NULL, 0, &refs,
-			 for_push ? REF_NORMAL : 0, &data->extra_have);
+			 for_push ? REF_NORMAL : 0,
+			 &data->extra_have,
+			 &data->shallow);
 	data->got_remote_heads = 1;
 
 	return refs;
@@ -536,16 +545,19 @@
 	args.depth = data->options.depth;
 	args.check_self_contained_and_connected =
 		data->options.check_self_contained_and_connected;
+	args.cloning = transport->cloning;
+	args.update_shallow = data->options.update_shallow;
 
 	if (!data->got_remote_heads) {
 		connect_setup(transport, 0, 0);
-		get_remote_heads(data->fd[0], NULL, 0, &refs_tmp, 0, NULL);
+		get_remote_heads(data->fd[0], NULL, 0, &refs_tmp, 0,
+				 NULL, &data->shallow);
 		data->got_remote_heads = 1;
 	}
 
 	refs = fetch_pack(&args, data->fd, data->conn,
 			  refs_tmp ? refs_tmp : transport->remote_refs,
-			  dest, to_fetch, nr_heads,
+			  dest, to_fetch, nr_heads, &data->shallow,
 			  &transport->pack_lockfile);
 	close(data->fd[0]);
 	close(data->fd[1]);
@@ -650,7 +662,7 @@
 		print_ref_status('-', "[deleted]", ref, NULL, NULL, porcelain);
 	else if (is_null_sha1(ref->old_sha1))
 		print_ref_status('*',
-			(!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" :
+			(starts_with(ref->name, "refs/tags/") ? "[new tag]" :
 			"[new branch]"),
 			ref, ref->peer_ref, NULL, porcelain);
 	else {
@@ -707,6 +719,14 @@
 		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 						 "needs force", porcelain);
 		break;
+	case REF_STATUS_REJECT_STALE:
+		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+						 "stale info", porcelain);
+		break;
+	case REF_STATUS_REJECT_SHALLOW:
+		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+						 "new shallow roots not allowed", porcelain);
+		break;
 	case REF_STATUS_REMOTE_REJECT:
 		print_ref_status('!', "[remote rejected]", ref,
 						 ref->deletion ? NULL : ref->peer_ref,
@@ -799,7 +819,8 @@
 		struct ref *tmp_refs;
 		connect_setup(transport, 1, 0);
 
-		get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL, NULL);
+		get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL,
+				 NULL, &data->shallow);
 		data->got_remote_heads = 1;
 	}
 
@@ -879,14 +900,6 @@
 	transport->cannot_reuse = 1;
 }
 
-static int is_local(const char *url)
-{
-	const char *colon = strchr(url, ':');
-	const char *slash = strchr(url, '/');
-	return !colon || (slash && slash < colon) ||
-		has_dos_drive_prefix(url);
-}
-
 static int is_file(const char *url)
 {
 	struct stat buf;
@@ -924,18 +937,18 @@
 
 		while (is_urlschemechar(p == url, *p))
 			p++;
-		if (!prefixcmp(p, "::"))
+		if (starts_with(p, "::"))
 			helper = xstrndup(url, p - url);
 	}
 
 	if (helper) {
 		transport_helper_init(ret, helper);
-	} else if (!prefixcmp(url, "rsync:")) {
+	} else if (starts_with(url, "rsync:")) {
 		ret->get_refs_list = get_refs_via_rsync;
 		ret->fetch = fetch_objs_via_rsync;
 		ret->push = rsync_transport_push;
 		ret->smart_options = NULL;
-	} else if (is_local(url) && is_file(url) && is_bundle(url, 1)) {
+	} else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) {
 		struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
 		ret->data = data;
 		ret->get_refs_list = get_refs_from_bundle;
@@ -943,11 +956,11 @@
 		ret->disconnect = close_bundle;
 		ret->smart_options = NULL;
 	} else if (!is_url(url)
-		|| !prefixcmp(url, "file://")
-		|| !prefixcmp(url, "git://")
-		|| !prefixcmp(url, "ssh://")
-		|| !prefixcmp(url, "git+ssh://")
-		|| !prefixcmp(url, "ssh+git://")) {
+		|| starts_with(url, "file://")
+		|| starts_with(url, "git://")
+		|| starts_with(url, "ssh://")
+		|| starts_with(url, "git+ssh://")
+		|| starts_with(url, "ssh+git://")) {
 		/* These are builtin smart transports. */
 		struct git_transport_data *data = xcalloc(1, sizeof(*data));
 		ret->data = data;
@@ -1078,6 +1091,7 @@
 	for (r = remote_refs; r; r = r->next) {
 		if (!r->peer_ref) continue;
 		if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue;
+		if (r->status == REF_STATUS_REJECT_STALE) continue;
 		if (r->status == REF_STATUS_UPTODATE) continue;
 
 		strbuf_reset(&buf);
@@ -1142,6 +1156,12 @@
 			return -1;
 		}
 
+		if (transport->smart_options &&
+		    transport->smart_options->cas &&
+		    !is_empty_cas(transport->smart_options->cas))
+			apply_push_cas(transport->smart_options->cas,
+				       transport->remote, remote_refs);
+
 		set_ref_status_for_push(remote_refs,
 			flags & TRANSPORT_PUSH_MIRROR,
 			flags & TRANSPORT_PUSH_FORCE);
@@ -1284,7 +1304,7 @@
 	size_t anon_len, prefix_len = 0;
 
 	anon_part = strchr(url, '@');
-	if (is_local(url) || !anon_part)
+	if (url_is_local_not_ssh(url) || !anon_part)
 		goto literal_copy;
 
 	anon_len = strlen(++anon_part);
diff --git a/transport.h b/transport.h
index 96e0ede..02ea248 100644
--- a/transport.h
+++ b/transport.h
@@ -2,6 +2,7 @@
 #define TRANSPORT_H
 
 #include "cache.h"
+#include "run-command.h"
 #include "remote.h"
 
 struct git_transport_options {
@@ -10,9 +11,11 @@
 	unsigned followtags : 1;
 	unsigned check_self_contained_and_connected : 1;
 	unsigned self_contained_and_connected : 1;
+	unsigned update_shallow : 1;
 	int depth;
 	const char *uploadpack;
 	const char *receivepack;
+	struct push_cas_option *cas;
 };
 
 struct transport {
@@ -33,6 +36,12 @@
 	 */
 	unsigned cannot_reuse : 1;
 
+	/*
+	 * A hint from caller that it will be performing a clone, not
+	 * normal fetch. IOW the repository is guaranteed empty.
+	 */
+	unsigned cloning : 1;
+
 	/**
 	 * Returns 0 if successful, positive if the option is not
 	 * recognized or is inapplicable, and negative if the option
@@ -132,6 +141,9 @@
 /* Transfer the data as a thin pack if not null */
 #define TRANS_OPT_THIN "thin"
 
+/* Check the current value of the remote ref */
+#define TRANS_OPT_CAS "cas"
+
 /* Keep the pack that was transferred if not null */
 #define TRANS_OPT_KEEP "keep"
 
@@ -141,6 +153,9 @@
 /* Aggressively fetch annotated tags if possible */
 #define TRANS_OPT_FOLLOWTAGS "followtags"
 
+/* Accept refs that may update .git/shallow without --depth */
+#define TRANS_OPT_UPDATE_SHALLOW "updateshallow"
+
 /**
  * Returns 0 if the option was used, non-zero otherwise. Prints a
  * message to stderr if the option is not used.
@@ -188,10 +203,4 @@
 
 typedef void alternate_ref_fn(const struct ref *, void *);
 extern void for_each_alternate_ref(alternate_ref_fn, void *);
-
-struct send_pack_args;
-extern int send_pack(struct send_pack_args *args,
-		     int fd[], struct child_process *conn,
-		     struct ref *remote_refs,
-		     struct extra_have_objects *extra_have);
 #endif
diff --git a/tree-diff.c b/tree-diff.c
index ba01563..456660c 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -138,7 +138,6 @@
 
 	/* Enable recursion indefinitely */
 	opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
-	opt->pathspec.max_depth = -1;
 
 	strbuf_init(&base, PATH_MAX);
 	strbuf_add(&base, base_str, baselen);
@@ -196,9 +195,27 @@
 	struct diff_options diff_opts;
 	struct diff_queue_struct *q = &diff_queued_diff;
 	struct diff_filepair *choice;
-	const char *paths[1];
 	int i;
 
+	/*
+	 * follow-rename code is very specific, we need exactly one
+	 * path. Magic that matches more than one path is not
+	 * supported.
+	 */
+	GUARD_PATHSPEC(&opt->pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+#if 0
+	/*
+	 * We should reject wildcards as well. Unfortunately we
+	 * haven't got a reliable way to detect that 'foo\*bar' in
+	 * fact has no wildcards. nowildcard_len is merely a hint for
+	 * optimization. Let it slip for now until wildmatch is taught
+	 * about dry-run mode and returns wildcard info.
+	 */
+	if (opt->pathspec.has_wildcard)
+		die("BUG:%s:%d: wildcards are not supported",
+		    __FILE__, __LINE__);
+#endif
+
 	/* Remove the file creation entry from the diff queue, and remember it */
 	choice = q->queue[0];
 	q->nr = 0;
@@ -207,15 +224,13 @@
 	DIFF_OPT_SET(&diff_opts, RECURSIVE);
 	DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
 	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
-	diff_opts.single_follow = opt->pathspec.raw[0];
+	diff_opts.single_follow = opt->pathspec.items[0].match;
 	diff_opts.break_opt = opt->break_opt;
 	diff_opts.rename_score = opt->rename_score;
-	paths[0] = NULL;
-	diff_tree_setup_paths(paths, &diff_opts);
 	diff_setup_done(&diff_opts);
 	diff_tree(t1, t2, base, &diff_opts);
 	diffcore_std(&diff_opts);
-	diff_tree_release_paths(&diff_opts);
+	free_pathspec(&diff_opts.pathspec);
 
 	/* Go through the new set of filepairing, and see if we find a more interesting one */
 	opt->found_follow = 0;
@@ -228,15 +243,20 @@
 		 * the future!
 		 */
 		if ((p->status == 'R' || p->status == 'C') &&
-		    !strcmp(p->two->path, opt->pathspec.raw[0])) {
+		    !strcmp(p->two->path, opt->pathspec.items[0].match)) {
+			const char *path[2];
+
 			/* Switch the file-pairs around */
 			q->queue[i] = choice;
 			choice = p;
 
 			/* Update the path we use from now on.. */
-			diff_tree_release_paths(opt);
-			opt->pathspec.raw[0] = xstrdup(p->one->path);
-			diff_tree_setup_paths(opt->pathspec.raw, opt);
+			path[0] = p->one->path;
+			path[1] = NULL;
+			free_pathspec(&opt->pathspec);
+			parse_pathspec(&opt->pathspec,
+				       PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
+				       PATHSPEC_LITERAL_PATH, "", path);
 
 			/*
 			 * The caller expects us to return a set of vanilla
@@ -310,13 +330,3 @@
 	free(tree);
 	return retval;
 }
-
-void diff_tree_release_paths(struct diff_options *opt)
-{
-	free_pathspec(&opt->pathspec);
-}
-
-void diff_tree_setup_paths(const char **p, struct diff_options *opt)
-{
-	init_pathspec(&opt->pathspec, p);
-}
diff --git a/tree-walk.c b/tree-walk.c
index d5914f5..79dba1d 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -3,6 +3,7 @@
 #include "unpack-trees.h"
 #include "dir.h"
 #include "tree.h"
+#include "pathspec.h"
 
 static const char *get_mode(const char *str, unsigned int *modep)
 {
@@ -487,13 +488,25 @@
 	return retval;
 }
 
-static int match_entry(const struct name_entry *entry, int pathlen,
+static int match_entry(const struct pathspec_item *item,
+		       const struct name_entry *entry, int pathlen,
 		       const char *match, int matchlen,
 		       enum interesting *never_interesting)
 {
 	int m = -1; /* signals that we haven't called strncmp() */
 
-	if (*never_interesting != entry_not_interesting) {
+	if (item->magic & PATHSPEC_ICASE)
+		/*
+		 * "Never interesting" trick requires exact
+		 * matching. We could do something clever with inexact
+		 * matching, but it's trickier (and not to forget that
+		 * strcasecmp is locale-dependent, at least in
+		 * glibc). Just disable it for now. It can't be worse
+		 * than the wildcard's codepath of '[Tt][Hi][Is][Ss]'
+		 * pattern.
+		 */
+		*never_interesting = entry_not_interesting;
+	else if (*never_interesting != entry_not_interesting) {
 		/*
 		 * We have not seen any match that sorts later
 		 * than the current path.
@@ -530,7 +543,7 @@
 	if (matchlen > pathlen) {
 		if (match[pathlen] != '/')
 			return 0;
-		if (!S_ISDIR(entry->mode))
+		if (!S_ISDIR(entry->mode) && !S_ISGITLINK(entry->mode))
 			return 0;
 	}
 
@@ -539,7 +552,7 @@
 		 * we cheated and did not do strncmp(), so we do
 		 * that here.
 		 */
-		m = strncmp(match, entry->path, pathlen);
+		m = ps_strncmp(item, match, entry->path, pathlen);
 
 	/*
 	 * If common part matched earlier then it is a hit,
@@ -547,15 +560,39 @@
 	 * leading directory and is shorter than match.
 	 */
 	if (!m)
+		/*
+		 * match_entry does not check if the prefix part is
+		 * matched case-sensitively. If the entry is a
+		 * directory and part of prefix, it'll be rematched
+		 * eventually by basecmp with special treatment for
+		 * the prefix.
+		 */
 		return 1;
 
 	return 0;
 }
 
-static int match_dir_prefix(const char *base,
+/* :(icase)-aware string compare */
+static int basecmp(const struct pathspec_item *item,
+		   const char *base, const char *match, int len)
+{
+	if (item->magic & PATHSPEC_ICASE) {
+		int ret, n = len > item->prefix ? item->prefix : len;
+		ret = strncmp(base, match, n);
+		if (ret)
+			return ret;
+		base += n;
+		match += n;
+		len -= n;
+	}
+	return ps_strncmp(item, base, match, len);
+}
+
+static int match_dir_prefix(const struct pathspec_item *item,
+			    const char *base,
 			    const char *match, int matchlen)
 {
-	if (strncmp(base, match, matchlen))
+	if (basecmp(item, base, match, matchlen))
 		return 0;
 
 	/*
@@ -592,7 +629,7 @@
 		 */
 		if (baselen >= matchlen) {
 			*matched = matchlen;
-			return !strncmp(base, match, matchlen);
+			return !basecmp(item, base, match, matchlen);
 		}
 
 		dirlen = matchlen;
@@ -605,7 +642,7 @@
 		 * base ends with '/' so we are sure it really matches
 		 * directory
 		 */
-		if (strncmp(base, match, baselen))
+		if (basecmp(item, base, match, baselen))
 			return 0;
 		*matched = baselen;
 	} else
@@ -625,17 +662,28 @@
  * Pre-condition: either baselen == base_offset (i.e. empty path)
  * or base[baselen-1] == '/' (i.e. with trailing slash).
  */
-enum interesting tree_entry_interesting(const struct name_entry *entry,
-					struct strbuf *base, int base_offset,
-					const struct pathspec *ps)
+static enum interesting do_match(const struct name_entry *entry,
+				 struct strbuf *base, int base_offset,
+				 const struct pathspec *ps,
+				 int exclude)
 {
 	int i;
 	int pathlen, baselen = base->len - base_offset;
 	enum interesting never_interesting = ps->has_wildcard ?
 		entry_not_interesting : all_entries_not_interesting;
 
+	GUARD_PATHSPEC(ps,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_MAXDEPTH |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE |
+		       PATHSPEC_EXCLUDE);
+
 	if (!ps->nr) {
-		if (!ps->recursive || ps->max_depth == -1)
+		if (!ps->recursive ||
+		    !(ps->magic & PATHSPEC_MAXDEPTH) ||
+		    ps->max_depth == -1)
 			return all_entries_interesting;
 		return within_depth(base->buf + base_offset, baselen,
 				    !!S_ISDIR(entry->mode),
@@ -651,12 +699,18 @@
 		const char *base_str = base->buf + base_offset;
 		int matchlen = item->len, matched = 0;
 
+		if ((!exclude &&   item->magic & PATHSPEC_EXCLUDE) ||
+		    ( exclude && !(item->magic & PATHSPEC_EXCLUDE)))
+			continue;
+
 		if (baselen >= matchlen) {
 			/* If it doesn't match, move along... */
-			if (!match_dir_prefix(base_str, match, matchlen))
+			if (!match_dir_prefix(item, base_str, match, matchlen))
 				goto match_wildcards;
 
-			if (!ps->recursive || ps->max_depth == -1)
+			if (!ps->recursive ||
+			    !(ps->magic & PATHSPEC_MAXDEPTH) ||
+			    ps->max_depth == -1)
 				return all_entries_interesting;
 
 			return within_depth(base_str + matchlen + 1,
@@ -667,15 +721,14 @@
 		}
 
 		/* Either there must be no base, or the base must match. */
-		if (baselen == 0 || !strncmp(base_str, match, baselen)) {
-			if (match_entry(entry, pathlen,
+		if (baselen == 0 || !basecmp(item, base_str, match, baselen)) {
+			if (match_entry(item, entry, pathlen,
 					match + baselen, matchlen - baselen,
 					&never_interesting))
 				return entry_interesting;
 
 			if (item->nowildcard_len < item->len) {
-				if (!git_fnmatch(match + baselen, entry->path,
-						 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+				if (!git_fnmatch(item, match + baselen, entry->path,
 						 item->nowildcard_len - baselen))
 					return entry_interesting;
 
@@ -716,8 +769,7 @@
 
 		strbuf_add(base, entry->path, pathlen);
 
-		if (!git_fnmatch(match, base->buf + base_offset,
-				 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+		if (!git_fnmatch(item, match, base->buf + base_offset,
 				 item->nowildcard_len)) {
 			strbuf_setlen(base, base_offset + baselen);
 			return entry_interesting;
@@ -736,3 +788,72 @@
 	}
 	return never_interesting; /* No matches */
 }
+
+/*
+ * Is a tree entry interesting given the pathspec we have?
+ *
+ * Pre-condition: either baselen == base_offset (i.e. empty path)
+ * or base[baselen-1] == '/' (i.e. with trailing slash).
+ */
+enum interesting tree_entry_interesting(const struct name_entry *entry,
+					struct strbuf *base, int base_offset,
+					const struct pathspec *ps)
+{
+	enum interesting positive, negative;
+	positive = do_match(entry, base, base_offset, ps, 0);
+
+	/*
+	 * case | entry | positive | negative | result
+	 * -----+-------+----------+----------+-------
+	 *   1  |  file |   -1     |  -1..2   |  -1
+	 *   2  |  file |    0     |  -1..2   |   0
+	 *   3  |  file |    1     |   -1     |   1
+	 *   4  |  file |    1     |    0     |   1
+	 *   5  |  file |    1     |    1     |   0
+	 *   6  |  file |    1     |    2     |   0
+	 *   7  |  file |    2     |   -1     |   2
+	 *   8  |  file |    2     |    0     |   2
+	 *   9  |  file |    2     |    1     |   0
+	 *  10  |  file |    2     |    2     |  -1
+	 * -----+-------+----------+----------+-------
+	 *  11  |  dir  |   -1     |  -1..2   |  -1
+	 *  12  |  dir  |    0     |  -1..2   |   0
+	 *  13  |  dir  |    1     |   -1     |   1
+	 *  14  |  dir  |    1     |    0     |   1
+	 *  15  |  dir  |    1     |    1     |   1 (*)
+	 *  16  |  dir  |    1     |    2     |   0
+	 *  17  |  dir  |    2     |   -1     |   2
+	 *  18  |  dir  |    2     |    0     |   2
+	 *  19  |  dir  |    2     |    1     |   1 (*)
+	 *  20  |  dir  |    2     |    2     |  -1
+	 *
+	 * (*) An exclude pattern interested in a directory does not
+	 * necessarily mean it will exclude all of the directory. In
+	 * wildcard case, it can't decide until looking at individual
+	 * files inside. So don't write such directories off yet.
+	 */
+
+	if (!(ps->magic & PATHSPEC_EXCLUDE) ||
+	    positive <= entry_not_interesting) /* #1, #2, #11, #12 */
+		return positive;
+
+	negative = do_match(entry, base, base_offset, ps, 1);
+
+	/* #3, #4, #7, #8, #13, #14, #17, #18 */
+	if (negative <= entry_not_interesting)
+		return positive;
+
+	/* #15, #19 */
+	if (S_ISDIR(entry->mode) &&
+	    positive >= entry_interesting &&
+	    negative == entry_interesting)
+		return entry_interesting;
+
+	if ((positive == entry_interesting &&
+	     negative >= entry_interesting) || /* #5, #6, #16 */
+	    (positive == all_entries_interesting &&
+	     negative == entry_interesting)) /* #9 */
+		return entry_not_interesting;
+
+	return all_entries_not_interesting; /* #10, #20 */
+}
diff --git a/tree.c b/tree.c
index c0e568c..c8c49d7 100644
--- a/tree.c
+++ b/tree.c
@@ -47,7 +47,7 @@
 }
 
 static int read_tree_1(struct tree *tree, struct strbuf *base,
-		       int stage, struct pathspec *pathspec,
+		       int stage, const struct pathspec *pathspec,
 		       read_tree_fn_t fn, void *context)
 {
 	struct tree_desc desc;
@@ -116,7 +116,7 @@
 
 int read_tree_recursive(struct tree *tree,
 			const char *base, int baselen,
-			int stage, struct pathspec *pathspec,
+			int stage, const struct pathspec *pathspec,
 			read_tree_fn_t fn, void *context)
 {
 	struct strbuf sb = STRBUF_INIT;
@@ -225,6 +225,14 @@
 	return parse_tree_buffer(item, buffer, size);
 }
 
+void free_tree_buffer(struct tree *tree)
+{
+	free(tree->buffer);
+	tree->buffer = NULL;
+	tree->size = 0;
+	tree->object.parsed = 0;
+}
+
 struct tree *parse_tree_indirect(const unsigned char *sha1)
 {
 	struct object *obj = parse_object(sha1);
diff --git a/tree.h b/tree.h
index 69bcb5e..d84ac63 100644
--- a/tree.h
+++ b/tree.h
@@ -16,6 +16,7 @@
 int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size);
 
 int parse_tree(struct tree *tree);
+void free_tree_buffer(struct tree *tree);
 
 /* Parses and returns the tree in the given ent, chasing tags and commits. */
 struct tree *parse_tree_indirect(const unsigned char *sha1);
@@ -25,7 +26,7 @@
 
 extern int read_tree_recursive(struct tree *tree,
 			       const char *base, int baselen,
-			       int stage, struct pathspec *pathspec,
+			       int stage, const struct pathspec *pathspec,
 			       read_tree_fn_t fn, void *context);
 
 extern int read_tree(struct tree *tree, int stage, struct pathspec *pathspec);
diff --git a/unpack-trees.c b/unpack-trees.c
index bf01717..164354d 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -830,23 +830,24 @@
 }
 
 static int clear_ce_flags_1(struct cache_entry **cache, int nr,
-			    char *prefix, int prefix_len,
+			    struct strbuf *prefix,
 			    int select_mask, int clear_mask,
 			    struct exclude_list *el, int defval);
 
 /* Whole directory matching */
 static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
-			      char *prefix, int prefix_len,
+			      struct strbuf *prefix,
 			      char *basename,
 			      int select_mask, int clear_mask,
 			      struct exclude_list *el, int defval)
 {
 	struct cache_entry **cache_end;
 	int dtype = DT_DIR;
-	int ret = is_excluded_from_list(prefix, prefix_len,
+	int ret = is_excluded_from_list(prefix->buf, prefix->len,
 					basename, &dtype, el);
+	int rc;
 
-	prefix[prefix_len++] = '/';
+	strbuf_addch(prefix, '/');
 
 	/* If undecided, use matching result of parent dir in defval */
 	if (ret < 0)
@@ -854,7 +855,7 @@
 
 	for (cache_end = cache; cache_end != cache + nr; cache_end++) {
 		struct cache_entry *ce = *cache_end;
-		if (strncmp(ce->name, prefix, prefix_len))
+		if (strncmp(ce->name, prefix->buf, prefix->len))
 			break;
 	}
 
@@ -865,10 +866,12 @@
 	 * calling clear_ce_flags_1(). That function will call
 	 * the expensive is_excluded_from_list() on every entry.
 	 */
-	return clear_ce_flags_1(cache, cache_end - cache,
-				prefix, prefix_len,
-				select_mask, clear_mask,
-				el, ret);
+	rc = clear_ce_flags_1(cache, cache_end - cache,
+			      prefix,
+			      select_mask, clear_mask,
+			      el, ret);
+	strbuf_setlen(prefix, prefix->len - 1);
+	return rc;
 }
 
 /*
@@ -887,7 +890,7 @@
  * Top level path has prefix_len zero.
  */
 static int clear_ce_flags_1(struct cache_entry **cache, int nr,
-			    char *prefix, int prefix_len,
+			    struct strbuf *prefix,
 			    int select_mask, int clear_mask,
 			    struct exclude_list *el, int defval)
 {
@@ -907,10 +910,10 @@
 			continue;
 		}
 
-		if (prefix_len && strncmp(ce->name, prefix, prefix_len))
+		if (prefix->len && strncmp(ce->name, prefix->buf, prefix->len))
 			break;
 
-		name = ce->name + prefix_len;
+		name = ce->name + prefix->len;
 		slash = strchr(name, '/');
 
 		/* If it's a directory, try whole directory match first */
@@ -918,29 +921,26 @@
 			int processed;
 
 			len = slash - name;
-			memcpy(prefix + prefix_len, name, len);
+			strbuf_add(prefix, name, len);
 
-			/*
-			 * terminate the string (no trailing slash),
-			 * clear_c_f_dir needs it
-			 */
-			prefix[prefix_len + len] = '\0';
 			processed = clear_ce_flags_dir(cache, cache_end - cache,
-						       prefix, prefix_len + len,
-						       prefix + prefix_len,
+						       prefix,
+						       prefix->buf + prefix->len - len,
 						       select_mask, clear_mask,
 						       el, defval);
 
 			/* clear_c_f_dir eats a whole dir already? */
 			if (processed) {
 				cache += processed;
+				strbuf_setlen(prefix, prefix->len - len);
 				continue;
 			}
 
-			prefix[prefix_len + len++] = '/';
+			strbuf_addch(prefix, '/');
 			cache += clear_ce_flags_1(cache, cache_end - cache,
-						  prefix, prefix_len + len,
+						  prefix,
 						  select_mask, clear_mask, el, defval);
+			strbuf_setlen(prefix, prefix->len - len - 1);
 			continue;
 		}
 
@@ -961,9 +961,12 @@
 			    int select_mask, int clear_mask,
 			    struct exclude_list *el)
 {
-	char prefix[PATH_MAX];
+	static struct strbuf prefix = STRBUF_INIT;
+
+	strbuf_reset(&prefix);
+
 	return clear_ce_flags_1(cache, nr,
-				prefix, 0,
+				&prefix,
 				select_mask, clear_mask,
 				el, 0);
 }
@@ -1154,8 +1157,10 @@
 
 	o->src_index = NULL;
 	ret = check_updates(o) ? (-2) : 0;
-	if (o->dst_index)
+	if (o->dst_index) {
+		discard_index(o->dst_index);
 		*o->dst_index = o->result;
+	}
 
 done:
 	clear_exclude_list(&el);
@@ -1355,7 +1360,7 @@
 {
 	const struct cache_entry *src;
 
-	src = index_name_exists(o->src_index, name, len, 1);
+	src = index_file_exists(o->src_index, name, len, 1);
 	return src && !ie_match_stat(o->src_index, src, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
 }
 
@@ -1401,7 +1406,7 @@
 	 * delete this path, which is in a subdirectory that
 	 * is being replaced with a blob.
 	 */
-	result = index_name_exists(&o->result, name, len, 0);
+	result = index_file_exists(&o->result, name, len, 0);
 	if (result) {
 		if (result->ce_flags & CE_REMOVE)
 			return 0;
@@ -1761,14 +1766,23 @@
 		newtree = NULL;
 
 	if (current) {
-		if ((!oldtree && !newtree) || /* 4 and 5 */
-		    (!oldtree && newtree &&
-		     same(current, newtree)) || /* 6 and 7 */
-		    (oldtree && newtree &&
-		     same(oldtree, newtree)) || /* 14 and 15 */
-		    (oldtree && newtree &&
-		     !same(oldtree, newtree) && /* 18 and 19 */
-		     same(current, newtree))) {
+		if (current->ce_flags & CE_CONFLICTED) {
+			if (same(oldtree, newtree) || o->reset) {
+				if (!newtree)
+					return deleted_entry(current, current, o);
+				else
+					return merged_entry(newtree, current, o);
+			}
+			return o->gently ? -1 : reject_merge(current, o);
+		}
+		else if ((!oldtree && !newtree) || /* 4 and 5 */
+			 (!oldtree && newtree &&
+			  same(current, newtree)) || /* 6 and 7 */
+			 (oldtree && newtree &&
+			  same(oldtree, newtree)) || /* 14 and 15 */
+			 (oldtree && newtree &&
+			  !same(oldtree, newtree) && /* 18 and 19 */
+			  same(current, newtree))) {
 			return keep_entry(current, o);
 		}
 		else if (oldtree && !newtree && same(current, oldtree)) {
diff --git a/upload-pack.c b/upload-pack.c
index a020d30..0c44f6b 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -10,6 +10,7 @@
 #include "revision.h"
 #include "list-objects.h"
 #include "run-command.h"
+#include "connect.h"
 #include "sigchain.h"
 #include "version.h"
 #include "string-list.h"
@@ -83,7 +84,7 @@
 	char *shallow_file = NULL;
 
 	if (shallow_nr) {
-		shallow_file = setup_temporary_shallow();
+		shallow_file = setup_temporary_shallow(NULL);
 		argv[arg++] = "--shallow-file";
 		argv[arg++] = shallow_file;
 	}
@@ -393,7 +394,7 @@
 			got_other = 0;
 			continue;
 		}
-		if (!prefixcmp(line, "have ")) {
+		if (starts_with(line, "have ")) {
 			switch (got_sha1(line+5, sha1)) {
 			case -1: /* they have what we do not */
 				got_other = 1;
@@ -539,7 +540,7 @@
 		if (!line)
 			break;
 
-		if (!prefixcmp(line, "shallow ")) {
+		if (starts_with(line, "shallow ")) {
 			unsigned char sha1[20];
 			struct object *object;
 			if (get_sha1_hex(line + 8, sha1))
@@ -555,14 +556,14 @@
 			}
 			continue;
 		}
-		if (!prefixcmp(line, "deepen ")) {
+		if (starts_with(line, "deepen ")) {
 			char *end;
 			depth = strtol(line + 7, &end, 0);
 			if (end == line + 7 || depth <= 0)
 				die("Invalid deepen: %s", line);
 			continue;
 		}
-		if (prefixcmp(line, "want ") ||
+		if (!starts_with(line, "want ") ||
 		    get_sha1_hex(line+5, sha1_buf))
 			die("git upload-pack: protocol error, "
 			    "expected to get sha, not '%s'", line);
@@ -618,7 +619,7 @@
 	if (depth > 0) {
 		struct commit_list *result = NULL, *backup = NULL;
 		int i;
-		if (depth == INFINITE_DEPTH)
+		if (depth == INFINITE_DEPTH && !is_repository_shallow())
 			for (i = 0; i < shallows.nr; i++) {
 				struct object *object = shallows.objects[i].item;
 				object->flags |= NOT_SHALLOW;
@@ -648,8 +649,7 @@
 				/* make sure the real parents are parsed */
 				unregister_shallow(object->sha1);
 				object->parsed = 0;
-				if (parse_commit((struct commit *)object))
-					die("invalid commit");
+				parse_commit_or_die((struct commit *)object);
 				parents = ((struct commit *)object)->parents;
 				while (parents) {
 					add_object_array(&parents->item->object,
@@ -757,6 +757,7 @@
 		reset_timeout();
 		head_ref_namespaced(send_ref, &symref);
 		for_each_namespaced_ref(send_ref, &symref);
+		advertise_shallow_grafts(1);
 		packet_flush(1);
 	} else {
 		head_ref_namespaced(mark_our_ref, NULL);
@@ -814,7 +815,7 @@
 			strict = 1;
 			continue;
 		}
-		if (!prefixcmp(arg, "--timeout=")) {
+		if (starts_with(arg, "--timeout=")) {
 			timeout = atoi(arg+10);
 			daemon_mode = 1;
 			continue;
@@ -834,8 +835,7 @@
 
 	if (!enter_repo(dir, strict))
 		die("'%s' does not appear to be a git repository", dir);
-	if (is_repository_shallow())
-		die("attempt to fetch/clone from a shallow repository");
+
 	git_config(upload_pack_config, NULL);
 	upload_pack();
 	return 0;
diff --git a/urlmatch.c b/urlmatch.c
new file mode 100644
index 0000000..ec87cba
--- /dev/null
+++ b/urlmatch.c
@@ -0,0 +1,539 @@
+#include "cache.h"
+#include "urlmatch.h"
+
+#define URL_ALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+#define URL_DIGIT "0123456789"
+#define URL_ALPHADIGIT URL_ALPHA URL_DIGIT
+#define URL_SCHEME_CHARS URL_ALPHADIGIT "+.-"
+#define URL_HOST_CHARS URL_ALPHADIGIT ".-[:]" /* IPv6 literals need [:] */
+#define URL_UNSAFE_CHARS " <>\"%{}|\\^`" /* plus 0x00-0x1F,0x7F-0xFF */
+#define URL_GEN_RESERVED ":/?#[]@"
+#define URL_SUB_RESERVED "!$&'()*+,;="
+#define URL_RESERVED URL_GEN_RESERVED URL_SUB_RESERVED /* only allowed delims */
+
+static int append_normalized_escapes(struct strbuf *buf,
+				     const char *from,
+				     size_t from_len,
+				     const char *esc_extra,
+				     const char *esc_ok)
+{
+	/*
+	 * Append to strbuf 'buf' characters from string 'from' with length
+	 * 'from_len' while unescaping characters that do not need to be escaped
+	 * and escaping characters that do.  The set of characters to escape
+	 * (the complement of which is unescaped) starts out as the RFC 3986
+	 * unsafe characters (0x00-0x1F,0x7F-0xFF," <>\"#%{}|\\^`").  If
+	 * 'esc_extra' is not NULL, those additional characters will also always
+	 * be escaped.  If 'esc_ok' is not NULL, those characters will be left
+	 * escaped if found that way, but will not be unescaped otherwise (used
+	 * for delimiters).  If a %-escape sequence is encountered that is not
+	 * followed by 2 hexadecimal digits, the sequence is invalid and
+	 * false (0) will be returned.  Otherwise true (1) will be returned for
+	 * success.
+	 *
+	 * Note that all %-escape sequences will be normalized to UPPERCASE
+	 * as indicated in RFC 3986.  Unless included in esc_extra or esc_ok
+	 * alphanumerics and "-._~" will always be unescaped as per RFC 3986.
+	 */
+
+	while (from_len) {
+		int ch = *from++;
+		int was_esc = 0;
+
+		from_len--;
+		if (ch == '%') {
+			if (from_len < 2 ||
+			    !isxdigit((unsigned char)from[0]) ||
+			    !isxdigit((unsigned char)from[1]))
+				return 0;
+			ch = hexval_table[(unsigned char)*from++] << 4;
+			ch |= hexval_table[(unsigned char)*from++];
+			from_len -= 2;
+			was_esc = 1;
+		}
+		if ((unsigned char)ch <= 0x1F || (unsigned char)ch >= 0x7F ||
+		    strchr(URL_UNSAFE_CHARS, ch) ||
+		    (esc_extra && strchr(esc_extra, ch)) ||
+		    (was_esc && strchr(esc_ok, ch)))
+			strbuf_addf(buf, "%%%02X", (unsigned char)ch);
+		else
+			strbuf_addch(buf, ch);
+	}
+
+	return 1;
+}
+
+char *url_normalize(const char *url, struct url_info *out_info)
+{
+	/*
+	 * Normalize NUL-terminated url using the following rules:
+	 *
+	 * 1. Case-insensitive parts of url will be converted to lower case
+	 * 2. %-encoded characters that do not need to be will be unencoded
+	 * 3. Characters that are not %-encoded and must be will be encoded
+	 * 4. All %-encodings will be converted to upper case hexadecimal
+	 * 5. Leading 0s are removed from port numbers
+	 * 6. If the default port for the scheme is given it will be removed
+	 * 7. A path part (including empty) not starting with '/' has one added
+	 * 8. Any dot segments (. or ..) in the path are resolved and removed
+	 * 9. IPv6 host literals are allowed (but not normalized or validated)
+	 *
+	 * The rules are based on information in RFC 3986.
+	 *
+	 * Please note this function requires a full URL including a scheme
+	 * and host part (except for file: URLs which may have an empty host).
+	 *
+	 * The return value is a newly allocated string that must be freed
+	 * or NULL if the url is not valid.
+	 *
+	 * If out_info is non-NULL, the url and err fields therein will always
+	 * be set.  If a non-NULL value is returned, it will be stored in
+	 * out_info->url as well, out_info->err will be set to NULL and the
+	 * other fields of *out_info will also be filled in.  If a NULL value
+	 * is returned, NULL will be stored in out_info->url and out_info->err
+	 * will be set to a brief, translated, error message, but no other
+	 * fields will be filled in.
+	 *
+	 * This is NOT a URL validation function.  Full URL validation is NOT
+	 * performed.  Some invalid host names are passed through this function
+	 * undetected.  However, most all other problems that make a URL invalid
+	 * will be detected (including a missing host for non file: URLs).
+	 */
+
+	size_t url_len = strlen(url);
+	struct strbuf norm;
+	size_t spanned;
+	size_t scheme_len, user_off=0, user_len=0, passwd_off=0, passwd_len=0;
+	size_t host_off=0, host_len=0, port_len=0, path_off, path_len, result_len;
+	const char *slash_ptr, *at_ptr, *colon_ptr, *path_start;
+	char *result;
+
+	/*
+	 * Copy lowercased scheme and :// suffix, %-escapes are not allowed
+	 * First character of scheme must be URL_ALPHA
+	 */
+	spanned = strspn(url, URL_SCHEME_CHARS);
+	if (!spanned || !isalpha(url[0]) || spanned + 3 > url_len ||
+	    url[spanned] != ':' || url[spanned+1] != '/' || url[spanned+2] != '/') {
+		if (out_info) {
+			out_info->url = NULL;
+			out_info->err = _("invalid URL scheme name or missing '://' suffix");
+		}
+		return NULL; /* Bad scheme and/or missing "://" part */
+	}
+	strbuf_init(&norm, url_len);
+	scheme_len = spanned;
+	spanned += 3;
+	url_len -= spanned;
+	while (spanned--)
+		strbuf_addch(&norm, tolower(*url++));
+
+
+	/*
+	 * Copy any username:password if present normalizing %-escapes
+	 */
+	at_ptr = strchr(url, '@');
+	slash_ptr = url + strcspn(url, "/?#");
+	if (at_ptr && at_ptr < slash_ptr) {
+		user_off = norm.len;
+		if (at_ptr > url) {
+			if (!append_normalized_escapes(&norm, url, at_ptr - url,
+						       "", URL_RESERVED)) {
+				if (out_info) {
+					out_info->url = NULL;
+					out_info->err = _("invalid %XX escape sequence");
+				}
+				strbuf_release(&norm);
+				return NULL;
+			}
+			colon_ptr = strchr(norm.buf + scheme_len + 3, ':');
+			if (colon_ptr) {
+				passwd_off = (colon_ptr + 1) - norm.buf;
+				passwd_len = norm.len - passwd_off;
+				user_len = (passwd_off - 1) - (scheme_len + 3);
+			} else {
+				user_len = norm.len - (scheme_len + 3);
+			}
+		}
+		strbuf_addch(&norm, '@');
+		url_len -= (++at_ptr - url);
+		url = at_ptr;
+	}
+
+
+	/*
+	 * Copy the host part excluding any port part, no %-escapes allowed
+	 */
+	if (!url_len || strchr(":/?#", *url)) {
+		/* Missing host invalid for all URL schemes except file */
+		if (strncmp(norm.buf, "file:", 5)) {
+			if (out_info) {
+				out_info->url = NULL;
+				out_info->err = _("missing host and scheme is not 'file:'");
+			}
+			strbuf_release(&norm);
+			return NULL;
+		}
+	} else {
+		host_off = norm.len;
+	}
+	colon_ptr = slash_ptr - 1;
+	while (colon_ptr > url && *colon_ptr != ':' && *colon_ptr != ']')
+		colon_ptr--;
+	if (*colon_ptr != ':') {
+		colon_ptr = slash_ptr;
+	} else if (!host_off && colon_ptr < slash_ptr && colon_ptr + 1 != slash_ptr) {
+		/* file: URLs may not have a port number */
+		if (out_info) {
+			out_info->url = NULL;
+			out_info->err = _("a 'file:' URL may not have a port number");
+		}
+		strbuf_release(&norm);
+		return NULL;
+	}
+	spanned = strspn(url, URL_HOST_CHARS);
+	if (spanned < colon_ptr - url) {
+		/* Host name has invalid characters */
+		if (out_info) {
+			out_info->url = NULL;
+			out_info->err = _("invalid characters in host name");
+		}
+		strbuf_release(&norm);
+		return NULL;
+	}
+	while (url < colon_ptr) {
+		strbuf_addch(&norm, tolower(*url++));
+		url_len--;
+	}
+
+
+	/*
+	 * Check the port part and copy if not the default (after removing any
+	 * leading 0s); no %-escapes allowed
+	 */
+	if (colon_ptr < slash_ptr) {
+		/* skip the ':' and leading 0s but not the last one if all 0s */
+		url++;
+		url += strspn(url, "0");
+		if (url == slash_ptr && url[-1] == '0')
+			url--;
+		if (url == slash_ptr) {
+			/* Skip ":" port with no number, it's same as default */
+		} else if (slash_ptr - url == 2 &&
+			   !strncmp(norm.buf, "http:", 5) &&
+			   !strncmp(url, "80", 2)) {
+			/* Skip http :80 as it's the default */
+		} else if (slash_ptr - url == 3 &&
+			   !strncmp(norm.buf, "https:", 6) &&
+			   !strncmp(url, "443", 3)) {
+			/* Skip https :443 as it's the default */
+		} else {
+			/*
+			 * Port number must be all digits with leading 0s removed
+			 * and since all the protocols we deal with have a 16-bit
+			 * port number it must also be in the range 1..65535
+			 * 0 is not allowed because that means "next available"
+			 * on just about every system and therefore cannot be used
+			 */
+			unsigned long pnum = 0;
+			spanned = strspn(url, URL_DIGIT);
+			if (spanned < slash_ptr - url) {
+				/* port number has invalid characters */
+				if (out_info) {
+					out_info->url = NULL;
+					out_info->err = _("invalid port number");
+				}
+				strbuf_release(&norm);
+				return NULL;
+			}
+			if (slash_ptr - url <= 5)
+				pnum = strtoul(url, NULL, 10);
+			if (pnum == 0 || pnum > 65535) {
+				/* port number not in range 1..65535 */
+				if (out_info) {
+					out_info->url = NULL;
+					out_info->err = _("invalid port number");
+				}
+				strbuf_release(&norm);
+				return NULL;
+			}
+			strbuf_addch(&norm, ':');
+			strbuf_add(&norm, url, slash_ptr - url);
+			port_len = slash_ptr - url;
+		}
+		url_len -= slash_ptr - colon_ptr;
+		url = slash_ptr;
+	}
+	if (host_off)
+		host_len = norm.len - host_off;
+
+
+	/*
+	 * Now copy the path resolving any . and .. segments being careful not
+	 * to corrupt the URL by unescaping any delimiters, but do add an
+	 * initial '/' if it's missing and do normalize any %-escape sequences.
+	 */
+	path_off = norm.len;
+	path_start = norm.buf + path_off;
+	strbuf_addch(&norm, '/');
+	if (*url == '/') {
+		url++;
+		url_len--;
+	}
+	for (;;) {
+		const char *seg_start;
+		size_t seg_start_off = norm.len;
+		const char *next_slash = url + strcspn(url, "/?#");
+		int skip_add_slash = 0;
+
+		/*
+		 * RFC 3689 indicates that any . or .. segments should be
+		 * unescaped before being checked for.
+		 */
+		if (!append_normalized_escapes(&norm, url, next_slash - url, "",
+					       URL_RESERVED)) {
+			if (out_info) {
+				out_info->url = NULL;
+				out_info->err = _("invalid %XX escape sequence");
+			}
+			strbuf_release(&norm);
+			return NULL;
+		}
+
+		seg_start = norm.buf + seg_start_off;
+		if (!strcmp(seg_start, ".")) {
+			/* ignore a . segment; be careful not to remove initial '/' */
+			if (seg_start == path_start + 1) {
+				strbuf_setlen(&norm, norm.len - 1);
+				skip_add_slash = 1;
+			} else {
+				strbuf_setlen(&norm, norm.len - 2);
+			}
+		} else if (!strcmp(seg_start, "..")) {
+			/*
+			 * ignore a .. segment and remove the previous segment;
+			 * be careful not to remove initial '/' from path
+			 */
+			const char *prev_slash = norm.buf + norm.len - 3;
+			if (prev_slash == path_start) {
+				/* invalid .. because no previous segment to remove */
+				if (out_info) {
+					out_info->url = NULL;
+					out_info->err = _("invalid '..' path segment");
+				}
+				strbuf_release(&norm);
+				return NULL;
+			}
+			while (*--prev_slash != '/') {}
+			if (prev_slash == path_start) {
+				strbuf_setlen(&norm, prev_slash - norm.buf + 1);
+				skip_add_slash = 1;
+			} else {
+				strbuf_setlen(&norm, prev_slash - norm.buf);
+			}
+		}
+		url_len -= next_slash - url;
+		url = next_slash;
+		/* if the next char is not '/' done with the path */
+		if (*url != '/')
+			break;
+		url++;
+		url_len--;
+		if (!skip_add_slash)
+			strbuf_addch(&norm, '/');
+	}
+	path_len = norm.len - path_off;
+
+
+	/*
+	 * Now simply copy the rest, if any, only normalizing %-escapes and
+	 * being careful not to corrupt the URL by unescaping any delimiters.
+	 */
+	if (*url) {
+		if (!append_normalized_escapes(&norm, url, url_len, "", URL_RESERVED)) {
+			if (out_info) {
+				out_info->url = NULL;
+				out_info->err = _("invalid %XX escape sequence");
+			}
+			strbuf_release(&norm);
+			return NULL;
+		}
+	}
+
+
+	result = strbuf_detach(&norm, &result_len);
+	if (out_info) {
+		out_info->url = result;
+		out_info->err = NULL;
+		out_info->url_len = result_len;
+		out_info->scheme_len = scheme_len;
+		out_info->user_off = user_off;
+		out_info->user_len = user_len;
+		out_info->passwd_off = passwd_off;
+		out_info->passwd_len = passwd_len;
+		out_info->host_off = host_off;
+		out_info->host_len = host_len;
+		out_info->port_len = port_len;
+		out_info->path_off = path_off;
+		out_info->path_len = path_len;
+	}
+	return result;
+}
+
+static size_t url_match_prefix(const char *url,
+			       const char *url_prefix,
+			       size_t url_prefix_len)
+{
+	/*
+	 * url_prefix matches url if url_prefix is an exact match for url or it
+	 * is a prefix of url and the match ends on a path component boundary.
+	 * Both url and url_prefix are considered to have an implicit '/' on the
+	 * end for matching purposes if they do not already.
+	 *
+	 * url must be NUL terminated.  url_prefix_len is the length of
+	 * url_prefix which need not be NUL terminated.
+	 *
+	 * The return value is the length of the match in characters (including
+	 * the final '/' even if it's implicit) or 0 for no match.
+	 *
+	 * Passing NULL as url and/or url_prefix will always cause 0 to be
+	 * returned without causing any faults.
+	 */
+	if (!url || !url_prefix)
+		return 0;
+	if (!url_prefix_len || (url_prefix_len == 1 && *url_prefix == '/'))
+		return (!*url || *url == '/') ? 1 : 0;
+	if (url_prefix[url_prefix_len - 1] == '/')
+		url_prefix_len--;
+	if (strncmp(url, url_prefix, url_prefix_len))
+		return 0;
+	if ((strlen(url) == url_prefix_len) || (url[url_prefix_len] == '/'))
+		return url_prefix_len + 1;
+	return 0;
+}
+
+int match_urls(const struct url_info *url,
+	       const struct url_info *url_prefix,
+	       int *exactusermatch)
+{
+	/*
+	 * url_prefix matches url if the scheme, host and port of url_prefix
+	 * are the same as those of url and the path portion of url_prefix
+	 * is the same as the path portion of url or it is a prefix that
+	 * matches at a '/' boundary.  If url_prefix contains a user name,
+	 * that must also exactly match the user name in url.
+	 *
+	 * If the user, host, port and path match in this fashion, the returned
+	 * value is the length of the path match including any implicit
+	 * final '/'.  For example, "http://me@example.com/path" is matched by
+	 * "http://example.com" with a path length of 1.
+	 *
+	 * If there is a match and exactusermatch is not NULL, then
+	 * *exactusermatch will be set to true if both url and url_prefix
+	 * contained a user name or false if url_prefix did not have a
+	 * user name.  If there is no match *exactusermatch is left untouched.
+	 */
+	int usermatched = 0;
+	int pathmatchlen;
+
+	if (!url || !url_prefix || !url->url || !url_prefix->url)
+		return 0;
+
+	/* check the scheme */
+	if (url_prefix->scheme_len != url->scheme_len ||
+	    strncmp(url->url, url_prefix->url, url->scheme_len))
+		return 0; /* schemes do not match */
+
+	/* check the user name if url_prefix has one */
+	if (url_prefix->user_off) {
+		if (!url->user_off || url->user_len != url_prefix->user_len ||
+		    strncmp(url->url + url->user_off,
+			    url_prefix->url + url_prefix->user_off,
+			    url->user_len))
+			return 0; /* url_prefix has a user but it's not a match */
+		usermatched = 1;
+	}
+
+	/* check the host and port */
+	if (url_prefix->host_len != url->host_len ||
+	    strncmp(url->url + url->host_off,
+		    url_prefix->url + url_prefix->host_off, url->host_len))
+		return 0; /* host names and/or ports do not match */
+
+	/* check the path */
+	pathmatchlen = url_match_prefix(
+		url->url + url->path_off,
+		url_prefix->url + url_prefix->path_off,
+		url_prefix->url_len - url_prefix->path_off);
+
+	if (pathmatchlen && exactusermatch)
+		*exactusermatch = usermatched;
+	return pathmatchlen;
+}
+
+int urlmatch_config_entry(const char *var, const char *value, void *cb)
+{
+	struct string_list_item *item;
+	struct urlmatch_config *collect = cb;
+	struct urlmatch_item *matched;
+	struct url_info *url = &collect->url;
+	const char *key, *dot;
+	struct strbuf synthkey = STRBUF_INIT;
+	size_t matched_len = 0;
+	int user_matched = 0;
+	int retval;
+
+	key = skip_prefix(var, collect->section);
+	if (!key || *(key++) != '.') {
+		if (collect->cascade_fn)
+			return collect->cascade_fn(var, value, cb);
+		return 0; /* not interested */
+	}
+	dot = strrchr(key, '.');
+	if (dot) {
+		char *config_url, *norm_url;
+		struct url_info norm_info;
+
+		config_url = xmemdupz(key, dot - key);
+		norm_url = url_normalize(config_url, &norm_info);
+		free(config_url);
+		if (!norm_url)
+			return 0;
+		matched_len = match_urls(url, &norm_info, &user_matched);
+		free(norm_url);
+		if (!matched_len)
+			return 0;
+		key = dot + 1;
+	}
+
+	if (collect->key && strcmp(key, collect->key))
+		return 0;
+
+	item = string_list_insert(&collect->vars, key);
+	if (!item->util) {
+		matched = xcalloc(1, sizeof(*matched));
+		item->util = matched;
+	} else {
+		matched = item->util;
+		/*
+		 * Is our match shorter?  Is our match the same
+		 * length, and without user while the current
+		 * candidate is with user?  Then we cannot use it.
+		 */
+		if (matched_len < matched->matched_len ||
+		    ((matched_len == matched->matched_len) &&
+		     (!user_matched && matched->user_matched)))
+			return 0;
+		/* Otherwise, replace it with this one. */
+	}
+
+	matched->matched_len = matched_len;
+	matched->user_matched = user_matched;
+	strbuf_addstr(&synthkey, collect->section);
+	strbuf_addch(&synthkey, '.');
+	strbuf_addstr(&synthkey, key);
+	retval = collect->collect_fn(synthkey.buf, value, collect->cb);
+
+	strbuf_release(&synthkey);
+	return retval;
+}
diff --git a/urlmatch.h b/urlmatch.h
new file mode 100644
index 0000000..b461dfd
--- /dev/null
+++ b/urlmatch.h
@@ -0,0 +1,54 @@
+#ifndef URL_MATCH_H
+#include "string-list.h"
+
+struct url_info {
+	/* normalized url on success, must be freed, otherwise NULL */
+	char *url;
+	/* if !url, a brief reason for the failure, otherwise NULL */
+	const char *err;
+
+	/* the rest of the fields are only set if url != NULL */
+
+	size_t url_len;		/* total length of url (which is now normalized) */
+	size_t scheme_len;	/* length of scheme name (excluding final :) */
+	size_t user_off;	/* offset into url to start of user name (0 => none) */
+	size_t user_len;	/* length of user name; if user_off != 0 but
+				   user_len == 0, an empty user name was given */
+	size_t passwd_off;	/* offset into url to start of passwd (0 => none) */
+	size_t passwd_len;	/* length of passwd; if passwd_off != 0 but
+				   passwd_len == 0, an empty passwd was given */
+	size_t host_off;	/* offset into url to start of host name (0 => none) */
+	size_t host_len;	/* length of host name; this INCLUDES any ':portnum';
+				 * file urls may have host_len == 0 */
+	size_t port_len;	/* if a portnum is present (port_len != 0), it has
+				 * this length (excluding the leading ':') at the
+				 * end of the host name (always 0 for file urls) */
+	size_t path_off;	/* offset into url to the start of the url path;
+				 * this will always point to a '/' character
+				 * after the url has been normalized */
+	size_t path_len;	/* length of path portion excluding any trailing
+				 * '?...' and '#...' portion; will always be >= 1 */
+};
+
+extern char *url_normalize(const char *, struct url_info *);
+extern int match_urls(const struct url_info *url, const struct url_info *url_prefix, int *exactusermatch);
+
+struct urlmatch_item {
+	size_t matched_len;
+	char user_matched;
+};
+
+struct urlmatch_config {
+	struct string_list vars;
+	struct url_info url;
+	const char *section;
+	const char *key;
+
+	void *cb;
+	int (*collect_fn)(const char *var, const char *value, void *cb);
+	int (*cascade_fn)(const char *var, const char *value, void *cb);
+};
+
+extern int urlmatch_config_entry(const char *var, const char *value, void *cb);
+
+#endif /* URL_MATCH_H */
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index f2b23c8..bd0f2c2 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -162,22 +162,13 @@
 	die("invalid dump: unexpected end of file");
 }
 
-static int ends_with(const char *s, size_t len, const char *suffix)
-{
-	const size_t suffixlen = strlen(suffix);
-	if (len < suffixlen)
-		return 0;
-	return !memcmp(s + len - suffixlen, suffix, suffixlen);
-}
-
 static int parse_cat_response_line(const char *header, off_t *len)
 {
-	size_t headerlen = strlen(header);
 	uintmax_t n;
 	const char *type;
 	const char *end;
 
-	if (ends_with(header, headerlen, " missing"))
+	if (ends_with(header, " missing"))
 		return error("cat-blob reports missing blob: %s", header);
 	type = strstr(header, " blob ");
 	if (!type)
diff --git a/walker.c b/walker.c
index be389dc..633596e 100644
--- a/walker.c
+++ b/walker.c
@@ -56,10 +56,7 @@
 		if (!obj || process(walker, obj))
 			return -1;
 	}
-	free(tree->buffer);
-	tree->buffer = NULL;
-	tree->size = 0;
-	tree->object.parsed = 0;
+	free_tree_buffer(tree);
 	return 0;
 }
 
diff --git a/wrapper.c b/wrapper.c
index f92b147..0cc5636 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -133,7 +133,7 @@
 /*
  * Limit size of IO chunks, because huge chunks only cause pain.  OS X
  * 64-bit is buggy, returning EINVAL if len >= INT_MAX; and even in
- * the absense of bugs, large chunks can result in bad latencies when
+ * the absence of bugs, large chunks can result in bad latencies when
  * you decide to kill the process.
  */
 #define MAX_IO_SIZE (8*1024*1024)
@@ -360,10 +360,12 @@
 	return git_mkstemps_mode(pattern, 0, mode);
 }
 
+#ifdef NO_MKSTEMPS
 int gitmkstemps(char *pattern, int suffix_len)
 {
 	return git_mkstemps_mode(pattern, suffix_len, 0600);
 }
+#endif
 
 int xmkstemp_mode(char *template, int mode)
 {
diff --git a/wt-status.c b/wt-status.c
index cb24f1f..4e55810 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "pathspec.h"
 #include "wt-status.h"
 #include "object.h"
 #include "dir.h"
@@ -8,11 +9,16 @@
 #include "diffcore.h"
 #include "quote.h"
 #include "run-command.h"
+#include "argv-array.h"
 #include "remote.h"
 #include "refs.h"
 #include "submodule.h"
 #include "column.h"
 #include "strbuf.h"
+#include "utf8.h"
+
+static char cut_line[] =
+"------------------------ >8 ------------------------\n";
 
 static char default_wt_status_colors[][COLOR_MAXLEN] = {
 	GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
@@ -45,9 +51,11 @@
 
 	strbuf_vaddf(&sb, fmt, ap);
 	if (!sb.len) {
-		strbuf_addch(&sb, comment_line_char);
-		if (!trail)
-			strbuf_addch(&sb, ' ');
+		if (s->display_comment_prefix) {
+			strbuf_addch(&sb, comment_line_char);
+			if (!trail)
+				strbuf_addch(&sb, ' ');
+		}
 		color_print_strbuf(s->fp, color, &sb);
 		if (trail)
 			fprintf(s->fp, "%s", trail);
@@ -58,7 +66,7 @@
 		eol = strchr(line, '\n');
 
 		strbuf_reset(&linebuf);
-		if (at_bol) {
+		if (at_bol && s->display_comment_prefix) {
 			strbuf_addch(&linebuf, comment_line_char);
 			if (*line != '\n' && *line != '\t')
 				strbuf_addch(&linebuf, ' ');
@@ -128,6 +136,7 @@
 	s->untracked.strdup_strings = 1;
 	s->ignored.strdup_strings = 1;
 	s->show_branch = -1;  /* unspecified */
+	s->display_comment_prefix = 0;
 }
 
 static void wt_status_print_unmerged_header(struct wt_status *s)
@@ -160,7 +169,7 @@
 		}
 	}
 
-	if (!advice_status_hints)
+	if (!s->hints)
 		return;
 	if (s->whence != FROM_COMMIT)
 		;
@@ -187,7 +196,7 @@
 	const char *c = color(WT_STATUS_HEADER, s);
 
 	status_printf_ln(s, c, _("Changes to be committed:"));
-	if (!advice_status_hints)
+	if (!s->hints)
 		return;
 	if (s->whence != FROM_COMMIT)
 		; /* NEEDSWORK: use "git reset --unresolve"??? */
@@ -205,7 +214,7 @@
 	const char *c = color(WT_STATUS_HEADER, s);
 
 	status_printf_ln(s, c, _("Changes not staged for commit:"));
-	if (!advice_status_hints)
+	if (!s->hints)
 		return;
 	if (!has_deleted)
 		status_printf_ln(s, c, _("  (use \"git add <file>...\" to update what will be committed)"));
@@ -223,7 +232,7 @@
 {
 	const char *c = color(WT_STATUS_HEADER, s);
 	status_printf_ln(s, c, "%s:", what);
-	if (!advice_status_hints)
+	if (!s->hints)
 		return;
 	status_printf_ln(s, c, _("  (use \"git %s <file>...\" to include in what will be committed)"), how);
 	status_printf_ln(s, c, "");
@@ -259,6 +268,30 @@
 	strbuf_release(&onebuf);
 }
 
+static const char *wt_status_diff_status_string(int status)
+{
+	switch (status) {
+	case DIFF_STATUS_ADDED:
+		return _("new file");
+	case DIFF_STATUS_COPIED:
+		return _("copied");
+	case DIFF_STATUS_DELETED:
+		return _("deleted");
+	case DIFF_STATUS_MODIFIED:
+		return _("modified");
+	case DIFF_STATUS_RENAMED:
+		return _("renamed");
+	case DIFF_STATUS_TYPE_CHANGED:
+		return _("typechange");
+	case DIFF_STATUS_UNKNOWN:
+		return _("unknown");
+	case DIFF_STATUS_UNMERGED:
+		return _("unmerged");
+	default:
+		return NULL;
+	}
+}
+
 static void wt_status_print_change_data(struct wt_status *s,
 					int change_type,
 					struct string_list_item *it)
@@ -271,6 +304,23 @@
 	const char *one, *two;
 	struct strbuf onebuf = STRBUF_INIT, twobuf = STRBUF_INIT;
 	struct strbuf extra = STRBUF_INIT;
+	static char *padding;
+	const char *what;
+	int len;
+
+	if (!padding) {
+		int width = 0;
+		/* If DIFF_STATUS_* uses outside this range, we're in trouble */
+		for (status = 'A'; status <= 'Z'; status++) {
+			what = wt_status_diff_status_string(status);
+			len = what ? strlen(what) : 0;
+			if (len > width)
+				width = len;
+		}
+		width += 2;	/* colon and a space */
+		padding = xmallocz(width);
+		memset(padding, ' ', width);
+	}
 
 	one_name = two_name = it->string;
 	switch (change_type) {
@@ -302,34 +352,18 @@
 	two = quote_path(two_name, s->prefix, &twobuf);
 
 	status_printf(s, color(WT_STATUS_HEADER, s), "\t");
-	switch (status) {
-	case DIFF_STATUS_ADDED:
-		status_printf_more(s, c, _("new file:   %s"), one);
-		break;
-	case DIFF_STATUS_COPIED:
-		status_printf_more(s, c, _("copied:     %s -> %s"), one, two);
-		break;
-	case DIFF_STATUS_DELETED:
-		status_printf_more(s, c, _("deleted:    %s"), one);
-		break;
-	case DIFF_STATUS_MODIFIED:
-		status_printf_more(s, c, _("modified:   %s"), one);
-		break;
-	case DIFF_STATUS_RENAMED:
-		status_printf_more(s, c, _("renamed:    %s -> %s"), one, two);
-		break;
-	case DIFF_STATUS_TYPE_CHANGED:
-		status_printf_more(s, c, _("typechange: %s"), one);
-		break;
-	case DIFF_STATUS_UNKNOWN:
-		status_printf_more(s, c, _("unknown:    %s"), one);
-		break;
-	case DIFF_STATUS_UNMERGED:
-		status_printf_more(s, c, _("unmerged:   %s"), one);
-		break;
-	default:
+	what = wt_status_diff_status_string(status);
+	if (!what)
 		die(_("bug: unhandled diff status %c"), status);
-	}
+	/* 1 for colon, which is not part of "what" */
+	len = strlen(padding) - (utf8_strwidth(what) + 1);
+	assert(len >= 0);
+	if (status == DIFF_STATUS_COPIED || status == DIFF_STATUS_RENAMED)
+		status_printf_more(s, c, "%s:%.*s%s -> %s",
+				   what, len, padding, one, two);
+	else
+		status_printf_more(s, c, "%s:%.*s%s",
+				   what, len, padding, one);
 	if (extra.len) {
 		status_printf_more(s, color(WT_STATUS_HEADER, s), "%s", extra.buf);
 		strbuf_release(&extra);
@@ -438,7 +472,7 @@
 	}
 	rev.diffopt.format_callback = wt_status_collect_changed_cb;
 	rev.diffopt.format_callback_data = s;
-	init_pathspec(&rev.prune_data, s->pathspec);
+	copy_pathspec(&rev.prune_data, &s->pathspec);
 	run_diff_files(&rev, 0);
 }
 
@@ -463,22 +497,20 @@
 	rev.diffopt.detect_rename = 1;
 	rev.diffopt.rename_limit = 200;
 	rev.diffopt.break_opt = 0;
-	init_pathspec(&rev.prune_data, s->pathspec);
+	copy_pathspec(&rev.prune_data, &s->pathspec);
 	run_diff_index(&rev, 1);
 }
 
 static void wt_status_collect_changes_initial(struct wt_status *s)
 {
-	struct pathspec pathspec;
 	int i;
 
-	init_pathspec(&pathspec, s->pathspec);
 	for (i = 0; i < active_nr; i++) {
 		struct string_list_item *it;
 		struct wt_status_change_data *d;
 		const struct cache_entry *ce = active_cache[i];
 
-		if (!ce_path_match(ce, &pathspec))
+		if (!ce_path_match(ce, &s->pathspec))
 			continue;
 		it = string_list_insert(&s->change, ce->name);
 		d = it->util;
@@ -493,7 +525,6 @@
 		else
 			d->index_status = DIFF_STATUS_ADDED;
 	}
-	free_pathspec(&pathspec);
 }
 
 static void wt_status_collect_untracked(struct wt_status *s)
@@ -516,12 +547,12 @@
 		dir.flags |= DIR_SHOW_IGNORED_TOO;
 	setup_standard_excludes(&dir);
 
-	fill_directory(&dir, s->pathspec);
+	fill_directory(&dir, &s->pathspec);
 
 	for (i = 0; i < dir.nr; i++) {
 		struct dir_entry *ent = dir.entries[i];
 		if (cache_name_is_other(ent->name, ent->len) &&
-		    match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
+		    match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))
 			string_list_insert(&s->untracked, ent->name);
 		free(ent);
 	}
@@ -529,7 +560,7 @@
 	for (i = 0; i < dir.ignored_nr; i++) {
 		struct dir_entry *ent = dir.ignored[i];
 		if (cache_name_is_other(ent->name, ent->len) &&
-		    match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
+		    match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))
 			string_list_insert(&s->ignored, ent->name);
 		free(ent);
 	}
@@ -663,29 +694,57 @@
 	char summary_limit[64];
 	char index[PATH_MAX];
 	const char *env[] = { NULL, NULL };
-	const char *argv[8];
-
-	env[0] =	index;
-	argv[0] =	"submodule";
-	argv[1] =	"summary";
-	argv[2] =	uncommitted ? "--files" : "--cached";
-	argv[3] =	"--for-status";
-	argv[4] =	"--summary-limit";
-	argv[5] =	summary_limit;
-	argv[6] =	uncommitted ? NULL : (s->amend ? "HEAD^" : "HEAD");
-	argv[7] =	NULL;
+	struct argv_array argv = ARGV_ARRAY_INIT;
+	struct strbuf cmd_stdout = STRBUF_INIT;
+	struct strbuf summary = STRBUF_INIT;
+	char *summary_content;
+	size_t len;
 
 	sprintf(summary_limit, "%d", s->submodule_summary);
 	snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", s->index_file);
 
+	env[0] = index;
+	argv_array_push(&argv, "submodule");
+	argv_array_push(&argv, "summary");
+	argv_array_push(&argv, uncommitted ? "--files" : "--cached");
+	argv_array_push(&argv, "--for-status");
+	argv_array_push(&argv, "--summary-limit");
+	argv_array_push(&argv, summary_limit);
+	if (!uncommitted)
+		argv_array_push(&argv, s->amend ? "HEAD^" : "HEAD");
+
 	memset(&sm_summary, 0, sizeof(sm_summary));
-	sm_summary.argv = argv;
+	sm_summary.argv = argv.argv;
 	sm_summary.env = env;
 	sm_summary.git_cmd = 1;
 	sm_summary.no_stdin = 1;
 	fflush(s->fp);
-	sm_summary.out = dup(fileno(s->fp));    /* run_command closes it */
+	sm_summary.out = -1;
+
 	run_command(&sm_summary);
+	argv_array_clear(&argv);
+
+	len = strbuf_read(&cmd_stdout, sm_summary.out, 1024);
+
+	/* prepend header, only if there's an actual output */
+	if (len) {
+		if (uncommitted)
+			strbuf_addstr(&summary, _("Submodules changed but not updated:"));
+		else
+			strbuf_addstr(&summary, _("Submodule changes to be committed:"));
+		strbuf_addstr(&summary, "\n\n");
+	}
+	strbuf_addbuf(&summary, &cmd_stdout);
+	strbuf_release(&cmd_stdout);
+
+	if (s->display_comment_prefix) {
+		summary_content = strbuf_detach(&summary, &len);
+		strbuf_add_commented_lines(&summary, summary_content, len);
+		free(summary_content);
+	}
+
+	fputs(summary.buf, s->fp);
+	strbuf_release(&summary);
 }
 
 static void wt_status_print_other(struct wt_status *s,
@@ -719,10 +778,11 @@
 
 	strbuf_release(&buf);
 	if (!column_active(s->colopts))
-		return;
+		goto conclude;
 
-	strbuf_addf(&buf, "%s#\t%s",
+	strbuf_addf(&buf, "%s%s\t%s",
 		    color(WT_STATUS_HEADER, s),
+		    s->display_comment_prefix ? "#" : "",
 		    color(WT_STATUS_UNTRACKED, s));
 	memset(&copts, 0, sizeof(copts));
 	copts.padding = 1;
@@ -732,6 +792,20 @@
 	print_columns(&output, s->colopts, &copts);
 	string_list_clear(&output, 0);
 	strbuf_release(&buf);
+conclude:
+	status_printf_ln(s, GIT_COLOR_NORMAL, "");
+}
+
+void wt_status_truncate_message_at_cut_line(struct strbuf *buf)
+{
+	const char *p;
+	struct strbuf pattern = STRBUF_INIT;
+
+	strbuf_addf(&pattern, "%c %s", comment_line_char, cut_line);
+	p = strstr(buf->buf, pattern.buf);
+	if (p && (p == buf->buf || p[-1] == '\n'))
+		strbuf_setlen(buf, p - buf->buf);
+	strbuf_release(&pattern);
 }
 
 static void wt_status_print_verbose(struct wt_status *s)
@@ -754,10 +828,20 @@
 	 * If we're not going to stdout, then we definitely don't
 	 * want color, since we are going to the commit message
 	 * file (and even the "auto" setting won't work, since it
-	 * will have checked isatty on stdout).
+	 * will have checked isatty on stdout). But we then do want
+	 * to insert the scissor line here to reliably remove the
+	 * diff before committing.
 	 */
-	if (s->fp != stdout)
+	if (s->fp != stdout) {
+		const char *explanation = _("Do not touch the line above.\nEverything below will be removed.");
+		struct strbuf buf = STRBUF_INIT;
+
 		rev.diffopt.use_color = 0;
+		fprintf(s->fp, "%c %s", comment_line_char, cut_line);
+		strbuf_add_commented_lines(&buf, explanation, strlen(explanation));
+		fputs(buf.buf, s->fp);
+		strbuf_release(&buf);
+	}
 	run_diff_index(&rev, 1);
 }
 
@@ -766,20 +850,32 @@
 	struct strbuf sb = STRBUF_INIT;
 	const char *cp, *ep;
 	struct branch *branch;
+	char comment_line_string[3];
+	int i;
 
 	assert(s->branch && !s->is_initial);
-	if (prefixcmp(s->branch, "refs/heads/"))
+	if (!starts_with(s->branch, "refs/heads/"))
 		return;
 	branch = branch_get(s->branch + 11);
 	if (!format_tracking_info(branch, &sb))
 		return;
 
+	i = 0;
+	if (s->display_comment_prefix) {
+		comment_line_string[i++] = comment_line_char;
+		comment_line_string[i++] = ' ';
+	}
+	comment_line_string[i] = '\0';
+
 	for (cp = sb.buf; (ep = strchr(cp, '\n')) != NULL; cp = ep + 1)
 		color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s),
-				 "%c %.*s", comment_line_char,
+				 "%s%.*s", comment_line_string,
 				 (int)(ep - cp), cp);
-	color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%c",
-			 comment_line_char);
+	if (s->display_comment_prefix)
+		color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%c",
+				 comment_line_char);
+	else
+		fprintf_ln(s->fp, "");
 }
 
 static int has_unmerged(struct wt_status *s)
@@ -801,13 +897,13 @@
 {
 	if (has_unmerged(s)) {
 		status_printf_ln(s, color, _("You have unmerged paths."));
-		if (advice_status_hints)
+		if (s->hints)
 			status_printf_ln(s, color,
 				_("  (fix conflicts and run \"git commit\")"));
 	} else {
 		status_printf_ln(s, color,
 			_("All conflicts fixed but you are still merging."));
-		if (advice_status_hints)
+		if (s->hints)
 			status_printf_ln(s, color,
 				_("  (use \"git commit\" to conclude merge)"));
 	}
@@ -823,7 +919,7 @@
 	if (state->am_empty_patch)
 		status_printf_ln(s, color,
 			_("The current patch is empty."));
-	if (advice_status_hints) {
+	if (s->hints) {
 		if (!state->am_empty_patch)
 			status_printf_ln(s, color,
 				_("  (fix conflicts and then run \"git am --continue\")"));
@@ -896,7 +992,7 @@
 		else
 			status_printf_ln(s, color,
 					 _("You are currently rebasing."));
-		if (advice_status_hints) {
+		if (s->hints) {
 			status_printf_ln(s, color,
 				_("  (fix conflicts and then run \"git rebase --continue\")"));
 			status_printf_ln(s, color,
@@ -913,7 +1009,7 @@
 		else
 			status_printf_ln(s, color,
 					 _("You are currently rebasing."));
-		if (advice_status_hints)
+		if (s->hints)
 			status_printf_ln(s, color,
 				_("  (all conflicts fixed: run \"git rebase --continue\")"));
 	} else if (split_commit_in_progress(s)) {
@@ -925,7 +1021,7 @@
 		else
 			status_printf_ln(s, color,
 					 _("You are currently splitting a commit during a rebase."));
-		if (advice_status_hints)
+		if (s->hints)
 			status_printf_ln(s, color,
 				_("  (Once your working directory is clean, run \"git rebase --continue\")"));
 	} else {
@@ -937,7 +1033,7 @@
 		else
 			status_printf_ln(s, color,
 					 _("You are currently editing a commit during a rebase."));
-		if (advice_status_hints && !s->amend) {
+		if (s->hints && !s->amend) {
 			status_printf_ln(s, color,
 				_("  (use \"git commit --amend\" to amend the current commit)"));
 			status_printf_ln(s, color,
@@ -951,8 +1047,9 @@
 					struct wt_status_state *state,
 					const char *color)
 {
-	status_printf_ln(s, color, _("You are currently cherry-picking."));
-	if (advice_status_hints) {
+	status_printf_ln(s, color, _("You are currently cherry-picking commit %s."),
+			find_unique_abbrev(state->cherry_pick_head_sha1, DEFAULT_ABBREV));
+	if (s->hints) {
 		if (has_unmerged(s))
 			status_printf_ln(s, color,
 				_("  (fix conflicts and run \"git cherry-pick --continue\")"));
@@ -971,7 +1068,7 @@
 {
 	status_printf_ln(s, color, _("You are currently reverting commit %s."),
 			 find_unique_abbrev(state->revert_head_sha1, DEFAULT_ABBREV));
-	if (advice_status_hints) {
+	if (s->hints) {
 		if (has_unmerged(s))
 			status_printf_ln(s, color,
 				_("  (fix conflicts and run \"git revert --continue\")"));
@@ -995,7 +1092,7 @@
 	else
 		status_printf_ln(s, color,
 				 _("You are currently bisecting."));
-	if (advice_status_hints)
+	if (s->hints)
 		status_printf_ln(s, color,
 			_("  (use \"git bisect reset\" to get back to the original branch)"));
 	wt_status_print_trailer(s);
@@ -1016,9 +1113,9 @@
 		strbuf_setlen(&sb, sb.len - 1);
 	if (!sb.len)
 		goto got_nothing;
-	if (!prefixcmp(sb.buf, "refs/heads/"))
+	if (starts_with(sb.buf, "refs/heads/"))
 		strbuf_remove(&sb,0, strlen("refs/heads/"));
-	else if (!prefixcmp(sb.buf, "refs/"))
+	else if (starts_with(sb.buf, "refs/"))
 		;
 	else if (!get_sha1_hex(sb.buf, sha1)) {
 		const char *abbrev;
@@ -1048,7 +1145,7 @@
 	struct grab_1st_switch_cbdata *cb = cb_data;
 	const char *target = NULL, *end;
 
-	if (prefixcmp(message, "checkout: moving from "))
+	if (!starts_with(message, "checkout: moving from "))
 		return 0;
 	message += strlen("checkout: moving from ");
 	target = strstr(message, " to ");
@@ -1083,9 +1180,9 @@
 	     ((commit = lookup_commit_reference_gently(sha1, 1)) != NULL &&
 	      !hashcmp(cb.nsha1, commit->object.sha1)))) {
 		int ofs;
-		if (!prefixcmp(ref, "refs/tags/"))
+		if (starts_with(ref, "refs/tags/"))
 			ofs = strlen("refs/tags/");
-		else if (!prefixcmp(ref, "refs/remotes/"))
+		else if (starts_with(ref, "refs/remotes/"))
 			ofs = strlen("refs/remotes/");
 		else
 			ofs = 0;
@@ -1124,8 +1221,10 @@
 			state->rebase_in_progress = 1;
 		state->branch = read_and_strip_branch("rebase-merge/head-name");
 		state->onto = read_and_strip_branch("rebase-merge/onto");
-	} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
+	} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st) &&
+			!get_sha1("CHERRY_PICK_HEAD", sha1)) {
 		state->cherry_pick_in_progress = 1;
+		hashcpy(state->cherry_pick_head_sha1, sha1);
 	}
 	if (!stat(git_path("BISECT_LOG"), &st)) {
 		state->bisect_in_progress = 1;
@@ -1172,7 +1271,7 @@
 	if (s->branch) {
 		const char *on_what = _("On branch ");
 		const char *branch_name = s->branch;
-		if (!prefixcmp(branch_name, "refs/heads/"))
+		if (starts_with(branch_name, "refs/heads/"))
 			branch_name += 11;
 		else if (!strcmp(branch_name, "HEAD")) {
 			branch_status_color = color(WT_STATUS_NOBRANCH, s);
@@ -1233,7 +1332,7 @@
 		}
 	} else if (s->commitable)
 		status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"),
-			advice_status_hints
+			s->hints
 			? _(" (use -u option to show untracked files)") : "");
 
 	if (s->verbose)
@@ -1244,25 +1343,25 @@
 		else if (s->nowarn)
 			; /* nothing */
 		else if (s->workdir_dirty) {
-			if (advice_status_hints)
+			if (s->hints)
 				printf(_("no changes added to commit "
 					 "(use \"git add\" and/or \"git commit -a\")\n"));
 			else
 				printf(_("no changes added to commit\n"));
 		} else if (s->untracked.nr) {
-			if (advice_status_hints)
+			if (s->hints)
 				printf(_("nothing added to commit but untracked files "
 					 "present (use \"git add\" to track)\n"));
 			else
 				printf(_("nothing added to commit but untracked files present\n"));
 		} else if (s->is_initial) {
-			if (advice_status_hints)
+			if (s->hints)
 				printf(_("nothing to commit (create/copy files "
 					 "and use \"git add\" to track)\n"));
 			else
 				printf(_("nothing to commit\n"));
 		} else if (!s->show_untracked_files) {
-			if (advice_status_hints)
+			if (s->hints)
 				printf(_("nothing to commit (use -u to show untracked files)\n"));
 			else
 				printf(_("nothing to commit\n"));
@@ -1365,6 +1464,7 @@
 	const char *base;
 	const char *branch_name;
 	int num_ours, num_theirs;
+	int upstream_is_gone = 0;
 
 	color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "## ");
 
@@ -1372,7 +1472,7 @@
 		return;
 	branch_name = s->branch;
 
-	if (!prefixcmp(branch_name, "refs/heads/"))
+	if (starts_with(branch_name, "refs/heads/"))
 		branch_name += 11;
 	else if (!strcmp(branch_name, "HEAD")) {
 		branch_name = _("HEAD (no branch)");
@@ -1382,20 +1482,37 @@
 	branch = branch_get(s->branch + 11);
 	if (s->is_initial)
 		color_fprintf(s->fp, header_color, _("Initial commit on "));
-	if (!stat_tracking_info(branch, &num_ours, &num_theirs)) {
-		color_fprintf(s->fp, branch_color_local, "%s", branch_name);
+
+	color_fprintf(s->fp, branch_color_local, "%s", branch_name);
+
+	switch (stat_tracking_info(branch, &num_ours, &num_theirs)) {
+	case 0:
+		/* no base */
 		fputc(s->null_termination ? '\0' : '\n', s->fp);
 		return;
+	case -1:
+		/* with "gone" base */
+		upstream_is_gone = 1;
+		break;
+	default:
+		/* with base */
+		break;
 	}
 
 	base = branch->merge[0]->dst;
 	base = shorten_unambiguous_ref(base, 0);
-	color_fprintf(s->fp, branch_color_local, "%s", branch_name);
 	color_fprintf(s->fp, header_color, "...");
 	color_fprintf(s->fp, branch_color_remote, "%s", base);
 
+	if (!upstream_is_gone && !num_ours && !num_theirs) {
+		fputc(s->null_termination ? '\0' : '\n', s->fp);
+		return;
+	}
+
 	color_fprintf(s->fp, header_color, " [");
-	if (!num_ours) {
+	if (upstream_is_gone) {
+		color_fprintf(s->fp, header_color, _("gone"));
+	} else if (!num_ours) {
 		color_fprintf(s->fp, header_color, _("behind "));
 		color_fprintf(s->fp, branch_color_remote, "%d", num_theirs);
 	} else if (!num_theirs) {
diff --git a/wt-status.h b/wt-status.h
index fb7152e..30a4812 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -44,12 +44,13 @@
 	int is_initial;
 	char *branch;
 	const char *reference;
-	const char **pathspec;
+	struct pathspec pathspec;
 	int verbose;
 	int amend;
 	enum commit_whence whence;
 	int nowarn;
 	int use_color;
+	int display_comment_prefix;
 	int relative_paths;
 	int submodule_summary;
 	int show_ignored_files;
@@ -59,6 +60,7 @@
 	unsigned colopts;
 	int null_termination;
 	int show_branch;
+	int hints;
 
 	/* These are computed during processing of the individual sections */
 	int commitable;
@@ -86,8 +88,10 @@
 	char *detached_from;
 	unsigned char detached_sha1[20];
 	unsigned char revert_head_sha1[20];
+	unsigned char cherry_pick_head_sha1[20];
 };
 
+void wt_status_truncate_message_at_cut_line(struct strbuf *);
 void wt_status_prepare(struct wt_status *s);
 void wt_status_print(struct wt_status *s);
 void wt_status_collect(struct wt_status *s);
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index 4d86458..4266ada 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -108,7 +108,7 @@
 {
 	if (len > 0 &&
 			(isalpha((unsigned char)*rec) || /* identifier? */
-			 *rec == '_' ||	/* also identifier? */
+			 *rec == '_' || /* also identifier? */
 			 *rec == '$')) { /* identifiers from VMS and other esoterico */
 		if (len > sz)
 			len = sz;