Merge branch 'sd/stash-wo-user-name'

A properly configured username/email is required under
user.useConfigOnly in order to create commits; now "git stash"
(even though it creates commit objects to represent stash entries)
command is exempt from the requirement.

* sd/stash-wo-user-name:
  stash: tolerate missing user identity
diff --git a/.gitattributes b/.gitattributes
index 49b3051..9fa72ad 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,10 +5,11 @@
 *.pl eof=lf diff=perl
 *.pm eol=lf diff=perl
 *.py eol=lf diff=python
-/Documentation/git-*.txt eol=lf
+/Documentation/**/*.txt eol=lf
 /command-list.txt eol=lf
 /GIT-VERSION-GEN eol=lf
 /mergetools/* eol=lf
+/t/oid-info/* eol=lf
 /Documentation/git-merge.txt conflict-marker-size=32
 /Documentation/gitk.txt conflict-marker-size=32
 /Documentation/user-manual.txt conflict-marker-size=32
diff --git a/.mailmap b/.mailmap
index bef3352..eb7b5fc 100644
--- a/.mailmap
+++ b/.mailmap
@@ -21,6 +21,8 @@
 Aneesh Kumar K.V <aneesh.kumar@gmail.com>
 Amos Waterland <apw@debian.org> <apw@rossby.metr.ou.edu>
 Amos Waterland <apw@debian.org> <apw@us.ibm.com>
+Ben Peart <benpeart@microsoft.com> <Ben.Peart@microsoft.com>
+Ben Peart <benpeart@microsoft.com> <peartben@gmail.com>
 Ben Walton <bdwalton@gmail.com> <bwalton@artsci.utoronto.ca>
 Benoit Sigoure <tsunanet@gmail.com> <tsuna@lrde.epita.fr>
 Bernt Hansen <bernt@norang.ca> <bernt@alumni.uwaterloo.ca>
@@ -32,6 +34,7 @@
 Cheng Renquan <crquan@gmail.com>
 Chris Shoemaker <c.shoemaker@cox.net>
 Chris Wright <chrisw@sous-sol.org> <chrisw@osdl.org>
+Christian Ludwig <chrissicool@gmail.com> <chrissicool@googlemail.com>
 Cord Seele <cowose@gmail.com> <cowose@googlemail.com>
 Christian Couder <chriscool@tuxfamily.org> <christian.couder@gmail.com>
 Christian Stimming <stimming@tuhh.de> <chs@ckiste.goetheallee>
@@ -51,6 +54,7 @@
 David S. Miller <davem@davemloft.net>
 David Turner <novalis@novalis.org> <dturner@twopensource.com>
 David Turner <novalis@novalis.org> <dturner@twosigma.com>
+Derrick Stolee <dstolee@microsoft.com> <stolee@gmail.com>
 Deskin Miller <deskinm@umich.edu>
 Dirk Süsserott <newsletter@dirk.my1.cc>
 Eric Blake <eblake@redhat.com> <ebb9@byu.net>
@@ -98,6 +102,7 @@
 Jens Lindström <jl@opera.com> Jens Lindstrom <jl@opera.com>
 Jim Meyering <jim@meyering.net> <meyering@redhat.com>
 Joachim Berdal Haga <cjhaga@fys.uio.no>
+Joachim Jablon <joachim.jablon@people-doc.com> <ewjoachim@gmail.com>
 Johannes Schindelin <Johannes.Schindelin@gmx.de> <johannes.schindelin@gmx.de>
 Johannes Sixt <j6t@kdbg.org> <J.Sixt@eudaptics.com>
 Johannes Sixt <j6t@kdbg.org> <j.sixt@viscovery.net>
@@ -150,6 +155,7 @@
 Mark Rada <marada@uwaterloo.ca>
 Martin Langhoff <martin@laptop.org> <martin@catalyst.net.nz>
 Martin von Zweigbergk <martinvonz@gmail.com> <martin.von.zweigbergk@gmail.com>
+Masaya Suzuki <masayasuzuki@google.com> <draftcode@gmail.com>
 Matt Draisey <matt@draisey.ca> <mattdraisey@sympatico.ca>
 Matt Kraai <kraai@ftbfs.org> <matt.kraai@amo.abbott.com>
 Matt McCutchen <matt@mattmccutchen.net> <hashproduct@gmail.com>
@@ -157,6 +163,7 @@
 Matthias Rüster <matthias.ruester@gmail.com> Matthias Ruester
 Matthias Urlichs <matthias@urlichs.de> <smurf@kiste.(none)>
 Matthias Urlichs <matthias@urlichs.de> <smurf@smurf.noris.de>
+Matthieu Moy <git@matthieu-moy.fr> <Matthieu.Moy@imag.fr>
 Michael Coleman <tutufan@gmail.com>
 Michael J Gruber <git@grubix.eu> <michaeljgruber+gmane@fastmail.fm>
 Michael J Gruber <git@grubix.eu> <git@drmicha.warpmail.net>
@@ -180,7 +187,11 @@
 Nick Stokoe <nick@noodlefactory.co.uk> Nick Woolley <nickwoolley@yahoo.co.uk>
 Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nicolas.morey@free.fr>
 Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nmorey@kalray.eu>
+Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nicolas@morey-chaisemartin.com>
+Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <NMoreyChaisemartin@suse.com>
+Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nmoreychaisemartin@suse.com>
 Nicolas Sebrecht <nicolas.s.dev@gmx.fr> <ni.s@laposte.net>
+Orgad Shaneh <orgads@gmail.com> <orgad.shaneh@audiocodes.com>
 Paolo Bonzini <bonzini@gnu.org> <paolo.bonzini@lu.unisi.ch>
 Pascal Obry <pascal@obry.net> <pascal.obry@gmail.com>
 Pascal Obry <pascal@obry.net> <pascal.obry@wanadoo.fr>
@@ -200,6 +211,7 @@
 Philippe Bruhat <book@cpan.org>
 Ralf Thielow <ralf.thielow@gmail.com> <ralf.thielow@googlemail.com>
 Ramsay Jones <ramsay@ramsayjones.plus.com> <ramsay@ramsay1.demon.co.uk>
+Randall S. Becker <randall.becker@nexbridge.ca> <rsbecker@nexbridge.com>
 René Scharfe <l.s.r@web.de> <rene.scharfe@lsrfire.ath.cx>
 René Scharfe <l.s.r@web.de> Rene Scharfe
 Richard Hansen <rhansen@rhansen.org> <hansenr@google.com>
@@ -238,6 +250,7 @@
 Sven Verdoolaege <skimo@kotnet.org> <Sven.Verdoolaege@cs.kuleuven.ac.be>
 Sven Verdoolaege <skimo@kotnet.org> <skimo@liacs.nl>
 SZEDER Gábor <szeder.dev@gmail.com> <szeder@ira.uka.de>
+Tao Qingyun <taoqy@ls-a.me> <845767657@qq.com>
 Tay Ray Chuan <rctay89@gmail.com>
 Ted Percival <ted@midg3t.net> <ted.percival@quest.com>
 Theodore Ts'o <tytso@mit.edu>
diff --git a/.travis.yml b/.travis.yml
index a5a82d6..03c8e4c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,7 @@
 
 matrix:
   include:
-    - env: jobname=GETTEXT_POISON
+    - env: jobname=GIT_TEST_GETTEXT_POISON
       os: linux
       compiler:
       addons:
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 48d261d..d5d936e 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -73,6 +73,7 @@
 TECH_DOCS += technical/http-protocol
 TECH_DOCS += technical/index-format
 TECH_DOCS += technical/long-running-process-protocol
+TECH_DOCS += technical/multi-pack-index
 TECH_DOCS += technical/pack-format
 TECH_DOCS += technical/pack-heuristics
 TECH_DOCS += technical/pack-protocol
diff --git a/Documentation/RelNotes/2.19.2.txt b/Documentation/RelNotes/2.19.2.txt
new file mode 100644
index 0000000..759e6ca
--- /dev/null
+++ b/Documentation/RelNotes/2.19.2.txt
@@ -0,0 +1,108 @@
+Git v2.19.2 Release Notes
+=========================
+
+Fixes since v2.19.1
+-------------------
+
+ * "git interpret-trailers" and its underlying machinery had a buggy
+   code that attempted to ignore patch text after commit log message,
+   which triggered in various codepaths that will always get the log
+   message alone and never get such an input.
+
+ * "git rebase -i" did not clear the state files correctly when a run
+   of "squash/fixup" is aborted and then the user manually amended the
+   commit instead, which has been corrected.
+
+ * When fsmonitor is in use, after operation on submodules updates
+   .gitmodules, we lost track of the fact that we did so and relied on
+   stale fsmonitor data.
+
+ * Fix for a long-standing bug that leaves the index file corrupt when
+   it shrinks during a partial commit.
+
+ * Further fix for O_APPEND emulation on Windows
+
+ * A corner case bugfix in "git rerere" code.
+
+ * "git add ':(attr:foo)'" is not supported and is supposed to be
+   rejected while the command line arguments are parsed, but we fail
+   to reject such a command line upfront.
+
+ * "git rebase" etc. in Git 2.19 fails to abort when given an empty
+   commit log message as result of editing, which has been corrected.
+
+ * The code to backfill objects in lazily cloned repository did not
+   work correctly, which has been corrected.
+
+ * Update error messages given by "git remote" and make them consistent.
+
+ * "git update-ref" learned to make both "--no-deref" and "--stdin"
+   work at the same time.
+
+ * Recently added "range-diff" had a corner-case bug to cause it
+   segfault, which has been corrected.
+
+ * The recently introduced commit-graph auxiliary data is incompatible
+   with mechanisms such as replace & grafts that "breaks" immutable
+   nature of the object reference relationship.  Disable optimizations
+   based on its use (and updating existing commit-graph) when these
+   incompatible features are in use in the repository.
+
+ * The mailmap file update.
+
+ * The code in "git status" sometimes hit an assertion failure.  This
+   was caused by a structure that was reused without cleaning the data
+   used for the first run, which has been corrected.
+
+ * A corner-case bugfix.
+
+ * A partial clone that is configured to lazily fetch missing objects
+   will on-demand issue a "git fetch" request to the originating
+   repository to fill not-yet-obtained objects.  The request has been
+   optimized for requesting a tree object (and not the leaf blob
+   objects contained in it) by telling the originating repository that
+   no blobs are needed.
+
+ * The codepath to support the experimental split-index mode had
+   remaining "racily clean" issues fixed.
+
+ * "git log --graph" showing an octopus merge sometimes miscounted the
+   number of display columns it is consuming to show the merge and its
+   parent commits, which has been corrected.
+
+ * The implementation of run_command() API on the UNIX platforms had a
+   bug that caused a command not on $PATH to be found in the current
+   directory.
+
+ * A mutex used in "git pack-objects" were not correctly initialized
+   and this caused "git repack" to dump core on Windows.
+
+ * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
+   Windows would strip initial parts from the paths because they
+   were not recognized as absolute, which has been corrected.
+
+ * The receive.denyCurrentBranch=updateInstead codepath kicked in even
+   when the push should have been rejected due to other reasons, such
+   as it does not fast-forward or the update-hook rejects it, which
+   has been corrected.
+
+ * "git repack" in a shallow clone did not correctly update the
+   shallow points in the repository, leading to a repository that
+   does not pass fsck.
+
+ * Operations on promisor objects make sense in the context of only a
+   small subset of the commands that internally use the revisions
+   machinery, but the "--exclude-promisor-objects" option were taken
+   and led to nonsense results by commands like "log", to which it
+   didn't make much sense.  This has been corrected.
+
+ * The "container" mode of TravisCI is going away.  Our .travis.yml
+   file is getting prepared for the transition.
+
+ * Our test scripts can now take the '-V' option as a synonym for the
+   '--verbose-log' option.
+
+ * A regression in Git 2.12 era made "git fsck" fall into an infinite
+   loop while processing truncated loose objects.
+
+Also contains various documentation updates and code clean-ups.
diff --git a/Documentation/RelNotes/2.20.0.txt b/Documentation/RelNotes/2.20.0.txt
index 519c894..e71fe3d 100644
--- a/Documentation/RelNotes/2.20.0.txt
+++ b/Documentation/RelNotes/2.20.0.txt
@@ -1,5 +1,5 @@
-Git Release Notes
-=================
+Git 2.20 Release Notes
+======================
 
 Backward Compatibility Notes
 ----------------------------
@@ -137,11 +137,6 @@
    command line, or setting sendemail.suppresscc configuration
    variable to "misc-by", can be used to disable this behaviour.
 
- * Developer builds now uses -Wunused-function compilation option.
-
- * One of our CI tests to run with "unusual/experimental/random"
-   settings now also uses commit-graph and midx.
-
  * "git mergetool" learned to take the "--[no-]gui" option, just like
    "git difftool" does.
 
@@ -173,9 +168,23 @@
    each other.
    (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).
 
+ * The "--no-patch" option, which can be used to get a high-level
+   overview without the actual line-by-line patch difference shown, of
+   the "range-diff" command was earlier broken, which has been
+   corrected.
+
+ * The recently merged "rebase in C" has an escape hatch to use the
+   scripted version when necessary, but it hasn't been documented,
+   which has been corrected.
+
 
 Performance, Internal Implementation, Development Support etc.
 
+ * Developer builds now use -Wunused-function compilation option.
+
+ * One of our CI tests to run with "unusual/experimental/random"
+   settings now also uses commit-graph and midx.
+
  * When there are too many packfiles in a repository (which is not
    recommended), looking up an object in these would require
    consulting many pack .idx files; a new mechanism to have a single
@@ -249,8 +258,8 @@
    used during tests are getting renamed for consistency.
    (merge 4231d1ba99 bp/rename-test-env-var later to maint).
 
- * A new extension to the index file has been introduced, which allows
-   the index file to be read in parallel for performance.
+ * A pair of new extensions to the index file have been introduced.
+   They allow the index file to be read in parallel for performance.
 
  * The oidset API was built on top of the oidmap API which in turn is
    on the hashmap API.  Replace the implementation to build on top of
@@ -296,7 +305,7 @@
 
  * The overly large Documentation/config.txt file have been split into
    million little pieces.  This potentially allows each individual piece
-   included into the manual page of the command it affects more easily.
+   to be included into the manual page of the command it affects more easily.
 
  * Replace three string-list instances used as look-up tables in "git
    fetch" with hashmaps.
@@ -332,6 +341,60 @@
  * The support for format-patch (and send-email) by the command-line
    completion script (in contrib/) has been simplified a bit.
 
+ * The revision walker machinery learned to take advantage of the
+   commit generation numbers stored in the commit-graph file.
+
+ * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".
+
+ * The way -lcurl library gets linked has been simplified by taking
+   advantage of the fact that we can just ask curl-config command how.
+
+ * Various functions have been audited for "-Wunused-parameter" warnings
+   and bugs in them got fixed.
+
+ * A sanity check for start-up sequence has been added in the config
+   API codepath.
+
+ * The build procedure to link for fuzzing test has been made
+   customizable with a new Makefile variable.
+
+ * The way "git rebase" parses and forwards the command line options
+   meant for underlying "git am" has been revamped, which fixed for
+   options with parameters that were not passed correctly.
+
+ * Our testing framework uses a special i18n "poisoned localization"
+   feature to find messages that ought to stay constant but are
+   incorrectly marked to be translated.  This feature has been made
+   into a runtime option (it used to be a compile-time option).
+
+ * "git push" used to check ambiguities between object-names and
+   refnames while processing the list of refs' old and new values,
+   which was unnecessary (as it knew that it is feeding raw object
+   names).  This has been optimized out.
+
+ * The xcurl_off_t() helper function is used to cast size_t to
+   curl_off_t, but some compilers gave warnings against the code to
+   ensure the casting is done without wraparound, when size_t is
+   narrower than curl_off_t.  This warning has been squelched.
+
+ * Code preparation to replace ulong vars with size_t vars where
+   appropriate continues.
+
+ * The "test installed Git" mode of our test suite has been updated to
+   work better.
+
+ * A coding convention around the Coccinelle semantic patches to have
+   two classes to ease code migration process has been proposed and
+   its support has been added to the Makefile.
+
+ * The "container" mode of TravisCI is going away.  Our .travis.yml
+   file is getting prepared for the transition.
+   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).
+
+ * Our test scripts can now take the '-V' option as a synonym for the
+   '--verbose-log' option.
+   (merge a5f52c6dab sg/test-verbose-log later to maint).
+
 
 Fixes since v2.19
 -----------------
@@ -489,14 +552,6 @@
    didn't make much sense.  This has been corrected.
    (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).
 
- * The "container" mode of TravisCI is going away.  Our .travis.yml
-   file is getting prepared for the transition.
-   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).
-
- * Our test scripts can now take the '-V' option as a synonym for the
-   '--verbose-log' option.
-   (merge a5f52c6dab sg/test-verbose-log later to maint).
-
  * A regression in Git 2.12 era made "git fsck" fall into an infinite
    loop while processing truncated loose objects.
    (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).
@@ -523,7 +578,7 @@
 
  * "git rev-parse --exclude=* --branches --branches"  (i.e. first
    saying "add only things that do not match '*' out of all branches"
-   and then adding all branches, without any exclusion this time")
+   and then adding all branches, without any exclusion this time)
    worked as expected, but "--exclude=* --all --all" did not work the
    same way, which has been fixed.
    (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).
@@ -544,6 +599,62 @@
    pathspec elements were involved, which has been fixed.
    (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).
 
+ * "git merge" and "git pull" that merges into an unborn branch used
+   to completely ignore "--verify-signatures", which has been
+   corrected.
+   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).
+
+ * "git rebase --autostash" did not correctly re-attach the HEAD at times.
+
+ * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
+   quite work, which has been corrected.
+   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).
+
+ * When editing a patch in a "git add -i" session, a hunk could be
+   made to no-op.  The "git apply" program used to reject a patch with
+   such a no-op hunk to catch user mistakes, but it is now updated to
+   explicitly allow a no-op hunk in an edited patch.
+   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).
+
+ * The URL to an MSDN page in a comment has been updated.
+   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).
+
+ * "git ls-remote --sort=<thing>" can feed an object that is not yet
+   available into the comparison machinery and segfault, which has
+   been corrected to check such a request upfront and reject it.
+
+ * When "git bundle" aborts due to an empty commit ranges
+   (i.e. resulting in an empty pack), it left a file descriptor to an
+   lockfile open, which resulted in leftover lockfile on Windows where
+   you cannot remove a file with an open file descriptor.  This has
+   been corrected.
+   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).
+
+ * "git format-patch --stat=<width>" can be used to specify the width
+   used by the diffstat (shown in the cover letter).
+   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).
+
+ * The way .git/index and .git/sharedindex* files were initially
+   created gave these files different perm bits until they were
+   adjusted for shared repository settings.  This was made consistent.
+   (merge c9d6c78870 cc/shared-index-permbits later to maint).
+
+ * "git rebase --stat" to transplant a piece of history onto a totally
+   unrelated history were not working before and silently showed wrong
+   result.  With the recent reimplementation in C, it started to instead
+   die with an error message, as the original logic was not prepared
+   to cope with this case.  This has now been fixed.
+
+ * The advice message to tell the user to migrate an existing graft
+   file to the replace system when a graft file was read was shown
+   even when "git replace --convert-graft-file" command, which is the
+   way the message suggests to use, was running, which made little
+   sense.
+   (merge 8821e90a09 ab/replace-graft-with-replace-advice later to maint).
+
+ * "git diff --raw" lost ellipses to adjust the output columns for
+   some time now, but the documentation still showed them.
+
  * Code cleanup, docfix, build fix, etc.
    (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
    (merge b9b07efdb2 tg/conflict-marker-size later to maint).
@@ -583,3 +694,7 @@
    (merge 3063477445 tb/char-may-be-unsigned later to maint).
    (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
    (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
+   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).
+   (merge 3006f5ee16 ma/reset-doc-rendering-fix later to maint).
+   (merge 4c2eb06419 sg/daemon-test-signal-fix later to maint).
+   (merge d27525e519 ss/msvc-strcasecmp later to maint).
diff --git a/Documentation/RelNotes/2.20.1.txt b/Documentation/RelNotes/2.20.1.txt
new file mode 100644
index 0000000..dcba888
--- /dev/null
+++ b/Documentation/RelNotes/2.20.1.txt
@@ -0,0 +1,20 @@
+Git v2.20.1 Release Notes
+=========================
+
+This release is primarily to fix brown-paper-bag breakages in the
+2.20.0 release.
+
+Fixes since v2.20
+-----------------
+
+ * A few newly added tests were not portable and caused minority
+   platforms to report false breakages, which have been fixed.
+
+ * Portability fix for a recent update to parse-options API.
+
+ * "git help -a" did not work well when an overly long alias is
+   defined, which has been corrected.
+
+ * A recent update accidentally squelched an error message when the
+   run_command API failed to run a missing command, which has been
+   corrected.
diff --git a/Documentation/RelNotes/2.21.0.txt b/Documentation/RelNotes/2.21.0.txt
new file mode 100644
index 0000000..ad681bd
--- /dev/null
+++ b/Documentation/RelNotes/2.21.0.txt
@@ -0,0 +1,22 @@
+Git 2.21 Release Notes
+======================
+
+Backward Compatibility Notes
+----------------------------
+
+
+Updates since v2.20
+-------------------
+
+UI, Workflows & Features
+
+
+
+Performance, Internal Implementation, Development Support etc.
+
+
+
+Fixes since v2.20
+-----------------
+
+ * Code cleanup, docfix, build fix, etc.
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 3e735f1..d87846f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -292,13 +292,6 @@
 
 include::config/core.txt[]
 
-extensions.worktreeConfig::
-	If set, by default "git config" reads from both "config" and
-	"config.worktree" file from GIT_DIR in that order. In
-	multiple working directory mode, "config" file is shared while
-	"config.worktree" is per-working directory (i.e., it's in
-	GIT_COMMON_DIR/worktrees/<id>/config.worktree)
-
 include::config/add.txt[]
 
 include::config/alias.txt[]
diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt
index 57fcd4c..8862042 100644
--- a/Documentation/config/advice.txt
+++ b/Documentation/config/advice.txt
@@ -30,6 +30,13 @@
 		tries to overwrite a remote ref that points at an
 		object that is not a commit-ish, or make the remote
 		ref point at an object that is not a commit-ish.
+	pushUnqualifiedRefname::
+		Shown when linkgit:git-push[1] gives up trying to
+		guess based on the source and destination refs what
+		remote ref namespace the source belongs in, but where
+		we can still suggest that the user push to either
+		refs/heads/* or refs/tags/* based on the type of the
+		source object.
 	statusHints::
 		Show directions on how to proceed from the current
 		state in the output of linkgit:git-status[1], in
diff --git a/Documentation/config/http.txt b/Documentation/config/http.txt
index a56d848..5a32f5b 100644
--- a/Documentation/config/http.txt
+++ b/Documentation/config/http.txt
@@ -68,6 +68,15 @@
 	If set, store cookies received during requests to the file specified by
 	http.cookieFile. Has no effect if http.cookieFile is unset.
 
+http.version::
+	Use the specified HTTP protocol version when communicating with a server.
+	If you want to force the default. The available and default version depend
+	on libcurl. Actually the possible values of
+	this option are:
+
+	- HTTP/2
+	- HTTP/1.1
+
 http.sslVersion::
 	The SSL version to use when negotiating an SSL connection, if you
 	want to force the default.  The available and default version
diff --git a/Documentation/config/index.txt b/Documentation/config/index.txt
index 4b94b6b..f181503 100644
--- a/Documentation/config/index.txt
+++ b/Documentation/config/index.txt
@@ -1,3 +1,19 @@
+index.recordEndOfIndexEntries::
+	Specifies whether the index file should include an "End Of Index
+	Entry" section. This reduces index load time on multiprocessor
+	machines but produces a message "ignoring EOIE extension" when
+	reading the index using Git versions before 2.20. Defaults to
+	'true' if index.threads has been explicitly enabled, 'false'
+	otherwise.
+
+index.recordOffsetTable::
+	Specifies whether the index file should include an "Index Entry
+	Offset Table" section. This reduces index load time on
+	multiprocessor machines but produces a message "ignoring IEOT
+	extension" when reading the index using Git versions before 2.20.
+	Defaults to 'true' if index.threads has been explicitly enabled,
+	'false' otherwise.
+
 index.threads::
 	Specifies the number of threads to spawn when loading the index.
 	This is meant to reduce index load time on multiprocessor machines.
diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt
index 42e1ba7..f079bf6 100644
--- a/Documentation/config/rebase.txt
+++ b/Documentation/config/rebase.txt
@@ -1,3 +1,17 @@
+rebase.useBuiltin::
+	Set to `false` to use the legacy shellscript implementation of
+	linkgit:git-rebase[1]. Is `true` by default, which means use
+	the built-in rewrite of it in C.
++
+The C rewrite is first included with Git version 2.20. This option
+serves an an escape hatch to re-enable the legacy version in case any
+bugs are found in the rewrite. This option and the shellscript version
+of linkgit:git-rebase[1] will be removed in some future release.
++
+If you find some reason to set this option to `false` other than
+one-off testing you should report the behavior difference as a bug in
+git.
+
 rebase.stat::
 	Whether to show a diffstat of what changed upstream since the last
 	rebase. False by default.
diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
index 706916c..cdcc17f 100644
--- a/Documentation/diff-format.txt
+++ b/Documentation/diff-format.txt
@@ -26,12 +26,12 @@
 An output line is formatted this way:
 
 ------------------------------------------------
-in-place edit  :100644 100644 bcd1234... 0123456... M file0
-copy-edit      :100644 100644 abcd123... 1234567... C68 file1 file2
-rename-edit    :100644 100644 abcd123... 1234567... R86 file1 file3
-create         :000000 100644 0000000... 1234567... A file4
-delete         :100644 000000 1234567... 0000000... D file5
-unmerged       :000000 000000 0000000... 0000000... U file6
+in-place edit  :100644 100644 bcd1234 0123456 M file0
+copy-edit      :100644 100644 abcd123 1234567 C68 file1 file2
+rename-edit    :100644 100644 abcd123 1234567 R86 file1 file3
+create         :000000 100644 0000000 1234567 A file4
+delete         :100644 000000 1234567 0000000 D file5
+unmerged       :000000 000000 0000000 0000000 U file6
 ------------------------------------------------
 
 That is, from the left to the right:
@@ -75,7 +75,7 @@
 Example:
 
 ------------------------------------------------
-:100644 100644 5be4a4...... 000000...... M file.c
+:100644 100644 5be4a4a 0000000 M file.c
 ------------------------------------------------
 
 Without the `-z` option, pathnames with "unusual" characters are
@@ -100,7 +100,7 @@
 Example:
 
 ------------------------------------------------
-::100644 100644 100644 fabadb8... cc95eb0... 4866510... MM	describe.c
+::100644 100644 100644 fabadb8 cc95eb0 4866510 MM	describe.c
 ------------------------------------------------
 
 Note that 'combined diff' lists only files which were modified from
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 801de2f..6acc3d9 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -276,6 +276,10 @@
 	Just like linkgit:git-submodule[1], this will detach the
 	submodules HEAD.
 
+--no-guess::
+	Do not attempt to create a branch if a remote tracking branch
+	of the same name exists.
+
 <branch>::
 	Branch to checkout; if it refers to a branch (i.e., a name that,
 	when prepended with "refs/heads/", is a valid ref), then that
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index a55536f..2fd1252 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -189,6 +189,12 @@
 	values are given for the same key, each value will be written to
 	the config file. This makes it safe, for example, to add
 	additional fetch refspecs to the origin remote.
++
+Due to limitations of the current implementation, some configuration
+variables do not take effect until after the initial fetch and checkout.
+Configuration variables known to not take effect are:
+`remote.<name>.mirror` and `remote.<name>.tagOpt`.  Use the
+corresponding `--mirror` and `--no-tags` options instead.
 
 --depth <depth>::
 	Create a 'shallow' clone with a history truncated to the
diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt
index ce954be..64c01ba 100644
--- a/Documentation/git-fast-export.txt
+++ b/Documentation/git-fast-export.txt
@@ -110,6 +110,25 @@
 	the shape of the history and stored tree.  See the section on
 	`ANONYMIZING` below.
 
+--reference-excluded-parents::
+	By default, running a command such as `git fast-export
+	master~5..master` will not include the commit master{tilde}5
+	and will make master{tilde}4 no longer have master{tilde}5 as
+	a parent (though both the old master{tilde}4 and new
+	master{tilde}4 will have all the same files).  Use
+	--reference-excluded-parents to instead have the the stream
+	refer to commits in the excluded range of history by their
+	sha1sum.  Note that the resulting stream can only be used by a
+	repository which already contains the necessary parent
+	commits.
+
+--show-original-ids::
+	Add an extra directive to the output for commits and blobs,
+	`original-oid <SHA1SUM>`.  While such directives will likely be
+	ignored by importers such as git-fast-import, it may be useful
+	for intermediary filters (e.g. for rewriting commit messages
+	which refer to older commits, or for stripping blobs by id).
+
 --refspec::
 	Apply the specified refspec to each ref exported. Multiple of them can
 	be specified.
@@ -119,7 +138,9 @@
 	'git rev-list', that specifies the specific objects and references
 	to export.  For example, `master~10..master` causes the
 	current master reference to be exported along with all objects
-	added since its 10th ancestor commit.
+	added since its 10th ancestor commit and (unless the
+	--reference-excluded-parents option is specified) all files
+	common to master{tilde}9 and master{tilde}10.
 
 EXAMPLES
 --------
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index e81117d..43ab3b1 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -40,9 +40,10 @@
 	not contain the old commit).
 
 --quiet::
-	Disable all non-fatal output, making fast-import silent when it
-	is successful.  This option disables the output shown by
-	--stats.
+	Disable the output shown by --stats, making fast-import usually
+	be silent when it is successful.  However, if the import stream
+	has directives intended to show user output (e.g. `progress`
+	directives), the corresponding messages will still be shown.
 
 --stats::
 	Display some basic statistics about the objects fast-import has
@@ -384,6 +385,7 @@
 ....
 	'commit' SP <ref> LF
 	mark?
+	original-oid?
 	('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
 	'committer' (SP <name>)? SP LT <email> GT SP <when> LF
 	data
@@ -740,6 +742,19 @@
 to another object simply by reusing the same `<idnum>` in another
 `mark` command.
 
+`original-oid`
+~~~~~~~~~~~~~~
+Provides the name of the object in the original source control system.
+fast-import will simply ignore this directive, but filter processes
+which operate on and modify the stream before feeding to fast-import
+may have uses for this information
+
+....
+	'original-oid' SP <object-identifier> LF
+....
+
+where `<object-identifer>` is any string not containing LF.
+
 `tag`
 ~~~~~
 Creates an annotated tag referring to a specific commit.  To create
@@ -748,6 +763,7 @@
 ....
 	'tag' SP <name> LF
 	'from' SP <commit-ish> LF
+	original-oid?
 	'tagger' (SP <name>)? SP LT <email> GT SP <when> LF
 	data
 ....
@@ -822,6 +838,7 @@
 ....
 	'blob' LF
 	mark?
+	original-oid?
 	data
 ....
 
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index aba4c5f..2730442 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -250,6 +250,11 @@
 	feature/v2`), or a revision range if the two versions of the series are
 	disjoint (for example `git format-patch --cover-letter
 	--range-diff=feature/v1~3..feature/v1 -3 feature/v2`).
++
+Note that diff options passed to the command affect how the primary
+product of `format-patch` is generated, and they are not passed to
+the underlying `range-diff` machinery used to generate the cover-letter
+material (this may change in the future).
 
 --creation-factor=<percent>::
 	Used with `--range-diff`, tweak the heuristic which matches up commits
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index a5fc54a..6a8a0d9 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -73,6 +73,26 @@
 without any `<refspec>` on the command line.  Otherwise, missing
 `:<dst>` means to update the same ref as the `<src>`.
 +
+If <dst> doesn't start with `refs/` (e.g. `refs/heads/master`) we will
+try to infer where in `refs/*` on the destination <repository> it
+belongs based on the the type of <src> being pushed and whether <dst>
+is ambiguous.
++
+--
+* If <dst> unambiguously refers to a ref on the <repository> remote,
+  then push to that ref.
+
+* If <src> resolves to a ref starting with refs/heads/ or refs/tags/,
+  then prepend that to <dst>.
+
+* Other ambiguity resolutions might be added in the future, but for
+  now any other cases will error out with an error indicating what we
+  tried, and depending on the `advice.pushUnqualifiedRefname`
+  configuration (see linkgit:git-config[1]) suggest what refs/
+  namespace you may have wanted to push to.
+
+--
++
 The object referenced by <src> is used to update the <dst> reference
 on the remote side. Whether this is allowed depends on where in
 `refs/*` the <dst> reference lives as described in detail below, in
@@ -591,6 +611,9 @@
 	`refs/remotes/satellite/master`) in the `mothership` repository;
 	do the same for `dev` and `satellite/dev`.
 +
+See the section describing `<refspec>...` above for a discussion of
+the matching semantics.
++
 This is to emulate `git fetch` run on the `mothership` using `git
 push` that is run in the opposite direction in order to integrate
 the work done on `satellite`, and is often necessary when you can
diff --git a/Documentation/git-range-diff.txt b/Documentation/git-range-diff.txt
index f693930..8a6ea2c 100644
--- a/Documentation/git-range-diff.txt
+++ b/Documentation/git-range-diff.txt
@@ -78,6 +78,23 @@
 corresponding old/new commits. There is currently no means to tweak the
 diff options passed to `git log` when generating those patches.
 
+OUTPUT STABILITY
+----------------
+
+The output of the `range-diff` command is subject to change. It is
+intended to be human-readable porcelain output, not something that can
+be used across versions of Git to get a textually stable `range-diff`
+(as opposed to something like the `--stable` option to
+linkgit:git-patch-id[1]). There's also no equivalent of
+linkgit:git-apply[1] for `range-diff`, the output is not intended to
+be machine-readable.
+
+This is particularly true when passing in diff options. Currently some
+options like `--stat` can, as an emergent effect, produce output
+that's quite useless in the context of `range-diff`. Future versions
+of `range-diff` may learn to interpret such options in a manner
+specific to `range-diff` (e.g. for `--stat` producing human-readable
+output which summarizes how the diffstat changed).
 
 CONFIGURATION
 -------------
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 80793ba..dff17b3 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -550,24 +550,28 @@
 BEHAVIORAL DIFFERENCES
 -----------------------
 
- * empty commits:
+There are some subtle differences how the backends behave.
 
-    am-based rebase will drop any "empty" commits, whether the
-    commit started empty (had no changes relative to its parent to
-    start with) or ended empty (all changes were already applied
-    upstream in other commits).
+Empty commits
+~~~~~~~~~~~~~
 
-    merge-based rebase does the same.
+The am backend drops any "empty" commits, regardless of whether the
+commit started empty (had no changes relative to its parent to
+start with) or ended empty (all changes were already applied
+upstream in other commits).
 
-    interactive-based rebase will by default drop commits that
-    started empty and halt if it hits a commit that ended up empty.
-    The `--keep-empty` option exists for interactive rebases to allow
-    it to keep commits that started empty.
+The merge backend does the same.
 
-  * directory rename detection:
+The interactive backend drops commits by default that
+started empty and halts if it hits a commit that ended up empty.
+The `--keep-empty` option exists for the interactive backend to allow
+it to keep commits that started empty.
 
-    merge-based and interactive-based rebases work fine with
-    directory rename detection.  am-based rebases sometimes do not.
+Directory rename detection
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The merge and interactive backends work fine with
+directory rename detection.  The am backend sometimes does not.
 
 include::merge-strategies.txt[]
 
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index 2dac95c..9f69ae8 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -14,14 +14,14 @@
 
 DESCRIPTION
 -----------
-In the first and second form, copy entries from <tree-ish> to the index.
-In the third form, set the current branch head (HEAD) to <commit>, optionally
-modifying index and working tree to match.  The <tree-ish>/<commit> defaults
-to HEAD in all forms.
+In the first and second form, copy entries from `<tree-ish>` to the index.
+In the third form, set the current branch head (`HEAD`) to `<commit>`,
+optionally modifying index and working tree to match.
+The `<tree-ish>`/`<commit>` defaults to `HEAD` in all forms.
 
 'git reset' [-q] [<tree-ish>] [--] <paths>...::
-	This form resets the index entries for all <paths> to their
-	state at <tree-ish>.  (It does not affect the working tree or
+	This form resets the index entries for all `<paths>` to their
+	state at `<tree-ish>`.  (It does not affect the working tree or
 	the current branch.)
 +
 This means that `git reset <paths>` is the opposite of `git add
@@ -36,7 +36,7 @@
 
 'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...]::
 	Interactively select hunks in the difference between the index
-	and <tree-ish> (defaults to HEAD).  The chosen hunks are applied
+	and `<tree-ish>` (defaults to `HEAD`).  The chosen hunks are applied
 	in reverse to the index.
 +
 This means that `git reset -p` is the opposite of `git add -p`, i.e.
@@ -44,16 +44,16 @@
 section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
 
 'git reset' [<mode>] [<commit>]::
-	This form resets the current branch head to <commit> and
-	possibly updates the index (resetting it to the tree of <commit>) and
-	the working tree depending on <mode>. If <mode> is omitted,
-	defaults to "--mixed". The <mode> must be one of the following:
+	This form resets the current branch head to `<commit>` and
+	possibly updates the index (resetting it to the tree of `<commit>`) and
+	the working tree depending on `<mode>`. If `<mode>` is omitted,
+	defaults to `--mixed`. The `<mode>` must be one of the following:
 +
 --
 --soft::
 	Does not touch the index file or the working tree at all (but
-	resets the head to <commit>, just like all modes do). This leaves
-	all your changed files "Changes to be committed", as 'git status'
+	resets the head to `<commit>`, just like all modes do). This leaves
+	all your changed files "Changes to be committed", as `git status`
 	would put it.
 
 --mixed::
@@ -66,24 +66,24 @@
 
 --hard::
 	Resets the index and working tree. Any changes to tracked files in the
-	working tree since <commit> are discarded.
+	working tree since `<commit>` are discarded.
 
 --merge::
 	Resets the index and updates the files in the working tree that are
-	different between <commit> and HEAD, but keeps those which are
+	different between `<commit>` and `HEAD`, but keeps those which are
 	different between the index and working tree (i.e. which have changes
 	which have not been added).
-	If a file that is different between <commit> and the index has unstaged
-	changes, reset is aborted.
+	If a file that is different between `<commit>` and the index has
+	unstaged changes, reset is aborted.
 +
-In other words, --merge does something like a 'git read-tree -u -m <commit>',
+In other words, `--merge` does something like a `git read-tree -u -m <commit>`,
 but carries forward unmerged index entries.
 
 --keep::
 	Resets index entries and updates files in the working tree that are
-	different between <commit> and HEAD.
-	If a file that is different between <commit> and HEAD has local changes,
-	reset is aborted.
+	different between `<commit>` and `HEAD`.
+	If a file that is different between `<commit>` and `HEAD` has local
+	changes, reset is aborted.
 --
 
 If you want to undo a commit other than the latest on a branch,
@@ -116,15 +116,15 @@
 +
 <1> You are happily working on something, and find the changes
 in these files are in good order.  You do not want to see them
-when you run "git diff", because you plan to work on other files
+when you run `git diff`, because you plan to work on other files
 and changes with these files are distracting.
 <2> Somebody asks you to pull, and the changes sound worthy of merging.
 <3> However, you already dirtied the index (i.e. your index does
-not match the HEAD commit).  But you know the pull you are going
-to make does not affect frotz.c or filfre.c, so you revert the
+not match the `HEAD` commit).  But you know the pull you are going
+to make does not affect `frotz.c` or `filfre.c`, so you revert the
 index changes for these two files.  Your changes in working tree
 remain there.
-<4> Then you can pull and merge, leaving frotz.c and filfre.c
+<4> Then you can pull and merge, leaving `frotz.c` and `filfre.c`
 changes still in the working tree.
 
 Undo a commit and redo::
@@ -140,11 +140,11 @@
 just committed is incomplete, or you misspelled your commit
 message, or both.  Leaves working tree as it was before "reset".
 <2> Make corrections to working tree files.
-<3> "reset" copies the old head to .git/ORIG_HEAD; redo the
+<3> "reset" copies the old head to `.git/ORIG_HEAD`; redo the
 commit by starting with its log message.  If you do not need to
-edit the message further, you can give -C option instead.
+edit the message further, you can give `-C` option instead.
 +
-See also the --amend option to linkgit:git-commit[1].
+See also the `--amend` option to linkgit:git-commit[1].
 
 Undo a commit, making it a topic branch::
 +
@@ -155,11 +155,11 @@
 ------------
 +
 <1> You have made some commits, but realize they were premature
-to be in the "master" branch.  You want to continue polishing
-them in a topic branch, so create "topic/wip" branch off of the
-current HEAD.
+to be in the `master` branch.  You want to continue polishing
+them in a topic branch, so create `topic/wip` branch off of the
+current `HEAD`.
 <2> Rewind the master branch to get rid of those three commits.
-<3> Switch to "topic/wip" branch and keep working.
+<3> Switch to `topic/wip` branch and keep working.
 
 Undo commits permanently::
 +
@@ -168,7 +168,7 @@
 $ git reset --hard HEAD~3   <1>
 ------------
 +
-<1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad
+<1> The last three commits (`HEAD`, `HEAD^`, and `HEAD~2`) were bad
 and you do not want to ever see them again.  Do *not* do this if
 you have already given these commits to somebody else.  (See the
 "RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1] for
@@ -191,14 +191,14 @@
 <1> Try to update from the upstream resulted in a lot of
 conflicts; you were not ready to spend a lot of time merging
 right now, so you decide to do that later.
-<2> "pull" has not made merge commit, so "git reset --hard"
-which is a synonym for "git reset --hard HEAD" clears the mess
+<2> "pull" has not made merge commit, so `git reset --hard`
+which is a synonym for `git reset --hard HEAD` clears the mess
 from the index file and the working tree.
 <3> Merge a topic branch into the current branch, which resulted
 in a fast-forward.
 <4> But you decided that the topic branch is not ready for public
 consumption yet.  "pull" or "merge" always leaves the original
-tip of the current branch in ORIG_HEAD, so resetting hard to it
+tip of the current branch in `ORIG_HEAD`, so resetting hard to it
 brings your index file and the working tree back to that state,
 and resets the tip of the branch to that commit.
 
@@ -214,14 +214,14 @@
 ------------
 +
 <1> Even if you may have local modifications in your
-working tree, you can safely say "git pull" when you know
+working tree, you can safely say `git pull` when you know
 that the change in the other branch does not overlap with
 them.
 <2> After inspecting the result of the merge, you may find
 that the change in the other branch is unsatisfactory.  Running
-"git reset --hard ORIG_HEAD" will let you go back to where you
+`git reset --hard ORIG_HEAD` will let you go back to where you
 were, but it will discard your local changes, which you do not
-want.  "git reset --merge" keeps your local changes.
+want.  `git reset --merge` keeps your local changes.
 
 
 Interrupted workflow::
@@ -287,13 +287,13 @@
 $ git reset --keep start                    <3>
 ------------
 +
-<1> This commits your first edits in branch1.
+<1> This commits your first edits in `branch1`.
 <2> In the ideal world, you could have realized that the earlier
     commit did not belong to the new topic when you created and switched
-    to branch2 (i.e. "git checkout -b branch2 start"), but nobody is
+    to `branch2` (i.e. `git checkout -b branch2 start`), but nobody is
     perfect.
-<3> But you can use "reset --keep" to remove the unwanted commit after
-    you switched to "branch2".
+<3> But you can use `reset --keep` to remove the unwanted commit after
+    you switched to `branch2`.
 
 Split a commit apart into a sequence of commits::
 +
@@ -317,26 +317,27 @@
 +
 <1> First, reset the history back one commit so that we remove the original
     commit, but leave the working tree with all the changes. The -N ensures
-    that any new files added with HEAD are still marked so that git add -p
+    that any new files added with `HEAD` are still marked so that `git add -p`
     will find them.
-<2> Next, we interactively select diff hunks to add using the git add -p
+<2> Next, we interactively select diff hunks to add using the `git add -p`
     facility. This will ask you about each diff hunk in sequence and you can
     use simple commands such as "yes, include this", "No don't include this"
     or even the very powerful "edit" facility.
 <3> Once satisfied with the hunks you want to include, you should verify what
-    has been prepared for the first commit by using git diff --cached. This
+    has been prepared for the first commit by using `git diff --cached`. This
     shows all the changes that have been moved into the index and are about
     to be committed.
-<4> Next, commit the changes stored in the index. The -c option specifies to
+<4> Next, commit the changes stored in the index. The `-c` option specifies to
     pre-populate the commit message from the original message that you started
-    with in the first commit. This is helpful to avoid retyping it. The HEAD@{1}
-    is a special notation for the commit that HEAD used to be at prior to the
-    original reset commit (1 change ago). See linkgit:git-reflog[1] for more
-    details. You may also use any other valid commit reference.
+    with in the first commit. This is helpful to avoid retyping it. The
+    `HEAD@{1}` is a special notation for the commit that `HEAD` used to be at
+    prior to the original reset commit (1 change ago).
+    See linkgit:git-reflog[1] for more details. You may also use any other
+    valid commit reference.
 <5> You can repeat steps 2-4 multiple times to break the original code into
     any number of commits.
 <6> Now you've split out many of the changes into their own commits, and might
-    no longer use the patch mode of git add, in order to select all remaining
+    no longer use the patch mode of `git add`, in order to select all remaining
     uncommitted changes.
 <7> Once again, check to verify that you've included what you want to. You may
     also wish to verify that git diff doesn't show any remaining changes to be
@@ -353,104 +354,120 @@
 git reset --option target
 ----------
 
-to reset the HEAD to another commit (`target`) with the different
+to reset the `HEAD` to another commit (`target`) with the different
 reset options depending on the state of the files.
 
-In these tables, A, B, C and D are some different states of a
+In these tables, `A`, `B`, `C` and `D` are some different states of a
 file. For example, the first line of the first table means that if a
-file is in state A in the working tree, in state B in the index, in
-state C in HEAD and in state D in the target, then "git reset --soft
-target" will leave the file in the working tree in state A and in the
-index in state B.  It resets (i.e. moves) the HEAD (i.e. the tip of
-the current branch, if you are on one) to "target" (which has the file
-in state D).
+file is in state `A` in the working tree, in state `B` in the index, in
+state `C` in `HEAD` and in state `D` in the target, then `git reset --soft
+target` will leave the file in the working tree in state `A` and in the
+index in state `B`.  It resets (i.e. moves) the `HEAD` (i.e. the tip of
+the current branch, if you are on one) to `target` (which has the file
+in state `D`).
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       A       B     C    D     --soft   A       B     D
-				--mixed  A       D     D
-				--hard   D       D     D
-				--merge (disallowed)
-				--keep  (disallowed)
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ A       B     C    D     --soft   A       B     D
+			  --mixed  A       D     D
+			  --hard   D       D     D
+			  --merge (disallowed)
+			  --keep  (disallowed)
+....
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       A       B     C    C     --soft   A       B     C
-				--mixed  A       C     C
-				--hard   C       C     C
-				--merge (disallowed)
-				--keep   A       C     C
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ A       B     C    C     --soft   A       B     C
+			  --mixed  A       C     C
+			  --hard   C       C     C
+			  --merge (disallowed)
+			  --keep   A       C     C
+....
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       B     C    D     --soft   B       B     D
-				--mixed  B       D     D
-				--hard   D       D     D
-				--merge  D       D     D
-				--keep  (disallowed)
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       B     C    D     --soft   B       B     D
+			  --mixed  B       D     D
+			  --hard   D       D     D
+			  --merge  D       D     D
+			  --keep  (disallowed)
+....
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       B     C    C     --soft   B       B     C
-				--mixed  B       C     C
-				--hard   C       C     C
-				--merge  C       C     C
-				--keep   B       C     C
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       B     C    C     --soft   B       B     C
+			  --mixed  B       C     C
+			  --hard   C       C     C
+			  --merge  C       C     C
+			  --keep   B       C     C
+....
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       C     C    D     --soft   B       C     D
-				--mixed  B       D     D
-				--hard   D       D     D
-				--merge (disallowed)
-				--keep  (disallowed)
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       C     C    D     --soft   B       C     D
+			  --mixed  B       D     D
+			  --hard   D       D     D
+			  --merge (disallowed)
+			  --keep  (disallowed)
+....
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       C     C    C     --soft   B       C     C
-				--mixed  B       C     C
-				--hard   C       C     C
-				--merge  B       C     C
-				--keep   B       C     C
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       C     C    C     --soft   B       C     C
+			  --mixed  B       C     C
+			  --hard   C       C     C
+			  --merge  B       C     C
+			  --keep   B       C     C
+....
 
-"reset --merge" is meant to be used when resetting out of a conflicted
+`reset --merge` is meant to be used when resetting out of a conflicted
 merge. Any mergy operation guarantees that the working tree file that is
 involved in the merge does not have local change wrt the index before
 it starts, and that it writes the result out to the working tree. So if
 we see some difference between the index and the target and also
 between the index and the working tree, then it means that we are not
 resetting out from a state that a mergy operation left after failing
-with a conflict. That is why we disallow --merge option in this case.
+with a conflict. That is why we disallow `--merge` option in this case.
 
-"reset --keep" is meant to be used when removing some of the last
+`reset --keep` is meant to be used when removing some of the last
 commits in the current branch while keeping changes in the working
 tree. If there could be conflicts between the changes in the commit we
 want to remove and the changes in the working tree we want to keep,
 the reset is disallowed. That's why it is disallowed if there are both
-changes between the working tree and HEAD, and between HEAD and the
+changes between the working tree and `HEAD`, and between `HEAD` and the
 target. To be safe, it is also disallowed when there are unmerged
 entries.
 
 The following tables show what happens when there are unmerged
 entries:
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       X       U     A    B     --soft  (disallowed)
-				--mixed  X       B     B
-				--hard   B       B     B
-				--merge  B       B     B
-				--keep  (disallowed)
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ X       U     A    B     --soft  (disallowed)
+			  --mixed  X       B     B
+			  --hard   B       B     B
+			  --merge  B       B     B
+			  --keep  (disallowed)
+....
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       X       U     A    A     --soft  (disallowed)
-				--mixed  X       A     A
-				--hard   A       A     A
-				--merge  A       A     A
-				--keep  (disallowed)
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ X       U     A    A     --soft  (disallowed)
+			  --mixed  X       A     A
+			  --hard   A       A     A
+			  --merge  A       A     A
+			  --keep  (disallowed)
+....
 
-X means any state and U means an unmerged index.
+`X` means any state and `U` means an unmerged index.
 
 GIT
 ---
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index d501af9..366dee2 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -290,6 +290,8 @@
 worktrees/<id>/config.worktree::
 	Working directory specific configuration file.
 
+include::technical/repository-version.txt[]
+
 SEE ALSO
 --------
 linkgit:git-init[1],
diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt
index 829b558..2b036d7 100644
--- a/Documentation/technical/api-parse-options.txt
+++ b/Documentation/technical/api-parse-options.txt
@@ -183,10 +183,6 @@
 	scale the provided value by 1024, 1024^2 or 1024^3 respectively.
 	The scaled value is put into `unsigned_long_var`.
 
-`OPT_DATE(short, long, &timestamp_t_var, description)`::
-	Introduce an option with date argument, see `approxidate()`.
-	The timestamp is put into `timestamp_t_var`.
-
 `OPT_EXPIRY_DATE(short, long, &timestamp_t_var, description)`::
 	Introduce an option with expiry date argument, see `parse_expiry_date()`.
 	The timestamp is put into `timestamp_t_var`.
diff --git a/Documentation/technical/repository-version.txt b/Documentation/technical/repository-version.txt
index e03eacc..7844ef3 100644
--- a/Documentation/technical/repository-version.txt
+++ b/Documentation/technical/repository-version.txt
@@ -1,5 +1,4 @@
-Git Repository Format Versions
-==============================
+== Git Repository Format Versions
 
 Every git repository is marked with a numeric version in the
 `core.repositoryformatversion` key of its `config` file. This version
@@ -40,16 +39,14 @@
 
 The currently defined format versions are:
 
-Version `0`
------------
+=== Version `0`
 
 This is the format defined by the initial version of git, including but
 not limited to the format of the repository directory, the repository
 configuration file, and the object and ref storage. Specifying the
 complete behavior of git is beyond the scope of this document.
 
-Version `1`
------------
+=== Version `1`
 
 This format is identical to version `0`, with the following exceptions:
 
@@ -74,21 +71,18 @@
 
 The defined extensions are:
 
-`noop`
-~~~~~~
+==== `noop`
 
 This extension does not change git's behavior at all. It is useful only
 for testing format-1 compatibility.
 
-`preciousObjects`
-~~~~~~~~~~~~~~~~~
+==== `preciousObjects`
 
 When the config key `extensions.preciousObjects` is set to `true`,
 objects in the repository MUST NOT be deleted (e.g., by `git-prune` or
 `git repack -d`).
 
-`partialclone`
-~~~~~~~~~~~~~~
+==== `partialclone`
 
 When the config key `extensions.partialclone` is set, it indicates
 that the repo was created with a partial clone (or later performed
@@ -98,3 +92,11 @@
 in the future.
 
 The value of this key is the name of the promisor remote.
+
+==== `worktreeConfig`
+
+If set, by default "git config" reads from both "config" and
+"config.worktree" file from GIT_DIR in that order. In
+multiple working directory mode, "config" file is shared while
+"config.worktree" is per-working directory (i.e., it's in
+GIT_COMMON_DIR/worktrees/<id>/config.worktree)
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 498fce8..0a3ccac 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.19.GIT
+DEF_VER=v2.20.GIT
 
 LF='
 '
diff --git a/Makefile b/Makefile
index 016fdcd..1a44c81 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,13 @@
 # Define CURL_CONFIG to curl's configuration program that prints information
 # about the library (e.g., its version number).  The default is 'curl-config'.
 #
+# Define CURL_LDFLAGS to specify flags that you need to link when using libcurl,
+# if you do not want to rely on the libraries provided by CURL_CONFIG.  The
+# default value is a result of `curl-config --libs`.  An example value for
+# CURL_LDFLAGS is as follows:
+#
+#     CURL_LDFLAGS=-lcurl
+#
 # Define NO_EXPAT if you do not have expat installed.  git-http-push is
 # not built, and you cannot push using http:// and https:// transports (dumb).
 #
@@ -183,10 +190,6 @@
 #
 # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
 #
-# Define NEEDS_SSL_WITH_CURL if you need -lssl with -lcurl (Minix).
-#
-# Define NEEDS_IDN_WITH_CURL if you need -lidn when using -lcurl (Minix).
-#
 # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
 #
 # Define NEEDS_LIBINTL_BEFORE_LIBICONV if you need libintl before libiconv.
@@ -207,10 +210,12 @@
 # Define MMAP_PREVENTS_DELETE if a file that is currently mmapped cannot be
 # deleted or cannot be replaced using rename().
 #
+# Define NO_POLL_H if you don't have poll.h.
+#
 # Define NO_SYS_POLL_H if you don't have sys/poll.h.
 #
 # Define NO_POLL if you do not have or don't want to use poll().
-# This also implies NO_SYS_POLL_H.
+# This also implies NO_POLL_H and NO_SYS_POLL_H.
 #
 # Define NEEDS_SYS_PARAM_H if you need to include sys/param.h to compile,
 # *PLEASE* REPORT to git@vger.kernel.org if your platform needs this;
@@ -362,11 +367,6 @@
 # Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
 # user.
 #
-# Define GETTEXT_POISON if you are debugging the choice of strings marked
-# for translation.  In a GETTEXT_POISON build, you can turn all strings marked
-# for translation into gibberish by setting the GIT_GETTEXT_POISON variable
-# (to any value) in your environment.
-#
 # Define JSMIN to point to JavaScript minifier that functions as
 # a filter to have gitweb.js minified.
 #
@@ -993,6 +993,7 @@
 LIB_OBJS += symlinks.o
 LIB_OBJS += tag.o
 LIB_OBJS += tempfile.o
+LIB_OBJS += thread-utils.o
 LIB_OBJS += tmp-objdir.o
 LIB_OBJS += trace.o
 LIB_OBJS += trailer.o
@@ -1308,19 +1309,16 @@
 	ifdef CURLDIR
 		# Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case.
 		BASIC_CFLAGS += -I$(CURLDIR)/include
-		CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) -lcurl
+		CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib)
 	else
-		CURL_LIBCURL = -lcurl
+		CURL_LIBCURL =
 	endif
-	ifdef NEEDS_SSL_WITH_CURL
-		CURL_LIBCURL += -lssl
-		ifdef NEEDS_CRYPTO_WITH_SSL
-			CURL_LIBCURL += -lcrypto
-		endif
-	endif
-	ifdef NEEDS_IDN_WITH_CURL
-		CURL_LIBCURL += -lidn
-	endif
+
+ifdef CURL_LDFLAGS
+	CURL_LIBCURL += $(CURL_LDFLAGS)
+else
+	CURL_LIBCURL += $(shell $(CURL_CONFIG) --libs)
+endif
 
 	REMOTE_CURL_PRIMARY = git-remote-http$X
 	REMOTE_CURL_ALIASES = git-remote-https$X git-remote-ftp$X git-remote-ftps$X
@@ -1453,13 +1451,14 @@
 	BASIC_CFLAGS += -DNO_SYMLINK_HEAD
 endif
 ifdef GETTEXT_POISON
-	BASIC_CFLAGS += -DGETTEXT_POISON
+$(warning The GETTEXT_POISON option has been removed in favor of runtime GIT_TEST_GETTEXT_POISON. See t/README!)
 endif
 ifdef NO_GETTEXT
 	BASIC_CFLAGS += -DNO_GETTEXT
 	USE_GETTEXT_SCHEME ?= fallthrough
 endif
 ifdef NO_POLL
+	NO_POLL_H = YesPlease
 	NO_SYS_POLL_H = YesPlease
 	COMPAT_CFLAGS += -DNO_POLL -Icompat/poll
 	COMPAT_OBJS += compat/poll/poll.o
@@ -1498,6 +1497,9 @@
 ifdef NO_SYS_SELECT_H
 	BASIC_CFLAGS += -DNO_SYS_SELECT_H
 endif
+ifdef NO_POLL_H
+	BASIC_CFLAGS += -DNO_POLL_H
+endif
 ifdef NO_SYS_POLL_H
 	BASIC_CFLAGS += -DNO_SYS_POLL_H
 endif
@@ -1677,7 +1679,6 @@
 else
 	BASIC_CFLAGS += $(PTHREAD_CFLAGS)
 	EXTLIBS += $(PTHREAD_LIBS)
-	LIB_OBJS += thread-utils.o
 endif
 
 ifdef HAVE_PATHS_H
@@ -2111,7 +2112,7 @@
 	$(QUIET_GEN)$(cmd_munge_script) && \
 	mv $@+ $@
 
-git.res: git.rc GIT-VERSION-FILE
+git.res: git.rc GIT-VERSION-FILE GIT-PREFIX
 	$(QUIET_RC)$(RC) \
 	  $(join -DMAJOR= -DMINOR= -DMICRO= -DPATCHLEVEL=, $(wordlist 1, 4, \
 	    $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \
@@ -2591,6 +2592,7 @@
 	@echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
 	@echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+
 	@echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
+	@echo X=\'$(X)\' >>$@+
 ifdef TEST_OUTPUT_DIRECTORY
 	@echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+
 endif
@@ -2604,7 +2606,6 @@
 	@echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@+
 endif
 	@echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+
-	@echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@+
 ifdef GIT_PERF_REPEAT_COUNT
 	@echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@+
 endif
@@ -2741,9 +2742,12 @@
 	then \
 		echo '    ' SPATCH result: $@; \
 	fi
-coccicheck: $(addsuffix .patch,$(wildcard contrib/coccinelle/*.cocci))
+coccicheck: $(addsuffix .patch,$(filter-out %.pending.cocci,$(wildcard contrib/coccinelle/*.cocci)))
 
-.PHONY: coccicheck
+# See contrib/coccinelle/README
+coccicheck-pending: $(addsuffix .patch,$(wildcard contrib/coccinelle/*.pending.cocci))
+
+.PHONY: coccicheck coccicheck-pending
 
 ### Installation rules
 
@@ -3099,14 +3103,16 @@
 # An example command to build against libFuzzer from LLVM 4.0.0:
 #
 # make CC=clang CXX=clang++ \
-#      CFLAGS="-fsanitize-coverage=trace-pc-guard -fsanitize=address" \
+#      FUZZ_CXXFLAGS="-fsanitize-coverage=trace-pc-guard -fsanitize=address" \
 #      LIB_FUZZING_ENGINE=/usr/lib/llvm-4.0/lib/libFuzzer.a \
 #      fuzz-all
 #
+FUZZ_CXXFLAGS ?= $(CFLAGS)
+
 .PHONY: fuzz-all
 
 $(FUZZ_PROGRAMS): all
-	$(QUIET_LINK)$(CXX) $(CFLAGS) $(LIB_OBJS) $(BUILTIN_OBJS) \
+	$(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) $(LIB_OBJS) $(BUILTIN_OBJS) \
 		$(XDIFF_OBJS) $(EXTLIBS) git.o $@.o $(LIB_FUZZING_ENGINE) -o $@
 
 fuzz-all: $(FUZZ_PROGRAMS)
diff --git a/RelNotes b/RelNotes
index 8d0b165..31e2135 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.20.0.txt
\ No newline at end of file
+Documentation/RelNotes/2.21.0.txt
\ No newline at end of file
diff --git a/advice.c b/advice.c
index 5f35656..567209a 100644
--- a/advice.c
+++ b/advice.c
@@ -9,6 +9,7 @@
 int advice_push_already_exists = 1;
 int advice_push_fetch_first = 1;
 int advice_push_needs_force = 1;
+int advice_push_unqualified_ref_name = 1;
 int advice_status_hints = 1;
 int advice_status_u_option = 1;
 int advice_commit_before_merge = 1;
@@ -63,6 +64,7 @@
 	{ "pushAlreadyExists", &advice_push_already_exists },
 	{ "pushFetchFirst", &advice_push_fetch_first },
 	{ "pushNeedsForce", &advice_push_needs_force },
+	{ "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
 	{ "statusHints", &advice_status_hints },
 	{ "statusUoption", &advice_status_u_option },
 	{ "commitBeforeMerge", &advice_commit_before_merge },
diff --git a/advice.h b/advice.h
index 696bf0e..f875f8c 100644
--- a/advice.h
+++ b/advice.h
@@ -9,6 +9,7 @@
 extern int advice_push_already_exists;
 extern int advice_push_fetch_first;
 extern int advice_push_needs_force;
+extern int advice_push_unqualified_ref_name;
 extern int advice_status_hints;
 extern int advice_status_u_option;
 extern int advice_commit_before_merge;
diff --git a/alias.c b/alias.c
index a7e4e57..c471538 100644
--- a/alias.c
+++ b/alias.c
@@ -47,8 +47,8 @@
 #define SPLIT_CMDLINE_BAD_ENDING 1
 #define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
 static const char *split_cmdline_errors[] = {
-	"cmdline ends with \\",
-	"unclosed quote"
+	N_("cmdline ends with \\"),
+	N_("unclosed quote")
 };
 
 int split_cmdline(char *cmdline, const char ***argv)
diff --git a/apply.c b/apply.c
index 073d5f0..01793d6 100644
--- a/apply.c
+++ b/apply.c
@@ -1748,7 +1748,7 @@
 	}
 	if (oldlines || newlines)
 		return -1;
-	if (!deleted && !added)
+	if (!patch->recount && !deleted && !added)
 		return -1;
 
 	fragment->leading = leading;
@@ -4772,6 +4772,9 @@
 				      const char *arg, int unset)
 {
 	struct apply_state *state = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
 	add_name_limit(state, arg, 1);
 	return 0;
 }
@@ -4780,6 +4783,9 @@
 				      const char *arg, int unset)
 {
 	struct apply_state *state = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
 	add_name_limit(state, arg, 0);
 	state->has_include = 1;
 	return 0;
@@ -4790,6 +4796,9 @@
 				int unset)
 {
 	struct apply_state *state = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
 	state->p_value = atoi(arg);
 	state->p_value_known = 1;
 	return 0;
@@ -4799,6 +4808,9 @@
 					   const char *arg, int unset)
 {
 	struct apply_state *state = opt->value;
+
+	BUG_ON_OPT_ARG(arg);
+
 	if (unset)
 		state->ws_ignore_action = ignore_ws_none;
 	else
@@ -4810,9 +4822,12 @@
 					 const char *arg, int unset)
 {
 	struct apply_state *state = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
 	state->whitespace_option = arg;
 	if (parse_whitespace_option(state, arg))
-		exit(1);
+		return -1;
 	return 0;
 }
 
@@ -4820,6 +4835,9 @@
 					const char *arg, int unset)
 {
 	struct apply_state *state = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
 	strbuf_reset(&state->root);
 	strbuf_addstr(&state->root, arg);
 	strbuf_complete(&state->root, '/');
@@ -4939,10 +4957,10 @@
 	struct option builtin_apply_options[] = {
 		{ OPTION_CALLBACK, 0, "exclude", state, N_("path"),
 			N_("don't apply changes matching the given path"),
-			0, apply_option_parse_exclude },
+			PARSE_OPT_NONEG, apply_option_parse_exclude },
 		{ OPTION_CALLBACK, 0, "include", state, N_("path"),
 			N_("apply changes matching the given path"),
-			0, apply_option_parse_include },
+			PARSE_OPT_NONEG, apply_option_parse_include },
 		{ OPTION_CALLBACK, 'p', NULL, state, N_("num"),
 			N_("remove <num> leading slashes from traditional diff paths"),
 			0, apply_option_parse_p },
diff --git a/archive-tar.c b/archive-tar.c
index 7a535cb..a58e1a8 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -202,7 +202,7 @@
 			   unsigned int mode, unsigned long size)
 {
 	xsnprintf(header->mode, sizeof(header->mode), "%07o", mode & 07777);
-	xsnprintf(header->size, sizeof(header->size), "%011lo", S_ISREG(mode) ? size : 0);
+	xsnprintf(header->size, sizeof(header->size), "%011"PRIoMAX , S_ISREG(mode) ? (uintmax_t)size : (uintmax_t)0);
 	xsnprintf(header->mtime, sizeof(header->mtime), "%011lo", (unsigned long) args->time);
 
 	xsnprintf(header->uid, sizeof(header->uid), "%07o", 0);
diff --git a/archive.c b/archive.c
index fd556c2..180d97c 100644
--- a/archive.c
+++ b/archive.c
@@ -391,12 +391,12 @@
 		int refnamelen = colon - name;
 
 		if (!dwim_ref(name, refnamelen, &oid, &ref))
-			die("no such ref: %.*s", refnamelen, name);
+			die(_("no such ref: %.*s"), refnamelen, name);
 		free(ref);
 	}
 
 	if (get_oid(name, &oid))
-		die("Not a valid object name");
+		die(_("not a valid object name: %s"), name);
 
 	commit = lookup_commit_reference_gently(ar_args->repo, &oid, 1);
 	if (commit) {
@@ -409,7 +409,7 @@
 
 	tree = parse_tree_indirect(&oid);
 	if (tree == NULL)
-		die("not a tree object");
+		die(_("not a tree object: %s"), oid_to_hex(&oid));
 
 	if (prefix) {
 		struct object_id tree_oid;
@@ -419,7 +419,7 @@
 		err = get_tree_entry(&tree->object.oid, prefix, &tree_oid,
 				     &mode);
 		if (err || !S_ISDIR(mode))
-			die("current working directory is untracked");
+			die(_("current working directory is untracked"));
 
 		tree = parse_tree_indirect(&tree_oid);
 	}
diff --git a/attr.c b/attr.c
index 60d2847..b63fe0f 100644
--- a/attr.c
+++ b/attr.c
@@ -41,23 +41,17 @@
 
 struct attr_hashmap {
 	struct hashmap map;
-#ifndef NO_PTHREADS
 	pthread_mutex_t mutex;
-#endif
 };
 
 static inline void hashmap_lock(struct attr_hashmap *map)
 {
-#ifndef NO_PTHREADS
 	pthread_mutex_lock(&map->mutex);
-#endif
 }
 
 static inline void hashmap_unlock(struct attr_hashmap *map)
 {
-#ifndef NO_PTHREADS
 	pthread_mutex_unlock(&map->mutex);
-#endif
 }
 
 /*
@@ -372,8 +366,8 @@
 	if (strlen(ATTRIBUTE_MACRO_PREFIX) < namelen &&
 	    starts_with(name, ATTRIBUTE_MACRO_PREFIX)) {
 		if (!macro_ok) {
-			fprintf(stderr, "%s not allowed: %s:%d\n",
-				name, src, lineno);
+			fprintf_ln(stderr, _("%s not allowed: %s:%d"),
+				   name, src, lineno);
 			goto fail_return;
 		}
 		is_macro = 1;
@@ -498,23 +492,17 @@
 	size_t nr;
 	size_t alloc;
 	struct attr_check **checks;
-#ifndef NO_PTHREADS
 	pthread_mutex_t mutex;
-#endif
 } check_vector;
 
 static inline void vector_lock(void)
 {
-#ifndef NO_PTHREADS
 	pthread_mutex_lock(&check_vector.mutex);
-#endif
 }
 
 static inline void vector_unlock(void)
 {
-#ifndef NO_PTHREADS
 	pthread_mutex_unlock(&check_vector.mutex);
-#endif
 }
 
 static void check_vector_add(struct attr_check *c)
@@ -1181,8 +1169,6 @@
 
 void attr_start(void)
 {
-#ifndef NO_PTHREADS
 	pthread_mutex_init(&g_attr_hashmap.mutex, NULL);
 	pthread_mutex_init(&check_vector.mutex, NULL);
-#endif
 }
diff --git a/bisect.c b/bisect.c
index 487675c..4c1b80b 100644
--- a/bisect.c
+++ b/bisect.c
@@ -626,14 +626,15 @@
 	return skip_away(list, count);
 }
 
-static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
+static void bisect_rev_setup(struct repository *r, struct rev_info *revs,
+			     const char *prefix,
 			     const char *bad_format, const char *good_format,
 			     int read_paths)
 {
 	struct argv_array rev_argv = ARGV_ARRAY_INIT;
 	int i;
 
-	repo_init_revisions(the_repository, revs, prefix);
+	repo_init_revisions(r, revs, prefix);
 	revs->abbrev = 0;
 	revs->commit_format = CMIT_FMT_UNSPECIFIED;
 
@@ -723,23 +724,25 @@
 	return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
 }
 
-static struct commit *get_commit_reference(const struct object_id *oid)
+static struct commit *get_commit_reference(struct repository *r,
+					   const struct object_id *oid)
 {
-	struct commit *r = lookup_commit_reference(the_repository, oid);
-	if (!r)
+	struct commit *c = lookup_commit_reference(r, oid);
+	if (!c)
 		die(_("Not a valid commit name %s"), oid_to_hex(oid));
-	return r;
+	return c;
 }
 
-static struct commit **get_bad_and_good_commits(int *rev_nr)
+static struct commit **get_bad_and_good_commits(struct repository *r,
+						int *rev_nr)
 {
 	struct commit **rev;
 	int i, n = 0;
 
 	ALLOC_ARRAY(rev, 1 + good_revs.nr);
-	rev[n++] = get_commit_reference(current_bad_oid);
+	rev[n++] = get_commit_reference(r, current_bad_oid);
 	for (i = 0; i < good_revs.nr; i++)
-		rev[n++] = get_commit_reference(good_revs.oid + i);
+		rev[n++] = get_commit_reference(r, good_revs.oid + i);
 	*rev_nr = n;
 
 	return rev;
@@ -823,12 +826,13 @@
 	free_commit_list(result);
 }
 
-static int check_ancestors(int rev_nr, struct commit **rev, const char *prefix)
+static int check_ancestors(struct repository *r, int rev_nr,
+			   struct commit **rev, const char *prefix)
 {
 	struct rev_info revs;
 	int res;
 
-	bisect_rev_setup(&revs, prefix, "^%s", "%s", 0);
+	bisect_rev_setup(r, &revs, prefix, "^%s", "%s", 0);
 
 	bisect_common(&revs);
 	res = (revs.commits != NULL);
@@ -847,7 +851,9 @@
  * If a merge base must be tested by the user, its source code will be
  * checked out to be tested by the user and we will exit.
  */
-static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
+static void check_good_are_ancestors_of_bad(struct repository *r,
+					    const char *prefix,
+					    int no_checkout)
 {
 	char *filename = git_pathdup("BISECT_ANCESTORS_OK");
 	struct stat st;
@@ -866,8 +872,8 @@
 		goto done;
 
 	/* Check if all good revs are ancestor of the bad rev. */
-	rev = get_bad_and_good_commits(&rev_nr);
-	if (check_ancestors(rev_nr, rev, prefix))
+	rev = get_bad_and_good_commits(r, &rev_nr);
+	if (check_ancestors(r, rev_nr, rev, prefix))
 		check_merge_bases(rev_nr, rev, no_checkout);
 	free(rev);
 
@@ -885,12 +891,14 @@
 /*
  * This does "git diff-tree --pretty COMMIT" without one fork+exec.
  */
-static void show_diff_tree(const char *prefix, struct commit *commit)
+static void show_diff_tree(struct repository *r,
+			   const char *prefix,
+			   struct commit *commit)
 {
 	struct rev_info opt;
 
 	/* diff-tree init */
-	repo_init_revisions(the_repository, &opt, prefix);
+	repo_init_revisions(r, &opt, prefix);
 	git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 	opt.abbrev = 0;
 	opt.diff = 1;
@@ -945,7 +953,7 @@
  * If no_checkout is non-zero, the bisection process does not
  * checkout the trial commit but instead simply updates BISECT_HEAD.
  */
-int bisect_next_all(const char *prefix, int no_checkout)
+int bisect_next_all(struct repository *r, const char *prefix, int no_checkout)
 {
 	struct rev_info revs;
 	struct commit_list *tried;
@@ -957,9 +965,9 @@
 	if (read_bisect_refs())
 		die(_("reading bisect refs failed"));
 
-	check_good_are_ancestors_of_bad(prefix, no_checkout);
+	check_good_are_ancestors_of_bad(r, prefix, no_checkout);
 
-	bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
+	bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1);
 	revs.limited = 1;
 
 	bisect_common(&revs);
@@ -993,7 +1001,7 @@
 		exit_if_skipped_commits(tried, current_bad_oid);
 		printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),
 			term_bad);
-		show_diff_tree(prefix, revs.commits->item);
+		show_diff_tree(r, prefix, revs.commits->item);
 		/* This means the bisection process succeeded. */
 		exit(10);
 	}
diff --git a/bisect.h b/bisect.h
index 34df209..821d16e 100644
--- a/bisect.h
+++ b/bisect.h
@@ -2,6 +2,7 @@
 #define BISECT_H
 
 struct commit_list;
+struct repository;
 
 /*
  * Find bisection. If something is found, `reaches` will be the number of
@@ -30,7 +31,9 @@
 	const char *header_prefix;
 };
 
-extern int bisect_next_all(const char *prefix, int no_checkout);
+extern int bisect_next_all(struct repository *r,
+			   const char *prefix,
+			   int no_checkout);
 
 extern int estimate_bisect_steps(int all);
 
diff --git a/blame.c b/blame.c
index d84c937..4386143 100644
--- a/blame.c
+++ b/blame.c
@@ -116,35 +116,38 @@
 		die("no such path '%s' in HEAD", path);
 }
 
-static struct commit_list **append_parent(struct commit_list **tail, const struct object_id *oid)
+static struct commit_list **append_parent(struct repository *r,
+					  struct commit_list **tail,
+					  const struct object_id *oid)
 {
 	struct commit *parent;
 
-	parent = lookup_commit_reference(the_repository, oid);
+	parent = lookup_commit_reference(r, oid);
 	if (!parent)
 		die("no such commit %s", oid_to_hex(oid));
 	return &commit_list_insert(parent, tail)->next;
 }
 
-static void append_merge_parents(struct commit_list **tail)
+static void append_merge_parents(struct repository *r,
+				 struct commit_list **tail)
 {
 	int merge_head;
 	struct strbuf line = STRBUF_INIT;
 
-	merge_head = open(git_path_merge_head(the_repository), O_RDONLY);
+	merge_head = open(git_path_merge_head(r), O_RDONLY);
 	if (merge_head < 0) {
 		if (errno == ENOENT)
 			return;
 		die("cannot open '%s' for reading",
-		    git_path_merge_head(the_repository));
+		    git_path_merge_head(r));
 	}
 
 	while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) {
 		struct object_id oid;
 		if (line.len < GIT_SHA1_HEXSZ || get_oid_hex(line.buf, &oid))
 			die("unknown line in '%s': %s",
-			    git_path_merge_head(the_repository), line.buf);
-		tail = append_parent(tail, &oid);
+			    git_path_merge_head(r), line.buf);
+		tail = append_parent(r, tail, &oid);
 	}
 	close(merge_head);
 	strbuf_release(&line);
@@ -155,11 +158,13 @@
  * want to transfer ownership of the buffer to the commit (so we
  * must use detach).
  */
-static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)
+static void set_commit_buffer_from_strbuf(struct repository *r,
+					  struct commit *c,
+					  struct strbuf *sb)
 {
 	size_t len;
 	void *buf = strbuf_detach(sb, &len);
-	set_commit_buffer(the_repository, c, buf, len);
+	set_commit_buffer(r, c, buf, len);
 }
 
 /*
@@ -185,7 +190,7 @@
 
 	read_index(r->index);
 	time(&now);
-	commit = alloc_commit_node(the_repository);
+	commit = alloc_commit_node(r);
 	commit->object.parsed = 1;
 	commit->date = now;
 	parent_tail = &commit->parents;
@@ -193,8 +198,8 @@
 	if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
 		die("no such ref: HEAD");
 
-	parent_tail = append_parent(parent_tail, &head_oid);
-	append_merge_parents(parent_tail);
+	parent_tail = append_parent(r, parent_tail, &head_oid);
+	append_merge_parents(r, parent_tail);
 	verify_working_tree_path(r, commit, path);
 
 	origin = make_origin(commit, path);
@@ -211,7 +216,7 @@
 		    ident, ident, path,
 		    (!contents_from ? path :
 		     (!strcmp(contents_from, "-") ? "standard input" : contents_from)));
-	set_commit_buffer_from_strbuf(commit, &msg);
+	set_commit_buffer_from_strbuf(r, commit, &msg);
 
 	if (!contents_from || strcmp("-", contents_from)) {
 		struct stat st;
@@ -1678,7 +1683,7 @@
 		struct object *obj = revs->pending.objects[i].item;
 		if (obj->flags & UNINTERESTING)
 			continue;
-		obj = deref_tag(the_repository, obj, NULL, 0);
+		obj = deref_tag(revs->repo, obj, NULL, 0);
 		if (obj->type != OBJ_COMMIT)
 			die("Non commit %s?", revs->pending.objects[i].name);
 		if (found)
@@ -1709,14 +1714,14 @@
 
 	/* Is that sole rev a committish? */
 	obj = revs->pending.objects[0].item;
-	obj = deref_tag(the_repository, obj, NULL, 0);
+	obj = deref_tag(revs->repo, obj, NULL, 0);
 	if (obj->type != OBJ_COMMIT)
 		return NULL;
 
 	/* Do we have HEAD? */
 	if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
 		return NULL;
-	head_commit = lookup_commit_reference_gently(the_repository,
+	head_commit = lookup_commit_reference_gently(revs->repo,
 						     &head_oid, 1);
 	if (!head_commit)
 		return NULL;
@@ -1745,7 +1750,7 @@
 		struct object *obj = revs->pending.objects[i].item;
 		if (!(obj->flags & UNINTERESTING))
 			continue;
-		obj = deref_tag(the_repository, obj, NULL, 0);
+		obj = deref_tag(revs->repo, obj, NULL, 0);
 		if (obj->type != OBJ_COMMIT)
 			die("Non commit %s?", revs->pending.objects[i].name);
 		if (found)
diff --git a/branch.c b/branch.c
index 776f55f..28b81a7 100644
--- a/branch.c
+++ b/branch.c
@@ -242,7 +242,8 @@
 "will track its remote counterpart, you may want to use\n"
 "\"git push -u\" to set the upstream config as you push.");
 
-void create_branch(const char *name, const char *start_name,
+void create_branch(struct repository *r,
+		   const char *name, const char *start_name,
 		   int force, int clobber_head_ok, int reflog,
 		   int quiet, enum branch_track track)
 {
@@ -300,7 +301,7 @@
 		break;
 	}
 
-	if ((commit = lookup_commit_reference(the_repository, &oid)) == NULL)
+	if ((commit = lookup_commit_reference(r, &oid)) == NULL)
 		die(_("Not a valid branch point: '%s'."), start_name);
 	oidcpy(&oid, &commit->object.oid);
 
@@ -336,15 +337,15 @@
 	free(real_ref);
 }
 
-void remove_branch_state(void)
+void remove_branch_state(struct repository *r)
 {
-	unlink(git_path_cherry_pick_head(the_repository));
-	unlink(git_path_revert_head(the_repository));
-	unlink(git_path_merge_head(the_repository));
-	unlink(git_path_merge_rr(the_repository));
-	unlink(git_path_merge_msg(the_repository));
-	unlink(git_path_merge_mode(the_repository));
-	unlink(git_path_squash_msg(the_repository));
+	unlink(git_path_cherry_pick_head(r));
+	unlink(git_path_revert_head(r));
+	unlink(git_path_merge_head(r));
+	unlink(git_path_merge_rr(r));
+	unlink(git_path_merge_msg(r));
+	unlink(git_path_merge_mode(r));
+	unlink(git_path_squash_msg(r));
 }
 
 void die_if_checked_out(const char *branch, int ignore_current_worktree)
diff --git a/branch.h b/branch.h
index 5cace45..29c1afa 100644
--- a/branch.h
+++ b/branch.h
@@ -1,6 +1,7 @@
 #ifndef BRANCH_H
 #define BRANCH_H
 
+struct repository;
 struct strbuf;
 
 enum branch_track {
@@ -19,6 +20,8 @@
 /*
  * Creates a new branch, where:
  *
+ *   - r is the repository to add a branch to
+ *
  *   - name is the new branch name
  *
  *   - start_name is the name of the existing branch that the new branch should
@@ -37,7 +40,8 @@
  *     that start_name is a tracking branch for (if any).
  *
  */
-void create_branch(const char *name, const char *start_name,
+void create_branch(struct repository *r,
+		   const char *name, const char *start_name,
 		   int force, int clobber_head_ok,
 		   int reflog, int quiet, enum branch_track track);
 
@@ -60,7 +64,7 @@
  * Remove information about the state of working on the current
  * branch. (E.g., MERGE_HEAD)
  */
-void remove_branch_state(void);
+void remove_branch_state(struct repository *r);
 
 /*
  * Configure local branch "local" as downstream to branch "remote"
diff --git a/builtin/am.c b/builtin/am.c
index dc576a3..9537031 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1970,7 +1970,7 @@
 	if (merge_tree(remote_tree))
 		return -1;
 
-	remove_branch_state();
+	remove_branch_state(the_repository);
 
 	return 0;
 }
@@ -1981,7 +1981,7 @@
 static void am_rerere_clear(void)
 {
 	struct string_list merge_rr = STRING_LIST_INIT_DUP;
-	rerere_clear(&merge_rr);
+	rerere_clear(the_repository, &merge_rr);
 	string_list_clear(&merge_rr, 1);
 }
 
@@ -2113,7 +2113,9 @@
 {
 	int *opt_value = opt->value;
 
-	if (!strcmp(arg, "mbox"))
+	if (unset)
+		*opt_value = PATCH_FORMAT_UNKNOWN;
+	else if (!strcmp(arg, "mbox"))
 		*opt_value = PATCH_FORMAT_MBOX;
 	else if (!strcmp(arg, "stgit"))
 		*opt_value = PATCH_FORMAT_STGIT;
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 4b5fadc..417d141 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -137,7 +137,7 @@
 
 	switch (cmdmode) {
 	case NEXT_ALL:
-		return bisect_next_all(prefix, no_checkout);
+		return bisect_next_all(the_repository, prefix, no_checkout);
 	case WRITE_TERMS:
 		if (argc != 2)
 			return error(_("--write-terms requires two arguments"));
diff --git a/builtin/blame.c b/builtin/blame.c
index a443af9..6d798f9 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -732,6 +732,8 @@
 {
 	int *opt = option->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	/*
 	 * -C enables copy from removed files;
 	 * -C -C enables copy from existing files, but only
@@ -754,6 +756,8 @@
 {
 	int *opt = option->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	*opt |= PICKAXE_BLAME_MOVE;
 
 	if (arg)
@@ -846,6 +850,8 @@
 		case PARSE_OPT_HELP:
 		case PARSE_OPT_ERROR:
 			exit(129);
+		case PARSE_OPT_COMPLETE:
+			exit(0);
 		case PARSE_OPT_DONE:
 			if (ctx.argv[0])
 				dashdash_pos = ctx.cpidx;
diff --git a/builtin/branch.c b/builtin/branch.c
index 0c55f7f..1be7272 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -783,7 +783,8 @@
 		 * create_branch takes care of setting up the tracking
 		 * info and making sure new_upstream is correct
 		 */
-		create_branch(branch->name, new_upstream, 0, 0, 0, quiet, BRANCH_TRACK_OVERRIDE);
+		create_branch(the_repository, branch->name, new_upstream,
+			      0, 0, 0, quiet, BRANCH_TRACK_OVERRIDE);
 	} else if (unset_upstream) {
 		struct branch *branch = branch_get(argv[0]);
 		struct strbuf buf = STRBUF_INIT;
@@ -814,7 +815,8 @@
 		if (track == BRANCH_TRACK_OVERRIDE)
 			die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead."));
 
-		create_branch(argv[0], (argc == 2) ? argv[1] : head,
+		create_branch(the_repository,
+			      argv[0], (argc == 2) ? argv[1] : head,
 			      force, 0, reflog, quiet, track);
 
 	} else
diff --git a/builtin/bundle.c b/builtin/bundle.c
index d0de59b..9e9c65d 100644
--- a/builtin/bundle.c
+++ b/builtin/bundle.c
@@ -40,7 +40,7 @@
 			usage(builtin_bundle_usage);
 			return 1;
 		}
-		if (verify_bundle(&header, 1))
+		if (verify_bundle(the_repository, &header, 1))
 			return 1;
 		fprintf(stderr, _("%s is okay\n"), bundle_file);
 		return 0;
@@ -56,11 +56,12 @@
 		}
 		if (!startup_info->have_repository)
 			die(_("Need a repository to create a bundle."));
-		return !!create_bundle(&header, bundle_file, argc, argv);
+		return !!create_bundle(the_repository, &header,
+				       bundle_file, argc, argv);
 	} else if (!strcmp(cmd, "unbundle")) {
 		if (!startup_info->have_repository)
 			die(_("Need a repository to unbundle."));
-		return !!unbundle(&header, bundle_fd, 0) ||
+		return !!unbundle(the_repository, &header, bundle_fd, 0) ||
 			list_bundle_refs(&header, argc, argv);
 	} else
 		usage(builtin_bundle_usage);
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 0d403eb..2ca56fd 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -99,7 +99,7 @@
 		oi.sizep = &size;
 		if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
 			die("git cat-file: could not get object info");
-		printf("%lu\n", size);
+		printf("%"PRIuMAX"\n", (uintmax_t)size);
 		return 0;
 
 	case 'e':
@@ -245,7 +245,7 @@
 		if (data->mark_query)
 			data->info.sizep = &data->size;
 		else
-			strbuf_addf(sb, "%lu", data->size);
+			strbuf_addf(sb, "%"PRIuMAX , (uintmax_t)data->size);
 	} else if (is_atom("objectsize:disk", atom, len)) {
 		if (data->mark_query)
 			data->info.disk_sizep = &data->disk_size;
@@ -603,8 +603,10 @@
 {
 	struct batch_options *bo = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (bo->enabled) {
-		return 1;
+		return error(_("only one batch option may be specified"));
 	}
 
 	bo->enabled = 1;
@@ -639,10 +641,12 @@
 		OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")),
 		{ OPTION_CALLBACK, 0, "batch", &batch, "format",
 			N_("show info and content of objects fed from the standard input"),
-			PARSE_OPT_OPTARG, batch_option_callback },
+			PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
+			batch_option_callback },
 		{ OPTION_CALLBACK, 0, "batch-check", &batch, "format",
 			N_("show info about objects fed from the standard input"),
-			PARSE_OPT_OPTARG, batch_option_callback },
+			PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
+			batch_option_callback },
 		OPT_BOOL(0, "follow-symlinks", &batch.follow_symlinks,
 			 N_("follow in-tree symlinks (used with --batch or --batch-check)")),
 		OPT_BOOL(0, "batch-all-objects", &batch.all_objects,
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index 88b86c8..eb74774 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -132,6 +132,8 @@
 static int option_parse_stage(const struct option *opt,
 			      const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
+
 	if (!strcmp(arg, "all")) {
 		to_tempfile = 1;
 		checkout_stage = CHECKOUT_ALL;
diff --git a/builtin/checkout.c b/builtin/checkout.c
index acdafc6..08b0ac4 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -753,7 +753,8 @@
 			free(refname);
 		}
 		else
-			create_branch(opts->new_branch, new_branch_info->name,
+			create_branch(the_repository,
+				      opts->new_branch, new_branch_info->name,
 				      opts->new_branch_force ? 1 : 0,
 				      opts->new_branch_force ? 1 : 0,
 				      opts->new_branch_log,
@@ -811,7 +812,7 @@
 				delete_reflog(old_branch_info->path);
 		}
 	}
-	remove_branch_state();
+	remove_branch_state(the_repository);
 	strbuf_release(&msg);
 	if (!opts->quiet &&
 	    (new_branch_info->path || (!opts->force_detach && !strcmp(new_branch_info->name, "HEAD"))))
@@ -1079,9 +1080,12 @@
 		 */
 		int recover_with_dwim = dwim_new_local_branch_ok;
 
-		if (!has_dash_dash &&
-		    (check_filename(opts->prefix, arg) || !no_wildcard(arg)))
+		int could_be_checkout_paths = !has_dash_dash &&
+			check_filename(opts->prefix, arg);
+
+		if (!has_dash_dash && !no_wildcard(arg))
 			recover_with_dwim = 0;
+
 		/*
 		 * Accept "git checkout foo" and "git checkout foo --"
 		 * as candidates for dwim.
@@ -1094,6 +1098,10 @@
 			const char *remote = unique_tracking_name(arg, rev,
 								  dwim_remotes_matched);
 			if (remote) {
+				if (could_be_checkout_paths)
+					die(_("'%s' could be both a local file and a tracking branch.\n"
+					      "Please use -- (and optionally --no-guess) to disambiguate"),
+					    arg);
 				*new_branch = arg;
 				arg = remote;
 				/* DWIMmed to create local branch, case (3).(b) */
@@ -1228,7 +1236,7 @@
 	struct checkout_opts opts;
 	struct branch_info new_branch_info;
 	char *conflict_style = NULL;
-	int dwim_new_local_branch = 1;
+	int dwim_new_local_branch, no_dwim_new_local_branch = 0;
 	int dwim_remotes_matched = 0;
 	struct option options[] = {
 		OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
@@ -1258,8 +1266,8 @@
 		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")),
-		OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch,
-				N_("second guess 'git checkout <no-such-branch>'")),
+		OPT_BOOL(0, "no-guess", &no_dwim_new_local_branch,
+			 N_("do not second guess 'git checkout <no-such-branch>'")),
 		OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees,
 			 N_("do not check if another worktree is holding the given ref")),
 		{ OPTION_CALLBACK, 0, "recurse-submodules", NULL,
@@ -1282,6 +1290,7 @@
 	argc = parse_options(argc, argv, prefix, options, checkout_usage,
 			     PARSE_OPT_KEEP_DASHDASH);
 
+	dwim_new_local_branch = !no_dwim_new_local_branch;
 	if (opts.show_progress < 0) {
 		if (opts.quiet)
 			opts.show_progress = 0;
diff --git a/builtin/clean.c b/builtin/clean.c
index 8d9a7dc..bbcdeb2 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -140,6 +140,7 @@
 static int exclude_cb(const struct option *opt, const char *arg, int unset)
 {
 	struct string_list *exclude_list = opt->value;
+	BUG_ON_OPT_NEG(unset);
 	string_list_append(exclude_list, arg);
 	return 0;
 }
diff --git a/builtin/clone.c b/builtin/clone.c
index 15b142d..7c7f98c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -548,7 +548,7 @@
 }
 
 static struct ref *wanted_peer_refs(const struct ref *refs,
-		struct refspec_item *refspec)
+		struct refspec *refspec)
 {
 	struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
 	struct ref *local_refs = head;
@@ -569,13 +569,19 @@
 			warning(_("Could not find remote branch %s to clone."),
 				option_branch);
 		else {
-			get_fetch_map(remote_head, refspec, &tail, 0);
+			int i;
+			for (i = 0; i < refspec->nr; i++)
+				get_fetch_map(remote_head, &refspec->items[i],
+					      &tail, 0);
 
 			/* if --branch=tag, pull the requested tag explicitly */
 			get_fetch_map(remote_head, tag_refspec, &tail, 0);
 		}
-	} else
-		get_fetch_map(refs, refspec, &tail, 0);
+	} else {
+		int i;
+		for (i = 0; i < refspec->nr; i++)
+			get_fetch_map(refs, &refspec->items[i], &tail, 0);
+	}
 
 	if (!option_mirror && !option_single_branch && !option_no_tags)
 		get_fetch_map(refs, tag_refspec, &tail, 0);
@@ -890,7 +896,8 @@
 	const struct ref *our_head_points_at;
 	struct ref *mapped_refs;
 	const struct ref *ref;
-	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
+	struct strbuf key = STRBUF_INIT;
+	struct strbuf default_refspec = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
 	const char *src_ref_prefix = "refs/heads/";
@@ -898,7 +905,6 @@
 	int err = 0, complete_refs_before_fetch = 1;
 	int submodule_progress;
 
-	struct refspec rs = REFSPEC_INIT_FETCH;
 	struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
 	fetch_if_missing = 0;
@@ -1067,7 +1073,6 @@
 		strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
 	}
 
-	strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
 	strbuf_addf(&key, "remote.%s.url", option_origin);
 	git_config_set(key.buf, repo);
 	strbuf_reset(&key);
@@ -1081,11 +1086,12 @@
 	if (option_required_reference.nr || option_optional_reference.nr)
 		setup_reference();
 
-	refspec_append(&rs, value.buf);
-
-	strbuf_reset(&value);
-
 	remote = remote_get(option_origin);
+
+	strbuf_addf(&default_refspec, "+%s*:%s*", src_ref_prefix,
+		    branch_top.buf);
+	refspec_append(&remote->fetch, default_refspec.buf);
+
 	transport = transport_get(remote, remote->url[0]);
 	transport_set_verbosity(transport, option_verbosity, option_progress);
 	transport->family = family;
@@ -1140,7 +1146,7 @@
 
 
 	argv_array_push(&ref_prefixes, "HEAD");
-	refspec_ref_prefixes(&rs, &ref_prefixes);
+	refspec_ref_prefixes(&remote->fetch, &ref_prefixes);
 	if (option_branch)
 		expand_ref_prefix(&ref_prefixes, option_branch);
 	if (!option_no_tags)
@@ -1149,7 +1155,7 @@
 	refs = transport_get_remote_refs(transport, &ref_prefixes);
 
 	if (refs) {
-		mapped_refs = wanted_peer_refs(refs, &rs.items[0]);
+		mapped_refs = wanted_peer_refs(refs, &remote->fetch);
 		/*
 		 * transport_get_remote_refs() may return refs with null sha-1
 		 * in mapped_refs (see struct transport->get_refs_list
@@ -1240,10 +1246,9 @@
 	strbuf_release(&reflog_msg);
 	strbuf_release(&branch_top);
 	strbuf_release(&key);
-	strbuf_release(&value);
+	strbuf_release(&default_refspec);
 	junk_mode = JUNK_LEAVE_ALL;
 
-	refspec_clear(&rs);
 	argv_array_clear(&ref_prefixes);
 	return err;
 }
diff --git a/builtin/commit.c b/builtin/commit.c
index 96d336e..004b816 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -161,6 +161,9 @@
 static int opt_parse_rename_score(const struct option *opt, const char *arg, int unset)
 {
 	const char **value = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
 	if (arg != NULL && *arg == '=')
 		arg = arg + 1;
 
@@ -185,7 +188,7 @@
 
 static void status_init_config(struct wt_status *s, config_fn_t fn)
 {
-	wt_status_prepare(s);
+	wt_status_prepare(the_repository, s);
 	init_diff_ui_defaults();
 	git_config(fn, s);
 	determine_whence(s);
@@ -908,7 +911,8 @@
 			if (ignore_submodule_arg &&
 			    !strcmp(ignore_submodule_arg, "all"))
 				flags.ignore_submodules = 1;
-			committable = index_differs_from(parent, &flags, 1);
+			committable = index_differs_from(the_repository,
+							 parent, &flags, 1);
 		}
 	}
 	strbuf_release(&committer_ident);
@@ -1335,7 +1339,7 @@
 		OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
 		{ OPTION_CALLBACK, 'M', "find-renames", &rename_score_arg,
 		  N_("n"), N_("detect renames, optionally set similarity index"),
-		  PARSE_OPT_OPTARG, opt_parse_rename_score },
+		  PARSE_OPT_OPTARG | PARSE_OPT_NONEG, opt_parse_rename_score },
 		OPT_END(),
 	};
 
@@ -1679,7 +1683,8 @@
 			flags |= SUMMARY_INITIAL_COMMIT;
 		if (author_date_is_interesting())
 			flags |= SUMMARY_SHOW_AUTHOR_DATE;
-		print_commit_summary(prefix, &oid, flags);
+		print_commit_summary(the_repository, prefix,
+				     &oid, flags);
 	}
 
 	UNLEAK(err);
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index a7cad05..3fae474 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -78,10 +78,10 @@
 	return 0;
 }
 
-static int print_alternate(struct alternate_object_database *alt, void *data)
+static int print_alternate(struct object_directory *odb, void *data)
 {
 	printf("alternate: ");
-	quote_c_style(alt->path, NULL, stdout, 0);
+	quote_c_style(odb->path, NULL, stdout, 0);
 	putchar('\n');
 	return 0;
 }
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 456797c..9e28348 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -31,13 +31,16 @@
 };
 
 static int progress;
-static enum { ABORT, VERBATIM, WARN, WARN_STRIP, STRIP } signed_tag_mode = ABORT;
-static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ERROR;
+static enum { SIGNED_TAG_ABORT, VERBATIM, WARN, WARN_STRIP, STRIP } signed_tag_mode = SIGNED_TAG_ABORT;
+static enum { TAG_FILTERING_ABORT, DROP, REWRITE } tag_of_filtered_mode = TAG_FILTERING_ABORT;
 static int fake_missing_tagger;
 static int use_done_feature;
 static int no_data;
 static int full_tree;
+static int reference_excluded_commits;
+static int show_original_ids;
 static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
+static struct string_list tag_refs = STRING_LIST_INIT_NODUP;
 static struct refspec refspecs = REFSPEC_INIT_FETCH;
 static int anonymize;
 static struct revision_sources revision_sources;
@@ -46,7 +49,7 @@
 				     const char *arg, int unset)
 {
 	if (unset || !strcmp(arg, "abort"))
-		signed_tag_mode = ABORT;
+		signed_tag_mode = SIGNED_TAG_ABORT;
 	else if (!strcmp(arg, "verbatim") || !strcmp(arg, "ignore"))
 		signed_tag_mode = VERBATIM;
 	else if (!strcmp(arg, "warn"))
@@ -64,7 +67,7 @@
 					  const char *arg, int unset)
 {
 	if (unset || !strcmp(arg, "abort"))
-		tag_of_filtered_mode = ERROR;
+		tag_of_filtered_mode = TAG_FILTERING_ABORT;
 	else if (!strcmp(arg, "drop"))
 		tag_of_filtered_mode = DROP;
 	else if (!strcmp(arg, "rewrite"))
@@ -187,6 +190,22 @@
 	return ptr_to_mark(decoration);
 }
 
+static struct commit *rewrite_commit(struct commit *p)
+{
+	for (;;) {
+		if (p->parents && p->parents->next)
+			break;
+		if (p->object.flags & UNINTERESTING)
+			break;
+		if (!(p->object.flags & TREESAME))
+			break;
+		if (!p->parents)
+			return NULL;
+		p = p->parents->item;
+	}
+	return p;
+}
+
 static void show_progress(void)
 {
 	static int counter = 0;
@@ -243,7 +262,7 @@
 		if (!buf)
 			die("could not read blob %s", oid_to_hex(oid));
 		if (check_object_signature(oid, buf, size, type_name(type)) < 0)
-			die("sha1 mismatch in blob %s", oid_to_hex(oid));
+			die("oid mismatch in blob %s", oid_to_hex(oid));
 		object = parse_object_buffer(the_repository, oid, type,
 					     size, buf, &eaten);
 	}
@@ -253,7 +272,10 @@
 
 	mark_next_object(object);
 
-	printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
+	printf("blob\nmark :%"PRIu32"\n", last_idnum);
+	if (show_original_ids)
+		printf("original-oid %s\n", oid_to_hex(oid));
+	printf("data %"PRIuMAX"\n", (uintmax_t)size);
 	if (size && fwrite(buf, size, 1, stdout) != 1)
 		die_errno("could not write blob '%s'", oid_to_hex(oid));
 	printf("\n");
@@ -330,17 +352,18 @@
 
 static void *generate_fake_oid(const void *old, size_t *len)
 {
-	static uint32_t counter = 1; /* avoid null sha1 */
-	unsigned char *out = xcalloc(GIT_SHA1_RAWSZ, 1);
-	put_be32(out + GIT_SHA1_RAWSZ - 4, counter++);
+	static uint32_t counter = 1; /* avoid null oid */
+	const unsigned hashsz = the_hash_algo->rawsz;
+	unsigned char *out = xcalloc(hashsz, 1);
+	put_be32(out + hashsz - 4, counter++);
 	return out;
 }
 
-static const unsigned char *anonymize_sha1(const struct object_id *oid)
+static const struct object_id *anonymize_oid(const struct object_id *oid)
 {
-	static struct hashmap sha1s;
-	size_t len = GIT_SHA1_RAWSZ;
-	return anonymize_mem(&sha1s, generate_fake_oid, oid, &len);
+	static struct hashmap objs;
+	size_t len = the_hash_algo->rawsz;
+	return anonymize_mem(&objs, generate_fake_oid, oid, &len);
 }
 
 static void show_filemodify(struct diff_queue_struct *q,
@@ -399,9 +422,9 @@
 			 */
 			if (no_data || S_ISGITLINK(spec->mode))
 				printf("M %06o %s ", spec->mode,
-				       sha1_to_hex(anonymize ?
-						   anonymize_sha1(&spec->oid) :
-						   spec->oid.hash));
+				       oid_to_hex(anonymize ?
+						  anonymize_oid(&spec->oid) :
+						  &spec->oid));
 			else {
 				struct object *object = lookup_object(the_repository,
 								      spec->oid.hash);
@@ -579,7 +602,8 @@
 		message += 2;
 
 	if (commit->parents &&
-	    get_object_mark(&commit->parents->item->object) != 0 &&
+	    (get_object_mark(&commit->parents->item->object) != 0 ||
+	     reference_excluded_commits) &&
 	    !full_tree) {
 		parse_commit_or_die(commit->parents->item);
 		diff_tree_oid(get_commit_tree_oid(commit->parents->item),
@@ -595,6 +619,13 @@
 			export_blob(&diff_queued_diff.queue[i]->two->oid);
 
 	refname = *revision_sources_at(&revision_sources, commit);
+	/*
+	 * FIXME: string_list_remove() below for each ref is overall
+	 * O(N^2).  Compared to a history walk and diffing trees, this is
+	 * just lost in the noise in practice.  However, theoretically a
+	 * repo may have enough refs for this to become slow.
+	 */
+	string_list_remove(&extra_refs, refname, 0);
 	if (anonymize) {
 		refname = anonymize_refname(refname);
 		anonymize_ident_line(&committer, &committer_end);
@@ -608,8 +639,10 @@
 		reencoded = reencode_string(message, "UTF-8", encoding);
 	if (!commit->parents)
 		printf("reset %s\n", refname);
-	printf("commit %s\nmark :%"PRIu32"\n%.*s\n%.*s\ndata %u\n%s",
-	       refname, last_idnum,
+	printf("commit %s\nmark :%"PRIu32"\n", refname, last_idnum);
+	if (show_original_ids)
+		printf("original-oid %s\n", oid_to_hex(&commit->object.oid));
+	printf("%.*s\n%.*s\ndata %u\n%s",
 	       (int)(author_end - author), author,
 	       (int)(committer_end - committer), committer,
 	       (unsigned)(reencoded
@@ -620,13 +653,21 @@
 	unuse_commit_buffer(commit, commit_buffer);
 
 	for (i = 0, p = commit->parents; p; p = p->next) {
-		int mark = get_object_mark(&p->item->object);
-		if (!mark)
+		struct object *obj = &p->item->object;
+		int mark = get_object_mark(obj);
+
+		if (!mark && !reference_excluded_commits)
 			continue;
 		if (i == 0)
-			printf("from :%d\n", mark);
+			printf("from ");
 		else
-			printf("merge :%d\n", mark);
+			printf("merge ");
+		if (mark)
+			printf(":%d\n", mark);
+		else
+			printf("%s\n", oid_to_hex(anonymize ?
+						  anonymize_oid(&obj->oid) :
+						  &obj->oid));
 		i++;
 	}
 
@@ -727,7 +768,7 @@
 					       "\n-----BEGIN PGP SIGNATURE-----\n");
 		if (signature)
 			switch(signed_tag_mode) {
-			case ABORT:
+			case SIGNED_TAG_ABORT:
 				die("encountered signed tag %s; use "
 				    "--signed-tags=<mode> to handle it",
 				    oid_to_hex(&tag->object.oid));
@@ -752,7 +793,7 @@
 	tagged_mark = get_object_mark(tagged);
 	if (!tagged_mark) {
 		switch(tag_of_filtered_mode) {
-		case ABORT:
+		case TAG_FILTERING_ABORT:
 			die("tag %s tags unexported object; use "
 			    "--tag-of-filtered-object=<mode> to handle it",
 			    oid_to_hex(&tag->object.oid));
@@ -766,18 +807,12 @@
 				    oid_to_hex(&tag->object.oid),
 				    type_name(tagged->type));
 			}
-			p = (struct commit *)tagged;
-			for (;;) {
-				if (p->parents && p->parents->next)
-					break;
-				if (p->object.flags & UNINTERESTING)
-					break;
-				if (!(p->object.flags & TREESAME))
-					break;
-				if (!p->parents)
-					die("can't find replacement commit for tag %s",
-					     oid_to_hex(&tag->object.oid));
-				p = p->parents->item;
+			p = rewrite_commit((struct commit *)tagged);
+			if (!p) {
+				printf("reset %s\nfrom %s\n\n",
+				       name, oid_to_hex(&null_oid));
+				free(buf);
+				return;
 			}
 			tagged_mark = get_object_mark(&p->object);
 		}
@@ -785,8 +820,10 @@
 
 	if (starts_with(name, "refs/tags/"))
 		name += 10;
-	printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n",
-	       name, tagged_mark,
+	printf("tag %s\nfrom :%d\n", name, tagged_mark);
+	if (show_original_ids)
+		printf("original-oid %s\n", oid_to_hex(&tag->object.oid));
+	printf("%.*s%sdata %d\n%.*s\n",
 	       (int)(tagger_end - tagger), tagger,
 	       tagger == tagger_end ? "" : "\n",
 	       (int)message_size, (int)message_size, message ? message : "");
@@ -804,7 +841,7 @@
 		/* handle nested tags */
 		while (tag && tag->object.type == OBJ_TAG) {
 			parse_object(the_repository, &tag->object.oid);
-			string_list_append(&extra_refs, full_name)->util = tag;
+			string_list_append(&tag_refs, full_name)->util = tag;
 			tag = (struct tag *)tag->tagged;
 		}
 		if (!tag)
@@ -863,25 +900,30 @@
 		}
 
 		/*
-		 * This ref will not be updated through a commit, lets make
-		 * sure it gets properly updated eventually.
+		 * Make sure this ref gets properly updated eventually, whether
+		 * through a commit or manually at the end.
 		 */
-		if (*revision_sources_at(&revision_sources, commit) ||
-		    commit->object.flags & SHOWN)
+		if (e->item->type != OBJ_TAG)
 			string_list_append(&extra_refs, full_name)->util = commit;
+
 		if (!*revision_sources_at(&revision_sources, commit))
 			*revision_sources_at(&revision_sources, commit) = full_name;
 	}
+
+	string_list_sort(&extra_refs);
+	string_list_remove_duplicates(&extra_refs, 0);
 }
 
-static void handle_tags_and_duplicates(void)
+static void handle_tags_and_duplicates(struct string_list *extras)
 {
 	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 = extras->nr - 1; i >= 0; i--) {
+		const char *name = extras->items[i].string;
+		struct object *object = extras->items[i].util;
+		int mark;
+
 		switch (object->type) {
 		case OBJ_TAG:
 			handle_tag(name, (struct tag *)object);
@@ -890,9 +932,45 @@
 			if (anonymize)
 				name = anonymize_refname(name);
 			/* create refs pointing to already seen commits */
-			commit = (struct commit *)object;
-			printf("reset %s\nfrom :%d\n\n", name,
-			       get_object_mark(&commit->object));
+			commit = rewrite_commit((struct commit *)object);
+			if (!commit) {
+				/*
+				 * Neither this object nor any of its
+				 * ancestors touch any relevant paths, so
+				 * it has been filtered to nothing.  Delete
+				 * it.
+				 */
+				printf("reset %s\nfrom %s\n\n",
+				       name, oid_to_hex(&null_oid));
+				continue;
+			}
+
+			mark = get_object_mark(&commit->object);
+			if (!mark) {
+				/*
+				 * Getting here means we have a commit which
+				 * was excluded by a negative refspec (e.g.
+				 * fast-export ^master master).  If we are
+				 * referencing excluded commits, set the ref
+				 * to the exact commit.  Otherwise, the user
+				 * wants the branch exported but every commit
+				 * in its history to be deleted, which basically
+				 * just means deletion of the ref.
+				 */
+				if (!reference_excluded_commits) {
+					/* delete the ref */
+					printf("reset %s\nfrom %s\n\n",
+					       name, oid_to_hex(&null_oid));
+					continue;
+				}
+				/* set ref to commit using oid, not mark */
+				printf("reset %s\nfrom %s\n\n", name,
+				       oid_to_hex(&commit->object.oid));
+				continue;
+			}
+
+			printf("reset %s\nfrom :%d\n\n", name, mark
+			       );
 			show_progress();
 			break;
 		}
@@ -988,7 +1066,7 @@
 			continue;
 
 		printf("reset %s\nfrom %s\n\n",
-				refspec->dst, sha1_to_hex(null_sha1));
+				refspec->dst, oid_to_hex(&null_oid));
 	}
 }
 
@@ -1024,6 +1102,11 @@
 		OPT_STRING_LIST(0, "refspec", &refspecs_list, N_("refspec"),
 			     N_("Apply refspec to exported refs")),
 		OPT_BOOL(0, "anonymize", &anonymize, N_("anonymize output")),
+		OPT_BOOL(0, "reference-excluded-parents",
+			 &reference_excluded_commits, N_("Reference parents which are not in fast-export stream by object id")),
+		OPT_BOOL(0, "show-original-ids", &show_original_ids,
+			    N_("Show original object ids of blobs/commits")),
+
 		OPT_END()
 	};
 
@@ -1080,7 +1163,8 @@
 		}
 	}
 
-	handle_tags_and_duplicates();
+	handle_tags_and_duplicates(&extra_refs);
+	handle_tags_and_duplicates(&tag_refs);
 	handle_deletes();
 
 	if (export_filename && lastimportid != last_idnum)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 6ec7c07..e014032 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -98,6 +98,8 @@
 
 static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
+
 	/*
 	 * "git fetch --refmap='' origin foo"
 	 * can be used to tell the command not to store anywhere
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 3c3e0f0..bf5ddff 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -51,16 +51,24 @@
 
 static const char *describe_object(struct object *obj)
 {
-	static struct strbuf buf = STRBUF_INIT;
-	char *name = name_objects ?
-		lookup_decoration(fsck_walk_options.object_names, obj) : NULL;
+	static struct strbuf bufs[] = {
+		STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
+	};
+	static int b = 0;
+	struct strbuf *buf;
+	char *name = NULL;
 
-	strbuf_reset(&buf);
-	strbuf_addstr(&buf, oid_to_hex(&obj->oid));
+	if (name_objects)
+		name = lookup_decoration(fsck_walk_options.object_names, obj);
+
+	buf = bufs + b;
+	b = (b + 1) % ARRAY_SIZE(bufs);
+	strbuf_reset(buf);
+	strbuf_addstr(buf, oid_to_hex(&obj->oid));
 	if (name)
-		strbuf_addf(&buf, " (%s)", name);
+		strbuf_addf(buf, " (%s)", name);
 
-	return buf.buf;
+	return buf->buf;
 }
 
 static const char *printable_type(struct object *obj)
@@ -76,7 +84,7 @@
 
 	ret = type_name(obj->type);
 	if (!ret)
-		ret = "unknown";
+		ret = _("unknown");
 
 	return ret;
 }
@@ -104,25 +112,32 @@
 	return git_default_config(var, value, cb);
 }
 
-static void objreport(struct object *obj, const char *msg_type,
-			const char *err)
-{
-	fprintf(stderr, "%s in %s %s: %s\n",
-		msg_type, printable_type(obj), describe_object(obj), err);
-}
-
 static int objerror(struct object *obj, const char *err)
 {
 	errors_found |= ERROR_OBJECT;
-	objreport(obj, "error", err);
+	/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
+	fprintf_ln(stderr, _("error in %s %s: %s"),
+		   printable_type(obj), describe_object(obj), err);
 	return -1;
 }
 
 static int fsck_error_func(struct fsck_options *o,
 	struct object *obj, int type, const char *message)
 {
-	objreport(obj, (type == FSCK_WARN) ? "warning" : "error", message);
-	return (type == FSCK_WARN) ? 0 : 1;
+	switch (type) {
+	case FSCK_WARN:
+		/* TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> */
+		fprintf_ln(stderr, _("warning in %s %s: %s"),
+			   printable_type(obj), describe_object(obj), message);
+		return 0;
+	case FSCK_ERROR:
+		/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
+		fprintf_ln(stderr, _("error in %s %s: %s"),
+			   printable_type(obj), describe_object(obj), message);
+		return 1;
+	default:
+		BUG("%d (FSCK_IGNORE?) should never trigger this callback", type);
+	}
 }
 
 static struct object_array pending;
@@ -138,17 +153,18 @@
 	 */
 	if (!obj) {
 		/* ... these references to parent->fld are safe here */
-		printf("broken link from %7s %s\n",
-			   printable_type(parent), describe_object(parent));
-		printf("broken link from %7s %s\n",
-			   (type == OBJ_ANY ? "unknown" : type_name(type)), "unknown");
+		printf_ln(_("broken link from %7s %s"),
+			  printable_type(parent), describe_object(parent));
+		printf_ln(_("broken link from %7s %s"),
+			  (type == OBJ_ANY ? _("unknown") : type_name(type)),
+			  _("unknown"));
 		errors_found |= ERROR_REACHABLE;
 		return 1;
 	}
 
 	if (type != OBJ_ANY && obj->type != type)
 		/* ... and the reference to parent is safe here */
-		objerror(parent, "wrong object type in link");
+		objerror(parent, _("wrong object type in link"));
 
 	if (obj->flags & REACHABLE)
 		return 0;
@@ -164,10 +180,12 @@
 
 	if (!(obj->flags & HAS_OBJ)) {
 		if (parent && !has_object_file(&obj->oid)) {
-			printf("broken link from %7s %s\n",
-				 printable_type(parent), describe_object(parent));
-			printf("              to %7s %s\n",
-				 printable_type(obj), describe_object(obj));
+			printf_ln(_("broken link from %7s %s\n"
+				    "              to %7s %s"),
+				  printable_type(parent),
+				  describe_object(parent),
+				  printable_type(obj),
+				  describe_object(obj));
 			errors_found |= ERROR_REACHABLE;
 		}
 		return 1;
@@ -231,8 +249,8 @@
 			return;
 		if (has_object_pack(&obj->oid))
 			return; /* it is in pack - forget about it */
-		printf("missing %s %s\n", printable_type(obj),
-			describe_object(obj));
+		printf_ln(_("missing %s %s"), printable_type(obj),
+			  describe_object(obj));
 		errors_found |= ERROR_REACHABLE;
 		return;
 	}
@@ -257,8 +275,8 @@
 	 * since this is something that is prunable.
 	 */
 	if (show_unreachable) {
-		printf("unreachable %s %s\n", printable_type(obj),
-			describe_object(obj));
+		printf_ln(_("unreachable %s %s"), printable_type(obj),
+			  describe_object(obj));
 		return;
 	}
 
@@ -276,8 +294,8 @@
 	 */
 	if (!(obj->flags & USED)) {
 		if (show_dangling)
-			printf("dangling %s %s\n", printable_type(obj),
-			       describe_object(obj));
+			printf_ln(_("dangling %s %s"), printable_type(obj),
+				  describe_object(obj));
 		if (write_lost_and_found) {
 			char *filename = git_pathdup("lost-found/%s/%s",
 				obj->type == OBJ_COMMIT ? "commit" : "other",
@@ -285,18 +303,18 @@
 			FILE *f;
 
 			if (safe_create_leading_directories_const(filename)) {
-				error("Could not create lost-found");
+				error(_("could not create lost-found"));
 				free(filename);
 				return;
 			}
 			f = xfopen(filename, "w");
 			if (obj->type == OBJ_BLOB) {
 				if (stream_blob_to_fd(fileno(f), &obj->oid, NULL, 1))
-					die_errno("Could not write '%s'", filename);
+					die_errno(_("could not write '%s'"), filename);
 			} else
 				fprintf(f, "%s\n", describe_object(obj));
 			if (fclose(f))
-				die_errno("Could not finish '%s'",
+				die_errno(_("could not finish '%s'"),
 					  filename);
 			free(filename);
 		}
@@ -313,7 +331,7 @@
 static void check_object(struct object *obj)
 {
 	if (verbose)
-		fprintf(stderr, "Checking %s\n", describe_object(obj));
+		fprintf_ln(stderr, _("Checking %s"), describe_object(obj));
 
 	if (obj->flags & REACHABLE)
 		check_reachable_object(obj);
@@ -331,7 +349,7 @@
 	/* Look up all the requirements, warn about missing objects.. */
 	max = get_max_object_index();
 	if (verbose)
-		fprintf(stderr, "Checking connectivity (%d objects)\n", max);
+		fprintf_ln(stderr, _("Checking connectivity (%d objects)"), max);
 
 	for (i = 0; i < max; i++) {
 		struct object *obj = get_indexed_object(i);
@@ -350,11 +368,11 @@
 	obj->flags |= SEEN;
 
 	if (verbose)
-		fprintf(stderr, "Checking %s %s\n",
-			printable_type(obj), describe_object(obj));
+		fprintf_ln(stderr, _("Checking %s %s"),
+			   printable_type(obj), describe_object(obj));
 
 	if (fsck_walk(obj, NULL, &fsck_obj_options))
-		objerror(obj, "broken links");
+		objerror(obj, _("broken links"));
 	err = fsck_object(obj, buffer, size, &fsck_obj_options);
 	if (err)
 		goto out;
@@ -363,17 +381,19 @@
 		struct commit *commit = (struct commit *) obj;
 
 		if (!commit->parents && show_root)
-			printf("root %s\n", describe_object(&commit->object));
+			printf_ln(_("root %s"),
+				  describe_object(&commit->object));
 	}
 
 	if (obj->type == OBJ_TAG) {
 		struct tag *tag = (struct tag *) obj;
 
 		if (show_tags && tag->tagged) {
-			printf("tagged %s %s", printable_type(tag->tagged),
-				describe_object(tag->tagged));
-			printf(" (%s) in %s\n", tag->tag,
-				describe_object(&tag->object));
+			printf_ln(_("tagged %s %s (%s) in %s"),
+				  printable_type(tag->tagged),
+				  describe_object(tag->tagged),
+				  tag->tag,
+				  describe_object(&tag->object));
 		}
 	}
 
@@ -397,7 +417,8 @@
 				  eaten);
 	if (!obj) {
 		errors_found |= ERROR_OBJECT;
-		return error("%s: object corrupt or missing", oid_to_hex(oid));
+		return error(_("%s: object corrupt or missing"),
+			     oid_to_hex(oid));
 	}
 	obj->flags &= ~(REACHABLE | SEEN);
 	obj->flags |= HAS_OBJ;
@@ -421,7 +442,8 @@
 			obj->flags |= USED;
 			mark_object_reachable(obj);
 		} else if (!is_promisor_object(oid)) {
-			error("%s: invalid reflog entry %s", refname, oid_to_hex(oid));
+			error(_("%s: invalid reflog entry %s"),
+			      refname, oid_to_hex(oid));
 			errors_found |= ERROR_REACHABLE;
 		}
 	}
@@ -434,8 +456,8 @@
 	const char *refname = cb_data;
 
 	if (verbose)
-		fprintf(stderr, "Checking reflog %s->%s\n",
-			oid_to_hex(ooid), oid_to_hex(noid));
+		fprintf_ln(stderr, _("Checking reflog %s->%s"),
+			   oid_to_hex(ooid), oid_to_hex(noid));
 
 	fsck_handle_reflog_oid(refname, ooid, 0);
 	fsck_handle_reflog_oid(refname, noid, timestamp);
@@ -468,13 +490,14 @@
 			 default_refs++;
 			 return 0;
 		}
-		error("%s: invalid sha1 pointer %s", refname, oid_to_hex(oid));
+		error(_("%s: invalid sha1 pointer %s"),
+		      refname, oid_to_hex(oid));
 		errors_found |= ERROR_REACHABLE;
 		/* We'll continue with the rest despite the error.. */
 		return 0;
 	}
 	if (obj->type != OBJ_COMMIT && is_branch(refname)) {
-		error("%s: not a commit", refname);
+		error(_("%s: not a commit"), refname);
 		errors_found |= ERROR_REFS;
 	}
 	default_refs++;
@@ -529,7 +552,7 @@
 	 * "show_unreachable" flag.
 	 */
 	if (!default_refs) {
-		fprintf(stderr, "notice: No default references\n");
+		fprintf_ln(stderr, _("notice: No default references"));
 		show_unreachable = 0;
 	}
 }
@@ -544,7 +567,7 @@
 
 	if (read_loose_object(path, oid, &type, &size, &contents) < 0) {
 		errors_found |= ERROR_OBJECT;
-		error("%s: object corrupt or missing: %s",
+		error(_("%s: object corrupt or missing: %s"),
 		      oid_to_hex(oid), path);
 		return 0; /* keep checking other objects */
 	}
@@ -557,7 +580,7 @@
 
 	if (!obj) {
 		errors_found |= ERROR_OBJECT;
-		error("%s: object could not be parsed: %s",
+		error(_("%s: object could not be parsed: %s"),
 		      oid_to_hex(oid), path);
 		if (!eaten)
 			free(contents);
@@ -577,7 +600,7 @@
 static int fsck_cruft(const char *basename, const char *path, void *data)
 {
 	if (!starts_with(basename, "tmp_obj_"))
-		fprintf(stderr, "bad sha1 file: %s\n", path);
+		fprintf_ln(stderr, _("bad sha1 file: %s"), path);
 	return 0;
 }
 
@@ -592,7 +615,7 @@
 	struct progress *progress = NULL;
 
 	if (verbose)
-		fprintf(stderr, "Checking object directory\n");
+		fprintf_ln(stderr, _("Checking object directory"));
 
 	if (show_progress)
 		progress = start_progress(_("Checking object directories"), 256);
@@ -610,29 +633,30 @@
 	int null_is_error = 0;
 
 	if (verbose)
-		fprintf(stderr, "Checking %s link\n", head_ref_name);
+		fprintf_ln(stderr, _("Checking %s link"), head_ref_name);
 
 	*head_points_at = resolve_ref_unsafe(head_ref_name, 0, head_oid, NULL);
 	if (!*head_points_at) {
 		errors_found |= ERROR_REFS;
-		return error("Invalid %s", head_ref_name);
+		return error(_("invalid %s"), head_ref_name);
 	}
 	if (!strcmp(*head_points_at, head_ref_name))
 		/* detached HEAD */
 		null_is_error = 1;
 	else if (!starts_with(*head_points_at, "refs/heads/")) {
 		errors_found |= ERROR_REFS;
-		return error("%s points to something strange (%s)",
+		return error(_("%s points to something strange (%s)"),
 			     head_ref_name, *head_points_at);
 	}
 	if (is_null_oid(head_oid)) {
 		if (null_is_error) {
 			errors_found |= ERROR_REFS;
-			return error("%s: detached HEAD points at nothing",
+			return error(_("%s: detached HEAD points at nothing"),
 				     head_ref_name);
 		}
-		fprintf(stderr, "notice: %s points to an unborn branch (%s)\n",
-			head_ref_name, *head_points_at + 11);
+		fprintf_ln(stderr,
+			   _("notice: %s points to an unborn branch (%s)"),
+			   head_ref_name, *head_points_at + 11);
 	}
 	return 0;
 }
@@ -643,12 +667,12 @@
 	int err = 0;
 
 	if (verbose)
-		fprintf(stderr, "Checking cache tree\n");
+		fprintf_ln(stderr, _("Checking cache tree"));
 
 	if (0 <= it->entry_count) {
 		struct object *obj = parse_object(the_repository, &it->oid);
 		if (!obj) {
-			error("%s: invalid sha1 pointer in cache-tree",
+			error(_("%s: invalid sha1 pointer in cache-tree"),
 			      oid_to_hex(&it->oid));
 			errors_found |= ERROR_REFS;
 			return 1;
@@ -659,7 +683,7 @@
 				obj, xstrdup(":"));
 		mark_object_reachable(obj);
 		if (obj->type != OBJ_TREE)
-			err |= objerror(obj, "non-tree in cache-tree");
+			err |= objerror(obj, _("non-tree in cache-tree"));
 	}
 	for (i = 0; i < it->subtree_nr; i++)
 		err |= fsck_cache_tree(it->down[i]->cache_tree);
@@ -715,7 +739,7 @@
 int cmd_fsck(int argc, const char **argv, const char *prefix)
 {
 	int i;
-	struct alternate_object_database *alt;
+	struct object_directory *odb;
 
 	/* fsck knows how to handle missing promisor objects */
 	fetch_if_missing = 0;
@@ -751,14 +775,9 @@
 		for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
 		for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
 	} else {
-		struct alternate_object_database *alt_odb_list;
-
-		fsck_object_dir(get_object_directory());
-
 		prepare_alt_odb(the_repository);
-		alt_odb_list = the_repository->objects->alt_odb_list;
-		for (alt = alt_odb_list; alt; alt = alt->next)
-			fsck_object_dir(alt->path);
+		for (odb = the_repository->objects->odb; odb; odb = odb->next)
+			fsck_object_dir(odb->path);
 
 		if (check_full) {
 			struct packed_git *p;
@@ -778,7 +797,8 @@
 			for (p = get_all_packs(the_repository); p;
 			     p = p->next) {
 				/* verify gives error messages itself */
-				if (verify_pack(p, fsck_obj_buffer,
+				if (verify_pack(the_repository,
+						p, fsck_obj_buffer,
 						progress, count))
 					errors_found |= ERROR_PACK;
 				count += p->num_objects;
@@ -800,7 +820,7 @@
 			if (!obj || !(obj->flags & HAS_OBJ)) {
 				if (is_promisor_object(&oid))
 					continue;
-				error("%s: object missing", oid_to_hex(&oid));
+				error(_("%s: object missing"), oid_to_hex(&oid));
 				errors_found |= ERROR_OBJECT;
 				continue;
 			}
@@ -812,7 +832,7 @@
 			mark_object_reachable(obj);
 			continue;
 		}
-		error("invalid parameter: expected sha1, got '%s'", arg);
+		error(_("invalid parameter: expected sha1, got '%s'"), arg);
 		errors_found |= ERROR_OBJECT;
 	}
 
@@ -860,15 +880,13 @@
 		struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
 		const char *verify_argv[] = { "commit-graph", "verify", NULL, NULL, NULL };
 
-		commit_graph_verify.argv = verify_argv;
-		commit_graph_verify.git_cmd = 1;
-		if (run_command(&commit_graph_verify))
-			errors_found |= ERROR_COMMIT_GRAPH;
-
 		prepare_alt_odb(the_repository);
-		for (alt =  the_repository->objects->alt_odb_list; alt; alt = alt->next) {
+		for (odb = the_repository->objects->odb; odb; odb = odb->next) {
+			child_process_init(&commit_graph_verify);
+			commit_graph_verify.argv = verify_argv;
+			commit_graph_verify.git_cmd = 1;
 			verify_argv[2] = "--object-dir";
-			verify_argv[3] = alt->path;
+			verify_argv[3] = odb->path;
 			if (run_command(&commit_graph_verify))
 				errors_found |= ERROR_COMMIT_GRAPH;
 		}
@@ -878,15 +896,13 @@
 		struct child_process midx_verify = CHILD_PROCESS_INIT;
 		const char *midx_argv[] = { "multi-pack-index", "verify", NULL, NULL, NULL };
 
-		midx_verify.argv = midx_argv;
-		midx_verify.git_cmd = 1;
-		if (run_command(&midx_verify))
-			errors_found |= ERROR_COMMIT_GRAPH;
-
 		prepare_alt_odb(the_repository);
-		for (alt =  the_repository->objects->alt_odb_list; alt; alt = alt->next) {
+		for (odb = the_repository->objects->odb; odb; odb = odb->next) {
+			child_process_init(&midx_verify);
+			midx_verify.argv = midx_argv;
+			midx_verify.git_cmd = 1;
 			midx_argv[2] = "--object-dir";
-			midx_argv[3] = alt->path;
+			midx_argv[3] = odb->path;
 			if (run_command(&midx_verify))
 				errors_found |= ERROR_COMMIT_GRAPH;
 		}
diff --git a/builtin/grep.c b/builtin/grep.c
index 56e4a11..bad9c0a 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -34,7 +34,6 @@
 #define GREP_NUM_THREADS_DEFAULT 8
 static int num_threads;
 
-#ifndef NO_PTHREADS
 static pthread_t *threads;
 
 /* We use one producer thread and THREADS consumer
@@ -70,13 +69,11 @@
 
 static inline void grep_lock(void)
 {
-	assert(num_threads);
 	pthread_mutex_lock(&grep_mutex);
 }
 
 static inline void grep_unlock(void)
 {
-	assert(num_threads);
 	pthread_mutex_unlock(&grep_mutex);
 }
 
@@ -234,6 +231,9 @@
 	int hit = 0;
 	int i;
 
+	if (!HAVE_THREADS)
+		BUG("Never call this function unless you have started threads");
+
 	grep_lock();
 	all_work_added = 1;
 
@@ -265,13 +265,6 @@
 
 	return hit;
 }
-#else /* !NO_PTHREADS */
-
-static int wait_all(void)
-{
-	return 0;
-}
-#endif
 
 static int grep_cmd_config(const char *var, const char *value, void *cb)
 {
@@ -284,17 +277,15 @@
 		if (num_threads < 0)
 			die(_("invalid number of threads specified (%d) for %s"),
 			    num_threads, var);
-#ifdef NO_PTHREADS
-		else if (num_threads && num_threads != 1) {
+		else if (!HAVE_THREADS && num_threads > 1) {
 			/*
 			 * TRANSLATORS: %s is the configuration
 			 * variable for tweaking threads, currently
 			 * grep.threads
 			 */
 			warning(_("no threads support, ignoring %s"), var);
-			num_threads = 0;
+			num_threads = 1;
 		}
-#endif
 	}
 
 	if (!strcmp(var, "submodule.recurse"))
@@ -330,17 +321,14 @@
 	grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid);
 	strbuf_release(&pathbuf);
 
-#ifndef NO_PTHREADS
-	if (num_threads) {
+	if (num_threads > 1) {
 		/*
 		 * add_work() copies gs and thus assumes ownership of
 		 * its fields, so do not call grep_source_clear()
 		 */
 		add_work(opt, &gs);
 		return 0;
-	} else
-#endif
-	{
+	} else {
 		int hit;
 
 		hit = grep_source(opt, &gs);
@@ -363,17 +351,14 @@
 	grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename);
 	strbuf_release(&buf);
 
-#ifndef NO_PTHREADS
-	if (num_threads) {
+	if (num_threads > 1) {
 		/*
 		 * add_work() copies gs and thus assumes ownership of
 		 * its fields, so do not call grep_source_clear()
 		 */
 		add_work(opt, &gs);
 		return 0;
-	} else
-#endif
-	{
+	} else {
 		int hit;
 
 		hit = grep_source(opt, &gs);
@@ -452,7 +437,7 @@
 	 * store is no longer global and instead is a member of the repository
 	 * object.
 	 */
-	add_to_alternates_memory(submodule.objects->objectdir);
+	add_to_alternates_memory(submodule.objects->odb->path);
 	grep_read_unlock();
 
 	if (oid) {
@@ -723,11 +708,14 @@
 static int file_callback(const struct option *opt, const char *arg, int unset)
 {
 	struct grep_opt *grep_opt = opt->value;
-	int from_stdin = !strcmp(arg, "-");
+	int from_stdin;
 	FILE *patterns;
 	int lno = 0;
 	struct strbuf sb = STRBUF_INIT;
 
+	BUG_ON_OPT_NEG(unset);
+
+	from_stdin = !strcmp(arg, "-");
 	patterns = from_stdin ? stdin : fopen(arg, "r");
 	if (!patterns)
 		die_errno(_("cannot open '%s'"), arg);
@@ -748,6 +736,8 @@
 static int not_callback(const struct option *opt, const char *arg, int unset)
 {
 	struct grep_opt *grep_opt = opt->value;
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	append_grep_pattern(grep_opt, "--not", "command line", 0, GREP_NOT);
 	return 0;
 }
@@ -755,6 +745,8 @@
 static int and_callback(const struct option *opt, const char *arg, int unset)
 {
 	struct grep_opt *grep_opt = opt->value;
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	append_grep_pattern(grep_opt, "--and", "command line", 0, GREP_AND);
 	return 0;
 }
@@ -762,6 +754,8 @@
 static int open_callback(const struct option *opt, const char *arg, int unset)
 {
 	struct grep_opt *grep_opt = opt->value;
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	append_grep_pattern(grep_opt, "(", "command line", 0, GREP_OPEN_PAREN);
 	return 0;
 }
@@ -769,6 +763,8 @@
 static int close_callback(const struct option *opt, const char *arg, int unset)
 {
 	struct grep_opt *grep_opt = opt->value;
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	append_grep_pattern(grep_opt, ")", "command line", 0, GREP_CLOSE_PAREN);
 	return 0;
 }
@@ -777,6 +773,7 @@
 			    int unset)
 {
 	struct grep_opt *grep_opt = opt->value;
+	BUG_ON_OPT_NEG(unset);
 	append_grep_pattern(grep_opt, arg, "-e option", 0, GREP_PATTERN);
 	return 0;
 }
@@ -1049,39 +1046,35 @@
 	pathspec.recursive = 1;
 	pathspec.recurse_submodules = !!recurse_submodules;
 
-#ifndef NO_PTHREADS
-	if (list.nr || cached || show_in_pager)
-		num_threads = 0;
-	else if (num_threads == 0)
-		num_threads = GREP_NUM_THREADS_DEFAULT;
-	else if (num_threads < 0)
-		die(_("invalid number of threads specified (%d)"), num_threads);
-	if (num_threads == 1)
-		num_threads = 0;
-#else
-	if (num_threads)
+	if (list.nr || cached || show_in_pager) {
+		if (num_threads > 1)
+			warning(_("invalid option combination, ignoring --threads"));
+		num_threads = 1;
+	} else if (!HAVE_THREADS && num_threads > 1) {
 		warning(_("no threads support, ignoring --threads"));
-	num_threads = 0;
-#endif
+		num_threads = 1;
+	} else if (num_threads < 0)
+		die(_("invalid number of threads specified (%d)"), num_threads);
+	else if (num_threads == 0)
+		num_threads = HAVE_THREADS ? GREP_NUM_THREADS_DEFAULT : 1;
 
-	if (!num_threads)
-		/*
-		 * The compiled patterns on the main path are only
-		 * used when not using threading. Otherwise
-		 * start_threads() below calls compile_grep_patterns()
-		 * for each thread.
-		 */
-		compile_grep_patterns(&opt);
-
-#ifndef NO_PTHREADS
-	if (num_threads) {
+	if (num_threads > 1) {
+		if (!HAVE_THREADS)
+			BUG("Somebody got num_threads calculation wrong!");
 		if (!(opt.name_only || opt.unmatch_name_only || opt.count)
 		    && (opt.pre_context || opt.post_context ||
 			opt.file_break || opt.funcbody))
 			skip_first_line = 1;
 		start_threads(&opt);
+	} else {
+		/*
+		 * The compiled patterns on the main path are only
+		 * used when not using threading. Otherwise
+		 * start_threads() above calls compile_grep_patterns()
+		 * for each thread.
+		 */
+		compile_grep_patterns(&opt);
 	}
-#endif
 
 	if (show_in_pager && (cached || list.nr))
 		die(_("--open-files-in-pager only works on the worktree"));
@@ -1132,7 +1125,7 @@
 		hit = grep_objects(&opt, &pathspec, &list);
 	}
 
-	if (num_threads)
+	if (num_threads > 1)
 		hit |= wait_all();
 	if (hit && show_in_pager)
 		run_pager(&opt, prefix);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 2004e25..ac1f4ea 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -42,9 +42,7 @@
 };
 
 struct thread_local {
-#ifndef NO_PTHREADS
 	pthread_t thread;
-#endif
 	struct base_data *base_cache;
 	size_t base_cache_used;
 	int pack_fd;
@@ -98,8 +96,6 @@
 static int input_fd, output_fd;
 static const char *curr_pack;
 
-#ifndef NO_PTHREADS
-
 static struct thread_local *thread_data;
 static int nr_dispatched;
 static int threads_active;
@@ -179,26 +175,6 @@
 	free(thread_data);
 }
 
-#else
-
-#define read_lock()
-#define read_unlock()
-
-#define counter_lock()
-#define counter_unlock()
-
-#define work_lock()
-#define work_unlock()
-
-#define deepest_delta_lock()
-#define deepest_delta_unlock()
-
-#define type_cas_lock()
-#define type_cas_unlock()
-
-#endif
-
-
 static int mark_link(struct object *obj, int type, void *data, struct fsck_options *options)
 {
 	if (!obj)
@@ -364,22 +340,20 @@
 
 static inline struct thread_local *get_thread_data(void)
 {
-#ifndef NO_PTHREADS
-	if (threads_active)
-		return pthread_getspecific(key);
-	assert(!threads_active &&
-	       "This should only be reached when all threads are gone");
-#endif
+	if (HAVE_THREADS) {
+		if (threads_active)
+			return pthread_getspecific(key);
+		assert(!threads_active &&
+		       "This should only be reached when all threads are gone");
+	}
 	return &nothread_data;
 }
 
-#ifndef NO_PTHREADS
 static void set_thread_data(struct thread_local *data)
 {
 	if (threads_active)
 		pthread_setspecific(key, data);
 }
-#endif
 
 static struct base_data *alloc_base_data(void)
 {
@@ -450,7 +424,8 @@
 	int hdrlen;
 
 	if (!is_delta_type(type)) {
-		hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), size) + 1;
+		hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX,
+				   type_name(type),(uintmax_t)size) + 1;
 		the_hash_algo->init_fn(&c);
 		the_hash_algo->update_fn(&c, hdr, hdrlen);
 	} else
@@ -1092,7 +1067,6 @@
 	find_unresolved_deltas(base_obj);
 }
 
-#ifndef NO_PTHREADS
 static void *threaded_second_pass(void *data)
 {
 	set_thread_data(data);
@@ -1116,7 +1090,6 @@
 	}
 	return NULL;
 }
-#endif
 
 /*
  * First pass:
@@ -1213,7 +1186,6 @@
 		progress = start_progress(_("Resolving deltas"),
 					  nr_ref_deltas + nr_ofs_deltas);
 
-#ifndef NO_PTHREADS
 	nr_dispatched = 0;
 	if (nr_threads > 1 || getenv("GIT_FORCE_THREADS")) {
 		init_thread();
@@ -1229,7 +1201,6 @@
 		cleanup_thread();
 		return;
 	}
-#endif
 
 	for (i = 0; i < nr_objects; i++) {
 		struct object_entry *obj = &objects[i];
@@ -1531,11 +1502,10 @@
 		if (nr_threads < 0)
 			die(_("invalid number of threads specified (%d)"),
 			    nr_threads);
-#ifdef NO_PTHREADS
-		if (nr_threads != 1)
+		if (!HAVE_THREADS && nr_threads != 1) {
 			warning(_("no threads support, ignoring %s"), k);
-		nr_threads = 1;
-#endif
+			nr_threads = 1;
+		}
 		return 0;
 	}
 	return git_default_config(k, v, cb);
@@ -1628,10 +1598,10 @@
 			chain_histogram[obj_stat[i].delta_depth - 1]++;
 		if (stat_only)
 			continue;
-		printf("%s %-6s %lu %lu %"PRIuMAX,
+		printf("%s %-6s %"PRIuMAX" %"PRIuMAX" %"PRIuMAX,
 		       oid_to_hex(&obj->idx.oid),
-		       type_name(obj->real_type), obj->size,
-		       (unsigned long)(obj[1].idx.offset - obj->idx.offset),
+		       type_name(obj->real_type), (uintmax_t)obj->size,
+		       (uintmax_t)(obj[1].idx.offset - obj->idx.offset),
 		       (uintmax_t)obj->idx.offset);
 		if (is_delta_type(obj->type)) {
 			struct object_entry *bobj = &objects[obj_stat[i].base_object_no];
@@ -1723,12 +1693,10 @@
 				nr_threads = strtoul(arg+10, &end, 0);
 				if (!arg[10] || *end || nr_threads < 0)
 					usage(index_pack_usage);
-#ifdef NO_PTHREADS
-				if (nr_threads != 1)
-					warning(_("no threads support, "
-						  "ignoring %s"), arg);
-				nr_threads = 1;
-#endif
+				if (!HAVE_THREADS && nr_threads != 1) {
+					warning(_("no threads support, ignoring %s"), arg);
+					nr_threads = 1;
+				}
 			} else if (starts_with(arg, "--pack_header=")) {
 				struct pack_header *hdr;
 				char *c;
@@ -1791,14 +1759,12 @@
 	if (strict)
 		opts.flags |= WRITE_IDX_STRICT;
 
-#ifndef NO_PTHREADS
-	if (!nr_threads) {
+	if (HAVE_THREADS && !nr_threads) {
 		nr_threads = online_cpus();
 		/* An experiment showed that more threads does not mean faster */
 		if (nr_threads > 3)
 			nr_threads = 3;
 	}
-#endif
 
 	curr_pack = open_pack_file(pack_name);
 	parse_pack_header();
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 12ddda7..41faffd 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -451,6 +451,7 @@
 
 static int shared_callback(const struct option *opt, const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
 	*((int *) opt->value) = (arg) ? git_config_perm("arg", arg) : PERM_GROUP;
 	return 0;
 }
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index 4b87e0d..8ae40de 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -80,6 +80,8 @@
 	v->only_trailers = 1;
 	v->only_input = 1;
 	v->unfold = 1;
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	return 0;
 }
 
diff --git a/builtin/log.c b/builtin/log.c
index 061d4fd..e8e5106 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -107,6 +107,8 @@
 {
 	struct line_opt_callback_data *data = option->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (!arg)
 		return -1;
 
@@ -1009,8 +1011,6 @@
 
 	memcpy(&opts, &rev->diffopt, sizeof(opts));
 	opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
-	opts.stat_width = MAIL_DEFAULT_WRAP;
-
 	diff_setup_done(&opts);
 
 	diff_tree_oid(get_commit_tree_oid(origin),
@@ -1094,9 +1094,18 @@
 	}
 
 	if (rev->rdiff1) {
+		/*
+		 * Pass minimum required diff-options to range-diff; others
+		 * can be added later if deemed desirable.
+		 */
+		struct diff_options opts;
+		diff_setup(&opts);
+		opts.file = rev->diffopt.file;
+		opts.use_color = rev->diffopt.use_color;
+		diff_setup_done(&opts);
 		fprintf_ln(rev->diffopt.file, "%s", rev->rdiff_title);
 		show_range_diff(rev->rdiff1, rev->rdiff2,
-				rev->creation_factor, 1, &rev->diffopt);
+				rev->creation_factor, 1, &opts);
 	}
 }
 
@@ -1151,6 +1160,8 @@
 
 static int keep_callback(const struct option *opt, const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	((struct rev_info *)opt->value)->total = -1;
 	keep_subject = 1;
 	return 0;
@@ -1161,6 +1172,7 @@
 static int subject_prefix_callback(const struct option *opt, const char *arg,
 			    int unset)
 {
+	BUG_ON_OPT_NEG(unset);
 	subject_prefix = 1;
 	((struct rev_info *)opt->value)->subject_prefix = arg;
 	return 0;
@@ -1168,6 +1180,8 @@
 
 static int rfc_callback(const struct option *opt, const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	return subject_prefix_callback(opt, "RFC PATCH", unset);
 }
 
@@ -1176,6 +1190,7 @@
 static int numbered_callback(const struct option *opt, const char *arg,
 			     int unset)
 {
+	BUG_ON_OPT_ARG(arg);
 	*(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
 	if (unset)
 		auto_number =  0;
@@ -1185,6 +1200,7 @@
 static int no_numbered_callback(const struct option *opt, const char *arg,
 				int unset)
 {
+	BUG_ON_OPT_NEG(unset);
 	return numbered_callback(opt, arg, 1);
 }
 
@@ -1192,6 +1208,7 @@
 			      int unset)
 {
 	const char **dir = (const char **)opt->value;
+	BUG_ON_OPT_NEG(unset);
 	if (*dir)
 		die(_("Two output directories?"));
 	*dir = arg;
@@ -1508,7 +1525,7 @@
 			    PARSE_OPT_NOARG, numbered_callback },
 		{ OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
 			    N_("use [PATCH] even with multiple patches"),
-			    PARSE_OPT_NOARG, no_numbered_callback },
+			    PARSE_OPT_NOARG | PARSE_OPT_NONEG, no_numbered_callback },
 		OPT_BOOL('s', "signoff", &do_signoff, N_("add Signed-off-by:")),
 		OPT_BOOL(0, "stdout", &use_stdout,
 			    N_("print patches to standard out")),
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 7f9919a..c70a9c7 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -475,6 +475,8 @@
 {
 	struct string_list *exclude_list = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	exc_given = 1;
 	string_list_append(exclude_list, arg);
 
@@ -486,6 +488,8 @@
 {
 	struct dir_struct *dir = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	exc_given = 1;
 	add_excludes_from_file(dir, arg);
 
@@ -497,6 +501,9 @@
 {
 	struct dir_struct *dir = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
+
 	exc_given = 1;
 	setup_standard_excludes(dir);
 
@@ -548,15 +555,16 @@
 			    N_("show resolve-undo information")),
 		{ OPTION_CALLBACK, 'x', "exclude", &exclude_list, N_("pattern"),
 			N_("skip files matching pattern"),
-			0, option_parse_exclude },
+			PARSE_OPT_NONEG, option_parse_exclude },
 		{ OPTION_CALLBACK, 'X', "exclude-from", &dir, N_("file"),
 			N_("exclude patterns are read from <file>"),
-			0, option_parse_exclude_from },
+			PARSE_OPT_NONEG, option_parse_exclude_from },
 		OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, N_("file"),
 			N_("read additional per-directory exclude patterns in <file>")),
 		{ OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
 			N_("add the standard git exclusions"),
-			PARSE_OPT_NOARG, option_parse_exclude_standard },
+			PARSE_OPT_NOARG | PARSE_OPT_NONEG,
+			option_parse_exclude_standard },
 		OPT_SET_INT_F(0, "full-name", &prefix_len,
 			      N_("make the output relative to the project top directory"),
 			      0, PARSE_OPT_NONEG),
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index fe3b952..7d581d6 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -100,7 +100,7 @@
 						  "BAD");
 				else
 					xsnprintf(size_text, sizeof(size_text),
-						  "%lu", size);
+						  "%"PRIuMAX, (uintmax_t)size);
 			} else
 				xsnprintf(size_text, sizeof(size_text), "-");
 			printf("%06o %s %s %7s\t", mode, type,
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index b08803e..06a2f90 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -15,6 +15,8 @@
 	static int label_count = 0;
 	const char **names = (const char **)opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (label_count >= 3)
 		return error("too many labels on the command line");
 	names[label_count++] = arg;
diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c
index c84c6e0..0b07263 100644
--- a/builtin/merge-ours.c
+++ b/builtin/merge-ours.c
@@ -26,7 +26,7 @@
 	 */
 	if (read_cache() < 0)
 		die_errno("read_cache failed");
-	if (index_differs_from("HEAD", NULL, 0))
+	if (index_differs_from(the_repository, "HEAD", NULL, 0))
 		exit(2);
 	exit(0);
 }
diff --git a/builtin/merge.c b/builtin/merge.c
index 4aa6071..dc0b7cc 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -128,7 +128,7 @@
 		ctx->argc--;
 		arg = *++ctx->argv;
 	} else
-		return opterror(opt, "requires a value", 0);
+		return error(_("option `%s' requires a value"), opt->long_name);
 
 	if (buf->len)
 		strbuf_addch(buf, '\n');
@@ -224,6 +224,7 @@
 static int option_parse_n(const struct option *opt,
 			  const char *arg, int unset)
 {
+	BUG_ON_OPT_ARG(arg);
 	show_diffstat = unset;
 	return 0;
 }
@@ -577,7 +578,7 @@
 	argc = split_cmdline(bmo, &argv);
 	if (argc < 0)
 		die(_("Bad branch.%s.mergeoptions string: %s"), branch,
-		    split_cmdline_strerror(argc));
+		    _(split_cmdline_strerror(argc)));
 	REALLOC_ARRAY(argv, argc + 2);
 	MOVE_ARRAY(argv + 1, argv, argc + 1);
 	argc++;
@@ -896,7 +897,7 @@
 	filename = git_path_merge_msg(the_repository);
 	fp = xfopen(filename, "a");
 
-	append_conflicts_hint(&msgbuf);
+	append_conflicts_hint(&the_index, &msgbuf);
 	fputs(msgbuf.buf, fp);
 	strbuf_release(&msgbuf);
 	fclose(fp);
@@ -1336,6 +1337,10 @@
 			die(_("%s - not something we can merge"), argv[0]);
 		if (remoteheads->next)
 			die(_("Can merge only exactly one commit into empty head"));
+
+		if (verify_signatures)
+			verify_merge_signature(remoteheads->item, verbosity);
+
 		remote_head_oid = &remoteheads->item->object.oid;
 		read_empty(remote_head_oid, 0);
 		update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0,
@@ -1357,31 +1362,7 @@
 
 	if (verify_signatures) {
 		for (p = remoteheads; p; p = p->next) {
-			struct commit *commit = p->item;
-			char hex[GIT_MAX_HEXSZ + 1];
-			struct signature_check signature_check;
-			memset(&signature_check, 0, sizeof(signature_check));
-
-			check_commit_signature(commit, &signature_check);
-
-			find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV);
-			switch (signature_check.result) {
-			case 'G':
-				break;
-			case 'U':
-				die(_("Commit %s has an untrusted GPG signature, "
-				      "allegedly by %s."), hex, signature_check.signer);
-			case 'B':
-				die(_("Commit %s has a bad GPG signature "
-				      "allegedly by %s."), hex, signature_check.signer);
-			default: /* 'N' */
-				die(_("Commit %s does not have a GPG signature."), hex);
-			}
-			if (verbosity >= 0 && signature_check.result == 'G')
-				printf(_("Commit %s has a good GPG signature by %s\n"),
-				       hex, signature_check.signer);
-
-			signature_check_clear(&signature_check);
+			verify_merge_signature(p->item, verbosity);
 		}
 	}
 
diff --git a/builtin/notes.c b/builtin/notes.c
index c05cd00..4996a67 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -215,6 +215,8 @@
 {
 	struct note_data *d = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	strbuf_grow(&d->buf, strlen(arg) + 2);
 	if (d->buf.len)
 		strbuf_addch(&d->buf, '\n');
@@ -229,6 +231,8 @@
 {
 	struct note_data *d = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (d->buf.len)
 		strbuf_addch(&d->buf, '\n');
 	if (!strcmp(arg, "-")) {
@@ -250,15 +254,15 @@
 	enum object_type type;
 	unsigned long len;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (d->buf.len)
 		strbuf_addch(&d->buf, '\n');
 
 	if (get_oid(arg, &object))
 		die(_("failed to resolve '%s' as a valid ref."), arg);
-	if (!(buf = read_object_file(&object, &type, &len))) {
-		free(buf);
+	if (!(buf = read_object_file(&object, &type, &len)))
 		die(_("failed to read object '%s'."), arg);
-	}
 	if (type != OBJ_BLOB) {
 		free(buf);
 		die(_("cannot read note data from non-blob object '%s'."), arg);
@@ -273,6 +277,7 @@
 static int parse_reedit_arg(const struct option *opt, const char *arg, int unset)
 {
 	struct note_data *d = opt->value;
+	BUG_ON_OPT_NEG(unset);
 	d->use_editor = 1;
 	return parse_reuse_arg(opt, arg, unset);
 }
@@ -808,7 +813,7 @@
 		usage_with_options(git_notes_merge_usage, options);
 	}
 
-	init_notes_merge_options(&o);
+	init_notes_merge_options(the_repository, &o);
 	o.verbosity = verbosity + NOTES_MERGE_VERBOSITY_DEFAULT;
 
 	if (do_abort)
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index c99ee79..24bba81 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1953,8 +1953,6 @@
 	return 0;
 }
 
-#ifndef NO_PTHREADS
-
 /* Protect access to object database */
 static pthread_mutex_t read_mutex;
 #define read_lock()		pthread_mutex_lock(&read_mutex)
@@ -1979,16 +1977,6 @@
  * ahead in the list because they can be stolen and would need
  * progress_mutex for protection.
  */
-#else
-
-#define read_lock()		(void)0
-#define read_unlock()		(void)0
-#define cache_lock()		(void)0
-#define cache_unlock()		(void)0
-#define progress_lock()		(void)0
-#define progress_unlock()	(void)0
-
-#endif
 
 /*
  * Return the size of the object without doing any delta
@@ -2095,9 +2083,9 @@
 			die(_("object %s cannot be read"),
 			    oid_to_hex(&trg_entry->idx.oid));
 		if (sz != trg_size)
-			die(_("object %s inconsistent object length (%lu vs %lu)"),
-			    oid_to_hex(&trg_entry->idx.oid), sz,
-			    trg_size);
+			die(_("object %s inconsistent object length (%"PRIuMAX" vs %"PRIuMAX")"),
+			    oid_to_hex(&trg_entry->idx.oid), (uintmax_t)sz,
+			    (uintmax_t)trg_size);
 		*mem_usage += sz;
 	}
 	if (!src->data) {
@@ -2122,9 +2110,9 @@
 			    oid_to_hex(&src_entry->idx.oid));
 		}
 		if (sz != src_size)
-			die(_("object %s inconsistent object length (%lu vs %lu)"),
-			    oid_to_hex(&src_entry->idx.oid), sz,
-			    src_size);
+			die(_("object %s inconsistent object length (%"PRIuMAX" vs %"PRIuMAX")"),
+			    oid_to_hex(&src_entry->idx.oid), (uintmax_t)sz,
+			    (uintmax_t)src_size);
 		*mem_usage += sz;
 	}
 	if (!src->index) {
@@ -2347,8 +2335,6 @@
 	free(array);
 }
 
-#ifndef NO_PTHREADS
-
 static void try_to_free_from_threads(size_t size)
 {
 	read_lock();
@@ -2577,10 +2563,6 @@
 	free(p);
 }
 
-#else
-#define ll_find_deltas(l, s, w, d, p)	find_deltas(l, &s, w, d, p)
-#endif
-
 static void add_tag_chain(const struct object_id *oid)
 {
 	struct tag *tag;
@@ -2628,7 +2610,7 @@
 	unsigned n;
 
 	if (use_delta_islands)
-		resolve_tree_islands(progress, &to_pack);
+		resolve_tree_islands(the_repository, progress, &to_pack);
 
 	get_object_details();
 
@@ -2733,12 +2715,10 @@
 		if (delta_search_threads < 0)
 			die(_("invalid number of threads specified (%d)"),
 			    delta_search_threads);
-#ifdef NO_PTHREADS
-		if (delta_search_threads != 1) {
+		if (!HAVE_THREADS && delta_search_threads != 1) {
 			warning(_("no threads support, ignoring %s"), k);
 			delta_search_threads = 0;
 		}
-#endif
 		return 0;
 	}
 	if (!strcmp(k, "pack.indexversion")) {
@@ -2806,9 +2786,11 @@
 
 	if (use_delta_islands) {
 		const char *p;
-		unsigned depth = 0;
+		unsigned depth;
 		struct object_entry *ent;
 
+		/* the empty string is a root tree, which is depth 0 */
+		depth = *name ? 1 : 0;
 		for (p = strchr(name, '/'); p; p = strchr(p + 1, '/'))
 			depth++;
 
@@ -3104,6 +3086,7 @@
 	struct rev_info revs;
 	char line[1000];
 	int flags = 0;
+	int save_warning;
 
 	repo_init_revisions(the_repository, &revs, NULL);
 	save_commit_buffer = 0;
@@ -3113,6 +3096,9 @@
 	/* make sure shallows are read */
 	is_repository_shallow(the_repository);
 
+	save_warning = warn_on_object_refname_ambiguity;
+	warn_on_object_refname_ambiguity = 0;
+
 	while (fgets(line, sizeof(line), stdin) != NULL) {
 		int len = strlen(line);
 		if (len && line[len - 1] == '\n')
@@ -3139,11 +3125,13 @@
 			die(_("bad revision '%s'"), line);
 	}
 
+	warn_on_object_refname_ambiguity = save_warning;
+
 	if (use_bitmap_index && !get_object_list_from_bitmap(&revs))
 		return;
 
 	if (use_delta_islands)
-		load_delta_islands();
+		load_delta_islands(the_repository);
 
 	if (prepare_revision_walk(&revs))
 		die(_("revision walk setup failed"));
@@ -3207,6 +3195,9 @@
 {
 	char *c;
 	const char *val = arg;
+
+	BUG_ON_OPT_NEG(unset);
+
 	pack_idx_opts.version = strtoul(val, &c, 10);
 	if (pack_idx_opts.version > 2)
 		die(_("unsupported index version %s"), val);
@@ -3253,7 +3244,7 @@
 			 N_("similar to --all-progress when progress meter is shown")),
 		{ OPTION_CALLBACK, 0, "index-version", NULL, N_("<version>[,<offset>]"),
 		  N_("write the pack index file in the specified idx format version"),
-		  0, option_parse_index_version },
+		  PARSE_OPT_NONEG, option_parse_index_version },
 		OPT_MAGNITUDE(0, "max-pack-size", &pack_size_limit,
 			      N_("maximum size of each output pack file")),
 		OPT_BOOL(0, "local", &local,
@@ -3402,10 +3393,8 @@
 	if (!delta_search_threads)	/* --threads=0 means autodetect */
 		delta_search_threads = online_cpus();
 
-#ifdef NO_PTHREADS
-	if (delta_search_threads != 1)
+	if (!HAVE_THREADS && delta_search_threads != 1)
 		warning(_("no threads support, ignoring --threads"));
-#endif
 	if (!pack_to_stdout && !pack_size_limit)
 		pack_size_limit = pack_size_limit_cfg;
 	if (pack_to_stdout && pack_size_limit)
@@ -3481,7 +3470,7 @@
 		}
 	}
 
-	prepare_packing_data(&to_pack);
+	prepare_packing_data(the_repository, &to_pack);
 
 	if (progress)
 		progress_state = start_progress(_("Enumerating objects"), 0);
diff --git a/builtin/pull.c b/builtin/pull.c
index c21aa27..74808b9 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -557,6 +557,17 @@
 static int pull_into_void(const struct object_id *merge_head,
 		const struct object_id *curr_head)
 {
+	if (opt_verify_signatures) {
+		struct commit *commit;
+
+		commit = lookup_commit(the_repository, merge_head);
+		if (!commit)
+			die(_("unable to access commit %s"),
+			    oid_to_hex(merge_head));
+
+		verify_merge_signature(commit, opt_verbosity);
+	}
+
 	/*
 	 * Two-way merge: we treat the index as based on an empty tree,
 	 * and try to fast-forward to HEAD. This ensures we will not lose
@@ -888,7 +899,8 @@
 			die(_("Updating an unborn branch with changes added to the index."));
 
 		if (!autostash)
-			require_clean_work_tree(N_("pull with rebase"),
+			require_clean_work_tree(the_repository,
+				N_("pull with rebase"),
 				_("please commit or stash them."), 1, 0);
 
 		if (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))
diff --git a/builtin/push.c b/builtin/push.c
index d09a420..ee1e842 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -173,10 +173,10 @@
 	      "\n"
 	      "To push to the branch of the same name on the remote, use\n"
 	      "\n"
-	      "    git push %s %s\n"
+	      "    git push %s HEAD\n"
 	      "%s"),
 	    remote->name, short_upstream,
-	    remote->name, branch->name, advice_maybe);
+	    remote->name, advice_maybe);
 }
 
 static const char message_detached_head_die[] =
@@ -355,7 +355,8 @@
 
 	if (verbosity > 0)
 		fprintf(stderr, _("Pushing to %s\n"), transport->url);
-	err = transport_push(transport, rs, flags, &reject_reasons);
+	err = transport_push(the_repository, transport,
+			     rs, flags, &reject_reasons);
 	if (err != 0) {
 		fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
 		error(_("failed to push some refs to '%s'"), transport->url);
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index fbbc98e..ac255ad 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -44,6 +44,7 @@
 static int index_output_cb(const struct option *opt, const char *arg,
 				 int unset)
 {
+	BUG_ON_OPT_NEG(unset);
 	set_alternate_index_output(arg);
 	return 0;
 }
@@ -54,6 +55,8 @@
 	struct dir_struct *dir;
 	struct unpack_trees_options *opts;
 
+	BUG_ON_OPT_NEG(unset);
+
 	opts = (struct unpack_trees_options *)opt->value;
 
 	if (opts->dir)
@@ -255,7 +258,9 @@
 	 * what came from the tree.
 	 */
 	if (nr_trees == 1 && !opts.prefix)
-		prime_cache_tree(&the_index, trees[0]);
+		prime_cache_tree(the_repository,
+				 the_repository->index,
+				 trees[0]);
 
 	if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
 		die("unable to write new index file");
diff --git a/builtin/rebase--interactive.c b/builtin/rebase--interactive.c
index a2ab68e..dd2a55a 100644
--- a/builtin/rebase--interactive.c
+++ b/builtin/rebase--interactive.c
@@ -105,7 +105,7 @@
 	if (restrict_revision)
 		argv_array_push(&make_script_args, restrict_revision);
 
-	ret = sequencer_make_script(todo_list,
+	ret = sequencer_make_script(the_repository, todo_list,
 				    make_script_args.argc, make_script_args.argv,
 				    flags);
 	fclose(todo_list);
@@ -114,7 +114,8 @@
 		error(_("could not generate todo list"));
 	else {
 		discard_cache();
-		ret = complete_action(opts, flags, shortrevisions, onto_name, onto,
+		ret = complete_action(the_repository, opts, flags,
+				      shortrevisions, onto_name, onto,
 				      head_hash, cmd, autosquash);
 	}
 
@@ -232,14 +233,14 @@
 	case SKIP: {
 		struct string_list merge_rr = STRING_LIST_INIT_DUP;
 
-		rerere_clear(&merge_rr);
+		rerere_clear(the_repository, &merge_rr);
 		/* fallthrough */
 	case CONTINUE:
-		ret = sequencer_continue(&opts);
+		ret = sequencer_continue(the_repository, &opts);
 		break;
 	}
 	case EDIT_TODO:
-		ret = edit_todo_list(flags);
+		ret = edit_todo_list(the_repository, flags);
 		break;
 	case SHOW_CURRENT_PATCH: {
 		struct child_process cmd = CHILD_PROCESS_INIT;
@@ -252,16 +253,16 @@
 	}
 	case SHORTEN_OIDS:
 	case EXPAND_OIDS:
-		ret = transform_todos(flags);
+		ret = transform_todos(the_repository, flags);
 		break;
 	case CHECK_TODO_LIST:
-		ret = check_todo_list();
+		ret = check_todo_list(the_repository);
 		break;
 	case REARRANGE_SQUASH:
-		ret = rearrange_squash();
+		ret = rearrange_squash(the_repository);
 		break;
 	case ADD_EXEC:
-		ret = sequencer_add_exec_commands(cmd);
+		ret = sequencer_add_exec_commands(the_repository, cmd);
 		break;
 	default:
 		BUG("invalid command '%d'", command);
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 0ee06aa..00de703 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -23,6 +23,7 @@
 #include "revision.h"
 #include "commit-reach.h"
 #include "rerere.h"
+#include "branch.h"
 
 static char const * const builtin_rebase_usage[] = {
 	N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
@@ -48,7 +49,10 @@
 {
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf out = STRBUF_INIT;
-	int ret;
+	int ret, env = git_env_bool("GIT_TEST_REBASE_USE_BUILTIN", -1);
+
+	if (env != -1)
+		return env;
 
 	argv_array_pushl(&cp.args,
 			 "config", "--bool", "rebase.usebuiltin", NULL);
@@ -87,7 +91,7 @@
 		REBASE_FORCE = 1<<3,
 		REBASE_INTERACTIVE_EXPLICIT = 1<<4,
 	} flags;
-	struct strbuf git_am_opt;
+	struct argv_array git_am_opts;
 	const char *action;
 	int signoff;
 	int allow_rerere_autoupdate;
@@ -339,7 +343,7 @@
 static int run_specific_rebase(struct rebase_options *opts)
 {
 	const char *argv[] = { NULL, NULL };
-	struct strbuf script_snippet = STRBUF_INIT;
+	struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;
 	int status;
 	const char *backend, *backend_func;
 
@@ -433,7 +437,9 @@
 		oid_to_hex(&opts->restrict_revision->object.oid) : NULL);
 	add_var(&script_snippet, "GIT_QUIET",
 		opts->flags & REBASE_NO_QUIET ? "" : "t");
-	add_var(&script_snippet, "git_am_opt", opts->git_am_opt.buf);
+	sq_quote_argv_pretty(&buf, opts->git_am_opts.argv);
+	add_var(&script_snippet, "git_am_opt", buf.buf);
+	strbuf_release(&buf);
 	add_var(&script_snippet, "verbose",
 		opts->flags & REBASE_VERBOSE ? "t" : "");
 	add_var(&script_snippet, "diffstat",
@@ -522,12 +528,17 @@
 
 #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
 
+#define RESET_HEAD_DETACH (1<<0)
+#define RESET_HEAD_HARD (1<<1)
+
 static int reset_head(struct object_id *oid, const char *action,
-		      const char *switch_to_branch, int detach_head,
+		      const char *switch_to_branch, unsigned flags,
 		      const char *reflog_orig_head, const char *reflog_head)
 {
+	unsigned detach_head = flags & RESET_HEAD_DETACH;
+	unsigned reset_hard = flags & RESET_HEAD_HARD;
 	struct object_id head_oid;
-	struct tree_desc desc;
+	struct tree_desc desc[2] = { { NULL }, { NULL } };
 	struct lock_file lock = LOCK_INIT;
 	struct unpack_trees_options unpack_tree_opts;
 	struct tree *tree;
@@ -536,60 +547,63 @@
 	size_t prefix_len;
 	struct object_id *orig = NULL, oid_orig,
 		*old_orig = NULL, oid_old_orig;
-	int ret = 0;
+	int ret = 0, nr = 0;
 
 	if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
 		BUG("Not a fully qualified branch: '%s'", switch_to_branch);
 
-	if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0)
-		return -1;
-
-	if (!oid) {
-		if (get_oid("HEAD", &head_oid)) {
-			rollback_lock_file(&lock);
-			return error(_("could not determine HEAD revision"));
-		}
-		oid = &head_oid;
+	if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) {
+		ret = -1;
+		goto leave_reset_head;
 	}
 
+	if ((!oid || !reset_hard) && get_oid("HEAD", &head_oid)) {
+		ret = error(_("could not determine HEAD revision"));
+		goto leave_reset_head;
+	}
+
+	if (!oid)
+		oid = &head_oid;
+
 	memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
 	setup_unpack_trees_porcelain(&unpack_tree_opts, action);
 	unpack_tree_opts.head_idx = 1;
 	unpack_tree_opts.src_index = the_repository->index;
 	unpack_tree_opts.dst_index = the_repository->index;
-	unpack_tree_opts.fn = oneway_merge;
+	unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
 	unpack_tree_opts.update = 1;
 	unpack_tree_opts.merge = 1;
 	if (!detach_head)
 		unpack_tree_opts.reset = 1;
 
 	if (read_index_unmerged(the_repository->index) < 0) {
-		rollback_lock_file(&lock);
-		return error(_("could not read index"));
+		ret = error(_("could not read index"));
+		goto leave_reset_head;
 	}
 
-	if (!fill_tree_descriptor(&desc, oid)) {
-		error(_("failed to find tree of %s"), oid_to_hex(oid));
-		rollback_lock_file(&lock);
-		free((void *)desc.buffer);
-		return -1;
+	if (!reset_hard && !fill_tree_descriptor(&desc[nr++], &head_oid)) {
+		ret = error(_("failed to find tree of %s"),
+			    oid_to_hex(&head_oid));
+		goto leave_reset_head;
 	}
 
-	if (unpack_trees(1, &desc, &unpack_tree_opts)) {
-		rollback_lock_file(&lock);
-		free((void *)desc.buffer);
-		return -1;
+	if (!fill_tree_descriptor(&desc[nr++], oid)) {
+		ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
+		goto leave_reset_head;
+	}
+
+	if (unpack_trees(nr, desc, &unpack_tree_opts)) {
+		ret = -1;
+		goto leave_reset_head;
 	}
 
 	tree = parse_tree_indirect(oid);
-	prime_cache_tree(the_repository->index, tree);
+	prime_cache_tree(the_repository, the_repository->index, tree);
 
-	if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0)
+	if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0) {
 		ret = error(_("could not write index"));
-	free((void *)desc.buffer);
-
-	if (ret)
-		return ret;
+		goto leave_reset_head;
+	}
 
 	reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
 	strbuf_addf(&msg, "%s: ", reflog_action ? reflog_action : "rebase");
@@ -613,7 +627,8 @@
 		reflog_head = msg.buf;
 	}
 	if (!switch_to_branch)
-		ret = update_ref(reflog_head, "HEAD", oid, orig, REF_NO_DEREF,
+		ret = update_ref(reflog_head, "HEAD", oid, orig,
+				 detach_head ? REF_NO_DEREF : 0,
 				 UPDATE_REFS_MSG_ON_ERR);
 	else {
 		ret = create_symref("HEAD", switch_to_branch, msg.buf);
@@ -622,7 +637,11 @@
 					 UPDATE_REFS_MSG_ON_ERR);
 	}
 
+leave_reset_head:
 	strbuf_release(&msg);
+	rollback_lock_file(&lock);
+	while (nr)
+		free((void *)desc[--nr].buffer);
 	return ret;
 }
 
@@ -703,6 +722,9 @@
 {
 	struct rebase_options *opts = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
+
 	if (!is_interactive(opts))
 		opts->type = REBASE_MERGE;
 
@@ -715,6 +737,9 @@
 {
 	struct rebase_options *opts = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
+
 	opts->type = REBASE_INTERACTIVE;
 	opts->flags |= REBASE_INTERACTIVE_EXPLICIT;
 
@@ -751,12 +776,29 @@
 	exit(1);
 }
 
+static void set_reflog_action(struct rebase_options *options)
+{
+	const char *env;
+	struct strbuf buf = STRBUF_INIT;
+
+	if (!is_interactive(options))
+		return;
+
+	env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
+	if (env && strcmp("rebase", env))
+		return; /* only override it if it is "rebase" */
+
+	strbuf_addf(&buf, "rebase -i (%s)", options->action);
+	setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);
+	strbuf_release(&buf);
+}
+
 int cmd_rebase(int argc, const char **argv, const char *prefix)
 {
 	struct rebase_options options = {
 		.type = REBASE_UNSPECIFIED,
 		.flags = REBASE_NO_QUIET,
-		.git_am_opt = STRBUF_INIT,
+		.git_am_opts = ARGV_ARRAY_INIT,
 		.allow_rerere_autoupdate  = -1,
 		.allow_empty_message = 1,
 		.git_format_patch_opt = STRBUF_INIT,
@@ -777,12 +819,7 @@
 		ACTION_EDIT_TODO,
 		ACTION_SHOW_CURRENT_PATCH,
 	} action = NO_ACTION;
-	int committer_date_is_author_date = 0;
-	int ignore_date = 0;
-	int ignore_whitespace = 0;
 	const char *gpg_sign = NULL;
-	int opt_c = -1;
-	struct string_list whitespace = STRING_LIST_INIT_NODUP;
 	struct string_list exec = STRING_LIST_INIT_NODUP;
 	const char *rebase_merges = NULL;
 	int fork_point = -1;
@@ -804,15 +841,20 @@
 		{OPTION_NEGBIT, 'n', "no-stat", &options.flags, NULL,
 			N_("do not show diffstat of what changed upstream"),
 			PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },
-		OPT_BOOL(0, "ignore-whitespace", &ignore_whitespace,
-			 N_("passed to 'git apply'")),
 		OPT_BOOL(0, "signoff", &options.signoff,
 			 N_("add a Signed-off-by: line to each commit")),
-		OPT_BOOL(0, "committer-date-is-author-date",
-			 &committer_date_is_author_date,
-			 N_("passed to 'git am'")),
-		OPT_BOOL(0, "ignore-date", &ignore_date,
-			 N_("passed to 'git am'")),
+		OPT_PASSTHRU_ARGV(0, "ignore-whitespace", &options.git_am_opts,
+				  NULL, N_("passed to 'git am'"),
+				  PARSE_OPT_NOARG),
+		OPT_PASSTHRU_ARGV(0, "committer-date-is-author-date",
+				  &options.git_am_opts, NULL,
+				  N_("passed to 'git am'"), PARSE_OPT_NOARG),
+		OPT_PASSTHRU_ARGV(0, "ignore-date", &options.git_am_opts, NULL,
+				  N_("passed to 'git am'"), PARSE_OPT_NOARG),
+		OPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_("n"),
+				  N_("passed to 'git apply'"), 0),
+		OPT_PASSTHRU_ARGV(0, "whitespace", &options.git_am_opts,
+				  N_("action"), N_("passed to 'git apply'"), 0),
 		OPT_BIT('f', "force-rebase", &options.flags,
 			N_("cherry-pick all commits, even if unchanged"),
 			REBASE_FORCE),
@@ -846,7 +888,7 @@
 			       "them"), REBASE_PRESERVE_MERGES),
 		OPT_BOOL(0, "rerere-autoupdate",
 			 &options.allow_rerere_autoupdate,
-			 N_("allow rerere to update index  with resolved "
+			 N_("allow rerere to update index with resolved "
 			    "conflict")),
 		OPT_BOOL('k', "keep-empty", &options.keep_empty,
 			 N_("preserve empty commits during rebase")),
@@ -856,10 +898,6 @@
 		{ OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
 			N_("GPG-sign commits"),
 			PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
-		OPT_STRING_LIST(0, "whitespace", &whitespace,
-				N_("whitespace"), N_("passed to 'git apply'")),
-		OPT_SET_INT('C', NULL, &opt_c, N_("passed to 'git apply'"),
-			    REBASE_AM),
 		OPT_BOOL(0, "autostash", &options.autostash,
 			 N_("automatically stash/stash pop before and after")),
 		OPT_STRING_LIST('x', "exec", &exec, N_("exec"),
@@ -884,6 +922,7 @@
 			 N_("rebase all reachable commits up to the root(s)")),
 		OPT_END(),
 	};
+	int i;
 
 	/*
 	 * NEEDSWORK: Once the builtin rebase has been tested enough
@@ -956,6 +995,7 @@
 
 	if (action != NO_ACTION && !in_progress)
 		die(_("No rebase in progress?"));
+	setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
 
 	if (action == ACTION_EDIT_TODO && !is_interactive(&options))
 		die(_("The --edit-todo action can only be used during "
@@ -968,6 +1008,7 @@
 		int fd;
 
 		options.action = "continue";
+		set_reflog_action(&options);
 
 		/* Sanity check */
 		if (get_oid("HEAD", &head))
@@ -983,7 +1024,7 @@
 					     &lock_file);
 		rollback_lock_file(&lock_file);
 
-		if (has_unstaged_changes(1)) {
+		if (has_unstaged_changes(the_repository, 1)) {
 			puts(_("You must edit all merge conflicts and then\n"
 			       "mark them as resolved using git add"));
 			exit(1);
@@ -996,12 +1037,15 @@
 		struct string_list merge_rr = STRING_LIST_INIT_DUP;
 
 		options.action = "skip";
+		set_reflog_action(&options);
 
-		rerere_clear(&merge_rr);
+		rerere_clear(the_repository, &merge_rr);
 		string_list_clear(&merge_rr, 1);
 
-		if (reset_head(NULL, "reset", NULL, 0, NULL, NULL) < 0)
+		if (reset_head(NULL, "reset", NULL, RESET_HEAD_HARD,
+			       NULL, NULL) < 0)
 			die(_("could not discard worktree changes"));
+		remove_branch_state(the_repository);
 		if (read_basic_state(&options))
 			exit(1);
 		goto run_rebase;
@@ -1009,16 +1053,19 @@
 	case ACTION_ABORT: {
 		struct string_list merge_rr = STRING_LIST_INIT_DUP;
 		options.action = "abort";
+		set_reflog_action(&options);
 
-		rerere_clear(&merge_rr);
+		rerere_clear(the_repository, &merge_rr);
 		string_list_clear(&merge_rr, 1);
 
 		if (read_basic_state(&options))
 			exit(1);
 		if (reset_head(&options.orig_head, "reset",
-			       options.head_name, 0, NULL, NULL) < 0)
+			       options.head_name, RESET_HEAD_HARD,
+			       NULL, NULL) < 0)
 			die(_("could not move back to %s"),
 			    oid_to_hex(&options.orig_head));
+		remove_branch_state(the_repository);
 		ret = finish_rebase(&options);
 		goto cleanup;
 	}
@@ -1064,22 +1111,27 @@
 		    state_dir_base, cmd_live_rebase, buf.buf);
 	}
 
+	for (i = 0; i < options.git_am_opts.argc; i++) {
+		const char *option = options.git_am_opts.argv[i], *p;
+		if (!strcmp(option, "--committer-date-is-author-date") ||
+		    !strcmp(option, "--ignore-date") ||
+		    !strcmp(option, "--whitespace=fix") ||
+		    !strcmp(option, "--whitespace=strip"))
+			options.flags |= REBASE_FORCE;
+		else if (skip_prefix(option, "-C", &p)) {
+			while (*p)
+				if (!isdigit(*(p++)))
+					die(_("switch `C' expects a "
+					      "numerical value"));
+		} else if (skip_prefix(option, "--whitespace=", &p)) {
+			if (*p && strcmp(p, "warn") && strcmp(p, "nowarn") &&
+			    strcmp(p, "error") && strcmp(p, "error-all"))
+				die("Invalid whitespace option: '%s'", p);
+		}
+	}
+
 	if (!(options.flags & REBASE_NO_QUIET))
-		strbuf_addstr(&options.git_am_opt, " -q");
-
-	if (committer_date_is_author_date) {
-		strbuf_addstr(&options.git_am_opt,
-			      " --committer-date-is-author-date");
-		options.flags |= REBASE_FORCE;
-	}
-
-	if (ignore_whitespace)
-		strbuf_addstr(&options.git_am_opt, " --ignore-whitespace");
-
-	if (ignore_date) {
-		strbuf_addstr(&options.git_am_opt, " --ignore-date");
-		options.flags |= REBASE_FORCE;
-	}
+		argv_array_push(&options.git_am_opts, "-q");
 
 	if (options.keep_empty)
 		imply_interactive(&options, "--keep-empty");
@@ -1089,23 +1141,6 @@
 		options.gpg_sign_opt = xstrfmt("-S%s", gpg_sign);
 	}
 
-	if (opt_c >= 0)
-		strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
-
-	if (whitespace.nr) {
-		int i;
-
-		for (i = 0; i < whitespace.nr; i++) {
-			const char *item = whitespace.items[i].string;
-
-			strbuf_addf(&options.git_am_opt, " --whitespace=%s",
-				    item);
-
-			if ((!strcmp(item, "fix")) || (!strcmp(item, "strip")))
-				options.flags |= REBASE_FORCE;
-		}
-	}
-
 	if (exec.nr) {
 		int i;
 
@@ -1181,23 +1216,18 @@
 		break;
 	}
 
-	if (options.git_am_opt.len) {
-		const char *p;
-
+	if (options.git_am_opts.argc) {
 		/* all am options except -q are compatible only with --am */
-		strbuf_reset(&buf);
-		strbuf_addbuf(&buf, &options.git_am_opt);
-		strbuf_addch(&buf, ' ');
-		while ((p = strstr(buf.buf, " -q ")))
-			strbuf_splice(&buf, p - buf.buf, 4, " ", 1);
-		strbuf_trim(&buf);
+		for (i = options.git_am_opts.argc - 1; i >= 0; i--)
+			if (strcmp(options.git_am_opts.argv[i], "-q"))
+				break;
 
-		if (is_interactive(&options) && buf.len)
+		if (is_interactive(&options) && i >= 0)
 			die(_("error: cannot combine interactive options "
 			      "(--interactive, --exec, --rebase-merges, "
 			      "--preserve-merges, --keep-empty, --root + "
 			      "--onto) with am options (%s)"), buf.buf);
-		if (options.type == REBASE_MERGE && buf.len)
+		if (options.type == REBASE_MERGE && i >= 0)
 			die(_("error: cannot combine merge options (--merge, "
 			      "--strategy, --strategy-option) with am options "
 			      "(%s)"), buf.buf);
@@ -1207,7 +1237,7 @@
 		if (options.type == REBASE_PRESERVE_MERGES)
 			die("cannot combine '--signoff' with "
 			    "'--preserve-merges'");
-		strbuf_addstr(&options.git_am_opt, " --signoff");
+		argv_array_push(&options.git_am_opts, "--signoff");
 		options.flags |= REBASE_FORCE;
 	}
 
@@ -1351,7 +1381,8 @@
 			update_index_if_able(&the_index, &lock_file);
 		rollback_lock_file(&lock_file);
 
-		if (has_unstaged_changes(1) || has_uncommitted_changes(1)) {
+		if (has_unstaged_changes(the_repository, 1) ||
+		    has_uncommitted_changes(the_repository, 1)) {
 			const char *autostash =
 				state_dir_path("autostash", &options);
 			struct child_process stash = CHILD_PROCESS_INIT;
@@ -1380,7 +1411,7 @@
 			write_file(autostash, "%s", oid_to_hex(&oid));
 			printf(_("Created autostash: %s\n"), buf.buf);
 			if (reset_head(&head->object.oid, "reset --hard",
-				       NULL, 0, NULL, NULL) < 0)
+				       NULL, RESET_HEAD_HARD, NULL, NULL) < 0)
 				die(_("could not reset --hard"));
 			printf(_("HEAD is now at %s"),
 			       find_unique_abbrev(&head->object.oid,
@@ -1397,7 +1428,7 @@
 		}
 	}
 
-	if (require_clean_work_tree("rebase",
+	if (require_clean_work_tree(the_repository, "rebase",
 				    _("Please commit or stash them."), 1, 1)) {
 		ret = 1;
 		goto cleanup;
@@ -1431,11 +1462,12 @@
 				}
 
 				strbuf_reset(&buf);
-				strbuf_addf(&buf, "rebase: checkout %s",
+				strbuf_addf(&buf, "%s: checkout %s",
+					    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
 					    options.switch_to);
 				if (reset_head(&oid, "checkout",
 					       options.head_name, 0,
-					       NULL, NULL) < 0) {
+					       NULL, buf.buf) < 0) {
 					ret = !!error(_("could not switch to "
 							"%s"),
 						      options.switch_to);
@@ -1472,10 +1504,15 @@
 	if (options.flags & REBASE_DIFFSTAT) {
 		struct diff_options opts;
 
-		if (options.flags & REBASE_VERBOSE)
-			printf(_("Changes from %s to %s:\n"),
-				oid_to_hex(&merge_base),
-				oid_to_hex(&options.onto->object.oid));
+		if (options.flags & REBASE_VERBOSE) {
+			if (is_null_oid(&merge_base))
+				printf(_("Changes to %s:\n"),
+				       oid_to_hex(&options.onto->object.oid));
+			else
+				printf(_("Changes from %s to %s:\n"),
+				       oid_to_hex(&merge_base),
+				       oid_to_hex(&options.onto->object.oid));
+		}
 
 		/* We want color (if set), but no pager */
 		diff_setup(&opts);
@@ -1485,8 +1522,9 @@
 			DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
 		opts.detect_rename = DIFF_DETECT_RENAME;
 		diff_setup_done(&opts);
-		diff_tree_oid(&merge_base, &options.onto->object.oid,
-			      "", &opts);
+		diff_tree_oid(is_null_oid(&merge_base) ?
+			      the_hash_algo->empty_tree : &merge_base,
+			      &options.onto->object.oid, "", &opts);
 		diffcore_std(&opts);
 		diff_flush(&opts);
 	}
@@ -1499,9 +1537,10 @@
 		printf(_("First, rewinding head to replay your work on top of "
 			 "it...\n"));
 
-	strbuf_addf(&msg, "rebase: checkout %s", options.onto_name);
-	if (reset_head(&options.onto->object.oid, "checkout", NULL, 1,
-	    NULL, msg.buf))
+	strbuf_addf(&msg, "%s: checkout %s",
+		    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
+	if (reset_head(&options.onto->object.oid, "checkout", NULL,
+		       RESET_HEAD_DETACH, NULL, msg.buf))
 		die(_("Could not detach HEAD"));
 	strbuf_release(&msg);
 
@@ -1511,7 +1550,7 @@
 	 */
 	strbuf_reset(&msg);
 	if (!oidcmp(&merge_base, &options.orig_head)) {
-		printf(_("Fast-forwarded %s to %s. \n"),
+		printf(_("Fast-forwarded %s to %s.\n"),
 			branch_name, options.onto_name);
 		strbuf_addf(&msg, "rebase finished: %s onto %s",
 			options.head_name ? options.head_name : "detached HEAD",
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 7a85e4b..64a8df4 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -14,11 +14,15 @@
 
 /* NEEDSWORK: switch to using parse_options */
 static const char reflog_expire_usage[] =
-"git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] <refs>...";
+N_("git reflog expire [--expire=<time>] "
+   "[--expire-unreachable=<time>] "
+   "[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
+   "[--verbose] [--all] <refs>...");
 static const char reflog_delete_usage[] =
-"git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] <refs>...";
+N_("git reflog delete [--rewrite] [--updateref] "
+   "[--dry-run | -n] [--verbose] <refs>...");
 static const char reflog_exists_usage[] =
-"git reflog exists <ref>";
+N_("git reflog exists <ref>");
 
 static timestamp_t default_reflog_expire;
 static timestamp_t default_reflog_expire_unreachable;
@@ -585,7 +589,7 @@
 			break;
 		}
 		else if (arg[0] == '-')
-			usage(reflog_expire_usage);
+			usage(_(reflog_expire_usage));
 		else
 			break;
 	}
@@ -598,7 +602,7 @@
 	if (cb.cmd.stalefix) {
 		repo_init_revisions(the_repository, &cb.cmd.revs, prefix);
 		if (flags & EXPIRE_REFLOGS_VERBOSE)
-			printf("Marking reachable objects...");
+			printf(_("Marking reachable objects..."));
 		mark_reachable_objects(&cb.cmd.revs, 0, 0, NULL);
 		if (flags & EXPIRE_REFLOGS_VERBOSE)
 			putchar('\n');
@@ -636,7 +640,7 @@
 		char *ref;
 		struct object_id oid;
 		if (!dwim_log(argv[i], strlen(argv[i]), &oid, &ref)) {
-			status |= error("%s points nowhere!", argv[i]);
+			status |= error(_("%s points nowhere!"), argv[i]);
 			continue;
 		}
 		set_reflog_expiry_param(&cb.cmd, explicit_expiry, ref);
@@ -682,13 +686,13 @@
 			break;
 		}
 		else if (arg[0] == '-')
-			usage(reflog_delete_usage);
+			usage(_(reflog_delete_usage));
 		else
 			break;
 	}
 
 	if (argc - i < 1)
-		return error("Nothing to delete?");
+		return error(_("no reflog specified to delete"));
 
 	for ( ; i < argc; i++) {
 		const char *spec = strstr(argv[i], "@{");
@@ -697,12 +701,12 @@
 		int recno;
 
 		if (!spec) {
-			status |= error("Not a reflog: %s", argv[i]);
+			status |= error(_("not a reflog: %s"), argv[i]);
 			continue;
 		}
 
 		if (!dwim_log(argv[i], spec - argv[i], &oid, &ref)) {
-			status |= error("no reflog for '%s'", argv[i]);
+			status |= error(_("no reflog for '%s'"), argv[i]);
 			continue;
 		}
 
@@ -737,7 +741,7 @@
 			break;
 		}
 		else if (arg[0] == '-')
-			usage(reflog_exists_usage);
+			usage(_(reflog_exists_usage));
 		else
 			break;
 	}
@@ -745,10 +749,10 @@
 	start = i;
 
 	if (argc - start != 1)
-		usage(reflog_exists_usage);
+		usage(_(reflog_exists_usage));
 
 	if (check_refname_format(argv[start], REFNAME_ALLOW_ONELEVEL))
-		die("invalid ref format: %s", argv[start]);
+		die(_("invalid ref format: %s"), argv[start]);
 	return !reflog_exists(argv[start]);
 }
 
@@ -757,12 +761,12 @@
  */
 
 static const char reflog_usage[] =
-"git reflog [ show | expire | delete | exists ]";
+N_("git reflog [ show | expire | delete | exists ]");
 
 int cmd_reflog(int argc, const char **argv, const char *prefix)
 {
 	if (argc > 1 && !strcmp(argv[1], "-h"))
-		usage(reflog_usage);
+		usage(_(reflog_usage));
 
 	/* With no command, we default to showing it. */
 	if (argc < 2 || *argv[1] == '-')
diff --git a/builtin/repack.c b/builtin/repack.c
index 4558368..2a1c7b2 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -197,7 +197,7 @@
 
 	if (cmd->in == -1) {
 		if (start_command(cmd))
-			die("Could not start pack-objects to repack promisor objects");
+			die(_("could not start pack-objects to repack promisor objects"));
 	}
 
 	xwrite(cmd->in, oid_to_hex(oid), GIT_SHA1_HEXSZ);
@@ -236,7 +236,7 @@
 		char *promisor_name;
 		int fd;
 		if (line.len != the_hash_algo->hexsz)
-			die("repack: Expecting full hex object ID lines only from pack-objects.");
+			die(_("repack: Expecting full hex object ID lines only from pack-objects."));
 		string_list_append(names, line.buf);
 
 		/*
@@ -247,13 +247,13 @@
 					  line.buf);
 		fd = open(promisor_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
 		if (fd < 0)
-			die_errno("unable to create '%s'", promisor_name);
+			die_errno(_("unable to create '%s'"), promisor_name);
 		close(fd);
 		free(promisor_name);
 	}
 	fclose(out);
 	if (finish_command(&cmd))
-		die("Could not finish pack-objects to repack promisor objects");
+		die(_("could not finish pack-objects to repack promisor objects"));
 }
 
 #define ALL_INTO_ONE 1
@@ -408,7 +408,7 @@
 	out = xfdopen(cmd.out, "r");
 	while (strbuf_getline_lf(&line, out) != EOF) {
 		if (line.len != the_hash_algo->hexsz)
-			die("repack: Expecting full hex object ID lines only from pack-objects.");
+			die(_("repack: Expecting full hex object ID lines only from pack-objects."));
 		string_list_append(&names, line.buf);
 	}
 	fclose(out);
@@ -417,7 +417,7 @@
 		return ret;
 
 	if (!names.nr && !po_args.quiet)
-		printf("Nothing new to pack.\n");
+		printf_ln(_("Nothing new to pack."));
 
 	/*
 	 * Ok we have prepared all new packfiles.
@@ -476,13 +476,13 @@
 		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);
+				_("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,
diff --git a/builtin/replace.c b/builtin/replace.c
index a58b9c6..affcdfb 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -495,6 +495,7 @@
 	if (!fp)
 		return -1;
 
+	advice_graft_file_deprecated = 0;
 	while (strbuf_getline(&buf, fp) != EOF) {
 		if (*buf.buf == '#')
 			continue;
diff --git a/builtin/rerere.c b/builtin/rerere.c
index d78eeae..fd3be17 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -83,11 +83,12 @@
 	}
 
 	if (!strcmp(argv[0], "clear")) {
-		rerere_clear(&merge_rr);
+		rerere_clear(the_repository, &merge_rr);
 	} else if (!strcmp(argv[0], "gc"))
-		rerere_gc(&merge_rr);
+		rerere_gc(the_repository, &merge_rr);
 	else if (!strcmp(argv[0], "status")) {
-		if (setup_rerere(&merge_rr, flags | RERERE_READONLY) < 0)
+		if (setup_rerere(the_repository, &merge_rr,
+				 flags | RERERE_READONLY) < 0)
 			return 0;
 		for (i = 0; i < merge_rr.nr; i++)
 			printf("%s\n", merge_rr.items[i].string);
@@ -102,7 +103,8 @@
 				merge_rr.items[i].util = NULL;
 		}
 	} else if (!strcmp(argv[0], "diff")) {
-		if (setup_rerere(&merge_rr, flags | RERERE_READONLY) < 0)
+		if (setup_rerere(the_repository, &merge_rr,
+				 flags | RERERE_READONLY) < 0)
 			return 0;
 		for (i = 0; i < merge_rr.nr; i++) {
 			const char *path = merge_rr.items[i].string;
diff --git a/builtin/reset.c b/builtin/reset.c
index 5816696..59898c9 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -95,7 +95,7 @@
 
 	if (reset_type == MIXED || reset_type == HARD) {
 		tree = parse_tree_indirect(oid);
-		prime_cache_tree(&the_index, tree);
+		prime_cache_tree(the_repository, the_repository->index, tree);
 	}
 
 	ret = 0;
@@ -413,7 +413,7 @@
 			print_new_head_line(lookup_commit_reference(the_repository, &oid));
 	}
 	if (!pathspec.nr)
-		remove_branch_state();
+		remove_branch_state(the_repository);
 
 	return update_ref_status;
 }
diff --git a/builtin/revert.c b/builtin/revert.c
index c93393c..a47b53c 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -69,7 +69,8 @@
 
 	replay->mainline = strtol(arg, &end, 10);
 	if (*end || replay->mainline <= 0)
-		return opterror(opt, "expects a number greater than zero", 0);
+		return error(_("option `%s' expects a number greater than zero"),
+			     opt->long_name);
 
 	return 0;
 }
@@ -195,14 +196,14 @@
 	if (cmd == 'q') {
 		int ret = sequencer_remove_state(opts);
 		if (!ret)
-			remove_branch_state();
+			remove_branch_state(the_repository);
 		return ret;
 	}
 	if (cmd == 'c')
-		return sequencer_continue(opts);
+		return sequencer_continue(the_repository, opts);
 	if (cmd == 'a')
-		return sequencer_rollback(opts);
-	return sequencer_pick_revisions(opts);
+		return sequencer_rollback(the_repository, opts);
+	return sequencer_pick_revisions(the_repository, opts);
 }
 
 int cmd_revert(int argc, const char **argv, const char *prefix)
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 88f88e9..65cd413 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -287,6 +287,8 @@
 		case PARSE_OPT_HELP:
 		case PARSE_OPT_ERROR:
 			exit(129);
+		case PARSE_OPT_COMPLETE:
+			exit(0);
 		case PARSE_OPT_DONE:
 			goto parse_done;
 		}
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 65f4a4c..934e514 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -604,6 +604,7 @@
 {
 	char *ep;
 	const char **base = (const char **)opt->value;
+	BUG_ON_OPT_NEG(unset);
 	if (!arg)
 		arg = "";
 	reflog = strtoul(arg, &ep, 10);
@@ -674,7 +675,7 @@
 		{ OPTION_CALLBACK, 'g', "reflog", &reflog_base, N_("<n>[,<base>]"),
 			    N_("show <n> most recent ref-log entries starting at "
 			       "base"),
-			    PARSE_OPT_OPTARG,
+			    PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
 			    parse_reflog_param },
 		OPT_END()
 	};
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 2f13f13..ed888ff 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -151,6 +151,7 @@
 static int exclude_existing_callback(const struct option *opt, const char *arg,
 				     int unset)
 {
+	BUG_ON_OPT_NEG(unset);
 	exclude_arg = 1;
 	*(const char **)opt->value = arg;
 	return 0;
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d38113a..b45514b 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1265,19 +1265,20 @@
 	SUBMODULE_ALTERNATE_ERROR_IGNORE, NULL }
 
 static int add_possible_reference_from_superproject(
-		struct alternate_object_database *alt, void *sas_cb)
+		struct object_directory *odb, void *sas_cb)
 {
 	struct submodule_alternate_setup *sas = sas_cb;
+	size_t len;
 
 	/*
 	 * If the alternate object store is another repository, try the
 	 * standard layout with .git/(modules/<name>)+/objects
 	 */
-	if (ends_with(alt->path, "/objects")) {
+	if (strip_suffix(odb->path, "/objects", &len)) {
 		char *sm_alternate;
 		struct strbuf sb = STRBUF_INIT;
 		struct strbuf err = STRBUF_INIT;
-		strbuf_add(&sb, alt->path, strlen(alt->path) - strlen("objects"));
+		strbuf_add(&sb, odb->path, len);
 
 		/*
 		 * We need to end the new path with '/' to mark it as a dir,
@@ -1285,7 +1286,7 @@
 		 * as the last part of a missing submodule reference would
 		 * be taken as a file name.
 		 */
-		strbuf_addf(&sb, "modules/%s/", sas->submodule_name);
+		strbuf_addf(&sb, "/modules/%s/", sas->submodule_name);
 
 		sm_alternate = compute_alternate_path(sb.buf, &err);
 		if (sm_alternate) {
diff --git a/builtin/tag.c b/builtin/tag.c
index f623632..02f6bd1 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -338,6 +338,8 @@
 {
 	struct msg_arg *msg = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (!arg)
 		return -1;
 	if (msg->buf.len)
@@ -390,8 +392,8 @@
 		OPT_GROUP(N_("Tag creation options")),
 		OPT_BOOL('a', "annotate", &annotate,
 					N_("annotated tag, needs a message")),
-		OPT_CALLBACK('m', "message", &msg, N_("message"),
-			     N_("tag message"), parse_msg_arg),
+		{ OPTION_CALLBACK, 'm', "message", &msg, N_("message"),
+		  N_("tag message"), PARSE_OPT_NONEG, parse_msg_arg },
 		OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
 		OPT_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")),
 		OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 0e1dcf0..e19da77 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -790,12 +790,16 @@
 static int refresh_callback(const struct option *opt,
 				const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	return refresh(opt->value, 0);
 }
 
 static int really_refresh_callback(const struct option *opt,
 				const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	return refresh(opt->value, REFRESH_REALLY);
 }
 
@@ -803,6 +807,7 @@
 				const char *arg, int unset)
 {
 	char *flip = opt->value;
+	BUG_ON_OPT_NEG(unset);
 	if ((arg[0] != '-' && arg[0] != '+') || arg[1] != 'x' || arg[2])
 		return error("option 'chmod' expects \"+x\" or \"-x\"");
 	*flip = arg[0];
@@ -812,6 +817,8 @@
 static int resolve_undo_clear_callback(const struct option *opt,
 				const char *arg, int unset)
 {
+	BUG_ON_OPT_NEG(unset);
+	BUG_ON_OPT_ARG(arg);
 	resolve_undo_clear();
 	return 0;
 }
@@ -847,6 +854,8 @@
 	unsigned int mode;
 	const char *path;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {
 		if (add_cacheinfo(mode, &oid, path, 0))
 			die("git update-index: --cacheinfo cannot add %s", path);
@@ -869,6 +878,8 @@
 {
 	int *nul_term_line = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (ctx->argc != 1)
 		return error("option '%s' must be the last argument", opt->long_name);
 	allow_add = allow_replace = allow_remove = 1;
@@ -881,6 +892,8 @@
 {
 	int *read_from_stdin = opt->value;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (ctx->argc != 1)
 		return error("option '%s' must be the last argument", opt->long_name);
 	*read_from_stdin = 1;
@@ -888,11 +901,13 @@
 }
 
 static int unresolve_callback(struct parse_opt_ctx_t *ctx,
-				const struct option *opt, int flags)
+				const struct option *opt, int unset)
 {
 	int *has_errors = opt->value;
 	const char *prefix = startup_info->prefix;
 
+	BUG_ON_OPT_NEG(unset);
+
 	/* consume remaining arguments. */
 	*has_errors = do_unresolve(ctx->argc, ctx->argv,
 				prefix, prefix ? strlen(prefix) : 0);
@@ -905,11 +920,13 @@
 }
 
 static int reupdate_callback(struct parse_opt_ctx_t *ctx,
-				const struct option *opt, int flags)
+				const struct option *opt, int unset)
 {
 	int *has_errors = opt->value;
 	const char *prefix = startup_info->prefix;
 
+	BUG_ON_OPT_NEG(unset);
+
 	/* consume remaining arguments. */
 	setup_work_tree();
 	*has_errors = do_reupdate(ctx->argc, ctx->argv,
@@ -1069,6 +1086,8 @@
 		case PARSE_OPT_HELP:
 		case PARSE_OPT_ERROR:
 			exit(129);
+		case PARSE_OPT_COMPLETE:
+			exit(0);
 		case PARSE_OPT_NON_OPTION:
 		case PARSE_OPT_DONE:
 		{
diff --git a/bundle.c b/bundle.c
index 1ef584b..37b1daa 100644
--- a/bundle.c
+++ b/bundle.c
@@ -127,7 +127,9 @@
 /* Remember to update object flag allocation in object.h */
 #define PREREQ_MARK (1u<<16)
 
-int verify_bundle(struct bundle_header *header, int verbose)
+int verify_bundle(struct repository *r,
+		  struct bundle_header *header,
+		  int verbose)
 {
 	/*
 	 * Do fast check, then if any prereqs are missing then go line by line
@@ -140,10 +142,10 @@
 	int i, ret = 0, req_nr;
 	const char *message = _("Repository lacks these prerequisite commits:");
 
-	repo_init_revisions(the_repository, &revs, NULL);
+	repo_init_revisions(r, &revs, NULL);
 	for (i = 0; i < p->nr; i++) {
 		struct ref_list_entry *e = p->list + i;
-		struct object *o = parse_object(the_repository, &e->oid);
+		struct object *o = parse_object(r, &e->oid);
 		if (o) {
 			o->flags |= PREREQ_MARK;
 			add_pending_object(&revs, o, e->name);
@@ -168,7 +170,7 @@
 
 	for (i = 0; i < p->nr; i++) {
 		struct ref_list_entry *e = p->list + i;
-		struct object *o = parse_object(the_repository, &e->oid);
+		struct object *o = parse_object(r, &e->oid);
 		assert(o); /* otherwise we'd have returned early */
 		if (o->flags & SHOWN)
 			continue;
@@ -180,7 +182,7 @@
 	/* Clean up objects used, as they will be reused. */
 	for (i = 0; i < p->nr; i++) {
 		struct ref_list_entry *e = p->list + i;
-		commit = lookup_commit_reference_gently(the_repository, &e->oid, 1);
+		commit = lookup_commit_reference_gently(r, &e->oid, 1);
 		if (commit)
 			clear_commit_marks(commit, ALL_REV_FLAGS);
 	}
@@ -243,7 +245,7 @@
 }
 
 
-/* Write the pack data to bundle_fd, then close it if it is > 1. */
+/* Write the pack data to bundle_fd */
 static int write_pack_data(int bundle_fd, struct rev_info *revs)
 {
 	struct child_process pack_objects = CHILD_PROCESS_INIT;
@@ -256,6 +258,20 @@
 	pack_objects.in = -1;
 	pack_objects.out = bundle_fd;
 	pack_objects.git_cmd = 1;
+
+	/*
+	 * start_command() will close our descriptor if it's >1. Duplicate it
+	 * to avoid surprising the caller.
+	 */
+	if (pack_objects.out > 1) {
+		pack_objects.out = dup(pack_objects.out);
+		if (pack_objects.out < 0) {
+			error_errno(_("unable to dup bundle descriptor"));
+			child_process_clear(&pack_objects);
+			return -1;
+		}
+	}
+
 	if (start_command(&pack_objects))
 		return error(_("Could not spawn pack-objects"));
 
@@ -375,8 +391,7 @@
 			 * in terms of a tag (e.g. v2.0 from the range
 			 * "v1.0..v2.0")?
 			 */
-			struct commit *one = lookup_commit_reference(the_repository,
-								     &oid);
+			struct commit *one = lookup_commit_reference(revs->repo, &oid);
 			struct object *obj;
 
 			if (e->item == &(one->object)) {
@@ -409,8 +424,8 @@
 	return ref_count;
 }
 
-int create_bundle(struct bundle_header *header, const char *path,
-		  int argc, const char **argv)
+int create_bundle(struct repository *r, struct bundle_header *header,
+		  const char *path, int argc, const char **argv)
 {
 	struct lock_file lock = LOCK_INIT;
 	int bundle_fd = -1;
@@ -421,27 +436,16 @@
 	bundle_to_stdout = !strcmp(path, "-");
 	if (bundle_to_stdout)
 		bundle_fd = 1;
-	else {
+	else
 		bundle_fd = hold_lock_file_for_update(&lock, path,
 						      LOCK_DIE_ON_ERROR);
 
-		/*
-		 * write_pack_data() will close the fd passed to it,
-		 * but commit_lock_file() will also try to close the
-		 * lockfile's fd. So make a copy of the file
-		 * descriptor to avoid trying to close it twice.
-		 */
-		bundle_fd = dup(bundle_fd);
-		if (bundle_fd < 0)
-			die_errno("unable to dup file descriptor");
-	}
-
 	/* write signature */
 	write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
 
 	/* init revs to list objects for pack-objects later */
 	save_commit_buffer = 0;
-	repo_init_revisions(the_repository, &revs, NULL);
+	repo_init_revisions(r, &revs, NULL);
 
 	/* write prerequisites */
 	if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
@@ -463,10 +467,8 @@
 		goto err;
 
 	/* write pack */
-	if (write_pack_data(bundle_fd, &revs)) {
-		bundle_fd = -1; /* already closed by the above call */
+	if (write_pack_data(bundle_fd, &revs))
 		goto err;
-	}
 
 	if (!bundle_to_stdout) {
 		if (commit_lock_file(&lock))
@@ -474,15 +476,12 @@
 	}
 	return 0;
 err:
-	if (!bundle_to_stdout) {
-		if (0 <= bundle_fd)
-			close(bundle_fd);
-		rollback_lock_file(&lock);
-	}
+	rollback_lock_file(&lock);
 	return -1;
 }
 
-int unbundle(struct bundle_header *header, int bundle_fd, int flags)
+int unbundle(struct repository *r, struct bundle_header *header,
+	     int bundle_fd, int flags)
 {
 	const char *argv_index_pack[] = {"index-pack",
 					 "--fix-thin", "--stdin", NULL, NULL};
@@ -491,7 +490,7 @@
 	if (flags & BUNDLE_VERBOSE)
 		argv_index_pack[3] = "-v";
 
-	if (verify_bundle(header, 0))
+	if (verify_bundle(r, header, 0))
 		return -1;
 	ip.argv = argv_index_pack;
 	ip.in = bundle_fd;
diff --git a/bundle.h b/bundle.h
index e9a4cb6..781e6f5 100644
--- a/bundle.h
+++ b/bundle.h
@@ -18,11 +18,12 @@
 
 int is_bundle(const char *path, int quiet);
 int read_bundle_header(const char *path, struct bundle_header *header);
-int create_bundle(struct bundle_header *header, const char *path,
-		int argc, const char **argv);
-int verify_bundle(struct bundle_header *header, int verbose);
+int create_bundle(struct repository *r, struct bundle_header *header,
+		  const char *path, int argc, const char **argv);
+int verify_bundle(struct repository *r, struct bundle_header *header, int verbose);
 #define BUNDLE_VERBOSE 1
-int unbundle(struct bundle_header *header, int bundle_fd, int flags);
+int unbundle(struct repository *r, struct bundle_header *header,
+	     int bundle_fd, int flags);
 int list_bundle_refs(struct bundle_header *header,
 		int argc, const char **argv);
 
diff --git a/cache-tree.c b/cache-tree.c
index 9d454d2..190c6e5 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -659,7 +659,9 @@
 	return ret;
 }
 
-static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
+static void prime_cache_tree_rec(struct repository *r,
+				 struct cache_tree *it,
+				 struct tree *tree)
 {
 	struct tree_desc desc;
 	struct name_entry entry;
@@ -673,24 +675,25 @@
 			cnt++;
 		else {
 			struct cache_tree_sub *sub;
-			struct tree *subtree = lookup_tree(the_repository,
-							   entry.oid);
+			struct tree *subtree = lookup_tree(r, entry.oid);
 			if (!subtree->object.parsed)
 				parse_tree(subtree);
 			sub = cache_tree_sub(it, entry.path);
 			sub->cache_tree = cache_tree();
-			prime_cache_tree_rec(sub->cache_tree, subtree);
+			prime_cache_tree_rec(r, sub->cache_tree, subtree);
 			cnt += sub->cache_tree->entry_count;
 		}
 	}
 	it->entry_count = cnt;
 }
 
-void prime_cache_tree(struct index_state *istate, struct tree *tree)
+void prime_cache_tree(struct repository *r,
+		      struct index_state *istate,
+		      struct tree *tree)
 {
 	cache_tree_free(&istate->cache_tree);
 	istate->cache_tree = cache_tree();
-	prime_cache_tree_rec(istate->cache_tree, tree);
+	prime_cache_tree_rec(r, istate->cache_tree, tree);
 	istate->cache_changed |= CACHE_TREE_CHANGED;
 }
 
@@ -726,7 +729,8 @@
 	return 0;
 }
 
-static void verify_one(struct index_state *istate,
+static void verify_one(struct repository *r,
+		       struct index_state *istate,
 		       struct cache_tree *it,
 		       struct strbuf *path)
 {
@@ -736,13 +740,13 @@
 
 	for (i = 0; i < it->subtree_nr; i++) {
 		strbuf_addf(path, "%s/", it->down[i]->name);
-		verify_one(istate, it->down[i]->cache_tree, path);
+		verify_one(r, istate, it->down[i]->cache_tree, path);
 		strbuf_setlen(path, len);
 	}
 
 	if (it->entry_count < 0 ||
 	    /* no verification on tests (t7003) that replace trees */
-	    lookup_replace_object(the_repository, &it->oid) != &it->oid)
+	    lookup_replace_object(r, &it->oid) != &it->oid)
 		return;
 
 	if (path->len) {
@@ -793,12 +797,12 @@
 	strbuf_release(&tree_buf);
 }
 
-void cache_tree_verify(struct index_state *istate)
+void cache_tree_verify(struct repository *r, struct index_state *istate)
 {
 	struct strbuf path = STRBUF_INIT;
 
 	if (!istate->cache_tree)
 		return;
-	verify_one(istate, istate->cache_tree, &path);
+	verify_one(r, istate, istate->cache_tree, &path);
 	strbuf_release(&path);
 }
diff --git a/cache-tree.h b/cache-tree.h
index 0ab6784..3262091 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -32,7 +32,7 @@
 
 int cache_tree_fully_valid(struct cache_tree *);
 int cache_tree_update(struct index_state *, int);
-void cache_tree_verify(struct index_state *);
+void cache_tree_verify(struct repository *, struct index_state *);
 
 /* bitmasks to write_cache_as_tree flags */
 #define WRITE_TREE_MISSING_OK 1
@@ -47,7 +47,7 @@
 #define WRITE_TREE_PREFIX_ERROR (-3)
 
 int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix);
-void prime_cache_tree(struct index_state *, struct tree *);
+void prime_cache_tree(struct repository *, struct index_state *, struct tree *);
 
 int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
 
diff --git a/ci/lib-travisci.sh b/ci/lib-travisci.sh
index 06970f7..69dff4d 100755
--- a/ci/lib-travisci.sh
+++ b/ci/lib-travisci.sh
@@ -123,7 +123,7 @@
 	# Travis CI OS X
 	export GIT_SKIP_TESTS="t9810 t9816"
 	;;
-GETTEXT_POISON)
-	export GETTEXT_POISON=YesPlease
+GIT_TEST_GETTEXT_POISON)
+	export GIT_TEST_GETTEXT_POISON=YesPlease
 	;;
 esac
diff --git a/combine-diff.c b/combine-diff.c
index ad7752e..a143c00 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -996,7 +996,7 @@
 	if (!userdiff)
 		userdiff = userdiff_find_by_name("default");
 	if (opt->flags.allow_textconv)
-		textconv = userdiff_get_textconv(userdiff);
+		textconv = userdiff_get_textconv(opt->repo, userdiff);
 
 	/* Read the result of merge first */
 	if (!working_tree_file)
diff --git a/commit-graph.c b/commit-graph.c
index 40c855f..99163c2 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -230,8 +230,7 @@
  */
 static int prepare_commit_graph(struct repository *r)
 {
-	struct alternate_object_database *alt;
-	char *obj_dir;
+	struct object_directory *odb;
 	int config_value;
 
 	if (r->objects->commit_graph_attempted)
@@ -252,13 +251,11 @@
 	if (!commit_graph_compatible(r))
 		return 0;
 
-	obj_dir = r->objects->objectdir;
-	prepare_commit_graph_one(r, obj_dir);
 	prepare_alt_odb(r);
-	for (alt = r->objects->alt_odb_list;
-	     !r->objects->commit_graph && alt;
-	     alt = alt->next)
-		prepare_commit_graph_one(r, alt->path);
+	for (odb = r->objects->odb;
+	     !r->objects->commit_graph && odb;
+	     odb = odb->next)
+		prepare_commit_graph_one(r, odb->path);
 	return !!r->objects->commit_graph;
 }
 
diff --git a/commit.c b/commit.c
index d566d7e..d13a7bc 100644
--- a/commit.c
+++ b/commit.c
@@ -657,11 +657,10 @@
 /* count number of children that have not been emitted */
 define_commit_slab(indegree_slab, int);
 
-/* record author-date for each commit object */
 define_commit_slab(author_date_slab, timestamp_t);
 
-static void record_author_date(struct author_date_slab *author_date,
-			       struct commit *commit)
+void record_author_date(struct author_date_slab *author_date,
+			struct commit *commit)
 {
 	const char *buffer = get_commit_buffer(commit, NULL);
 	struct ident_split ident;
@@ -686,8 +685,8 @@
 	unuse_commit_buffer(commit, buffer);
 }
 
-static int compare_commits_by_author_date(const void *a_, const void *b_,
-					  void *cb_data)
+int compare_commits_by_author_date(const void *a_, const void *b_,
+				   void *cb_data)
 {
 	const struct commit *a = a_, *b = b_;
 	struct author_date_slab *author_date = cb_data;
@@ -1100,7 +1099,33 @@
 	return ret;
 }
 
+void verify_merge_signature(struct commit *commit, int verbosity)
+{
+	char hex[GIT_MAX_HEXSZ + 1];
+	struct signature_check signature_check;
+	memset(&signature_check, 0, sizeof(signature_check));
 
+	check_commit_signature(commit, &signature_check);
+
+	find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV);
+	switch (signature_check.result) {
+	case 'G':
+		break;
+	case 'U':
+		die(_("Commit %s has an untrusted GPG signature, "
+		      "allegedly by %s."), hex, signature_check.signer);
+	case 'B':
+		die(_("Commit %s has a bad GPG signature "
+		      "allegedly by %s."), hex, signature_check.signer);
+	default: /* 'N' */
+		die(_("Commit %s does not have a GPG signature."), hex);
+	}
+	if (verbosity >= 0 && signature_check.result == 'G')
+		printf(_("Commit %s has a good GPG signature by %s\n"),
+		       hex, signature_check.signer);
+
+	signature_check_clear(&signature_check);
+}
 
 void append_merge_tag_headers(struct commit_list *parents,
 			      struct commit_extra_header ***tail)
diff --git a/commit.h b/commit.h
index 8f15cfd..9866453 100644
--- a/commit.h
+++ b/commit.h
@@ -8,6 +8,7 @@
 #include "gpg-interface.h"
 #include "string-list.h"
 #include "pretty.h"
+#include "commit-slab.h"
 
 #define COMMIT_NOT_FROM_GRAPH 0xFFFFFFFF
 #define GENERATION_NUMBER_INFINITY 0xFFFFFFFF
@@ -333,6 +334,20 @@
  */
 extern int check_commit_signature(const struct commit *commit, struct signature_check *sigc);
 
+/* record author-date for each commit object */
+struct author_date_slab;
+void record_author_date(struct author_date_slab *author_date,
+			struct commit *commit);
+
+int compare_commits_by_author_date(const void *a_, const void *b_, void *unused);
+
+/*
+ * Verify a single commit with check_commit_signature() and die() if it is not
+ * a good signature. This isn't really suitable for general use, but is a
+ * helper to implement consistent logic for pull/merge --verify-signatures.
+ */
+void verify_merge_signature(struct commit *commit, int verbose);
+
 int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);
 int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused);
 
diff --git a/compat/mingw.c b/compat/mingw.c
index d2f4fab..34b3880 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1028,8 +1028,8 @@
 }
 
 /*
- * See http://msdn2.microsoft.com/en-us/library/17w5ykft(vs.71).aspx
- * (Parsing C++ Command-Line Arguments)
+ * See "Parsing C++ Command-Line Arguments" at Microsoft's Docs:
+ * https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments
  */
 static const char *quote_arg(const char *arg)
 {
@@ -2211,24 +2211,12 @@
 
 int link(const char *oldpath, const char *newpath)
 {
-	typedef BOOL (WINAPI *T)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
-	static T create_hard_link = NULL;
 	wchar_t woldpath[MAX_PATH], wnewpath[MAX_PATH];
 	if (xutftowcs_path(woldpath, oldpath) < 0 ||
 		xutftowcs_path(wnewpath, newpath) < 0)
 		return -1;
 
-	if (!create_hard_link) {
-		create_hard_link = (T) GetProcAddress(
-			GetModuleHandle("kernel32.dll"), "CreateHardLinkW");
-		if (!create_hard_link)
-			create_hard_link = (T)-1;
-	}
-	if (create_hard_link == (T)-1) {
-		errno = ENOSYS;
-		return -1;
-	}
-	if (!create_hard_link(wnewpath, woldpath, NULL)) {
+	if (!CreateHardLinkW(wnewpath, woldpath, NULL)) {
 		errno = err_win_to_posix(GetLastError());
 		return -1;
 	}
diff --git a/compat/msvc.h b/compat/msvc.h
index 580bb55..29a8ce8 100644
--- a/compat/msvc.h
+++ b/compat/msvc.h
@@ -10,18 +10,12 @@
 #define inline __inline
 #define __inline__ __inline
 #define __attribute__(x)
+#define strcasecmp   _stricmp
 #define strncasecmp  _strnicmp
 #define ftruncate    _chsize
 #define strtoull     _strtoui64
 #define strtoll      _strtoi64
 
-static __inline int strcasecmp (const char *s1, const char *s2)
-{
-	int size1 = strlen(s1);
-	int sisz2 = strlen(s2);
-	return _strnicmp(s1, s2, sisz2 > size1 ? sisz2 : size1);
-}
-
 #undef ERROR
 
 #include "compat/mingw.h"
diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c
index e18f5c6..2e7eead 100644
--- a/compat/win32/pthread.c
+++ b/compat/win32/pthread.c
@@ -56,141 +56,3 @@
 	t.tid = GetCurrentThreadId();
 	return t;
 }
-
-int pthread_cond_init(pthread_cond_t *cond, const void *unused)
-{
-	cond->waiters = 0;
-	cond->was_broadcast = 0;
-	InitializeCriticalSection(&cond->waiters_lock);
-
-	cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
-	if (!cond->sema)
-		die("CreateSemaphore() failed");
-
-	cond->continue_broadcast = CreateEvent(NULL,	/* security */
-				FALSE,			/* auto-reset */
-				FALSE,			/* not signaled */
-				NULL);			/* name */
-	if (!cond->continue_broadcast)
-		die("CreateEvent() failed");
-
-	return 0;
-}
-
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
-	CloseHandle(cond->sema);
-	CloseHandle(cond->continue_broadcast);
-	DeleteCriticalSection(&cond->waiters_lock);
-	return 0;
-}
-
-int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)
-{
-	int last_waiter;
-
-	EnterCriticalSection(&cond->waiters_lock);
-	cond->waiters++;
-	LeaveCriticalSection(&cond->waiters_lock);
-
-	/*
-	 * Unlock external mutex and wait for signal.
-	 * NOTE: we've held mutex locked long enough to increment
-	 * waiters count above, so there's no problem with
-	 * leaving mutex unlocked before we wait on semaphore.
-	 */
-	LeaveCriticalSection(mutex);
-
-	/* let's wait - ignore return value */
-	WaitForSingleObject(cond->sema, INFINITE);
-
-	/*
-	 * Decrease waiters count. If we are the last waiter, then we must
-	 * notify the broadcasting thread that it can continue.
-	 * But if we continued due to cond_signal, we do not have to do that
-	 * because the signaling thread knows that only one waiter continued.
-	 */
-	EnterCriticalSection(&cond->waiters_lock);
-	cond->waiters--;
-	last_waiter = cond->was_broadcast && cond->waiters == 0;
-	LeaveCriticalSection(&cond->waiters_lock);
-
-	if (last_waiter) {
-		/*
-		 * cond_broadcast was issued while mutex was held. This means
-		 * that all other waiters have continued, but are contending
-		 * for the mutex at the end of this function because the
-		 * broadcasting thread did not leave cond_broadcast, yet.
-		 * (This is so that it can be sure that each waiter has
-		 * consumed exactly one slice of the semaphor.)
-		 * The last waiter must tell the broadcasting thread that it
-		 * can go on.
-		 */
-		SetEvent(cond->continue_broadcast);
-		/*
-		 * Now we go on to contend with all other waiters for
-		 * the mutex. Auf in den Kampf!
-		 */
-	}
-	/* lock external mutex again */
-	EnterCriticalSection(mutex);
-
-	return 0;
-}
-
-/*
- * IMPORTANT: This implementation requires that pthread_cond_signal
- * is called while the mutex is held that is used in the corresponding
- * pthread_cond_wait calls!
- */
-int pthread_cond_signal(pthread_cond_t *cond)
-{
-	int have_waiters;
-
-	EnterCriticalSection(&cond->waiters_lock);
-	have_waiters = cond->waiters > 0;
-	LeaveCriticalSection(&cond->waiters_lock);
-
-	/*
-	 * Signal only when there are waiters
-	 */
-	if (have_waiters)
-		return ReleaseSemaphore(cond->sema, 1, NULL) ?
-			0 : err_win_to_posix(GetLastError());
-	else
-		return 0;
-}
-
-/*
- * DOUBLY IMPORTANT: This implementation requires that pthread_cond_broadcast
- * is called while the mutex is held that is used in the corresponding
- * pthread_cond_wait calls!
- */
-int pthread_cond_broadcast(pthread_cond_t *cond)
-{
-	EnterCriticalSection(&cond->waiters_lock);
-
-	if ((cond->was_broadcast = cond->waiters > 0)) {
-		/* wake up all waiters */
-		ReleaseSemaphore(cond->sema, cond->waiters, NULL);
-		LeaveCriticalSection(&cond->waiters_lock);
-		/*
-		 * At this point all waiters continue. Each one takes its
-		 * slice of the semaphor. Now it's our turn to wait: Since
-		 * the external mutex is held, no thread can leave cond_wait,
-		 * yet. For this reason, we can be sure that no thread gets
-		 * a chance to eat *more* than one slice. OTOH, it means
-		 * that the last waiter must send us a wake-up.
-		 */
-		WaitForSingleObject(cond->continue_broadcast, INFINITE);
-		/*
-		 * Since the external mutex is held, no thread can enter
-		 * cond_wait, and, hence, it is safe to reset this flag
-		 * without cond->waiters_lock held.
-		 */
-		cond->was_broadcast = 0;
-	} else {
-		LeaveCriticalSection(&cond->waiters_lock);
-	}
-	return 0;
-}
diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h
index 1c16408..c6cb8dd 100644
--- a/compat/win32/pthread.h
+++ b/compat/win32/pthread.h
@@ -32,27 +32,13 @@
 #define pthread_mutexattr_settype(a, t) 0
 #define PTHREAD_MUTEX_RECURSIVE 0
 
-/*
- * Implement simple condition variable for Windows threads, based on ACE
- * implementation.
- *
- * See original implementation: http://bit.ly/1vkDjo
- * ACE homepage: http://www.cse.wustl.edu/~schmidt/ACE.html
- * See also: http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
- */
-typedef struct {
-	LONG waiters;
-	int was_broadcast;
-	CRITICAL_SECTION waiters_lock;
-	HANDLE sema;
-	HANDLE continue_broadcast;
-} pthread_cond_t;
+#define pthread_cond_t CONDITION_VARIABLE
 
-extern int pthread_cond_init(pthread_cond_t *cond, const void *unused);
-extern int pthread_cond_destroy(pthread_cond_t *cond);
-extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex);
-extern int pthread_cond_signal(pthread_cond_t *cond);
-extern int pthread_cond_broadcast(pthread_cond_t *cond);
+#define pthread_cond_init(a,b) InitializeConditionVariable((a))
+#define pthread_cond_destroy(a) do {} while (0)
+#define pthread_cond_wait(a,b) return_0(SleepConditionVariableCS((a), (b), INFINITE))
+#define pthread_cond_signal WakeConditionVariable
+#define pthread_cond_broadcast WakeAllConditionVariable
 
 /*
  * Simple thread creation implementation using pthread API
diff --git a/config.c b/config.c
index 2ffd39c..ff521eb 100644
--- a/config.c
+++ b/config.c
@@ -1668,6 +1668,8 @@
 
 	if (opts->commondir)
 		repo_config = mkpathdup("%s/config", opts->commondir);
+	else if (opts->git_dir)
+		BUG("git_dir without commondir");
 	else
 		repo_config = NULL;
 
@@ -2292,22 +2294,25 @@
 	return 0;
 }
 
-int git_config_get_index_threads(void)
+int git_config_get_index_threads(int *dest)
 {
-	int is_bool, val = 0;
+	int is_bool, val;
 
 	val = git_env_ulong("GIT_TEST_INDEX_THREADS", 0);
-	if (val)
-		return val;
+	if (val) {
+		*dest = val;
+		return 0;
+	}
 
 	if (!git_config_get_bool_or_int("index.threads", &is_bool, &val)) {
 		if (is_bool)
-			return val ? 0 : 1;
+			*dest = val ? 0 : 1;
 		else
-			return val;
+			*dest = val;
+		return 0;
 	}
 
-	return 0; /* auto */
+	return 1;
 }
 
 NORETURN
diff --git a/config.h b/config.h
index a06027e..ee5d3fa 100644
--- a/config.h
+++ b/config.h
@@ -246,11 +246,11 @@
 extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);
 extern int git_config_get_maybe_bool(const char *key, int *dest);
 extern int git_config_get_pathname(const char *key, const char **dest);
+extern int git_config_get_index_threads(int *dest);
 extern int git_config_get_untracked_cache(void);
 extern int git_config_get_split_index(void);
 extern int git_config_get_max_percent_split_change(void);
 extern int git_config_get_fsmonitor(void);
-extern int git_config_get_index_threads(void);
 
 /* This dies if the configured or default date is in the future */
 extern int git_config_get_expiry(const char *key, const char **output);
diff --git a/config.mak.uname b/config.mak.uname
index f179d7a..3ee7da0 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -430,8 +430,6 @@
 	NO_NSEC = YesPlease
 	NEEDS_LIBGEN =
 	NEEDS_CRYPTO_WITH_SSL = YesPlease
-	NEEDS_IDN_WITH_CURL = YesPlease
-	NEEDS_SSL_WITH_CURL = YesPlease
 	NEEDS_RESOLV =
 	NO_HSTRERROR = YesPlease
 	NO_MMAP = YesPlease
@@ -457,7 +455,6 @@
 	# Missdetected, hence commented out, see below.
 	#NO_CURL = YesPlease
 	# Added manually, see above.
-	NEEDS_SSL_WITH_CURL = YesPlease
 	HAVE_LIBCHARSET_H = YesPlease
 	HAVE_STRINGS_H = YesPlease
 	NEEDS_LIBICONV = YesPlease
diff --git a/configure.ac b/configure.ac
index e11b797..e0d0da3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -600,17 +600,14 @@
 
 if test $CURL_CONFIG != no; then
     GIT_CONF_SUBST([CURL_CONFIG])
-    if test -z "${NO_OPENSSL}"; then
-      AC_MSG_CHECKING([if Curl supports SSL])
-      if test $(curl-config --features|grep SSL) = SSL; then
-         NEEDS_SSL_WITH_CURL=YesPlease
-         AC_MSG_RESULT([yes])
-      else
-         NEEDS_SSL_WITH_CURL=
-         AC_MSG_RESULT([no])
-      fi
-      GIT_CONF_SUBST([NEEDS_SSL_WITH_CURL])
+
+    if test -z "$CURL_CONFIG_OPTS"; then
+        CURL_CONFIG_OPTS="--libs"
     fi
+
+    CURL_LDFLAGS=$($CURL_CONFIG $CURL_CONFIG_OPTS)
+    AC_MSG_NOTICE([Setting CURL_LDFLAGS to '$CURL_LDFLAGS'])
+    GIT_CONF_SUBST([CURL_LDFLAGS], [$CURL_LDFLAGS])
 fi
 
 fi
@@ -792,6 +789,12 @@
 [NO_SYS_SELECT_H=UnfortunatelyYes])
 GIT_CONF_SUBST([NO_SYS_SELECT_H])
 #
+# Define NO_POLL_H if you don't have poll.h
+AC_CHECK_HEADER([poll.h],
+[NO_POLL_H=],
+[NO_POLL_H=UnfortunatelyYes])
+GIT_CONF_SUBST([NO_POLL_H])
+#
 # Define NO_SYS_POLL_H if you don't have sys/poll.h
 AC_CHECK_HEADER([sys/poll.h],
 [NO_SYS_POLL_H=],
diff --git a/contrib/coccinelle/README b/contrib/coccinelle/README
index 9c2f887..f0e80bd 100644
--- a/contrib/coccinelle/README
+++ b/contrib/coccinelle/README
@@ -1,2 +1,43 @@
 This directory provides examples of Coccinelle (http://coccinelle.lip6.fr/)
 semantic patches that might be useful to developers.
+
+There are two types of semantic patches:
+
+ * Using the semantic transformation to check for bad patterns in the code;
+   The target 'make coccicheck' is designed to check for these patterns and
+   it is expected that any resulting patch indicates a regression.
+   The patches resulting from 'make coccicheck' are small and infrequent,
+   so once they are found, they can be sent to the mailing list as per usual.
+
+   Example for introducing new patterns:
+   67947c34ae (convert "hashcmp() != 0" to "!hasheq()", 2018-08-28)
+   b84c783882 (fsck: s/++i > 1/i++/, 2018-10-24)
+
+   Example of fixes using this approach:
+   248f66ed8e (run-command: use strbuf_addstr() for adding a string to
+               a strbuf, 2018-03-25)
+   f919ffebed (Use MOVE_ARRAY, 2018-01-22)
+
+   These types of semantic patches are usually part of testing, c.f.
+   0860a7641b (travis-ci: fail if Coccinelle static analysis found something
+               to transform, 2018-07-23)
+
+ * Using semantic transformations in large scale refactorings throughout
+   the code base.
+
+   When applying the semantic patch into a real patch, sending it to the
+   mailing list in the usual way, such a patch would be expected to have a
+   lot of textual and semantic conflicts as such large scale refactorings
+   change function signatures that are used widely in the code base.
+   A textual conflict would arise if surrounding code near any call of such
+   function changes. A semantic conflict arises when other patch series in
+   flight introduce calls to such functions.
+
+   So to aid these large scale refactorings, semantic patches can be used.
+   However we do not want to store them in the same place as the checks for
+   bad patterns, as then automated builds would fail.
+   That is why semantic patches 'contrib/coccinelle/*.pending.cocci'
+   are ignored for checks, and can be applied using 'make coccicheck-pending'.
+
+   This allows to expose plans of pending large scale refactorings without
+   impacting the bad pattern checks.
diff --git a/delta-islands.c b/delta-islands.c
index 8e5018e..191a930 100644
--- a/delta-islands.c
+++ b/delta-islands.c
@@ -190,13 +190,15 @@
 	island_bitmap_or(b, marks);
 }
 
-static void mark_remote_island_1(struct remote_island *rl, int is_core_island)
+static void mark_remote_island_1(struct repository *r,
+				 struct remote_island *rl,
+				 int is_core_island)
 {
 	uint32_t i;
 
 	for (i = 0; i < rl->oids.nr; ++i) {
 		struct island_bitmap *marks;
-		struct object *obj = parse_object(the_repository, &rl->oids.oid[i]);
+		struct object *obj = parse_object(r, &rl->oids.oid[i]);
 
 		if (!obj)
 			continue;
@@ -211,7 +213,7 @@
 		while (obj && obj->type == OBJ_TAG) {
 			obj = ((struct tag *)obj)->tagged;
 			if (obj) {
-				parse_object(the_repository, &obj->oid);
+				parse_object(r, &obj->oid);
 				marks = create_or_get_island_marks(obj);
 				island_bitmap_set(marks, island_counter);
 			}
@@ -237,7 +239,9 @@
 	return todo_a->depth - todo_b->depth;
 }
 
-void resolve_tree_islands(int progress, struct packing_data *to_pack)
+void resolve_tree_islands(struct repository *r,
+			  int progress,
+			  struct packing_data *to_pack)
 {
 	struct progress *progress_state = NULL;
 	struct tree_islands_todo *todo;
@@ -281,7 +285,7 @@
 
 		root_marks = kh_value(island_marks, pos);
 
-		tree = lookup_tree(the_repository, &ent->idx.oid);
+		tree = lookup_tree(r, &ent->idx.oid);
 		if (!tree || parse_tree(tree) < 0)
 			die(_("bad tree object %s"), oid_to_hex(&ent->idx.oid));
 
@@ -292,7 +296,7 @@
 			if (S_ISGITLINK(entry.mode))
 				continue;
 
-			obj = lookup_object(the_repository, entry.oid->hash);
+			obj = lookup_object(r, entry.oid->hash);
 			if (!obj)
 				continue;
 
@@ -415,7 +419,7 @@
 	return NULL;
 }
 
-static void deduplicate_islands(void)
+static void deduplicate_islands(struct repository *r)
 {
 	struct remote_island *island, *core = NULL, **list;
 	unsigned int island_count, dst, src, ref, i = 0;
@@ -444,20 +448,20 @@
 	core = get_core_island();
 
 	for (i = 0; i < island_count; ++i) {
-		mark_remote_island_1(list[i], core && list[i]->hash == core->hash);
+		mark_remote_island_1(r, list[i], core && list[i]->hash == core->hash);
 	}
 
 	free(list);
 }
 
-void load_delta_islands(void)
+void load_delta_islands(struct repository *r)
 {
 	island_marks = kh_init_sha1();
 	remote_islands = kh_init_str();
 
 	git_config(island_config_callback, NULL);
 	for_each_ref(find_island_for_ref, NULL);
-	deduplicate_islands();
+	deduplicate_islands(r);
 
 	fprintf(stderr, _("Marked %d islands, done.\n"), island_counter);
 }
diff --git a/delta-islands.h b/delta-islands.h
index b635cd0..3ac8045 100644
--- a/delta-islands.h
+++ b/delta-islands.h
@@ -1,14 +1,17 @@
 #ifndef DELTA_ISLANDS_H
 #define DELTA_ISLANDS_H
 
+struct commit;
 struct object_id;
 struct packing_data;
-struct commit;
+struct repository;
 
 int island_delta_cmp(const struct object_id *a, const struct object_id *b);
 int in_same_island(const struct object_id *, const struct object_id *);
-void resolve_tree_islands(int progress, struct packing_data *to_pack);
-void load_delta_islands(void);
+void resolve_tree_islands(struct repository *r,
+			  int progress,
+			  struct packing_data *to_pack);
+void load_delta_islands(struct repository *r);
 void propagate_island_marks(struct commit *commit);
 int compute_pack_layers(struct packing_data *to_pack);
 
diff --git a/diff-lib.c b/diff-lib.c
index 83fce51..23c8d35 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -542,7 +542,7 @@
 {
 	struct rev_info revs;
 
-	repo_init_revisions(the_repository, &revs, NULL);
+	repo_init_revisions(opt->repo, &revs, NULL);
 	copy_pathspec(&revs.prune_data, &opt->pathspec);
 	revs.diffopt = *opt;
 
@@ -551,13 +551,14 @@
 	return 0;
 }
 
-int index_differs_from(const char *def, const struct diff_flags *flags,
+int index_differs_from(struct repository *r,
+		       const char *def, const struct diff_flags *flags,
 		       int ita_invisible_in_index)
 {
 	struct rev_info rev;
 	struct setup_revision_opt opt;
 
-	repo_init_revisions(the_repository, &rev, NULL);
+	repo_init_revisions(r, &rev, NULL);
 	memset(&opt, 0, sizeof(opt));
 	opt.def = def;
 	setup_revisions(0, NULL, &rev, &opt);
diff --git a/diff.c b/diff.c
index e38d1ec..15556c1 100644
--- a/diff.c
+++ b/diff.c
@@ -3228,7 +3228,7 @@
 	}
 
 	if (delta && delta_size < deflate_size) {
-		char *s = xstrfmt("%lu", orig_size);
+		char *s = xstrfmt("%"PRIuMAX , (uintmax_t)orig_size);
 		emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_HEADER_DELTA,
 				 s, strlen(s), 0);
 		free(s);
@@ -3313,14 +3313,14 @@
 		options->b_prefix = b;
 }
 
-struct userdiff_driver *get_textconv(struct index_state *istate,
+struct userdiff_driver *get_textconv(struct repository *r,
 				     struct diff_filespec *one)
 {
 	if (!DIFF_FILE_VALID(one))
 		return NULL;
 
-	diff_filespec_load_driver(one, istate);
-	return userdiff_get_textconv(one->driver);
+	diff_filespec_load_driver(one, r->index);
+	return userdiff_get_textconv(r, one->driver);
 }
 
 static void builtin_diff(const char *name_a,
@@ -3369,8 +3369,8 @@
 	}
 
 	if (o->flags.allow_textconv) {
-		textconv_one = get_textconv(o->repo->index, one);
-		textconv_two = get_textconv(o->repo->index, two);
+		textconv_one = get_textconv(o->repo, one);
+		textconv_two = get_textconv(o->repo, two);
 	}
 
 	/* Never use a non-valid filename anywhere if at all possible */
@@ -6434,7 +6434,7 @@
 
 	df = alloc_filespec(path);
 	fill_filespec(df, oid, oid_valid, mode);
-	textconv = get_textconv(r->index, df);
+	textconv = get_textconv(r, df);
 	if (!textconv) {
 		free_filespec(df);
 		return 0;
diff --git a/diff.h b/diff.h
index ce5e8a8..412138b 100644
--- a/diff.h
+++ b/diff.h
@@ -436,7 +436,8 @@
 
 void diff_no_index(struct repository *, struct rev_info *, int, const char **);
 
-int index_differs_from(const char *def, const struct diff_flags *flags,
+int index_differs_from(struct repository *r, const char *def,
+		       const struct diff_flags *flags,
 		       int ita_invisible_in_index);
 
 /*
@@ -460,7 +461,7 @@
  * and only if it has textconv enabled (otherwise return NULL). The result
  * can be passed to fill_textconv().
  */
-struct userdiff_driver *get_textconv(struct index_state *istate,
+struct userdiff_driver *get_textconv(struct repository *r,
 				     struct diff_filespec *one);
 
 /*
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index 69fc55e..ad939d2 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -140,8 +140,8 @@
 		return 0;
 
 	if (o->flags.allow_textconv) {
-		textconv_one = get_textconv(o->repo->index, p->one);
-		textconv_two = get_textconv(o->repo->index, p->two);
+		textconv_one = get_textconv(o->repo, p->one);
+		textconv_two = get_textconv(o->repo, p->two);
 	}
 
 	/*
diff --git a/entry.c b/entry.c
index 5d136c5..0a3c451 100644
--- a/entry.c
+++ b/entry.c
@@ -404,7 +404,7 @@
 {
 	int i, trust_ino = check_stat;
 
-#if defined(GIT_WINDOWS_NATIVE)
+#if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__)
 	trust_ino = 0;
 #endif
 
@@ -419,7 +419,7 @@
 		if (dup->ce_flags & (CE_MATCHED | CE_VALID | CE_SKIP_WORKTREE))
 			continue;
 
-		if ((trust_ino && dup->ce_stat_data.sd_ino == st->st_ino) ||
+		if ((trust_ino && !match_stat_data(&dup->ce_stat_data, st)) ||
 		    (!trust_ino && !fspathcmp(ce->name, dup->name))) {
 			dup->ce_flags |= CE_MATCHED;
 			break;
diff --git a/environment.c b/environment.c
index 3465597..0e37741 100644
--- a/environment.c
+++ b/environment.c
@@ -274,9 +274,9 @@
 
 char *get_object_directory(void)
 {
-	if (!the_repository->objects->objectdir)
+	if (!the_repository->objects->odb)
 		BUG("git environment hasn't been setup");
-	return the_repository->objects->objectdir;
+	return the_repository->objects->odb->path;
 }
 
 int odb_mkstemp(struct strbuf *temp_filename, const char *pattern)
diff --git a/fast-import.c b/fast-import.c
index 95600c7..b7ba755 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1,157 +1,3 @@
-/*
-(See Documentation/git-fast-import.txt for maintained documentation.)
-Format of STDIN stream:
-
-  stream ::= cmd*;
-
-  cmd ::= new_blob
-        | new_commit
-        | new_tag
-        | reset_branch
-        | checkpoint
-        | progress
-        ;
-
-  new_blob ::= 'blob' lf
-    mark?
-    file_content;
-  file_content ::= data;
-
-  new_commit ::= 'commit' sp ref_str lf
-    mark?
-    ('author' (sp name)? sp '<' email '>' sp when lf)?
-    'committer' (sp name)? sp '<' email '>' sp when lf
-    commit_msg
-    ('from' sp commit-ish lf)?
-    ('merge' sp commit-ish lf)*
-    (file_change | ls)*
-    lf?;
-  commit_msg ::= data;
-
-  ls ::= 'ls' sp '"' quoted(path) '"' lf;
-
-  file_change ::= file_clr
-    | file_del
-    | file_rnm
-    | file_cpy
-    | file_obm
-    | file_inm;
-  file_clr ::= 'deleteall' lf;
-  file_del ::= 'D' sp path_str lf;
-  file_rnm ::= 'R' sp path_str sp path_str lf;
-  file_cpy ::= 'C' sp path_str sp path_str lf;
-  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 commit-ish lf;
-  note_inm ::= 'N' sp 'inline' sp commit-ish lf
-    data;
-
-  new_tag ::= 'tag' sp tag_str 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 commit-ish lf)?
-    lf?;
-
-  checkpoint ::= 'checkpoint' lf
-    lf?;
-
-  progress ::= 'progress' sp not_lf* lf
-    lf?;
-
-     # note: the first idnum in a stream should be 1 and subsequent
-     # idnums should not have gaps between values as this will cause
-     # the stream parser to reserve space for the gapped values.  An
-     # idnum can be updated in the future to a new object by issuing
-     # a new mark directive with the old idnum.
-     #
-  mark ::= 'mark' sp idnum lf;
-  data ::= (delimited_data | exact_data)
-    lf?;
-
-    # note: delim may be any string but must not contain lf.
-    # data_line may contain any data but must not be exactly
-    # delim.
-  delimited_data ::= 'data' sp '<<' delim lf
-    (data_line lf)*
-    delim lf;
-
-     # note: declen indicates the length of binary_data in bytes.
-     # declen does not include the lf preceding the binary data.
-     #
-  exact_data ::= 'data' sp declen lf
-    binary_data;
-
-     # note: quoted strings are C-style quoting supporting \c for
-     # common escapes of 'c' (e..g \n, \t, \\, \") or \nnn where nnn
-     # is the signed byte value in octal.  Note that the only
-     # characters which must actually be escaped to protect the
-     # stream formatting is: \, " and LF.  Otherwise these values
-     # are UTF8.
-     #
-  commit-ish  ::= (ref_str | hexsha1 | sha1exp_str | idnum);
-  ref_str     ::= ref;
-  sha1exp_str ::= sha1exp;
-  tag_str     ::= tag;
-  path_str    ::= path    | '"' quoted(path)    '"' ;
-  mode        ::= '100644' | '644'
-                | '100755' | '755'
-                | '120000'
-                ;
-
-  declen ::= # unsigned 32 bit value, ascii base10 notation;
-  bigint ::= # unsigned integer value, ascii base10 notation;
-  binary_data ::= # file content, not interpreted;
-
-  when         ::= raw_when | rfc2822_when;
-  raw_when     ::= ts sp tz;
-  rfc2822_when ::= # Valid RFC 2822 date and time;
-
-  sp ::= # ASCII space character;
-  lf ::= # ASCII newline (LF) character;
-
-     # note: a colon (':') must precede the numerical value assigned to
-     # an idnum.  This is to distinguish it from a ref or tag name as
-     # GIT does not permit ':' in ref or tag strings.
-     #
-  idnum   ::= ':' bigint;
-  path    ::= # GIT style file path, e.g. "a/b/c";
-  ref     ::= # GIT ref name, e.g. "refs/heads/MOZ_GECKO_EXPERIMENT";
-  tag     ::= # GIT tag name, e.g. "FIREFOX_1_5";
-  sha1exp ::= # Any valid GIT SHA1 expression;
-  hexsha1 ::= # SHA1 in hexadecimal format;
-
-     # note: name and email are UTF8 strings, however name must not
-     # contain '<' or lf and email must not contain any of the
-     # following: '<', '>', lf.
-     #
-  name  ::= # valid GIT author/committer name;
-  email ::= # valid GIT author/committer email;
-  ts    ::= # time since the epoch in seconds, ascii base10 notation;
-  tz    ::= # GIT style timezone;
-
-     # note: comments, get-mark, ls-tree, and cat-blob requests may
-     # appear anywhere in the input, except within a data command. Any
-     # form of the data command always escapes the related input from
-     # comment processing.
-     #
-     # In case it is not clear, the '#' that starts the comment
-     # must be the first character on that line (an lf
-     # preceded it).
-     #
-
-  get_mark ::= 'get-mark' sp idnum lf;
-  cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf;
-  ls_tree  ::= 'ls' sp (hexsha1 | idnum) sp path_str lf;
-
-  comment ::= '#' not_lf* lf;
-  not_lf  ::= # Any byte that is not ASCII newline (LF);
-*/
-
 #include "builtin.h"
 #include "cache.h"
 #include "repository.h"
@@ -1968,6 +1814,13 @@
 		next_mark = 0;
 }
 
+static void parse_original_identifier(void)
+{
+	const char *v;
+	if (skip_prefix(command_buf.buf, "original-oid ", &v))
+		read_next_command();
+}
+
 static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res)
 {
 	const char *data;
@@ -2110,6 +1963,7 @@
 {
 	read_next_command();
 	parse_mark();
+	parse_original_identifier();
 	parse_and_store_blob(&last_blob, NULL, next_mark);
 }
 
@@ -2733,6 +2587,7 @@
 
 	read_next_command();
 	parse_mark();
+	parse_original_identifier();
 	if (skip_prefix(command_buf.buf, "author ", &v)) {
 		author = parse_ident(v);
 		read_next_command();
@@ -2865,6 +2720,9 @@
 		die("Invalid ref name or SHA1 expression: %s", from);
 	read_next_command();
 
+	/* original-oid ... */
+	parse_original_identifier();
+
 	/* tagger ... */
 	if (skip_prefix(command_buf.buf, "tagger ", &v)) {
 		tagger = parse_ident(v);
@@ -2955,8 +2813,8 @@
 		die("Object %s is a %s but a blob was expected.",
 		    oid_to_hex(oid), type_name(type));
 	strbuf_reset(&line);
-	strbuf_addf(&line, "%s %s %lu\n", oid_to_hex(oid),
-						type_name(type), size);
+	strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),
+		    type_name(type), (uintmax_t)size);
 	cat_blob_write(line.buf, line.len);
 	strbuf_release(&line);
 	cat_blob_write(buf, size);
diff --git a/fetch-pack.c b/fetch-pack.c
index 9691046..dd6700b 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -637,23 +637,6 @@
 };
 
 /*
- *  If the number of refs is not larger than the number of loose objects,
- *  this function stops inserting.
- */
-static int add_loose_objects_to_set(const struct object_id *oid,
-				    const char *path,
-				    void *data)
-{
-	struct loose_object_iter *iter = data;
-	oidset_insert(iter->loose_object_set, oid);
-	if (iter->refs == NULL)
-		return 1;
-
-	iter->refs = iter->refs->next;
-	return 0;
-}
-
-/*
  * Mark recent commits available locally and reachable from a local ref as
  * COMPLETE. If args->no_dependents is false, also mark COMPLETE remote refs as
  * COMMON_REF (otherwise, we are not planning to participate in negotiation, and
@@ -670,30 +653,14 @@
 	struct ref *ref;
 	int old_save_commit_buffer = save_commit_buffer;
 	timestamp_t cutoff = 0;
-	struct oidset loose_oid_set = OIDSET_INIT;
-	int use_oidset = 0;
-	struct loose_object_iter iter = {&loose_oid_set, *refs};
-
-	/* Enumerate all loose objects or know refs are not so many. */
-	use_oidset = !for_each_loose_object(add_loose_objects_to_set,
-					    &iter, 0);
 
 	save_commit_buffer = 0;
 
 	for (ref = *refs; ref; ref = ref->next) {
 		struct object *o;
-		unsigned int flags = OBJECT_INFO_QUICK;
 
-		if (use_oidset &&
-		    !oidset_contains(&loose_oid_set, &ref->old_oid)) {
-			/*
-			 * I know this does not exist in the loose form,
-			 * so check if it exists in a non-loose form.
-			 */
-			flags |= OBJECT_INFO_IGNORE_LOOSE;
-		}
-
-		if (!has_object_file_with_flags(&ref->old_oid, flags))
+		if (!has_object_file_with_flags(&ref->old_oid,
+						OBJECT_INFO_QUICK))
 			continue;
 		o = parse_object(the_repository, &ref->old_oid);
 		if (!o)
@@ -710,8 +677,6 @@
 		}
 	}
 
-	oidset_clear(&loose_oid_set);
-
 	if (!args->deepen) {
 		for_each_ref(mark_complete_oid, NULL);
 		for_each_cached_alternate(NULL, mark_alternate_complete);
diff --git a/gettext.c b/gettext.c
index 7272771..d4021d6 100644
--- a/gettext.c
+++ b/gettext.c
@@ -7,6 +7,7 @@
 #include "gettext.h"
 #include "strbuf.h"
 #include "utf8.h"
+#include "config.h"
 
 #ifndef NO_GETTEXT
 #	include <locale.h>
@@ -46,15 +47,15 @@
 	return NULL;
 }
 
-#ifdef GETTEXT_POISON
 int use_gettext_poison(void)
 {
 	static int poison_requested = -1;
-	if (poison_requested == -1)
-		poison_requested = getenv("GIT_GETTEXT_POISON") ? 1 : 0;
+	if (poison_requested == -1) {
+		const char *v = getenv("GIT_TEST_GETTEXT_POISON");
+		poison_requested = v && strlen(v) ? 1 : 0;
+	}
 	return poison_requested;
 }
-#endif
 
 #ifndef NO_GETTEXT
 static int test_vsnprintf(const char *fmt, ...)
@@ -164,6 +165,8 @@
 	if (!podir)
 		podir = p = system_path(GIT_LOCALE_PATH);
 
+	use_gettext_poison(); /* getenv() reentrancy paranoia */
+
 	if (!is_directory(podir)) {
 		free(p);
 		return;
diff --git a/gettext.h b/gettext.h
index 7eee64a..71255e5 100644
--- a/gettext.h
+++ b/gettext.h
@@ -28,12 +28,15 @@
 
 #define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
 
+extern int use_gettext_poison(void);
+
 #ifndef NO_GETTEXT
 extern void git_setup_gettext(void);
 extern int gettext_width(const char *s);
 #else
 static inline void git_setup_gettext(void)
 {
+	use_gettext_poison(); /* getenv() reentrancy paranoia */
 }
 static inline int gettext_width(const char *s)
 {
@@ -41,12 +44,6 @@
 }
 #endif
 
-#ifdef GETTEXT_POISON
-extern int use_gettext_poison(void);
-#else
-#define use_gettext_poison() 0
-#endif
-
 static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
 {
 	if (!*msgid)
diff --git a/git-compat-util.h b/git-compat-util.h
index 3a08d99..09b0102 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -180,9 +180,12 @@
 #include <regex.h>
 #include <utime.h>
 #include <syslog.h>
-#ifndef NO_SYS_POLL_H
+#if !defined(NO_POLL_H)
+#include <poll.h>
+#elif !defined(NO_SYS_POLL_H)
 #include <sys/poll.h>
 #else
+/* Pull the compat stuff */
 #include <poll.h>
 #endif
 #ifdef HAVE_BSD_SYSCTL
@@ -858,6 +861,7 @@
 #define FREE_AND_NULL(p) do { free(p); (p) = NULL; } while (0)
 
 #define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
+#define CALLOC_ARRAY(x, alloc) (x) = xcalloc((alloc), sizeof(*(x)));
 #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
 
 #define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \
diff --git a/git-legacy-rebase.sh b/git-legacy-rebase.sh
index 75a08b2..b4c7dbf 100755
--- a/git-legacy-rebase.sh
+++ b/git-legacy-rebase.sh
@@ -337,6 +337,11 @@
 		fix|strip)
 			force_rebase=t
 			;;
+		warn|nowarn|error|error-all)
+			;; # okay, known whitespace option
+		*)
+			die "fatal: Invalid whitespace option: '${1#*=}'"
+			;;
 		esac
 		;;
 	--ignore-whitespace)
@@ -352,6 +357,9 @@
 		git_am_opt="$git_am_opt $1"
 		force_rebase=t
 		;;
+	-C*[!0-9]*)
+		die "fatal: switch \`C' expects a numerical value"
+		;;
 	-C*)
 		git_am_opt="$git_am_opt $1"
 		;;
@@ -710,10 +718,16 @@
 then
 	if test -n "$verbose"
 	then
-		echo "$(eval_gettext "Changes from \$mb to \$onto:")"
+		if test -z "$mb"
+		then
+			echo "$(eval_gettext "Changes to \$onto:")"
+		else
+			echo "$(eval_gettext "Changes from \$mb to \$onto:")"
+		fi
 	fi
+	mb_tree="${mb:-$(git hash-object -t tree /dev/null)}"
 	# We want color (if set), but no pager
-	GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
+	GIT_PAGER='' git diff --stat --summary "$mb_tree" "$onto"
 fi
 
 test -n "$interactive_rebase" && run_specific_rebase
diff --git a/git-sh-i18n.sh b/git-sh-i18n.sh
index 9d065fb..e1d917f 100644
--- a/git-sh-i18n.sh
+++ b/git-sh-i18n.sh
@@ -17,7 +17,7 @@
 
 # First decide what scheme to use...
 GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
-if test -n "$GIT_GETTEXT_POISON"
+if test -n "$GIT_TEST_GETTEXT_POISON"
 then
 	GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
 elif test -n "@@USE_GETTEXT_SCHEME@@"
diff --git a/git.c b/git.c
index 2f604a4..4d53a3d 100644
--- a/git.c
+++ b/git.c
@@ -338,27 +338,27 @@
 			if (ret >= 0)   /* normal exit */
 				exit(ret);
 
-			die_errno("while expanding alias '%s': '%s'",
-			    alias_command, alias_string + 1);
+			die_errno(_("while expanding alias '%s': '%s'"),
+				  alias_command, alias_string + 1);
 		}
 		count = split_cmdline(alias_string, &new_argv);
 		if (count < 0)
-			die("Bad alias.%s string: %s", alias_command,
-			    split_cmdline_strerror(count));
+			die(_("bad alias.%s string: %s"), alias_command,
+			    _(split_cmdline_strerror(count)));
 		option_count = handle_options(&new_argv, &count, &envchanged);
 		if (envchanged)
-			die("alias '%s' changes environment variables.\n"
-				 "You can use '!git' in the alias to do this",
-				 alias_command);
+			die(_("alias '%s' changes environment variables.\n"
+			      "You can use '!git' in the alias to do this"),
+			    alias_command);
 		memmove(new_argv - option_count, new_argv,
 				count * sizeof(char *));
 		new_argv -= option_count;
 
 		if (count < 1)
-			die("empty alias for %s", alias_command);
+			die(_("empty alias for %s"), alias_command);
 
 		if (!strcmp(alias_command, new_argv[0]))
-			die("recursive alias: %s", alias_command);
+			die(_("recursive alias: %s"), alias_command);
 
 		trace_argv_printf(new_argv,
 				  "trace: alias expansion: %s =>",
@@ -409,7 +409,7 @@
 
 	if (!help && get_super_prefix()) {
 		if (!(p->option & SUPPORT_SUPER_PREFIX))
-			die("%s doesn't support --super-prefix", p->cmd);
+			die(_("%s doesn't support --super-prefix"), p->cmd);
 	}
 
 	if (!help && p->option & NEED_WORK_TREE)
@@ -433,11 +433,11 @@
 
 	/* Check for ENOSPC and EIO errors.. */
 	if (fflush(stdout))
-		die_errno("write failure on standard output");
+		die_errno(_("write failure on standard output"));
 	if (ferror(stdout))
-		die("unknown write failure on standard output");
+		die(_("unknown write failure on standard output"));
 	if (fclose(stdout))
-		die_errno("close failed on standard output");
+		die_errno(_("close failed on standard output"));
 	return 0;
 }
 
@@ -654,7 +654,7 @@
 	int status;
 
 	if (get_super_prefix())
-		die("%s doesn't support --super-prefix", argv[0]);
+		die(_("%s doesn't support --super-prefix"), argv[0]);
 
 	if (use_pager == -1 && !is_builtin(argv[0]))
 		use_pager = check_pager_config(argv[0]);
@@ -766,7 +766,7 @@
 	if (skip_prefix(cmd, "git-", &cmd)) {
 		argv[0] = cmd;
 		handle_builtin(argc, argv);
-		die("cannot handle %s as a builtin", cmd);
+		die(_("cannot handle %s as a builtin"), cmd);
 	}
 
 	/* Look for flags.. */
@@ -779,7 +779,7 @@
 	} else {
 		/* The user didn't specify a command; give them help */
 		commit_pager_choice();
-		printf("usage: %s\n\n", git_usage_string);
+		printf(_("usage: %s\n\n"), git_usage_string);
 		list_common_cmds_help();
 		printf("\n%s\n", _(git_more_info_string));
 		exit(1);
diff --git a/grep.c b/grep.c
index f6bd89e..0d50598 100644
--- a/grep.c
+++ b/grep.c
@@ -1513,7 +1513,6 @@
 	}
 }
 
-#ifndef NO_PTHREADS
 int grep_use_locks;
 
 /*
@@ -1539,11 +1538,6 @@
  */
 pthread_mutex_t grep_read_mutex;
 
-#else
-#define grep_attr_lock()
-#define grep_attr_unlock()
-#endif
-
 static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bol, char *eol)
 {
 	xdemitconf_t *xecfg = opt->priv;
@@ -1811,7 +1805,7 @@
 		 * is not thread-safe.
 		 */
 		grep_attr_lock();
-		textconv = userdiff_get_textconv(gs->driver);
+		textconv = userdiff_get_textconv(opt->repo, gs->driver);
 		grep_attr_unlock();
 	}
 
diff --git a/grep.h b/grep.h
index 1a57d12..fb04893 100644
--- a/grep.h
+++ b/grep.h
@@ -229,7 +229,6 @@
 extern struct grep_opt *grep_opt_dup(const struct grep_opt *opt);
 extern int grep_threads_ok(const struct grep_opt *opt);
 
-#ifndef NO_PTHREADS
 /*
  * Mutex used around access to the attributes machinery if
  * opt->use_threads.  Must be initialized/destroyed by callers!
@@ -250,9 +249,4 @@
 		pthread_mutex_unlock(&grep_read_mutex);
 }
 
-#else
-#define grep_read_lock()
-#define grep_read_unlock()
-#endif
-
 #endif
diff --git a/help.c b/help.c
index 4745b32..ff05fd2 100644
--- a/help.c
+++ b/help.c
@@ -83,8 +83,9 @@
 
 	for (i = 0; cmds[i].name; i++) {
 		if (cmds[i].category & mask) {
+			size_t len = strlen(cmds[i].name);
 			printf("   %s   ", cmds[i].name);
-			mput_char(' ', longest - strlen(cmds[i].name));
+			mput_char(' ', longest > len ? longest - len : 1);
 			puts(_(cmds[i].help));
 		}
 	}
@@ -526,6 +527,13 @@
 
 	git_config(get_alias, &alias_list);
 	string_list_sort(&alias_list);
+
+	for (i = 0; i < alias_list.nr; i++) {
+		size_t len = strlen(alias_list.items[i].string);
+		if (longest < len)
+			longest = len;
+	}
+
 	if (alias_list.nr) {
 		printf("\n%s\n", _("Command aliases"));
 		ALLOC_ARRAY(aliases, alias_list.nr + 1);
diff --git a/help.h b/help.h
index 9eab6a3..a141e20 100644
--- a/help.h
+++ b/help.h
@@ -15,7 +15,7 @@
 
 static inline void mput_char(char c, unsigned int num)
 {
-	while(num--)
+	while (num--)
 		putchar(c);
 }
 
diff --git a/http-push.c b/http-push.c
index d1f52cb..cd48590 100644
--- a/http-push.c
+++ b/http-push.c
@@ -365,7 +365,7 @@
 	git_zstream stream;
 
 	unpacked = read_object_file(&request->obj->oid, &type, &len);
-	hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1;
+	hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
 
 	/* Set it up */
 	git_deflate_init(&stream, zlib_compression_level);
diff --git a/http-walker.c b/http-walker.c
index b3334bf..0a392c8 100644
--- a/http-walker.c
+++ b/http-walker.c
@@ -547,7 +547,7 @@
 		ret = error("File %s has bad hash", hex);
 	} else if (req->rename < 0) {
 		struct strbuf buf = STRBUF_INIT;
-		sha1_file_name(the_repository, &buf, req->sha1);
+		loose_object_path(the_repository, &buf, req->sha1);
 		ret = error("unable to write sha1 filename %s", buf.buf);
 		strbuf_release(&buf);
 	}
diff --git a/http.c b/http.c
index 3dc8c56..0b6807c 100644
--- a/http.c
+++ b/http.c
@@ -48,6 +48,7 @@
 
 static int curl_ssl_verify = -1;
 static int curl_ssl_try;
+static const char *curl_http_version = NULL;
 static const char *ssl_cert;
 static const char *ssl_cipherlist;
 static const char *ssl_version;
@@ -284,6 +285,9 @@
 
 static int http_options(const char *var, const char *value, void *cb)
 {
+	if (!strcmp("http.version", var)) {
+		return git_config_string(&curl_http_version, var, value);
+	}
 	if (!strcmp("http.sslverify", var)) {
 		curl_ssl_verify = git_config_bool(var, value);
 		return 0;
@@ -789,6 +793,31 @@
 }
 #endif
 
+#if LIBCURL_VERSION_NUM >=0x072f00
+static int get_curl_http_version_opt(const char *version_string, long *opt)
+{
+	int i;
+	static struct {
+		const char *name;
+		long opt_token;
+	} choice[] = {
+		{ "HTTP/1.1", CURL_HTTP_VERSION_1_1 },
+		{ "HTTP/2", CURL_HTTP_VERSION_2 }
+	};
+
+	for (i = 0; i < ARRAY_SIZE(choice); i++) {
+		if (!strcmp(version_string, choice[i].name)) {
+			*opt = choice[i].opt_token;
+			return 0;
+		}
+	}
+
+	warning("unknown value given to http.version: '%s'", version_string);
+	return -1; /* not found */
+}
+
+#endif
+
 static CURL *get_curl_handle(void)
 {
 	CURL *result = curl_easy_init();
@@ -806,6 +835,16 @@
 		curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
 	}
 
+#if LIBCURL_VERSION_NUM >= 0x072f00 // 7.47.0
+    if (curl_http_version) {
+		long opt;
+		if (!get_curl_http_version_opt(curl_http_version, &opt)) {
+			/* Set request use http version */
+			curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);
+		}
+    }
+#endif
+
 #if LIBCURL_VERSION_NUM >= 0x070907
 	curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
 #endif
@@ -834,7 +873,7 @@
 #if LIBCURL_VERSION_NUM >= 0x072c00
 		curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
 #else
-		warning(_("CURLSSLOPT_NO_REVOKE not suported with cURL < 7.44.0"));
+		warning(_("CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"));
 #endif
 	}
 
@@ -2314,7 +2353,7 @@
 	hashcpy(freq->sha1, sha1);
 	freq->localfile = -1;
 
-	sha1_file_name(the_repository, &filename, sha1);
+	loose_object_path(the_repository, &filename, sha1);
 	strbuf_addf(&freq->tmpfile, "%s.temp", filename.buf);
 
 	strbuf_addf(&prevfile, "%s.prev", filename.buf);
@@ -2465,7 +2504,7 @@
 		unlink_or_warn(freq->tmpfile.buf);
 		return -1;
 	}
-	sha1_file_name(the_repository, &filename, freq->sha1);
+	loose_object_path(the_repository, &filename, freq->sha1);
 	freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf);
 	strbuf_release(&filename);
 
diff --git a/line-log.c b/line-log.c
index d1d429d..24e2173 100644
--- a/line-log.c
+++ b/line-log.c
@@ -479,7 +479,7 @@
 		struct object *obj = revs->pending.objects[i].item;
 		if (obj->flags & UNINTERESTING)
 			continue;
-		obj = deref_tag(the_repository, obj, NULL, 0);
+		obj = deref_tag(revs->repo, obj, NULL, 0);
 		if (obj->type != OBJ_COMMIT)
 			die("Non commit %s?", revs->pending.objects[i].name);
 		if (commit)
diff --git a/list-objects-filter.c b/list-objects-filter.c
index 765f3df..a62624a 100644
--- a/list-objects-filter.c
+++ b/list-objects-filter.c
@@ -34,6 +34,7 @@
 };
 
 static enum list_objects_filter_result filter_blobs_none(
+	struct repository *r,
 	enum list_objects_filter_situation filter_situation,
 	struct object *obj,
 	const char *pathname,
@@ -88,6 +89,7 @@
 };
 
 static enum list_objects_filter_result filter_trees_none(
+	struct repository *r,
 	enum list_objects_filter_situation filter_situation,
 	struct object *obj,
 	const char *pathname,
@@ -144,6 +146,7 @@
 };
 
 static enum list_objects_filter_result filter_blobs_limit(
+	struct repository *r,
 	enum list_objects_filter_situation filter_situation,
 	struct object *obj,
 	const char *pathname,
@@ -171,7 +174,7 @@
 		assert(obj->type == OBJ_BLOB);
 		assert((obj->flags & SEEN) == 0);
 
-		t = oid_object_info(the_repository, &obj->oid, &object_length);
+		t = oid_object_info(r, &obj->oid, &object_length);
 		if (t != OBJ_BLOB) { /* probably OBJ_NONE */
 			/*
 			 * We DO NOT have the blob locally, so we cannot
@@ -249,6 +252,7 @@
 };
 
 static enum list_objects_filter_result filter_sparse(
+	struct repository *r,
 	enum list_objects_filter_situation filter_situation,
 	struct object *obj,
 	const char *pathname,
@@ -268,7 +272,7 @@
 		dtype = DT_DIR;
 		val = is_excluded_from_list(pathname, strlen(pathname),
 					    filename, &dtype, &filter_data->el,
-					    &the_index);
+					    r->index);
 		if (val < 0)
 			val = filter_data->array_frame[filter_data->nr].defval;
 
@@ -331,7 +335,7 @@
 		dtype = DT_REG;
 		val = is_excluded_from_list(pathname, strlen(pathname),
 					    filename, &dtype, &filter_data->el,
-					    &the_index);
+					    r->index);
 		if (val < 0)
 			val = frame->defval;
 		if (val > 0) {
diff --git a/list-objects-filter.h b/list-objects-filter.h
index 52b4a84..1d45a4a 100644
--- a/list-objects-filter.h
+++ b/list-objects-filter.h
@@ -4,6 +4,7 @@
 struct list_objects_filter_options;
 struct object;
 struct oidset;
+struct repository;
 
 /*
  * During list-object traversal we allow certain objects to be
@@ -60,6 +61,7 @@
 };
 
 typedef enum list_objects_filter_result (*filter_object_fn)(
+	struct repository *r,
 	enum list_objects_filter_situation filter_situation,
 	struct object *obj,
 	const char *pathname,
diff --git a/list-objects.c b/list-objects.c
index c41cc80..cf7f25b 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -55,7 +55,8 @@
 	pathlen = path->len;
 	strbuf_addstr(path, name);
 	if ((obj->flags & NOT_USER_GIVEN) && ctx->filter_fn)
-		r = ctx->filter_fn(LOFS_BLOB, obj,
+		r = ctx->filter_fn(ctx->revs->repo,
+				   LOFS_BLOB, obj,
 				   path->buf, &path->buf[pathlen],
 				   ctx->filter_data);
 	if (r & LOFR_MARK_SEEN)
@@ -122,7 +123,7 @@
 		}
 
 		if (S_ISDIR(entry.mode)) {
-			struct tree *t = lookup_tree(the_repository, entry.oid);
+			struct tree *t = lookup_tree(ctx->revs->repo, entry.oid);
 			t->object.flags |= NOT_USER_GIVEN;
 			process_tree(ctx, t, base, entry.path);
 		}
@@ -130,7 +131,7 @@
 			process_gitlink(ctx, entry.oid->hash,
 					base, entry.path);
 		else {
-			struct blob *b = lookup_blob(the_repository, entry.oid);
+			struct blob *b = lookup_blob(ctx->revs->repo, entry.oid);
 			b->object.flags |= NOT_USER_GIVEN;
 			process_blob(ctx, b, base, entry.path);
 		}
@@ -175,7 +176,8 @@
 
 	strbuf_addstr(base, name);
 	if ((obj->flags & NOT_USER_GIVEN) && ctx->filter_fn)
-		r = ctx->filter_fn(LOFS_BEGIN_TREE, obj,
+		r = ctx->filter_fn(ctx->revs->repo,
+				   LOFS_BEGIN_TREE, obj,
 				   base->buf, &base->buf[baselen],
 				   ctx->filter_data);
 	if (r & LOFR_MARK_SEEN)
@@ -191,7 +193,8 @@
 		process_tree_contents(ctx, tree, base);
 
 	if ((obj->flags & NOT_USER_GIVEN) && ctx->filter_fn) {
-		r = ctx->filter_fn(LOFS_END_TREE, obj,
+		r = ctx->filter_fn(ctx->revs->repo,
+				   LOFS_END_TREE, obj,
 				   base->buf, &base->buf[baselen],
 				   ctx->filter_data);
 		if (r & LOFR_MARK_SEEN)
diff --git a/ll-merge.c b/ll-merge.c
index 3c8fb91..5b8d46a 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -384,7 +384,9 @@
 	if (opts->virtual_ancestor) {
 		if (driver->recursive)
 			driver = find_ll_merge_driver(driver->recursive);
-		marker_size += 2;
+	}
+	if (opts->extra_marker_size) {
+		marker_size += opts->extra_marker_size;
 	}
 	return driver->fn(driver, result_buf, path, ancestor, ancestor_label,
 			  ours, our_label, theirs, their_label,
diff --git a/ll-merge.h b/ll-merge.h
index 6c6e22e..b9e2af1 100644
--- a/ll-merge.h
+++ b/ll-merge.h
@@ -13,6 +13,7 @@
 	unsigned virtual_ancestor : 1;
 	unsigned variant : 2;	/* favor ours, favor theirs, or union merge */
 	unsigned renormalize : 1;
+	unsigned extra_marker_size;
 	long xdl_opts;
 };
 
diff --git a/log-tree.c b/log-tree.c
index 7a83e99..10680c1 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -755,14 +755,23 @@
 
 	if (cmit_fmt_is_mail(ctx.fmt) && opt->rdiff1) {
 		struct diff_queue_struct dq;
+		struct diff_options opts;
 
 		memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));
 		DIFF_QUEUE_CLEAR(&diff_queued_diff);
 
 		next_commentary_block(opt, NULL);
 		fprintf_ln(opt->diffopt.file, "%s", opt->rdiff_title);
+		/*
+		 * Pass minimum required diff-options to range-diff; others
+		 * can be added later if deemed desirable.
+		 */
+		diff_setup(&opts);
+		opts.file = opt->diffopt.file;
+		opts.use_color = opt->diffopt.use_color;
+		diff_setup_done(&opts);
 		show_range_diff(opt->rdiff1, opt->rdiff2,
-				opt->creation_factor, 1, &opt->diffopt);
+				opt->creation_factor, 1, &opts);
 
 		memcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));
 	}
diff --git a/merge-recursive.c b/merge-recursive.c
index acc2f64..ecf8db0 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -186,6 +186,7 @@
 enum rename_type {
 	RENAME_NORMAL = 0,
 	RENAME_VIA_DIR,
+	RENAME_ADD,
 	RENAME_DELETE,
 	RENAME_ONE_FILE_TO_ONE,
 	RENAME_ONE_FILE_TO_TWO,
@@ -228,6 +229,7 @@
 					      struct stage_data *src_entry1,
 					      struct stage_data *src_entry2)
 {
+	int ostage1 = 0, ostage2;
 	struct rename_conflict_info *ci;
 
 	/*
@@ -264,18 +266,22 @@
 		dst_entry2->rename_conflict_info = ci;
 	}
 
-	if (rename_type == RENAME_TWO_FILES_TO_ONE) {
-		/*
-		 * For each rename, there could have been
-		 * modifications on the side of history where that
-		 * file was not renamed.
-		 */
-		int ostage1 = o->branch1 == branch1 ? 3 : 2;
-		int ostage2 = ostage1 ^ 1;
+	/*
+	 * For each rename, there could have been
+	 * modifications on the side of history where that
+	 * file was not renamed.
+	 */
+	if (rename_type == RENAME_ADD ||
+	    rename_type == RENAME_TWO_FILES_TO_ONE) {
+		ostage1 = o->branch1 == branch1 ? 3 : 2;
 
 		ci->ren1_other.path = pair1->one->path;
 		oidcpy(&ci->ren1_other.oid, &src_entry1->stages[ostage1].oid);
 		ci->ren1_other.mode = src_entry1->stages[ostage1].mode;
+	}
+
+	if (rename_type == RENAME_TWO_FILES_TO_ONE) {
+		ostage2 = ostage1 ^ 1;
 
 		ci->ren2_other.path = pair2->one->path;
 		oidcpy(&ci->ren2_other.oid, &src_entry2->stages[ostage2].oid);
@@ -690,27 +696,6 @@
 	return 0;
 }
 
-static int update_stages_for_stage_data(struct merge_options *opt,
-					const char *path,
-					const struct stage_data *stage_data)
-{
-	struct diff_filespec o, a, b;
-
-	o.mode = stage_data->stages[1].mode;
-	oidcpy(&o.oid, &stage_data->stages[1].oid);
-
-	a.mode = stage_data->stages[2].mode;
-	oidcpy(&a.oid, &stage_data->stages[2].oid);
-
-	b.mode = stage_data->stages[3].mode;
-	oidcpy(&b.oid, &stage_data->stages[3].oid);
-
-	return update_stages(opt, path,
-			     is_null_oid(&o.oid) ? NULL : &o,
-			     is_null_oid(&a.oid) ? NULL : &a,
-			     is_null_oid(&b.oid) ? NULL : &b);
-}
-
 static void update_entry(struct stage_data *entry,
 			 struct diff_filespec *o,
 			 struct diff_filespec *a,
@@ -1058,7 +1043,8 @@
 		      const struct diff_filespec *a,
 		      const struct diff_filespec *b,
 		      const char *branch1,
-		      const char *branch2)
+		      const char *branch2,
+		      const int extra_marker_size)
 {
 	mmfile_t orig, src1, src2;
 	struct ll_merge_options ll_opts = {0};
@@ -1066,6 +1052,7 @@
 	int merge_status;
 
 	ll_opts.renormalize = o->renormalize;
+	ll_opts.extra_marker_size = extra_marker_size;
 	ll_opts.xdl_opts = o->xdl_opts;
 
 	if (o->call_depth) {
@@ -1301,6 +1288,7 @@
 				   const char *filename,
 				   const char *branch1,
 				   const char *branch2,
+				   const int extra_marker_size,
 				   struct merge_file_info *result)
 {
 	if (o->branch1 != branch1) {
@@ -1311,7 +1299,8 @@
 		 */
 		return merge_mode_and_contents(o, one, b, a,
 					       filename,
-					       branch2, branch1, result);
+					       branch2, branch1,
+					       extra_marker_size, result);
 	}
 
 	result->merge = 0;
@@ -1352,7 +1341,8 @@
 			int ret = 0, merge_status;
 
 			merge_status = merge_3way(o, &result_buf, one, a, b,
-						  branch1, branch2);
+						  branch1, branch2,
+						  extra_marker_size);
 
 			if ((merge_status < 0) || !result_buf.ptr)
 				ret = err(o, _("Failed to execute internal merge"));
@@ -1555,80 +1545,203 @@
 	return target;
 }
 
-static int handle_file(struct merge_options *o,
-			struct diff_filespec *rename,
-			int stage,
-			struct rename_conflict_info *ci)
+static int handle_file_collision(struct merge_options *o,
+				 const char *collide_path,
+				 const char *prev_path1,
+				 const char *prev_path2,
+				 const char *branch1, const char *branch2,
+				 const struct object_id *a_oid,
+				 unsigned int a_mode,
+				 const struct object_id *b_oid,
+				 unsigned int b_mode)
 {
-	char *dst_name = rename->path;
-	struct stage_data *dst_entry;
-	const char *cur_branch, *other_branch;
-	struct diff_filespec other;
-	struct diff_filespec *add;
-	int ret;
+	struct merge_file_info mfi;
+	struct diff_filespec null, a, b;
+	char *alt_path = NULL;
+	const char *update_path = collide_path;
 
-	if (stage == 2) {
-		dst_entry = ci->dst_entry1;
-		cur_branch = ci->branch1;
-		other_branch = ci->branch2;
-	} else {
-		dst_entry = ci->dst_entry2;
-		cur_branch = ci->branch2;
-		other_branch = ci->branch1;
+	/*
+	 * It's easiest to get the correct things into stage 2 and 3, and
+	 * to make sure that the content merge puts HEAD before the other
+	 * branch if we just ensure that branch1 == o->branch1.  So, simply
+	 * flip arguments around if we don't have that.
+	 */
+	if (branch1 != o->branch1) {
+		return handle_file_collision(o, collide_path,
+					     prev_path2, prev_path1,
+					     branch2, branch1,
+					     b_oid, b_mode,
+					     a_oid, a_mode);
 	}
 
-	add = filespec_from_entry(&other, dst_entry, stage ^ 1);
-	if (add) {
-		int ren_src_was_dirty = was_dirty(o, rename->path);
-		char *add_name = unique_path(o, rename->path, other_branch);
-		if (update_file(o, 0, &add->oid, add->mode, add_name))
-			return -1;
-
-		if (ren_src_was_dirty) {
-			output(o, 1, _("Refusing to lose dirty file at %s"),
-			       rename->path);
+	/*
+	 * In the recursive case, we just opt to undo renames
+	 */
+	if (o->call_depth && (prev_path1 || prev_path2)) {
+		/* Put first file (a_oid, a_mode) in its original spot */
+		if (prev_path1) {
+			if (update_file(o, 1, a_oid, a_mode, prev_path1))
+				return -1;
+		} else {
+			if (update_file(o, 1, a_oid, a_mode, collide_path))
+				return -1;
 		}
+
+		/* Put second file (b_oid, b_mode) in its original spot */
+		if (prev_path2) {
+			if (update_file(o, 1, b_oid, b_mode, prev_path2))
+				return -1;
+		} else {
+			if (update_file(o, 1, b_oid, b_mode, collide_path))
+				return -1;
+		}
+
+		/* Don't leave something at collision path if unrenaming both */
+		if (prev_path1 && prev_path2)
+			remove_file(o, 1, collide_path, 0);
+
+		return 0;
+	}
+
+	/* Remove rename sources if rename/add or rename/rename(2to1) */
+	if (prev_path1)
+		remove_file(o, 1, prev_path1,
+			    o->call_depth || would_lose_untracked(prev_path1));
+	if (prev_path2)
+		remove_file(o, 1, prev_path2,
+			    o->call_depth || would_lose_untracked(prev_path2));
+
+	/*
+	 * Remove the collision path, if it wouldn't cause dirty contents
+	 * or an untracked file to get lost.  We'll either overwrite with
+	 * merged contents, or just write out to differently named files.
+	 */
+	if (was_dirty(o, collide_path)) {
+		output(o, 1, _("Refusing to lose dirty file at %s"),
+		       collide_path);
+		update_path = alt_path = unique_path(o, collide_path, "merged");
+	} else if (would_lose_untracked(collide_path)) {
 		/*
-		 * Because the double negatives somehow keep confusing me...
-		 *    1) update_wd iff !ren_src_was_dirty.
-		 *    2) no_wd iff !update_wd
-		 *    3) so, no_wd == !!ren_src_was_dirty == ren_src_was_dirty
+		 * Only way we get here is if both renames were from
+		 * a directory rename AND user had an untracked file
+		 * at the location where both files end up after the
+		 * two directory renames.  See testcase 10d of t6043.
 		 */
-		remove_file(o, 0, rename->path, ren_src_was_dirty);
-		dst_name = unique_path(o, rename->path, cur_branch);
+		output(o, 1, _("Refusing to lose untracked file at "
+			       "%s, even though it's in the way."),
+		       collide_path);
+		update_path = alt_path = unique_path(o, collide_path, "merged");
 	} else {
-		if (dir_in_way(rename->path, !o->call_depth, 0)) {
-			dst_name = unique_path(o, rename->path, cur_branch);
-			output(o, 1, _("%s is a directory in %s adding as %s instead"),
-			       rename->path, other_branch, dst_name);
-		} else if (!o->call_depth &&
-			   would_lose_untracked(rename->path)) {
-			dst_name = unique_path(o, rename->path, cur_branch);
-			output(o, 1, _("Refusing to lose untracked file at %s; "
-				       "adding as %s instead"),
-			       rename->path, dst_name);
-		}
+		/*
+		 * FIXME: It's possible that the two files are identical
+		 * and that the current working copy happens to match, in
+		 * which case we are unnecessarily touching the working
+		 * tree file.  It's not a likely enough scenario that I
+		 * want to code up the checks for it and a better fix is
+		 * available if we restructure how unpack_trees() and
+		 * merge-recursive interoperate anyway, so punting for
+		 * now...
+		 */
+		remove_file(o, 0, collide_path, 0);
 	}
-	if ((ret = update_file(o, 0, &rename->oid, rename->mode, dst_name)))
-		; /* fall through, do allow dst_name to be released */
-	else if (stage == 2)
-		ret = update_stages(o, rename->path, NULL, rename, add);
-	else
-		ret = update_stages(o, rename->path, NULL, add, rename);
 
-	if (dst_name != rename->path)
-		free(dst_name);
+	/* Store things in diff_filespecs for functions that need it */
+	memset(&a, 0, sizeof(struct diff_filespec));
+	memset(&b, 0, sizeof(struct diff_filespec));
+	null.path = a.path = b.path = (char *)collide_path;
+	oidcpy(&null.oid, &null_oid);
+	null.mode = 0;
+	oidcpy(&a.oid, a_oid);
+	a.mode = a_mode;
+	a.oid_valid = 1;
+	oidcpy(&b.oid, b_oid);
+	b.mode = b_mode;
+	b.oid_valid = 1;
 
-	return ret;
+	if (merge_mode_and_contents(o, &null, &a, &b, collide_path,
+				    branch1, branch2, o->call_depth * 2, &mfi))
+		return -1;
+	mfi.clean &= !alt_path;
+	if (update_file(o, mfi.clean, &mfi.oid, mfi.mode, update_path))
+		return -1;
+	if (!mfi.clean && !o->call_depth &&
+	    update_stages(o, collide_path, NULL, &a, &b))
+		return -1;
+	free(alt_path);
+	/*
+	 * FIXME: If both a & b both started with conflicts (only possible
+	 * if they came from a rename/rename(2to1)), but had IDENTICAL
+	 * contents including those conflicts, then in the next line we claim
+	 * it was clean.  If someone cares about this case, we should have the
+	 * caller notify us if we started with conflicts.
+	 */
+	return mfi.clean;
+}
+
+static int handle_rename_add(struct merge_options *o,
+			     struct rename_conflict_info *ci)
+{
+	/* a was renamed to c, and a separate c was added. */
+	struct diff_filespec *a = ci->pair1->one;
+	struct diff_filespec *c = ci->pair1->two;
+	char *path = c->path;
+	char *prev_path_desc;
+	struct merge_file_info mfi;
+
+	int other_stage = (ci->branch1 == o->branch1 ? 3 : 2);
+
+	output(o, 1, _("CONFLICT (rename/add): "
+	       "Rename %s->%s in %s.  Added %s in %s"),
+	       a->path, c->path, ci->branch1,
+	       c->path, ci->branch2);
+
+	prev_path_desc = xstrfmt("version of %s from %s", path, a->path);
+	if (merge_mode_and_contents(o, a, c, &ci->ren1_other, prev_path_desc,
+				    o->branch1, o->branch2,
+				    1 + o->call_depth * 2, &mfi))
+		return -1;
+	free(prev_path_desc);
+
+	return handle_file_collision(o,
+				     c->path, a->path, NULL,
+				     ci->branch1, ci->branch2,
+				     &mfi.oid, mfi.mode,
+				     &ci->dst_entry1->stages[other_stage].oid,
+				     ci->dst_entry1->stages[other_stage].mode);
+}
+
+static char *find_path_for_conflict(struct merge_options *o,
+				    const char *path,
+				    const char *branch1,
+				    const char *branch2)
+{
+	char *new_path = NULL;
+	if (dir_in_way(path, !o->call_depth, 0)) {
+		new_path = unique_path(o, path, branch1);
+		output(o, 1, _("%s is a directory in %s adding "
+			       "as %s instead"),
+		       path, branch2, new_path);
+	} else if (would_lose_untracked(path)) {
+		new_path = unique_path(o, path, branch1);
+		output(o, 1, _("Refusing to lose untracked file"
+			       " at %s; adding as %s instead"),
+		       path, new_path);
+	}
+
+	return new_path;
 }
 
 static int handle_rename_rename_1to2(struct merge_options *o,
 				     struct rename_conflict_info *ci)
 {
 	/* One file was renamed in both branches, but to different names. */
+	struct merge_file_info mfi;
+	struct diff_filespec other;
+	struct diff_filespec *add;
 	struct diff_filespec *one = ci->pair1->one;
 	struct diff_filespec *a = ci->pair1->two;
 	struct diff_filespec *b = ci->pair2->two;
+	char *path_desc;
 
 	output(o, 1, _("CONFLICT (rename/rename): "
 	       "Rename \"%s\"->\"%s\" in branch \"%s\" "
@@ -1636,14 +1749,16 @@
 	       one->path, a->path, ci->branch1,
 	       one->path, b->path, ci->branch2,
 	       o->call_depth ? _(" (left unresolved)") : "");
-	if (o->call_depth) {
-		struct merge_file_info mfi;
-		struct diff_filespec other;
-		struct diff_filespec *add;
-		if (merge_mode_and_contents(o, one, a, b, one->path,
-					    ci->branch1, ci->branch2, &mfi))
-			return -1;
 
+	path_desc = xstrfmt("%s and %s, both renamed from %s",
+			    a->path, b->path, one->path);
+	if (merge_mode_and_contents(o, one, a, b, path_desc,
+				    ci->branch1, ci->branch2,
+				    o->call_depth * 2, &mfi))
+		return -1;
+	free(path_desc);
+
+	if (o->call_depth) {
 		/*
 		 * FIXME: For rename/add-source conflicts (if we could detect
 		 * such), this is wrong.  We should instead find a unique
@@ -1675,8 +1790,50 @@
 		}
 		else
 			remove_file_from_cache(b->path);
-	} else if (handle_file(o, a, 2, ci) || handle_file(o, b, 3, ci))
-		return -1;
+	} else {
+		/*
+		 * For each destination path, we need to see if there is a
+		 * rename/add collision.  If not, we can write the file out
+		 * to the specified location.
+		 */
+		add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1);
+		if (add) {
+			if (handle_file_collision(o, a->path,
+						  NULL, NULL,
+						  ci->branch1, ci->branch2,
+						  &mfi.oid, mfi.mode,
+						  &add->oid, add->mode) < 0)
+				return -1;
+		} else {
+			char *new_path = find_path_for_conflict(o, a->path,
+								ci->branch1,
+								ci->branch2);
+			if (update_file(o, 0, &mfi.oid, mfi.mode, new_path ? new_path : a->path))
+				return -1;
+			free(new_path);
+			if (update_stages(o, a->path, NULL, a, NULL))
+				return -1;
+		}
+
+		add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1);
+		if (add) {
+			if (handle_file_collision(o, b->path,
+						  NULL, NULL,
+						  ci->branch1, ci->branch2,
+						  &add->oid, add->mode,
+						  &mfi.oid, mfi.mode) < 0)
+				return -1;
+		} else {
+			char *new_path = find_path_for_conflict(o, b->path,
+								ci->branch2,
+								ci->branch1);
+			if (update_file(o, 0, &mfi.oid, mfi.mode, new_path ? new_path : b->path))
+				return -1;
+			free(new_path);
+			if (update_stages(o, b->path, NULL, NULL, b))
+				return -1;
+		}
+	}
 
 	return 0;
 }
@@ -1694,7 +1851,6 @@
 	char *path_side_2_desc;
 	struct merge_file_info mfi_c1;
 	struct merge_file_info mfi_c2;
-	int ret;
 
 	output(o, 1, _("CONFLICT (rename/rename): "
 	       "Rename %s->%s in %s. "
@@ -1702,79 +1858,22 @@
 	       a->path, c1->path, ci->branch1,
 	       b->path, c2->path, ci->branch2);
 
-	remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path));
-	remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path));
-
 	path_side_1_desc = xstrfmt("version of %s from %s", path, a->path);
 	path_side_2_desc = xstrfmt("version of %s from %s", path, b->path);
 	if (merge_mode_and_contents(o, a, c1, &ci->ren1_other, path_side_1_desc,
-				    o->branch1, o->branch2, &mfi_c1) ||
+				    o->branch1, o->branch2,
+				    1 + o->call_depth * 2, &mfi_c1) ||
 	    merge_mode_and_contents(o, b, &ci->ren2_other, c2, path_side_2_desc,
-				    o->branch1, o->branch2, &mfi_c2))
+				    o->branch1, o->branch2,
+				    1 + o->call_depth * 2, &mfi_c2))
 		return -1;
 	free(path_side_1_desc);
 	free(path_side_2_desc);
 
-	if (o->call_depth) {
-		/*
-		 * If mfi_c1.clean && mfi_c2.clean, then it might make
-		 * sense to do a two-way merge of those results.  But, I
-		 * think in all cases, it makes sense to have the virtual
-		 * merge base just undo the renames; they can be detected
-		 * again later for the non-recursive merge.
-		 */
-		remove_file(o, 0, path, 0);
-		ret = update_file(o, 0, &mfi_c1.oid, mfi_c1.mode, a->path);
-		if (!ret)
-			ret = update_file(o, 0, &mfi_c2.oid, mfi_c2.mode,
-					  b->path);
-	} else {
-		char *new_path1 = unique_path(o, path, ci->branch1);
-		char *new_path2 = unique_path(o, path, ci->branch2);
-		output(o, 1, _("Renaming %s to %s and %s to %s instead"),
-		       a->path, new_path1, b->path, new_path2);
-		if (was_dirty(o, path))
-			output(o, 1, _("Refusing to lose dirty file at %s"),
-			       path);
-		else if (would_lose_untracked(path))
-			/*
-			 * Only way we get here is if both renames were from
-			 * a directory rename AND user had an untracked file
-			 * at the location where both files end up after the
-			 * two directory renames.  See testcase 10d of t6043.
-			 */
-			output(o, 1, _("Refusing to lose untracked file at "
-				       "%s, even though it's in the way."),
-			       path);
-		else
-			remove_file(o, 0, path, 0);
-		ret = update_file(o, 0, &mfi_c1.oid, mfi_c1.mode, new_path1);
-		if (!ret)
-			ret = update_file(o, 0, &mfi_c2.oid, mfi_c2.mode,
-					  new_path2);
-		/*
-		 * unpack_trees() actually populates the index for us for
-		 * "normal" rename/rename(2to1) situtations so that the
-		 * correct entries are at the higher stages, which would
-		 * make the call below to update_stages_for_stage_data
-		 * unnecessary.  However, if either of the renames came
-		 * from a directory rename, then unpack_trees() will not
-		 * have gotten the right data loaded into the index, so we
-		 * need to do so now.  (While it'd be tempting to move this
-		 * call to update_stages_for_stage_data() to
-		 * apply_directory_rename_modifications(), that would break
-		 * our intermediate calls to would_lose_untracked() since
-		 * those rely on the current in-memory index.  See also the
-		 * big "NOTE" in update_stages()).
-		 */
-		if (update_stages_for_stage_data(o, path, ci->dst_entry1))
-			ret = -1;
-
-		free(new_path2);
-		free(new_path1);
-	}
-
-	return ret;
+	return handle_file_collision(o, path, a->path, b->path,
+				     ci->branch1, ci->branch2,
+				     &mfi_c1.oid, mfi_c1.mode,
+				     &mfi_c2.oid, mfi_c2.mode);
 }
 
 /*
@@ -2732,47 +2831,23 @@
 						      0  /* update_wd    */))
 					clean_merge = -1;
 			} else if (!oid_eq(&dst_other.oid, &null_oid)) {
-				clean_merge = 0;
-				try_merge = 1;
-				output(o, 1, _("CONFLICT (rename/add): Rename %s->%s in %s. "
-				       "%s added in %s"),
-				       ren1_src, ren1_dst, branch1,
-				       ren1_dst, branch2);
-				if (o->call_depth) {
-					struct merge_file_info mfi;
-					struct diff_filespec one, a, b;
-
-					oidcpy(&one.oid, &null_oid);
-					one.mode = 0;
-					one.path = ren1->pair->two->path;
-
-					oidcpy(&a.oid, &ren1->pair->two->oid);
-					a.mode = ren1->pair->two->mode;
-					a.path = one.path;
-
-					oidcpy(&b.oid, &dst_other.oid);
-					b.mode = dst_other.mode;
-					b.path = one.path;
-
-					if (merge_mode_and_contents(o, &one, &a, &b, ren1_dst,
-								    branch1, branch2,
-								    &mfi)) {
-						clean_merge = -1;
-						goto cleanup_and_return;
-					}
-					output(o, 1, _("Adding merged %s"), ren1_dst);
-					if (update_file(o, 0, &mfi.oid,
-							mfi.mode, ren1_dst))
-						clean_merge = -1;
-					try_merge = 0;
-				} else {
-					char *new_path = unique_path(o, ren1_dst, branch2);
-					output(o, 1, _("Adding as %s instead"), new_path);
-					if (update_file(o, 0, &dst_other.oid,
-							dst_other.mode, new_path))
-						clean_merge = -1;
-					free(new_path);
-				}
+				/*
+				 * Probably not a clean merge, but it's
+				 * premature to set clean_merge to 0 here,
+				 * because if the rename merges cleanly and
+				 * the merge exactly matches the newly added
+				 * file, then the merge will be clean.
+				 */
+				setup_rename_conflict_info(RENAME_ADD,
+							   ren1->pair,
+							   NULL,
+							   branch1,
+							   branch2,
+							   ren1->dst_entry,
+							   NULL,
+							   o,
+							   ren1->src_entry,
+							   NULL);
 			} else
 				try_merge = 1;
 
@@ -3053,7 +3128,8 @@
 			df_conflict_remains = 1;
 	}
 	if (merge_mode_and_contents(o, &one, &a, &b, path,
-				    o->branch1, o->branch2, &mfi))
+				    o->branch1, o->branch2,
+				    o->call_depth * 2, &mfi))
 		return -1;
 
 	/*
@@ -3183,6 +3259,15 @@
 						  conflict_info->branch2))
 				clean_merge = -1;
 			break;
+		case RENAME_ADD:
+			/*
+			 * Probably unclean merge, but if the renamed file
+			 * merges cleanly and the result can then be
+			 * two-way merged cleanly with the added file, I
+			 * guess it's a clean merge?
+			 */
+			clean_merge = handle_rename_add(o, conflict_info);
+			break;
 		case RENAME_DELETE:
 			clean_merge = 0;
 			if (handle_rename_delete(o,
@@ -3197,9 +3282,14 @@
 				clean_merge = -1;
 			break;
 		case RENAME_TWO_FILES_TO_ONE:
-			clean_merge = 0;
-			if (handle_rename_rename_2to1(o, conflict_info))
-				clean_merge = -1;
+			/*
+			 * Probably unclean merge, but if the two renamed
+			 * files merge cleanly and the two resulting files
+			 * can then be two-way merged cleanly, I guess it's
+			 * a clean merge?
+			 */
+			clean_merge = handle_rename_rename_2to1(o,
+								conflict_info);
 			break;
 		default:
 			entry->processed = 0;
@@ -3267,14 +3357,27 @@
 				clean_merge = -1;
 		}
 	} else if (a_oid && b_oid) {
-		/* Case C: Added in both (check for same permissions) and */
-		/* case D: Modified in both, but differently. */
-		int is_dirty = 0; /* unpack_trees would have bailed if dirty */
-		clean_merge = handle_content_merge(o, path, is_dirty,
-						   o_oid, o_mode,
-						   a_oid, a_mode,
-						   b_oid, b_mode,
-						   NULL);
+		if (!o_oid) {
+			/* Case C: Added in both (check for same permissions) */
+			output(o, 1,
+			       _("CONFLICT (add/add): Merge conflict in %s"),
+			       path);
+			clean_merge = handle_file_collision(o,
+							    path, NULL, NULL,
+							    o->branch1,
+							    o->branch2,
+							    a_oid, a_mode,
+							    b_oid, b_mode);
+		} else {
+			/* case D: Modified in both, but differently. */
+			int is_dirty = 0; /* unpack_trees would have bailed if dirty */
+			clean_merge = handle_content_merge(o, path,
+							   is_dirty,
+							   o_oid, o_mode,
+							   a_oid, a_mode,
+							   b_oid, b_mode,
+							   NULL);
+		}
 	} else if (!o_oid && !a_oid && !b_oid) {
 		/*
 		 * this entry was deleted altogether. a_mode == 0 means
diff --git a/midx.c b/midx.c
index a50b117..8a505fd 100644
--- a/midx.c
+++ b/midx.c
@@ -202,7 +202,7 @@
 	struct strbuf pack_name = STRBUF_INIT;
 
 	if (pack_int_id >= m->num_packs)
-		die(_("bad pack-int-id: %u (%u total packs"),
+		die(_("bad pack-int-id: %u (%u total packs)"),
 		    pack_int_id, m->num_packs);
 
 	if (m->packs[pack_int_id])
@@ -721,12 +721,18 @@
 static size_t write_midx_large_offsets(struct hashfile *f, uint32_t nr_large_offset,
 				       struct pack_midx_entry *objects, uint32_t nr_objects)
 {
-	struct pack_midx_entry *list = objects;
+	struct pack_midx_entry *list = objects, *end = objects + nr_objects;
 	size_t written = 0;
 
 	while (nr_large_offset) {
-		struct pack_midx_entry *obj = list++;
-		uint64_t offset = obj->offset;
+		struct pack_midx_entry *obj;
+		uint64_t offset;
+
+		if (list >= end)
+			BUG("too many large-offset objects");
+
+		obj = list++;
+		offset = obj->offset;
 
 		if (!(offset >> 31))
 			continue;
@@ -925,7 +931,7 @@
 
 void clear_midx_file(struct repository *r)
 {
-	char *midx = get_midx_filename(r->objects->objectdir);
+	char *midx = get_midx_filename(r->objects->odb->path);
 
 	if (r->objects && r->objects->multi_pack_index) {
 		close_midx(r->objects->multi_pack_index);
diff --git a/name-hash.c b/name-hash.c
index 1fcda73..623ca69 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -7,6 +7,7 @@
  */
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
+#include "thread-utils.h"
 
 struct dir_entry {
 	struct hashmap_entry ent;
@@ -131,22 +132,6 @@
 static int lazy_try_threaded = 1;
 static int lazy_nr_dir_threads;
 
-#ifdef NO_PTHREADS
-
-static inline int lookup_lazy_params(struct index_state *istate)
-{
-	return 0;
-}
-
-static inline void threaded_lazy_init_name_hash(
-	struct index_state *istate)
-{
-}
-
-#else
-
-#include "thread-utils.h"
-
 /*
  * Set a minimum number of cache_entries that we will handle per
  * thread and use that to decide how many threads to run (upto
@@ -509,6 +494,7 @@
 static void threaded_lazy_init_name_hash(
 	struct index_state *istate)
 {
+	int err;
 	int nr_each;
 	int k_start;
 	int t;
@@ -516,6 +502,9 @@
 	struct lazy_dir_thread_data *td_dir;
 	struct lazy_name_thread_data *td_name;
 
+	if (!HAVE_THREADS)
+		return;
+
 	k_start = 0;
 	nr_each = DIV_ROUND_UP(istate->cache_nr, lazy_nr_dir_threads);
 
@@ -538,8 +527,9 @@
 		if (k_start > istate->cache_nr)
 			k_start = istate->cache_nr;
 		td_dir_t->k_end = k_start;
-		if (pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t))
-			die("unable to create lazy_dir_thread");
+		err = pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t);
+		if (err)
+			die(_("unable to create lazy_dir thread: %s"), strerror(err));
 	}
 	for (t = 0; t < lazy_nr_dir_threads; t++) {
 		struct lazy_dir_thread_data *td_dir_t = td_dir + t;
@@ -559,13 +549,15 @@
 	 */
 	td_name->istate = istate;
 	td_name->lazy_entries = lazy_entries;
-	if (pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name))
-		die("unable to create lazy_name_thread");
+	err = pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name);
+	if (err)
+		die(_("unable to create lazy_name thread: %s"), strerror(err));
 
 	lazy_update_dir_ref_counts(istate, lazy_entries);
 
-	if (pthread_join(td_name->pthread, NULL))
-		die("unable to join lazy_name_thread");
+	err = pthread_join(td_name->pthread, NULL);
+	if (err)
+		die(_("unable to join lazy_name thread: %s"), strerror(err));
 
 	cleanup_dir_mutex();
 
@@ -574,8 +566,6 @@
 	free(lazy_entries);
 }
 
-#endif
-
 static void lazy_init_name_hash(struct index_state *istate)
 {
 
diff --git a/notes-cache.c b/notes-cache.c
index d87e7ca..2473314 100644
--- a/notes-cache.c
+++ b/notes-cache.c
@@ -5,7 +5,9 @@
 #include "commit.h"
 #include "refs.h"
 
-static int notes_cache_match_validity(const char *ref, const char *validity)
+static int notes_cache_match_validity(struct repository *r,
+				      const char *ref,
+				      const char *validity)
 {
 	struct object_id oid;
 	struct commit *commit;
@@ -16,7 +18,7 @@
 	if (read_ref(ref, &oid) < 0)
 		return 0;
 
-	commit = lookup_commit_reference_gently(the_repository, &oid, 1);
+	commit = lookup_commit_reference_gently(r, &oid, 1);
 	if (!commit)
 		return 0;
 
@@ -30,8 +32,8 @@
 	return ret;
 }
 
-void notes_cache_init(struct notes_cache *c, const char *name,
-		     const char *validity)
+void notes_cache_init(struct repository *r, struct notes_cache *c,
+		      const char *name, const char *validity)
 {
 	struct strbuf ref = STRBUF_INIT;
 	int flags = NOTES_INIT_WRITABLE;
@@ -40,7 +42,7 @@
 	c->validity = xstrdup(validity);
 
 	strbuf_addf(&ref, "refs/notes/%s", name);
-	if (!notes_cache_match_validity(ref.buf, validity))
+	if (!notes_cache_match_validity(r, ref.buf, validity))
 		flags |= NOTES_INIT_EMPTY;
 	init_notes(&c->tree, ref.buf, combine_notes_overwrite, flags);
 	strbuf_release(&ref);
diff --git a/notes-cache.h b/notes-cache.h
index aeeee84..56f8c98 100644
--- a/notes-cache.h
+++ b/notes-cache.h
@@ -3,13 +3,15 @@
 
 #include "notes.h"
 
+struct repository;
+
 struct notes_cache {
 	struct notes_tree tree;
 	char *validity;
 };
 
-void notes_cache_init(struct notes_cache *c, const char *name,
-		     const char *validity);
+void notes_cache_init(struct repository *r, struct notes_cache *c,
+		      const char *name, const char *validity);
 int notes_cache_write(struct notes_cache *c);
 
 char *notes_cache_get(struct notes_cache *c, struct object_id *oid, size_t
diff --git a/notes-merge.c b/notes-merge.c
index bd05d50..72688d3 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -18,11 +18,13 @@
 	struct object_id obj, base, local, remote;
 };
 
-void init_notes_merge_options(struct notes_merge_options *o)
+void init_notes_merge_options(struct repository *r,
+			      struct notes_merge_options *o)
 {
 	memset(o, 0, sizeof(struct notes_merge_options));
 	strbuf_init(&(o->commit_msg), 0);
 	o->verbosity = NOTES_MERGE_VERBOSITY_DEFAULT;
+	o->repo = r;
 }
 
 static int path_to_oid(const char *path, struct object_id *oid)
@@ -127,7 +129,7 @@
 	trace_printf("\tdiff_tree_remote(base = %.7s, remote = %.7s)\n",
 	       oid_to_hex(base), oid_to_hex(remote));
 
-	repo_diff_setup(the_repository, &opt);
+	repo_diff_setup(o->repo, &opt);
 	opt.flags.recursive = 1;
 	opt.output_format = DIFF_FORMAT_NO_OUTPUT;
 	diff_setup_done(&opt);
@@ -190,7 +192,7 @@
 	trace_printf("\tdiff_tree_local(len = %i, base = %.7s, local = %.7s)\n",
 	       len, oid_to_hex(base), oid_to_hex(local));
 
-	repo_diff_setup(the_repository, &opt);
+	repo_diff_setup(o->repo, &opt);
 	opt.flags.recursive = 1;
 	opt.output_format = DIFF_FORMAT_NO_OUTPUT;
 	diff_setup_done(&opt);
@@ -350,7 +352,7 @@
 
 	status = ll_merge(&result_buf, oid_to_hex(&p->obj), &base, NULL,
 			  &local, o->local_ref, &remote, o->remote_ref,
-			  &the_index, NULL);
+			  o->repo->index, NULL);
 
 	free(base.ptr);
 	free(local.ptr);
@@ -556,7 +558,7 @@
 	else if (!check_refname_format(o->local_ref, 0) &&
 		is_null_oid(&local_oid))
 		local = NULL; /* local_oid == null_oid indicates unborn ref */
-	else if (!(local = lookup_commit_reference(the_repository, &local_oid)))
+	else if (!(local = lookup_commit_reference(o->repo, &local_oid)))
 		die("Could not parse local commit %s (%s)",
 		    oid_to_hex(&local_oid), o->local_ref);
 	trace_printf("\tlocal commit: %.7s\n", oid_to_hex(&local_oid));
@@ -574,7 +576,7 @@
 			die("Failed to resolve remote notes ref '%s'",
 			    o->remote_ref);
 		}
-	} else if (!(remote = lookup_commit_reference(the_repository, &remote_oid))) {
+	} else if (!(remote = lookup_commit_reference(o->repo, &remote_oid))) {
 		die("Could not parse remote commit %s (%s)",
 		    oid_to_hex(&remote_oid), o->remote_ref);
 	}
@@ -711,7 +713,7 @@
 		/* write file as blob, and add to partial_tree */
 		if (stat(path.buf, &st))
 			die_errno("Failed to stat '%s'", path.buf);
-		if (index_path(&the_index, &blob_oid, path.buf, &st, HASH_WRITE_OBJECT))
+		if (index_path(o->repo->index, &blob_oid, path.buf, &st, HASH_WRITE_OBJECT))
 			die("Failed to write blob object from '%s'", path.buf);
 		if (add_note(partial_tree, &obj_oid, &blob_oid, NULL))
 			die("Failed to add resolved note '%s' to notes tree",
diff --git a/notes-merge.h b/notes-merge.h
index 6c74e93..99f9c70 100644
--- a/notes-merge.h
+++ b/notes-merge.h
@@ -6,6 +6,7 @@
 
 struct commit;
 struct object_id;
+struct repository;
 
 #define NOTES_MERGE_WORKTREE "NOTES_MERGE_WORKTREE"
 
@@ -15,6 +16,7 @@
 };
 
 struct notes_merge_options {
+	struct repository *repo;
 	const char *local_ref;
 	const char *remote_ref;
 	struct strbuf commit_msg;
@@ -23,7 +25,8 @@
 	unsigned has_worktree:1;
 };
 
-void init_notes_merge_options(struct notes_merge_options *o);
+void init_notes_merge_options(struct repository *r,
+			      struct notes_merge_options *o);
 
 /*
  * Merge notes from o->remote_ref into o->local_ref
diff --git a/object-store.h b/object-store.h
index 63b7605..60758ef 100644
--- a/object-store.h
+++ b/object-store.h
@@ -7,19 +7,17 @@
 #include "sha1-array.h"
 #include "strbuf.h"
 
-struct alternate_object_database {
-	struct alternate_object_database *next;
-
-	/* see alt_scratch_buf() */
-	struct strbuf scratch;
-	size_t base_len;
+struct object_directory {
+	struct object_directory *next;
 
 	/*
-	 * Used to store the results of readdir(3) calls when searching
-	 * for unique abbreviated hashes.  This cache is never
-	 * invalidated, thus it's racy and not necessarily accurate.
-	 * That's fine for its purpose; don't use it for tasks requiring
-	 * greater accuracy!
+	 * Used to store the results of readdir(3) calls when we are OK
+	 * sacrificing accuracy due to races for speed. That includes
+	 * object existence with OBJECT_INFO_QUICK, as well as
+	 * our search for unique abbreviated hashes. Don't use it for tasks
+	 * requiring greater accuracy!
+	 *
+	 * Be sure to call odb_load_loose_cache() before using.
 	 */
 	char loose_objects_subdir_seen[256];
 	struct oid_array loose_objects_cache;
@@ -28,20 +26,15 @@
 	 * Path to the alternative object store. If this is a relative path,
 	 * it is relative to the current working directory.
 	 */
-	char path[FLEX_ARRAY];
+	char *path;
 };
+
 void prepare_alt_odb(struct repository *r);
 char *compute_alternate_path(const char *path, struct strbuf *err);
-typedef int alt_odb_fn(struct alternate_object_database *, void *);
+typedef int alt_odb_fn(struct object_directory *, void *);
 int foreach_alt_odb(alt_odb_fn, void*);
 
 /*
- * Allocate a "struct alternate_object_database" but do _not_ actually
- * add it to the list of alternates.
- */
-struct alternate_object_database *alloc_alt_odb(const char *dir);
-
-/*
  * Add the directory to the on-disk alternates file; the new entry will also
  * take effect in the current process.
  */
@@ -55,12 +48,11 @@
 void add_to_alternates_memory(const char *dir);
 
 /*
- * Returns a scratch strbuf pre-filled with the alternate object directory,
- * including a trailing slash, which can be used to access paths in the
- * alternate. Always use this over direct access to alt->scratch, as it
- * cleans up any previous use of the scratch buffer.
+ * Populate an odb's loose object cache for one particular subdirectory (i.e.,
+ * the one that corresponds to the first byte of objects you're interested in,
+ * from 0 to 255 inclusive).
  */
-struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
+void odb_load_loose_cache(struct object_directory *odb, int subdir_nr);
 
 struct packed_git {
 	struct packed_git *next;
@@ -92,17 +84,21 @@
 
 struct raw_object_store {
 	/*
-	 * Path to the repository's object store.
-	 * Cannot be NULL after initialization.
+	 * Set of all object directories; the main directory is first (and
+	 * cannot be NULL after initialization). Subsequent directories are
+	 * alternates.
 	 */
-	char *objectdir;
+	struct object_directory *odb;
+	struct object_directory **odb_tail;
+	int loaded_alternates;
 
-	/* Path to extra alternate object database if not NULL */
+	/*
+	 * A list of alternate object directories loaded from the environment;
+	 * this should not generally need to be accessed directly, but will
+	 * populate the "odb" list when prepare_alt_odb() is run.
+	 */
 	char *alternate_db;
 
-	struct alternate_object_database *alt_odb_list;
-	struct alternate_object_database **alt_odb_tail;
-
 	/*
 	 * Objects that should be substituted by other objects
 	 * (see git-replace(1)).
@@ -157,7 +153,7 @@
  * Put in `buf` the name of the file in the local object database that
  * would be used to store a loose object with the specified sha1.
  */
-void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);
+const char *loose_object_path(struct repository *r, struct strbuf *buf, const unsigned char *sha1);
 
 void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);
 
diff --git a/object.c b/object.c
index e541605..79d6360 100644
--- a/object.c
+++ b/object.c
@@ -482,27 +482,26 @@
 	return o;
 }
 
-static void free_alt_odb(struct alternate_object_database *alt)
+static void free_object_directory(struct object_directory *odb)
 {
-	strbuf_release(&alt->scratch);
-	oid_array_clear(&alt->loose_objects_cache);
-	free(alt);
+	free(odb->path);
+	oid_array_clear(&odb->loose_objects_cache);
+	free(odb);
 }
 
-static void free_alt_odbs(struct raw_object_store *o)
+static void free_object_directories(struct raw_object_store *o)
 {
-	while (o->alt_odb_list) {
-		struct alternate_object_database *next;
+	while (o->odb) {
+		struct object_directory *next;
 
-		next = o->alt_odb_list->next;
-		free_alt_odb(o->alt_odb_list);
-		o->alt_odb_list = next;
+		next = o->odb->next;
+		free_object_directory(o->odb);
+		o->odb = next;
 	}
 }
 
 void raw_object_store_clear(struct raw_object_store *o)
 {
-	FREE_AND_NULL(o->objectdir);
 	FREE_AND_NULL(o->alternate_db);
 
 	oidmap_free(o->replace_map, 1);
@@ -512,8 +511,9 @@
 	o->commit_graph = NULL;
 	o->commit_graph_attempted = 0;
 
-	free_alt_odbs(o);
-	o->alt_odb_tail = NULL;
+	free_object_directories(o);
+	o->odb_tail = NULL;
+	o->loaded_alternates = 0;
 
 	INIT_LIST_HEAD(&o->packed_git_mru);
 	close_all_packs(o);
diff --git a/object.h b/object.h
index 0feb90a..796792c 100644
--- a/object.h
+++ b/object.h
@@ -59,7 +59,7 @@
 
 /*
  * object flag allocation:
- * revision.h:               0---------10                              2526
+ * revision.h:               0---------10                              25----28
  * fetch-pack.c:             01
  * negotiator/default.c:       2--5
  * walker.c:                 0-2
@@ -78,7 +78,7 @@
  * builtin/show-branch.c:    0-------------------------------------------26
  * builtin/unpack-objects.c:                                 2021
  */
-#define FLAG_BITS  27
+#define FLAG_BITS  29
 
 /*
  * The object type is stored in 3 bits.
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index 9d1b951..5566e94 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -77,7 +77,7 @@
 			break;
 
 		default:
-			real_type = oid_object_info(the_repository,
+			real_type = oid_object_info(to_pack->repo,
 						    &entry->idx.oid, NULL);
 			break;
 		}
@@ -262,7 +262,7 @@
 	if (writer.show_progress)
 		writer.progress = start_progress("Building bitmaps", writer.selected_nr);
 
-	repo_init_revisions(the_repository, &revs, NULL);
+	repo_init_revisions(to_pack->repo, &revs, NULL);
 	revs.tag_objects = 1;
 	revs.tree_objects = 1;
 	revs.blob_objects = 1;
@@ -363,7 +363,7 @@
 void bitmap_writer_reuse_bitmaps(struct packing_data *to_pack)
 {
 	struct bitmap_index *bitmap_git;
-	if (!(bitmap_git = prepare_bitmap_git()))
+	if (!(bitmap_git = prepare_bitmap_git(to_pack->repo)))
 		return;
 
 	writer.reused = kh_init_sha1();
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 5848cc9..4695aaf 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -328,14 +328,15 @@
 	return -1;
 }
 
-static int open_pack_bitmap(struct bitmap_index *bitmap_git)
+static int open_pack_bitmap(struct repository *r,
+			    struct bitmap_index *bitmap_git)
 {
 	struct packed_git *p;
 	int ret = -1;
 
 	assert(!bitmap_git->map);
 
-	for (p = get_all_packs(the_repository); p; p = p->next) {
+	for (p = get_all_packs(r); p; p = p->next) {
 		if (open_pack_bitmap_1(bitmap_git, p) == 0)
 			ret = 0;
 	}
@@ -343,11 +344,11 @@
 	return ret;
 }
 
-struct bitmap_index *prepare_bitmap_git(void)
+struct bitmap_index *prepare_bitmap_git(struct repository *r)
 {
 	struct bitmap_index *bitmap_git = xcalloc(1, sizeof(*bitmap_git));
 
-	if (!open_pack_bitmap(bitmap_git) && !load_pack_bitmap(bitmap_git))
+	if (!open_pack_bitmap(r, bitmap_git) && !load_pack_bitmap(bitmap_git))
 		return bitmap_git;
 
 	free_bitmap_index(bitmap_git);
@@ -690,7 +691,7 @@
 	struct bitmap_index *bitmap_git = xcalloc(1, sizeof(*bitmap_git));
 	/* try to open a bitmapped pack, but don't parse it yet
 	 * because we may not need to use it */
-	if (open_pack_bitmap(bitmap_git) < 0)
+	if (open_pack_bitmap(revs->repo, bitmap_git) < 0)
 		goto cleanup;
 
 	for (i = 0; i < revs->pending.nr; ++i) {
@@ -955,7 +956,7 @@
 	struct bitmap_test_data tdata;
 	struct bitmap_index *bitmap_git;
 
-	if (!(bitmap_git = prepare_bitmap_git()))
+	if (!(bitmap_git = prepare_bitmap_git(revs->repo)))
 		die("failed to load bitmap indexes");
 
 	if (revs->pending.nr != 1)
diff --git a/pack-bitmap.h b/pack-bitmap.h
index 189dd68..8418ba8 100644
--- a/pack-bitmap.h
+++ b/pack-bitmap.h
@@ -6,6 +6,7 @@
 #include "pack-objects.h"
 
 struct commit;
+struct repository;
 struct rev_info;
 
 struct bitmap_disk_header {
@@ -39,7 +40,7 @@
 
 struct bitmap_index;
 
-struct bitmap_index *prepare_bitmap_git(void);
+struct bitmap_index *prepare_bitmap_git(struct repository *r);
 void count_bitmap_commit_list(struct bitmap_index *, uint32_t *commits,
 			      uint32_t *trees, uint32_t *blobs, uint32_t *tags);
 void traverse_bitmap_commit_list(struct bitmap_index *,
diff --git a/pack-check.c b/pack-check.c
index fa5f0ff..2cc3603 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -48,7 +48,8 @@
 	return data_crc != ntohl(*index_crc);
 }
 
-static int verify_packfile(struct packed_git *p,
+static int verify_packfile(struct repository *r,
+			   struct packed_git *p,
 			   struct pack_window **w_curs,
 			   verify_fn fn,
 			   struct progress *progress, uint32_t base_count)
@@ -135,7 +136,7 @@
 			data = NULL;
 			data_valid = 0;
 		} else {
-			data = unpack_entry(the_repository, p, entries[i].offset, &type, &size);
+			data = unpack_entry(r, p, entries[i].offset, &type, &size);
 			data_valid = 1;
 		}
 
@@ -186,7 +187,7 @@
 	return err;
 }
 
-int verify_pack(struct packed_git *p, verify_fn fn,
+int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn,
 		struct progress *progress, uint32_t base_count)
 {
 	int err = 0;
@@ -196,7 +197,7 @@
 	if (!p->index_data)
 		return -1;
 
-	err |= verify_packfile(p, &w_curs, fn, progress, base_count);
+	err |= verify_packfile(r, p, &w_curs, fn, progress, base_count);
 	unuse_pack(&w_curs);
 
 	return err;
diff --git a/pack-objects.c b/pack-objects.c
index b6cdbb0..9c45842 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -99,7 +99,7 @@
 	 * (i.e. in_pack_idx also zero) should return NULL.
 	 */
 	mapping[cnt++] = NULL;
-	for (p = get_all_packs(the_repository); p; p = p->next, cnt++) {
+	for (p = get_all_packs(pdata->repo); p; p = p->next, cnt++) {
 		if (cnt == nr) {
 			free(mapping);
 			return;
@@ -133,8 +133,10 @@
 }
 
 /* assume pdata is already zero'd by caller */
-void prepare_packing_data(struct packing_data *pdata)
+void prepare_packing_data(struct repository *r, struct packing_data *pdata)
 {
+	pdata->repo = r;
+
 	if (git_env_bool("GIT_TEST_FULL_IN_PACK_ARRAY", 0)) {
 		/*
 		 * do not initialize in_pack_by_idx[] to force the
diff --git a/pack-objects.h b/pack-objects.h
index 86ee93f..3cd8d1f 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -5,6 +5,8 @@
 #include "thread-utils.h"
 #include "pack.h"
 
+struct repository;
+
 #define DEFAULT_DELTA_CACHE_SIZE (256 * 1024 * 1024)
 
 #define OE_DFS_STATE_BITS	2
@@ -127,6 +129,7 @@
 };
 
 struct packing_data {
+	struct repository *repo;
 	struct object_entry *objects;
 	uint32_t nr_objects, nr_alloc;
 
@@ -145,9 +148,7 @@
 	struct packed_git **in_pack_by_idx;
 	struct packed_git **in_pack;
 
-#ifndef NO_PTHREADS
 	pthread_mutex_t lock;
-#endif
 
 	/*
 	 * This list contains entries for bases which we know the other side
@@ -165,19 +166,15 @@
 	unsigned char *layer;
 };
 
-void prepare_packing_data(struct packing_data *pdata);
+void prepare_packing_data(struct repository *r, struct packing_data *pdata);
 
 static inline void packing_data_lock(struct packing_data *pdata)
 {
-#ifndef NO_PTHREADS
 	pthread_mutex_lock(&pdata->lock);
-#endif
 }
 static inline void packing_data_unlock(struct packing_data *pdata)
 {
-#ifndef NO_PTHREADS
 	pthread_mutex_unlock(&pdata->lock);
-#endif
 }
 
 struct object_entry *packlist_alloc(struct packing_data *pdata,
@@ -418,7 +415,7 @@
 				     unsigned int tree_depth)
 {
 	if (!pack->tree_depth)
-		ALLOC_ARRAY(pack->tree_depth, pack->nr_objects);
+		CALLOC_ARRAY(pack->tree_depth, pack->nr_alloc);
 	pack->tree_depth[e - pack->objects] = tree_depth;
 }
 
@@ -435,7 +432,7 @@
 				unsigned char layer)
 {
 	if (!pack->layer)
-		ALLOC_ARRAY(pack->layer, pack->nr_objects);
+		CALLOC_ARRAY(pack->layer, pack->nr_alloc);
 	pack->layer[e - pack->objects] = layer;
 }
 
diff --git a/pack.h b/pack.h
index 34a9d45..da99fdd 100644
--- a/pack.h
+++ b/pack.h
@@ -4,6 +4,8 @@
 #include "object.h"
 #include "csum-file.h"
 
+struct repository;
+
 /*
  * Packed object header
  */
@@ -80,7 +82,7 @@
 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);
+extern int verify_pack(struct repository *, struct packed_git *, verify_fn fn, struct progress *, uint32_t);
 extern off_t write_pack_header(struct hashfile *f, uint32_t);
 extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
 extern char *index_pack_lockfile(int fd);
diff --git a/packfile.c b/packfile.c
index d1e6683..8c6b47c 100644
--- a/packfile.c
+++ b/packfile.c
@@ -971,16 +971,16 @@
 
 static void prepare_packed_git(struct repository *r)
 {
-	struct alternate_object_database *alt;
+	struct object_directory *odb;
 
 	if (r->objects->packed_git_initialized)
 		return;
-	prepare_multi_pack_index_one(r, r->objects->objectdir, 1);
-	prepare_packed_git_one(r, r->objects->objectdir, 1);
+
 	prepare_alt_odb(r);
-	for (alt = r->objects->alt_odb_list; alt; alt = alt->next) {
-		prepare_multi_pack_index_one(r, alt->path, 0);
-		prepare_packed_git_one(r, alt->path, 0);
+	for (odb = r->objects->odb; odb; odb = odb->next) {
+		int local = (odb == r->objects->odb);
+		prepare_multi_pack_index_one(r, odb->path, local);
+		prepare_packed_git_one(r, odb->path, local);
 	}
 	rearrange_packed_git(r);
 
@@ -992,6 +992,14 @@
 
 void reprepare_packed_git(struct repository *r)
 {
+	struct object_directory *odb;
+
+	for (odb = r->objects->odb; odb; odb = odb->next) {
+		oid_array_clear(&odb->loose_objects_cache);
+		memset(&odb->loose_objects_subdir_seen, 0,
+		       sizeof(odb->loose_objects_subdir_seen));
+	}
+
 	r->objects->approximate_object_count_valid = 0;
 	r->objects->packed_git_initialized = 0;
 	prepare_packed_git(r);
diff --git a/parse-options-cb.c b/parse-options-cb.c
index e823653..e2f3eae 100644
--- a/parse-options-cb.c
+++ b/parse-options-cb.c
@@ -18,7 +18,8 @@
 	} else {
 		v = strtol(arg, (char **)&arg, 10);
 		if (*arg)
-			return opterror(opt, "expects a numerical value", 0);
+			return error(_("option `%s' expects a numerical value"),
+				     opt->long_name);
 		if (v && v < MINIMUM_ABBREV)
 			v = MINIMUM_ABBREV;
 		else if (v > 40)
@@ -28,13 +29,6 @@
 	return 0;
 }
 
-int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
-			     int unset)
-{
-	*(timestamp_t *)(opt->value) = approxidate(arg);
-	return 0;
-}
-
 int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
 			     int unset)
 {
@@ -54,8 +48,8 @@
 		arg = unset ? "never" : (const char *)opt->defval;
 	value = git_config_colorbool(NULL, arg);
 	if (value < 0)
-		return opterror(opt,
-			"expects \"always\", \"auto\", or \"never\"", 0);
+		return error(_("option `%s' expects \"always\", \"auto\", or \"never\""),
+			     opt->long_name);
 	*(int *)opt->value = value;
 	return 0;
 }
@@ -65,6 +59,8 @@
 {
 	int *target = opt->value;
 
+	BUG_ON_OPT_ARG(arg);
+
 	if (unset)
 		/* --no-quiet, --no-verbose */
 		*target = 0;
@@ -87,6 +83,8 @@
 	struct object_id oid;
 	struct commit *commit;
 
+	BUG_ON_OPT_NEG(unset);
+
 	if (!arg)
 		return -1;
 	if (get_oid(arg, &oid))
@@ -117,6 +115,9 @@
 int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
 {
 	int *target = opt->value;
+
+	BUG_ON_OPT_ARG(arg);
+
 	*target = unset ? 2 : 1;
 	return 0;
 }
diff --git a/parse-options.c b/parse-options.c
index 3b874a8..01c2acb 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -32,7 +32,7 @@
 		p->argc--;
 		*arg = *++p->argv;
 	} else
-		return opterror(opt, "requires a value", flags);
+		return error(_("%s requires a value"), optname(opt, flags));
 	return 0;
 }
 
@@ -49,7 +49,6 @@
 				  int flags)
 {
 	const struct option *that;
-	struct strbuf message = STRBUF_INIT;
 	struct strbuf that_name = STRBUF_INIT;
 
 	/*
@@ -67,13 +66,13 @@
 			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);
+		error(_("%s is incompatible with %s"),
+		      optname(opt, flags), 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);
+	return error(_("%s : incompatible with something else"),
+		     optname(opt, flags));
 }
 
 static int get_value(struct parse_opt_ctx_t *p,
@@ -86,11 +85,11 @@
 	int err;
 
 	if (unset && p->opt)
-		return opterror(opt, "takes no value", flags);
+		return error(_("%s takes no value"), optname(opt, flags));
 	if (unset && (opt->flags & PARSE_OPT_NONEG))
-		return opterror(opt, "isn't available", flags);
+		return error(_("%s isn't available"), optname(opt, flags));
 	if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
-		return opterror(opt, "takes no value", flags);
+		return error(_("%s takes no value"), optname(opt, flags));
 
 	switch (opt->type) {
 	case OPTION_LOWLEVEL_CALLBACK:
@@ -176,7 +175,8 @@
 			return -1;
 		*(int *)opt->value = strtol(arg, (char **)&s, 10);
 		if (*s)
-			return opterror(opt, "expects a numerical value", flags);
+			return error(_("%s expects a numerical value"),
+				     optname(opt, flags));
 		return 0;
 
 	case OPTION_MAGNITUDE:
@@ -191,13 +191,13 @@
 		if (get_arg(p, opt, flags, &arg))
 			return -1;
 		if (!git_parse_ulong(arg, opt->value))
-			return opterror(opt,
-				"expects a non-negative integer value with an optional k/m/g suffix",
-				flags);
+			return error(_("%s expects a non-negative integer value"
+				       " with an optional k/m/g suffix"),
+				     optname(opt, flags));
 		return 0;
 
 	default:
-		die("should not happen, someone must be hit on the forehead");
+		BUG("opt->type %d should not happen", opt->type);
 	}
 }
 
@@ -257,7 +257,8 @@
 			if (!rest)
 				continue;
 			if (*rest == '=')
-				return opterror(options, "takes no value", flags);
+				return error(_("%s takes no value"),
+					     optname(options, flags));
 			if (*rest)
 				continue;
 			p->out[p->cpidx++] = arg - 2;
@@ -318,8 +319,8 @@
 	}
 
 	if (ambiguous_option) {
-		error("Ambiguous option: %s "
-			"(could be --%s%s or --%s%s)",
+		error(_("ambiguous option: %s "
+			"(could be --%s%s or --%s%s)"),
 			arg,
 			(ambiguous_flags & OPT_UNSET) ?  "no-" : "",
 			ambiguous_option->long_name,
@@ -352,7 +353,7 @@
 		return;
 
 	if (starts_with(arg, "no-")) {
-		error ("did you mean `--%s` (with two dashes ?)", arg);
+		error(_("did you mean `--%s` (with two dashes ?)"), arg);
 		exit(129);
 	}
 
@@ -360,7 +361,7 @@
 		if (!options->long_name)
 			continue;
 		if (starts_with(options->long_name, arg)) {
-			error ("did you mean `--%s` (with two dashes ?)", arg);
+			error(_("did you mean `--%s` (with two dashes ?)"), arg);
 			exit(129);
 		}
 	}
@@ -423,7 +424,7 @@
 	ctx->flags = flags;
 	if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
 	    (flags & PARSE_OPT_STOP_AT_NON_OPTION))
-		die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
+		BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
 	parse_options_check(options);
 }
 
@@ -516,7 +517,7 @@
 	show_negated_gitcomp(original_opts, -1);
 	show_negated_gitcomp(original_opts, nr_noopts);
 	fputc('\n', stdout);
-	exit(0);
+	return PARSE_OPT_COMPLETE;
 }
 
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
@@ -638,16 +639,18 @@
 	case PARSE_OPT_HELP:
 	case PARSE_OPT_ERROR:
 		exit(129);
+	case PARSE_OPT_COMPLETE:
+		exit(0);
 	case PARSE_OPT_NON_OPTION:
 	case PARSE_OPT_DONE:
 		break;
 	default: /* PARSE_OPT_UNKNOWN */
 		if (ctx.argv[0][1] == '-') {
-			error("unknown option `%s'", ctx.argv[0] + 2);
+			error(_("unknown option `%s'"), ctx.argv[0] + 2);
 		} else if (isascii(*ctx.opt)) {
-			error("unknown switch `%c'", *ctx.opt);
+			error(_("unknown switch `%c'"), *ctx.opt);
 		} else {
-			error("unknown non-ascii option in string: `%s'",
+			error(_("unknown non-ascii option in string: `%s'"),
 			      ctx.argv[0]);
 		}
 		usage_with_options(usagestr, options);
@@ -773,12 +776,17 @@
 	usage_with_options(usagestr, options);
 }
 
-#undef opterror
-int opterror(const struct option *opt, const char *reason, int flags)
+const char *optname(const struct option *opt, int flags)
 {
+	static struct strbuf sb = STRBUF_INIT;
+
+	strbuf_reset(&sb);
 	if (flags & OPT_SHORT)
-		return error("switch `%c' %s", opt->short_name, reason);
-	if (flags & OPT_UNSET)
-		return error("option `no-%s' %s", opt->long_name, reason);
-	return error("option `%s' %s", opt->long_name, reason);
+		strbuf_addf(&sb, "switch `%c'", opt->short_name);
+	else if (flags & OPT_UNSET)
+		strbuf_addf(&sb, "option `no-%s'", opt->long_name);
+	else
+		strbuf_addf(&sb, "option `%s'", opt->long_name);
+
+	return sb.buf;
 }
diff --git a/parse-options.h b/parse-options.h
index dd14911..81380c2 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -150,9 +150,6 @@
 				      (h), 0, &parse_opt_string_list }
 #define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
-#define OPT_DATE(s, l, v, h) \
-	{ OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,	\
-	  parse_opt_approxidate_cb }
 #define OPT_EXPIRY_DATE(s, l, v, h) \
 	{ OPTION_CALLBACK, (s), (l), (v), N_("expiry-date"),(h), 0,	\
 	  parse_opt_expiry_date_cb }
@@ -189,14 +186,26 @@
 				   const struct option *options);
 
 extern int optbug(const struct option *opt, const char *reason);
-extern int opterror(const struct option *opt, const char *reason, int flags);
-#if defined(__GNUC__)
-#define opterror(o,r,f) (opterror((o),(r),(f)), const_error())
-#endif
+const char *optname(const struct option *opt, int flags);
+
+/*
+ * Use these assertions for callbacks that expect to be called with NONEG and
+ * NOARG respectively, and do not otherwise handle the "unset" and "arg"
+ * parameters.
+ */
+#define BUG_ON_OPT_NEG(unset) do { \
+	if ((unset)) \
+		BUG("option callback does not expect negation"); \
+} while (0)
+#define BUG_ON_OPT_ARG(arg) do { \
+	if ((arg)) \
+		BUG("option callback does not expect an argument"); \
+} while (0)
 
 /*----- incremental advanced APIs -----*/
 
 enum {
+	PARSE_OPT_COMPLETE = -2,
 	PARSE_OPT_HELP = -1,
 	PARSE_OPT_DONE,
 	PARSE_OPT_NON_OPTION,
@@ -232,7 +241,6 @@
 
 /*----- some often used options -----*/
 extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
-extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
 extern int parse_opt_expiry_date_cb(const struct option *, const char *, int);
 extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
 extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
diff --git a/path.c b/path.c
index dc3294c..03ab712 100644
--- a/path.c
+++ b/path.c
@@ -385,7 +385,7 @@
 		strbuf_splice(buf, 0, buf->len,
 			      repo->index_file, strlen(repo->index_file));
 	else if (dir_prefix(base, "objects"))
-		replace_dir(buf, git_dir_len + 7, repo->objects->objectdir);
+		replace_dir(buf, git_dir_len + 7, repo->objects->odb->path);
 	else if (git_hooks_path && dir_prefix(base, "hooks"))
 		replace_dir(buf, git_dir_len + 5, git_hooks_path);
 	else if (repo->different_commondir)
diff --git a/po/README b/po/README
index fef4c0f..aa704ff 100644
--- a/po/README
+++ b/po/README
@@ -289,16 +289,11 @@
 version of the strings, e.g. to grep some error message or other
 output.
 
-To smoke out issues like these Git can be compiled with gettext poison
-support, at the top-level:
+To smoke out issues like these, Git tested with a translation mode that
+emits gibberish on every call to gettext. To use it run the test suite
+with it, e.g.:
 
-    make GETTEXT_POISON=YesPlease
-
-That'll give you a git which emits gibberish on every call to
-gettext. It's obviously not meant to be installed, but you should run
-the test suite with it:
-
-    cd t && prove -j 9 ./t[0-9]*.sh
+    cd t && GIT_TEST_GETTEXT_POISON=YesPlease prove -j 9 ./t[0-9]*.sh
 
 If tests break with it you should inspect them manually and see if
 what you're translating is sane, i.e. that you're not translating
diff --git a/po/bg.po b/po/bg.po
index cc6bc1a..814d40a 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -13,7 +13,7 @@
 # dangling objects обект извън клон
 # fast-forward превъртане
 # tree-level merge тривиално сливане (различни файлове са променяни, слива се като дърво)
-# automatic merge автоманично сливаве (еднакви файлове са променяни, но в неприпокриващи се части)
+# automatic merge автоматично сливане (еднакви файлове са променяни, но в неприпокриващи се части)
 # real merge същинско сливане (а не превъртане)
 # three-way merge тройно сливане
 # octopus merge множествено сливане
@@ -22,7 +22,7 @@
 # merge base база за сливане
 # force (push) принудително изтласквам
 # stash/index индекс
-# squash commit вкарвам подаване в преднходното
+# squash commit вкарвам подаване в предходното
 # fixup commit вкарвам подаване в предходното без следа
 # root commit начално подаване
 # remote-tracking branch следящ клон
@@ -77,7 +77,7 @@
 # term управляваща дума (за git-bisect)
 # mergetag етикет при сливане
 # packfile пакет
-# promisory гаратиращ, гарант promisory packfile гарантиращ пакет, promisory remote хранилище-гарант
+# promisory гарантиращ, гарант promisory packfile гарантиращ пакет, promisory remote хранилище-гарант
 # delta - разлика, делта, обект-разлика
 # peeled tag - проследен етикет - когато етикет сочи към друг етикет, а не подаване и проследяваме подобно на символна връзка
 # strip - премахвам (за компонент при филтриране)
@@ -87,7 +87,7 @@
 # binary patch двоична кръпка
 # reverse-apply прилагам в обратна посока
 # todo file файл с команди
-# todo command запланувава команда
+# todo command запланувана команда
 # alternate алтернативен източник
 # superproject обхващащ проект
 # split index разделяне на индекса
@@ -117,7 +117,16 @@
 # fork създаване на процес
 # capabilities възможности
 # remote-helper насрещна помощна програма
-#
+# command alias псевдоним на команда
+# rerere преизползване на запазена корекция на сливане с конфликт
+# preimage предварителен вариант
+# offset отместване
+# multi-pack-index индекс за множество пакети
+# range diff диапазонна разлика
+# inter diff разлика в разликите
+# ssl backend реализация на SSL
+# delta island група разлики
+# island marks граници на групите
 # ------------------------
 # „$var“ - може да не сработва за shell има gettext и eval_gettext - проверка - намират се лесно по „$
 # ------------------------
@@ -134,10 +143,10 @@
 # for i in `sort -u FILES`; do cnt=`grep $i FILES | wc -l`; echo $cnt $i ;done | sort -n
 msgid ""
 msgstr ""
-"Project-Id-Version: git master\n"
+"Project-Id-Version: git 2.20\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-09-04 08:50+0800\n"
-"PO-Revision-Date: 2018-09-09 11:28+0200\n"
+"POT-Creation-Date: 2018-12-02 10:55+0800\n"
+"PO-Revision-Date: 2018-12-02 13:41+0100\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
 "Language: bg\n"
@@ -146,37 +155,37 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: advice.c:97
+#: advice.c:99
 #, c-format
 msgid "%shint: %.*s%s\n"
 msgstr "%sподсказка: %.*s%s\n"
 
-#: advice.c:150
+#: advice.c:152
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "Отбирането на подавания е блокирано от неслети файлове."
 
-#: advice.c:152
+#: advice.c:154
 msgid "Committing is not possible because you have unmerged files."
 msgstr "Подаването е блокирано от неслети файлове."
 
-#: advice.c:154
+#: advice.c:156
 msgid "Merging is not possible because you have unmerged files."
 msgstr "Сливането е блокирано от неслети файлове."
 
-#: advice.c:156
+#: advice.c:158
 msgid "Pulling is not possible because you have unmerged files."
 msgstr "Издърпването е блокирано от неслети файлове."
 
-#: advice.c:158
+#: advice.c:160
 msgid "Reverting is not possible because you have unmerged files."
 msgstr "Отмяната е блокирана от неслети файлове."
 
-#: advice.c:160
+#: advice.c:162
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr "Действието „%s“ е блокирано от неслети файлове."
 
-#: advice.c:168
+#: advice.c:170
 msgid ""
 "Fix them up in the work tree, and then use 'git add/rm <file>'\n"
 "as appropriate to mark resolution and make a commit."
@@ -184,23 +193,23 @@
 "Редактирайте ги в работното дърво, и тогава ползвайте „git add/rm ФАЙЛ“,\n"
 "за да отбележите коригирането им.  След това извършете подаването."
 
-#: advice.c:176
+#: advice.c:178
 msgid "Exiting because of an unresolved conflict."
 msgstr "Изход от програмата заради некоригиран конфликт."
 
-#: advice.c:181 builtin/merge.c:1286
+#: advice.c:183 builtin/merge.c:1289
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "Не сте завършили сливане.  (Указателят „MERGE_HEAD“ съществува)."
 
-#: advice.c:183
+#: advice.c:185
 msgid "Please, commit your changes before merging."
 msgstr "Промените трябва да се подадат преди сливане."
 
-#: advice.c:184
+#: advice.c:186
 msgid "Exiting because of unfinished merge."
 msgstr "Изход от програмата заради незавършено сливане."
 
-#: advice.c:190
+#: advice.c:192
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -307,22 +316,22 @@
 msgid "invalid mode on line %d: %s"
 msgstr "грешен режим на ред №%d: %s"
 
-#: apply.c:1306
+#: apply.c:1307
 #, c-format
 msgid "inconsistent header lines %d and %d"
 msgstr "несъвместими заглавни части на редове №%d и №%d"
 
-#: apply.c:1478
+#: apply.c:1479
 #, c-format
 msgid "recount: unexpected line: %.*s"
 msgstr "при повторното преброяване бе получен неочакван ред: „%.*s“"
 
-#: apply.c:1547
+#: apply.c:1548
 #, c-format
 msgid "patch fragment without header at line %d: %.*s"
 msgstr "част от кръпка без заглавна част на ред %d: %.*s"
 
-#: apply.c:1567
+#: apply.c:1568
 #, c-format
 msgid ""
 "git diff header lacks filename information when removing %d leading pathname "
@@ -337,71 +346,71 @@
 "След съкращаването на първите %d части от компонентите на пътя, в заглавната "
 "част на „git diff“ липсва информация за име на файл (ред: %d)"
 
-#: apply.c:1580
+#: apply.c:1581
 #, c-format
 msgid "git diff header lacks filename information (line %d)"
 msgstr ""
 "в заглавната част на „git diff“ липсва информация за име на файл (ред: %d)"
 
-#: apply.c:1768
+#: apply.c:1769
 msgid "new file depends on old contents"
 msgstr "новият файл зависи от старото съдържание на файла"
 
-#: apply.c:1770
+#: apply.c:1771
 msgid "deleted file still has contents"
 msgstr "изтритият файл не е празен"
 
-#: apply.c:1804
+#: apply.c:1805
 #, c-format
 msgid "corrupt patch at line %d"
 msgstr "грешка в кръпката на ред %d"
 
-#: apply.c:1841
+#: apply.c:1842
 #, c-format
 msgid "new file %s depends on old contents"
 msgstr "новият файл „%s“ зависи от старото съдържание на файла"
 
-#: apply.c:1843
+#: apply.c:1844
 #, c-format
 msgid "deleted file %s still has contents"
 msgstr "изтритият файл „%s“ не е празен"
 
-#: apply.c:1846
+#: apply.c:1847
 #, c-format
 msgid "** warning: file %s becomes empty but is not deleted"
 msgstr "● предупреждение: файлът „%s“ вече е празен, но не е изтрит"
 
-#: apply.c:1993
+#: apply.c:1994
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
 msgstr "грешка в двоичната кръпка на ред %d: %.*s"
 
-#: apply.c:2030
+#: apply.c:2031
 #, c-format
 msgid "unrecognized binary patch at line %d"
 msgstr "неразпозната двоичната кръпка на ред %d"
 
-#: apply.c:2190
+#: apply.c:2193
 #, c-format
 msgid "patch with only garbage at line %d"
 msgstr "кръпката е с изцяло повредени данни на ред %d"
 
-#: apply.c:2276
+#: apply.c:2279
 #, c-format
 msgid "unable to read symlink %s"
 msgstr "символната връзка „%s“ не може да бъде прочетена"
 
-#: apply.c:2280
+#: apply.c:2283
 #, c-format
 msgid "unable to open or read %s"
 msgstr "файлът „%s“ не може да бъде отворен или прочетен"
 
-#: apply.c:2939
+#: apply.c:2942
 #, c-format
 msgid "invalid start of line: '%c'"
 msgstr "неправилно начало на ред: „%c“"
 
-#: apply.c:3060
+#: apply.c:3063
 #, c-format
 msgid "Hunk #%d succeeded at %d (offset %d line)."
 msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
@@ -410,13 +419,13 @@
 msgstr[1] ""
 "%d-то парче код бе успешно приложено на ред %d (отместване от %d реда)."
 
-#: apply.c:3072
+#: apply.c:3075
 #, c-format
 msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
 msgstr ""
 "Контекстът е намален на (%ld/%ld) за прилагането на парчето код на ред %d"
 
-#: apply.c:3078
+#: apply.c:3081
 #, c-format
 msgid ""
 "while searching for:\n"
@@ -425,316 +434,316 @@
 "при търсене за:\n"
 "%.*s"
 
-#: apply.c:3100
+#: apply.c:3103
 #, c-format
 msgid "missing binary patch data for '%s'"
 msgstr "липсват данните за двоичната кръпка за „%s“"
 
-#: apply.c:3108
+#: apply.c:3111
 #, c-format
 msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'"
 msgstr ""
 "двоичната кръпка не може да се приложи в обратна посока, когато обратното "
 "парче за „%s“ липсва"
 
-#: apply.c:3154
+#: apply.c:3158
 #, c-format
 msgid "cannot apply binary patch to '%s' without full index line"
 msgstr "към „%s“ не може да се приложи двоична кръпка без пълен индекс"
 
-#: apply.c:3164
+#: apply.c:3168
 #, c-format
 msgid ""
 "the patch applies to '%s' (%s), which does not match the current contents."
 msgstr "кръпката съответства на „%s“ (%s), който не съвпада по съдържание."
 
-#: apply.c:3172
+#: apply.c:3176
 #, c-format
 msgid "the patch applies to an empty '%s' but it is not empty"
 msgstr "кръпката съответства на „%s“, който трябва да е празен, но не е"
 
-#: apply.c:3190
+#: apply.c:3194
 #, c-format
 msgid "the necessary postimage %s for '%s' cannot be read"
 msgstr ""
 "необходимият резултат след операцията  — „%s“ за „%s“ не може да бъде "
 "прочетен"
 
-#: apply.c:3203
+#: apply.c:3207
 #, c-format
 msgid "binary patch does not apply to '%s'"
 msgstr "двоичната кръпка не може да бъде приложена върху „%s“"
 
-#: apply.c:3209
+#: apply.c:3213
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
 msgstr ""
 "двоичната кръпка за „%s“ води до неправилни резултати (очакваше се: „%s“, а "
 "бе получено: „%s“)"
 
-#: apply.c:3230
+#: apply.c:3234
 #, c-format
 msgid "patch failed: %s:%ld"
 msgstr "неуспешно прилагане на кръпка: „%s:%ld“"
 
-#: apply.c:3352
+#: apply.c:3356
 #, c-format
 msgid "cannot checkout %s"
 msgstr "„%s“ не може да се изтегли"
 
-#: apply.c:3404 apply.c:3415 apply.c:3461 setup.c:278
+#: apply.c:3408 apply.c:3419 apply.c:3465 midx.c:58 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "файлът „%s“ не може да бъде прочетен"
 
-#: apply.c:3412
+#: apply.c:3416
 #, c-format
 msgid "reading from '%s' beyond a symbolic link"
 msgstr "изчитане на „%s“ след проследяване на символна връзка"
 
-#: apply.c:3441 apply.c:3681
+#: apply.c:3445 apply.c:3688
 #, c-format
 msgid "path %s has been renamed/deleted"
 msgstr "обектът с път „%s“ е преименуван или изтрит"
 
-#: apply.c:3524 apply.c:3696
+#: apply.c:3531 apply.c:3703
 #, c-format
 msgid "%s: does not exist in index"
 msgstr "„%s“ не съществува в индекса"
 
-#: apply.c:3533 apply.c:3704
+#: apply.c:3540 apply.c:3711
 #, c-format
 msgid "%s: does not match index"
 msgstr "„%s“ не съответства на индекса"
 
-#: apply.c:3568
+#: apply.c:3575
 msgid "repository lacks the necessary blob to fall back on 3-way merge."
 msgstr ""
 "в хранилището липсват необходимите обекти-BLOB, за да се премине към тройно "
 "сливане."
 
-#: apply.c:3571
+#: apply.c:3578
 #, c-format
 msgid "Falling back to three-way merge...\n"
 msgstr "Преминаване към тройно сливане…\n"
 
-#: apply.c:3587 apply.c:3591
+#: apply.c:3594 apply.c:3598
 #, c-format
 msgid "cannot read the current contents of '%s'"
 msgstr "текущото съдържание на „%s“ не може да бъде прочетено"
 
-#: apply.c:3603
+#: apply.c:3610
 #, c-format
 msgid "Failed to fall back on three-way merge...\n"
 msgstr "Неуспешно преминаване към тройно сливане…\n"
 
-#: apply.c:3617
+#: apply.c:3624
 #, c-format
 msgid "Applied patch to '%s' with conflicts.\n"
 msgstr "Конфликти при прилагането на кръпката към „%s“.\n"
 
-#: apply.c:3622
+#: apply.c:3629
 #, c-format
 msgid "Applied patch to '%s' cleanly.\n"
 msgstr "Кръпката бе приложена чисто към „%s“.\n"
 
-#: apply.c:3648
+#: apply.c:3655
 msgid "removal patch leaves file contents"
 msgstr "изтриващата кръпка оставя файла непразен"
 
-#: apply.c:3721
+#: apply.c:3728
 #, c-format
 msgid "%s: wrong type"
 msgstr "„%s“: неправилен вид"
 
-#: apply.c:3723
+#: apply.c:3730
 #, c-format
 msgid "%s has type %o, expected %o"
 msgstr "„%s“ е от вид „%o“, а се очакваше „%o“"
 
-#: apply.c:3874 apply.c:3876
+#: apply.c:3881 apply.c:3883
 #, c-format
 msgid "invalid path '%s'"
 msgstr "неправилен път: „%s“"
 
-#: apply.c:3932
+#: apply.c:3939
 #, c-format
 msgid "%s: already exists in index"
 msgstr "„%s“: вече съществува в индекса"
 
-#: apply.c:3935
+#: apply.c:3942
 #, c-format
 msgid "%s: already exists in working directory"
 msgstr "„%s“: вече съществува в работното дърво"
 
-#: apply.c:3955
+#: apply.c:3962
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
 msgstr "новите права за достъп (%o) на „%s“ не съвпадат със старите (%o)"
 
-#: apply.c:3960
+#: apply.c:3967
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
 msgstr ""
 "новите права за достъп (%o) на „%s“ не съвпадат със старите (%o) на „%s“"
 
-#: apply.c:3980
+#: apply.c:3987
 #, c-format
 msgid "affected file '%s' is beyond a symbolic link"
 msgstr "засегнатият файл „%s“ е след символна връзка"
 
-#: apply.c:3984
+#: apply.c:3991
 #, c-format
 msgid "%s: patch does not apply"
 msgstr "Кръпката „%s“ не може да бъде приложена"
 
-#: apply.c:3999
+#: apply.c:4006
 #, c-format
 msgid "Checking patch %s..."
 msgstr "Проверяване на кръпката „%s“…"
 
-#: apply.c:4091
+#: apply.c:4098
 #, c-format
 msgid "sha1 information is lacking or useless for submodule %s"
 msgstr ""
 "информацията за сумата по SHA1 за подмодула липсва или не е достатъчна (%s)."
 
-#: apply.c:4098
+#: apply.c:4105
 #, c-format
 msgid "mode change for %s, which is not in current HEAD"
 msgstr "смяна на режима на достъпа на „%s“, който не е в текущия връх „HEAD“"
 
-#: apply.c:4101
+#: apply.c:4108
 #, c-format
 msgid "sha1 information is lacking or useless (%s)."
 msgstr "информацията за сумата по SHA1 липсва или не е достатъчна (%s)."
 
-#: apply.c:4106 builtin/checkout.c:237 builtin/reset.c:140
+#: apply.c:4113 builtin/checkout.c:244 builtin/reset.c:142
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "неуспешно създаване на запис в кеша чрез „make_cache_entry“ за „%s“"
 
-#: apply.c:4110
+#: apply.c:4117
 #, c-format
 msgid "could not add %s to temporary index"
 msgstr "„%s“ не може да се добави към временния индекс"
 
-#: apply.c:4120
+#: apply.c:4127
 #, c-format
 msgid "could not write temporary index to %s"
 msgstr "временният индекс не може да се запази в „%s“"
 
-#: apply.c:4258
+#: apply.c:4265
 #, c-format
 msgid "unable to remove %s from index"
 msgstr "„%s“ не може да се извади от индекса"
 
-#: apply.c:4292
+#: apply.c:4299
 #, c-format
 msgid "corrupt patch for submodule %s"
 msgstr "повредена кръпка за модула „%s“"
 
-#: apply.c:4298
+#: apply.c:4305
 #, c-format
 msgid "unable to stat newly created file '%s'"
 msgstr ""
 "не може да се получи информация чрез „stat“ за новосъздадения файл „%s“"
 
-#: apply.c:4306
+#: apply.c:4313
 #, c-format
 msgid "unable to create backing store for newly created file %s"
 msgstr ""
 "не може да се за създаде мястото за съхранение на новосъздадения файл „%s“"
 
-#: apply.c:4312 apply.c:4457
+#: apply.c:4319 apply.c:4464
 #, c-format
 msgid "unable to add cache entry for %s"
 msgstr "не може да се добави запис в кеша за „%s“"
 
-#: apply.c:4355
+#: apply.c:4362
 #, c-format
 msgid "failed to write to '%s'"
 msgstr "в „%s“ не може да се пише"
 
-#: apply.c:4359
+#: apply.c:4366
 #, c-format
 msgid "closing file '%s'"
 msgstr "затваряне на файла „%s“"
 
-#: apply.c:4429
+#: apply.c:4436
 #, c-format
 msgid "unable to write file '%s' mode %o"
 msgstr "файлът „%s“ не може да се запише с режим на достъп „%o“"
 
-#: apply.c:4527
+#: apply.c:4534
 #, c-format
 msgid "Applied patch %s cleanly."
 msgstr "Кръпката „%s“ бе приложена чисто."
 
-#: apply.c:4535
+#: apply.c:4542
 msgid "internal error"
 msgstr "вътрешна грешка"
 
-#: apply.c:4538
+#: apply.c:4545
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
 msgstr[0] "Прилагане на кръпката „%%s“ с %d отхвърлено парче…"
 msgstr[1] "Прилагане на кръпката „%%s“ с %d отхвърлени парчета…"
 
-#: apply.c:4549
+#: apply.c:4556
 #, c-format
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "съкращаване на името на файла с отхвърлените парчета на „ %.*s.rej“"
 
-#: apply.c:4557 builtin/fetch.c:780 builtin/fetch.c:1048
+#: apply.c:4564 builtin/fetch.c:843 builtin/fetch.c:1122
 #, c-format
 msgid "cannot open %s"
 msgstr "„%s“ не може да бъде отворен"
 
-#: apply.c:4571
+#: apply.c:4578
 #, c-format
 msgid "Hunk #%d applied cleanly."
 msgstr "%d-то парче бе успешно приложено."
 
-#: apply.c:4575
+#: apply.c:4582
 #, c-format
 msgid "Rejected hunk #%d."
 msgstr "%d-то парче бе отхвърлено."
 
-#: apply.c:4685
+#: apply.c:4692
 #, c-format
 msgid "Skipped patch '%s'."
 msgstr "Пропусната кръпка: „%s“"
 
-#: apply.c:4693
+#: apply.c:4700
 msgid "unrecognized input"
 msgstr "непознат вход"
 
-#: apply.c:4712
+#: apply.c:4719
 msgid "unable to read index file"
 msgstr "индексът не може да бъде записан"
 
-#: apply.c:4849
+#: apply.c:4874
 #, c-format
 msgid "can't open patch '%s': %s"
 msgstr "кръпката „%s“ не може да бъде отворена: %s"
 
-#: apply.c:4876
+#: apply.c:4901
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
 msgstr[0] "пренебрегната е %d грешка в знаците за интервали"
 msgstr[1] "пренебрегнати са %d грешки в знаците за интервали"
 
-#: apply.c:4882 apply.c:4897
+#: apply.c:4907 apply.c:4922
 #, c-format
 msgid "%d line adds whitespace errors."
 msgid_plural "%d lines add whitespace errors."
 msgstr[0] "%d ред добавя грешки в знаците за интервали."
 msgstr[1] "%d реда добавят грешки в знаците за интервали."
 
-#: apply.c:4890
+#: apply.c:4915
 #, c-format
 msgid "%d line applied after fixing whitespace errors."
 msgid_plural "%d lines applied after fixing whitespace errors."
@@ -743,144 +752,145 @@
 msgstr[1] ""
 "Добавени са %d реда след корекцията на грешките в знаците за интервали."
 
-#: apply.c:4906 builtin/add.c:539 builtin/mv.c:300 builtin/rm.c:389
+#: apply.c:4931 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr "Новият индекс не може да бъде записан"
 
-#: apply.c:4933 apply.c:4936 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:121 builtin/fetch.c:115 builtin/merge.c:260
-#: builtin/pull.c:198 builtin/submodule--helper.c:406
-#: builtin/submodule--helper.c:1355 builtin/submodule--helper.c:1358
-#: builtin/submodule--helper.c:1729 builtin/submodule--helper.c:1732
-#: builtin/submodule--helper.c:1952 git-add--interactive.perl:197
+#: apply.c:4958 apply.c:4961 builtin/am.c:2209 builtin/am.c:2212
+#: builtin/clone.c:121 builtin/fetch.c:118 builtin/merge.c:262
+#: builtin/pull.c:199 builtin/submodule--helper.c:406
+#: builtin/submodule--helper.c:1362 builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1846 builtin/submodule--helper.c:1849
+#: builtin/submodule--helper.c:2088 git-add--interactive.perl:197
 msgid "path"
 msgstr "път"
 
-#: apply.c:4934
+#: apply.c:4959
 msgid "don't apply changes matching the given path"
 msgstr "без прилагане на промените напасващи на дадения път"
 
-#: apply.c:4937
+#: apply.c:4962
 msgid "apply changes matching the given path"
 msgstr "прилагане на промените напасващи на дадения път"
 
-#: apply.c:4939 builtin/am.c:2263
+#: apply.c:4964 builtin/am.c:2218
 msgid "num"
 msgstr "БРОЙ"
 
-#: apply.c:4940
+#: apply.c:4965
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr "премахване на този БРОЙ водещи елементи от пътищата в разликата"
 
-#: apply.c:4943
+#: apply.c:4968
 msgid "ignore additions made by the patch"
 msgstr "игнориране на редовете добавени от тази кръпка"
 
-#: apply.c:4945
+#: apply.c:4970
 msgid "instead of applying the patch, output diffstat for the input"
 msgstr "извеждане на статистика на промените без прилагане на кръпката"
 
-#: apply.c:4949
+#: apply.c:4974
 msgid "show number of added and deleted lines in decimal notation"
 msgstr "извеждане на броя на добавените и изтритите редове"
 
-#: apply.c:4951
+#: apply.c:4976
 msgid "instead of applying the patch, output a summary for the input"
 msgstr "извеждане на статистика на входните данни без прилагане на кръпката"
 
-#: apply.c:4953
+#: apply.c:4978
 msgid "instead of applying the patch, see if the patch is applicable"
 msgstr "проверка дали кръпката може да се приложи, без действително прилагане"
 
-#: apply.c:4955
+#: apply.c:4980
 msgid "make sure the patch is applicable to the current index"
 msgstr "проверка дали кръпката може да бъде приложена към текущия индекс"
 
-#: apply.c:4957
+#: apply.c:4982
 msgid "mark new files with `git add --intent-to-add`"
 msgstr "отбелязване на новите файлове с „git add --intent-to-add“"
 
-#: apply.c:4959
+#: apply.c:4984
 msgid "apply a patch without touching the working tree"
 msgstr "прилагане на кръпката без промяна на работното дърво"
 
-#: apply.c:4961
+#: apply.c:4986
 msgid "accept a patch that touches outside the working area"
 msgstr "прилагане на кръпка, която променя и файлове извън работното дърво"
 
-#: apply.c:4964
+#: apply.c:4989
 msgid "also apply the patch (use with --stat/--summary/--check)"
 msgstr ""
 "кръпката да бъде приложена.  Опцията се комбинира с „--check“/„--stat“/„--"
 "summary“"
 
-#: apply.c:4966
+#: apply.c:4991
 msgid "attempt three-way merge if a patch does not apply"
 msgstr "пробване с тройно сливане, ако кръпката не може да се приложи директно"
 
-#: apply.c:4968
+#: apply.c:4993
 msgid "build a temporary index based on embedded index information"
 msgstr ""
 "създаване на временен индекс на база на включената информация за индекса"
 
-#: apply.c:4971 builtin/checkout-index.c:168 builtin/ls-files.c:516
+#: apply.c:4996 builtin/checkout-index.c:170 builtin/ls-files.c:523
 msgid "paths are separated with NUL character"
 msgstr "разделяне на пътищата с нулевия знак „NUL“"
 
-#: apply.c:4973
+#: apply.c:4998
 msgid "ensure at least <n> lines of context match"
 msgstr "да се осигури контекст от поне такъв БРОЙ съвпадащи редове"
 
-#: apply.c:4974 builtin/am.c:2242 builtin/interpret-trailers.c:95
-#: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3202
+#: apply.c:4999 builtin/am.c:2197 builtin/interpret-trailers.c:97
+#: builtin/interpret-trailers.c:99 builtin/interpret-trailers.c:101
+#: builtin/pack-objects.c:3312 builtin/rebase.c:857
 msgid "action"
 msgstr "действие"
 
-#: apply.c:4975
+#: apply.c:5000
 msgid "detect new or modified lines that have whitespace errors"
 msgstr "засичане на нови или променени редове с грешки в знаците за интервали"
 
-#: apply.c:4978 apply.c:4981
+#: apply.c:5003 apply.c:5006
 msgid "ignore changes in whitespace when finding context"
 msgstr ""
 "игнориране на промените в знаците за интервали при откриване на контекста"
 
-#: apply.c:4984
+#: apply.c:5009
 msgid "apply the patch in reverse"
 msgstr "прилагане на кръпката в обратна посока"
 
-#: apply.c:4986
+#: apply.c:5011
 msgid "don't expect at least one line of context"
 msgstr "без изискване на дори и един ред контекст"
 
-#: apply.c:4988
+#: apply.c:5013
 msgid "leave the rejected hunks in corresponding *.rej files"
 msgstr "оставяне на отхвърлените парчета във файлове с разширение „.rej“"
 
-#: apply.c:4990
+#: apply.c:5015
 msgid "allow overlapping hunks"
 msgstr "позволяване на застъпващи се парчета"
 
-#: apply.c:4991 builtin/add.c:290 builtin/check-ignore.c:21
-#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:671
-#: builtin/log.c:1914 builtin/mv.c:122 builtin/read-tree.c:124
+#: apply.c:5016 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1309 builtin/count-objects.c:98 builtin/fsck.c:698
+#: builtin/log.c:2023 builtin/mv.c:122 builtin/read-tree.c:127
+#: builtin/rebase--interactive.c:157
 msgid "be verbose"
 msgstr "повече подробности"
 
-#: apply.c:4993
+#: apply.c:5018
 msgid "tolerate incorrectly detected missing new-line at the end of file"
 msgstr "пренебрегване на неправилно липсващ знак за нов ред в края на файл"
 
-#: apply.c:4996
+#: apply.c:5021
 msgid "do not trust the line counts in the hunk headers"
 msgstr "без доверяване на номерата на редовете в заглавните части на парчетата"
 
-#: apply.c:4998 builtin/am.c:2251
+#: apply.c:5023 builtin/am.c:2206
 msgid "root"
 msgstr "НАЧАЛНА_ДИРЕКТОРИЯ"
 
-#: apply.c:4999
+#: apply.c:5024
 msgid "prepend <root> to all filenames"
 msgstr "добавяне на тази НАЧАЛНА_ДИРЕКТОРИЯ към имената на всички файлове"
 
@@ -903,114 +913,114 @@
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote ХРАНИЛИЩЕ [--exec КОМАНДА] --list"
 
-#: archive.c:363 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:298
+#: archive.c:370 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "пътят „%s“ не съвпада с никой файл"
 
-#: archive.c:446
+#: archive.c:453
 msgid "fmt"
 msgstr "ФОРМАТ"
 
-#: archive.c:446
+#: archive.c:453
 msgid "archive format"
 msgstr "ФОРМАТ на архива"
 
-#: archive.c:447 builtin/log.c:1473
+#: archive.c:454 builtin/log.c:1536
 msgid "prefix"
 msgstr "ПРЕФИКС"
 
-#: archive.c:448
+#: archive.c:455
 msgid "prepend prefix to each pathname in the archive"
 msgstr "добавяне на този ПРЕФИКС към всеки път в архива"
 
-#: archive.c:449 builtin/blame.c:816 builtin/blame.c:817 builtin/config.c:126
-#: builtin/fast-export.c:1013 builtin/fast-export.c:1015 builtin/grep.c:873
-#: builtin/hash-object.c:104 builtin/ls-files.c:552 builtin/ls-files.c:555
-#: builtin/notes.c:407 builtin/notes.c:570 builtin/read-tree.c:119
-#: parse-options.h:165
+#: archive.c:456 builtin/blame.c:820 builtin/blame.c:821 builtin/config.c:129
+#: builtin/fast-export.c:1013 builtin/fast-export.c:1015 builtin/grep.c:884
+#: builtin/hash-object.c:104 builtin/ls-files.c:559 builtin/ls-files.c:562
+#: builtin/notes.c:412 builtin/notes.c:575 builtin/read-tree.c:122
+#: parse-options.h:162
 msgid "file"
 msgstr "ФАЙЛ"
 
-#: archive.c:450 builtin/archive.c:89
+#: archive.c:457 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "запазване на архива в този ФАЙЛ"
 
-#: archive.c:452
+#: archive.c:459
 msgid "read .gitattributes in working directory"
 msgstr "изчитане на „.gitattributes“ в работната директория"
 
-#: archive.c:453
+#: archive.c:460
 msgid "report archived files on stderr"
 msgstr "извеждане на архивираните файлове на стандартната грешка"
 
-#: archive.c:454
+#: archive.c:461
 msgid "store only"
 msgstr "само съхранение без компресиране"
 
-#: archive.c:455
+#: archive.c:462
 msgid "compress faster"
 msgstr "бързо компресиране"
 
-#: archive.c:463
+#: archive.c:470
 msgid "compress better"
 msgstr "добро компресиране"
 
-#: archive.c:466
+#: archive.c:473
 msgid "list supported archive formats"
 msgstr "извеждане на списъка с поддържаните формати"
 
-#: archive.c:468 builtin/archive.c:90 builtin/clone.c:111 builtin/clone.c:114
-#: builtin/submodule--helper.c:1367 builtin/submodule--helper.c:1738
+#: archive.c:475 builtin/archive.c:90 builtin/clone.c:111 builtin/clone.c:114
+#: builtin/submodule--helper.c:1374 builtin/submodule--helper.c:1855
 msgid "repo"
 msgstr "хранилище"
 
-#: archive.c:469 builtin/archive.c:91
+#: archive.c:476 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "изтегляне на архива от отдалеченото ХРАНИЛИЩЕ"
 
-#: archive.c:470 builtin/archive.c:92 builtin/difftool.c:714
-#: builtin/notes.c:491
+#: archive.c:477 builtin/archive.c:92 builtin/difftool.c:714
+#: builtin/notes.c:496
 msgid "command"
 msgstr "команда"
 
-#: archive.c:471 builtin/archive.c:93
+#: archive.c:478 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "път към отдалечената команда „git-upload-archive“"
 
-#: archive.c:478
+#: archive.c:485
 msgid "Unexpected option --remote"
 msgstr "Неочаквана опция „--remote“"
 
-#: archive.c:480
+#: archive.c:487
 msgid "Option --exec can only be used together with --remote"
 msgstr "Опцията „--exec“ изисква „--remote“"
 
-#: archive.c:482
+#: archive.c:489
 msgid "Unexpected option --output"
 msgstr "Неочаквана опция „--output“"
 
-#: archive.c:504
+#: archive.c:511
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Непознат формат на архив: „%s“"
 
-#: archive.c:511
+#: archive.c:518
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "Аргументът не се поддържа за форма̀та „%s“: -%d"
 
-#: archive-tar.c:125 archive-zip.c:344
+#: archive-tar.c:125 archive-zip.c:345
 #, c-format
 msgid "cannot stream blob %s"
 msgstr "обектът-BLOB „%s“ не може да бъде обработен"
 
-#: archive-tar.c:260 archive-zip.c:361
+#: archive-tar.c:260 archive-zip.c:363
 #, c-format
 msgid "unsupported file mode: 0%o (SHA1: %s)"
 msgstr "неподдържани права за достъп до файл: 0%o (SHA1: %s)"
 
-#: archive-tar.c:287 archive-zip.c:352
+#: archive-tar.c:287 archive-zip.c:353
 #, c-format
 msgid "cannot read %s"
 msgstr "обектът „%s“ не може да бъде прочетен"
@@ -1029,32 +1039,32 @@
 msgid "'%s' filter reported error"
 msgstr "филтърът „%s“ върна грешка"
 
-#: archive-zip.c:313
+#: archive-zip.c:314
 #, c-format
 msgid "path is not valid UTF-8: %s"
 msgstr "пътят не е правилно кодиран в UTF-8: %s"
 
-#: archive-zip.c:317
+#: archive-zip.c:318
 #, c-format
 msgid "path too long (%d chars, SHA1: %s): %s"
 msgstr "твърде дълъг път (%d знака, SHA1: %s): %s"
 
-#: archive-zip.c:470 builtin/pack-objects.c:216 builtin/pack-objects.c:219
+#: archive-zip.c:474 builtin/pack-objects.c:224 builtin/pack-objects.c:227
 #, c-format
 msgid "deflate error (%d)"
 msgstr "грешка при декомпресиране с „deflate“ (%d)"
 
-#: archive-zip.c:605
+#: archive-zip.c:609
 #, c-format
 msgid "timestamp too large for this system: %<PRIuMAX>"
 msgstr "времевата стойност е твърде голяма за тази система: %<PRIuMAX>"
 
-#: attr.c:218
+#: attr.c:212
 #, c-format
 msgid "%.*s is not a valid attribute name"
 msgstr "„%.*s“ е неправилно име за атрибут"
 
-#: attr.c:415
+#: attr.c:409
 msgid ""
 "Negative patterns are ignored in git attributes\n"
 "Use '\\!' for literal leading exclamation."
@@ -1062,22 +1072,22 @@
 "Отрицателните шаблони се игнорират в атрибутите на git.\n"
 "Ако ви трябва начална удивителна, ползвайте „\\!“."
 
-#: bisect.c:467
+#: bisect.c:468
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Неправилно цитирано съдържание във файла „%s“: %s"
 
-#: bisect.c:675
+#: bisect.c:676
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "Повече не може да се търси двоично!\n"
 
-#: bisect.c:729
+#: bisect.c:730
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "Неправилно име на подаване „%s“"
 
-#: bisect.c:753
+#: bisect.c:754
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -1086,7 +1096,7 @@
 "Неправилна база за сливане: %s.\n"
 "Следователно грешката е коригирана между „%s“ и [%s].\n"
 
-#: bisect.c:758
+#: bisect.c:759
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -1095,7 +1105,7 @@
 "Нова база за сливане: %s.\n"
 "Свойството е променено между „%s“ и [%s].\n"
 
-#: bisect.c:763
+#: bisect.c:764
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -1104,7 +1114,7 @@
 "Базата за сливане „%s“ е %s.\n"
 "Следователно първото %s подаване е между „%s“ и [%s].\n"
 
-#: bisect.c:771
+#: bisect.c:772
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -1115,7 +1125,7 @@
 "Двоичното търсене с git bisect няма да работи правилно.\n"
 "Дали не сте объркали указателите „%s“ и „%s“?\n"
 
-#: bisect.c:784
+#: bisect.c:785
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -1126,36 +1136,36 @@
 "Не може да сме сигурни, че първото %s подаване е между „%s“ и „%s“.\n"
 "Двоичното търсене продължава."
 
-#: bisect.c:817
+#: bisect.c:818
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr "Двоично търсене: трябва да се провери база за сливане\n"
 
-#: bisect.c:857
+#: bisect.c:858
 #, c-format
 msgid "a %s revision is needed"
 msgstr "необходима е версия „%s“"
 
-#: bisect.c:876 builtin/notes.c:177 builtin/tag.c:237
+#: bisect.c:877 builtin/notes.c:177 builtin/tag.c:237
 #, c-format
 msgid "could not create file '%s'"
 msgstr "файлът „%s“ не може да бъде създаден"
 
-#: bisect.c:927 builtin/merge.c:137
+#: bisect.c:928 builtin/merge.c:138
 #, c-format
 msgid "could not read file '%s'"
 msgstr "файлът „%s“ не може да бъде прочетен"
 
-#: bisect.c:957
+#: bisect.c:958
 msgid "reading bisect refs failed"
 msgstr "неуспешно прочитане на указателите за двоично търсене"
 
-#: bisect.c:976
+#: bisect.c:977
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "„%s“ e както „%s“, така и „%s“\n"
 
-#: bisect.c:984
+#: bisect.c:985
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -1164,7 +1174,7 @@
 "Липсва подходящо за тестване подаване.\n"
 "Проверете параметрите за пътищата.\n"
 
-#: bisect.c:1003
+#: bisect.c:1004
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -1174,48 +1184,48 @@
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1009
+#: bisect.c:1010
 #, c-format
 msgid "Bisecting: %d revision left to test after this %s\n"
 msgid_plural "Bisecting: %d revisions left to test after this %s\n"
 msgstr[0] "Двоично търсене: остава %d версия след тази %s\n"
 msgstr[1] "Двоично търсене: остават %d версии след тази %s\n"
 
-#: blame.c:1784
+#: blame.c:1787
 msgid "--contents and --reverse do not blend well."
 msgstr "Опциите „--contents“ и „--reverse“ са несъвместими"
 
-#: blame.c:1798
+#: blame.c:1801
 msgid "cannot use --contents with final commit object name"
 msgstr "Опцията „--contents“ е несъвместима с име на обект от крайно подаване"
 
-#: blame.c:1819
+#: blame.c:1822
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 "Едновременното задаване на опциите „--reverse“ и „--first-parent“ изисква "
 "указването на крайно подаване"
 
-#: blame.c:1828 bundle.c:162 ref-filter.c:2154 sequencer.c:1874
-#: sequencer.c:3772 builtin/commit.c:994 builtin/log.c:372 builtin/log.c:926
-#: builtin/log.c:1381 builtin/log.c:1713 builtin/log.c:1963 builtin/merge.c:404
-#: builtin/pack-objects.c:3029 builtin/pack-objects.c:3044
+#: blame.c:1831 bundle.c:162 ref-filter.c:2046 sequencer.c:1963
+#: sequencer.c:4002 builtin/commit.c:1001 builtin/log.c:377 builtin/log.c:932
+#: builtin/log.c:1407 builtin/log.c:1783 builtin/log.c:2072 builtin/merge.c:406
+#: builtin/pack-objects.c:3137 builtin/pack-objects.c:3152
 #: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr "неуспешно настройване на обхождането на версиите"
 
-#: blame.c:1846
+#: blame.c:1849
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 "Едновременното задаване на опциите „--reverse“ и „--first-parent“ изисква "
 "указването на диапазон по веригата на първите наследници"
 
-#: blame.c:1857
+#: blame.c:1860
 #, c-format
 msgid "no such path %s in %s"
 msgstr "няма път на име „%s“ в „%s“"
 
-#: blame.c:1868
+#: blame.c:1871
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr "обектът-BLOB „%s“ в пътя %s не може да бъде прочетен"
@@ -1368,7 +1378,8 @@
 msgid "unrecognized header: %s%s (%d)"
 msgstr "непозната заглавна част: %s%s (%d)"
 
-#: bundle.c:90 sequencer.c:2092 sequencer.c:2578 builtin/commit.c:768
+#: bundle.c:90 rerere.c:480 rerere.c:690 sequencer.c:2182 sequencer.c:2722
+#: builtin/commit.c:774
 #, c-format
 msgid "could not open '%s'"
 msgstr "„%s“ не може да се отвори"
@@ -1395,39 +1406,43 @@
 msgstr[0] "Пратката изисква следния указател:"
 msgstr[1] "Пратката изисква следните %d указатели:"
 
-#: bundle.c:260
+#: bundle.c:267
+msgid "unable to dup bundle descriptor"
+msgstr "неуспешно дублиране на дескриптора на пратката с „dup“"
+
+#: bundle.c:274
 msgid "Could not spawn pack-objects"
 msgstr "Командата „git pack-objects“ не може да бъде стартирана"
 
-#: bundle.c:271
+#: bundle.c:285
 msgid "pack-objects died"
 msgstr "Командата „git pack-objects“ не завърши успешно"
 
-#: bundle.c:313
+#: bundle.c:327
 msgid "rev-list died"
 msgstr "Командата „git rev-list“ не завърши успешно"
 
-#: bundle.c:362
+#: bundle.c:376
 #, c-format
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr ""
 "указателят „%s“ не е бил включен поради опциите зададени на „git rev-list“"
 
-#: bundle.c:453 builtin/log.c:187 builtin/log.c:1618 builtin/shortlog.c:304
+#: bundle.c:456 builtin/log.c:192 builtin/log.c:1688 builtin/shortlog.c:304
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "непознат аргумент: %s"
 
-#: bundle.c:461
+#: bundle.c:464
 msgid "Refusing to create empty bundle."
 msgstr "Създаването на празна пратка е невъзможно."
 
-#: bundle.c:473
+#: bundle.c:474
 #, c-format
 msgid "cannot create '%s'"
 msgstr "Файлът „%s“ не може да бъде създаден"
 
-#: bundle.c:501
+#: bundle.c:498
 msgid "index-pack died"
 msgstr "Командата „git index-pack“ не завърши успешно"
 
@@ -1436,19 +1451,19 @@
 msgid "invalid color value: %.*s"
 msgstr "неправилна стойност за цвят: %.*s"
 
-#: commit.c:48 sequencer.c:2384 builtin/am.c:422 builtin/am.c:466
-#: builtin/am.c:1438 builtin/am.c:2072 builtin/replace.c:376
+#: commit.c:50 sequencer.c:2528 builtin/am.c:370 builtin/am.c:414
+#: builtin/am.c:1390 builtin/am.c:2025 builtin/replace.c:376
 #: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "„%s“ не може да се анализира"
 
-#: commit.c:50
+#: commit.c:52
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s не е подаване!"
 
-#: commit.c:191
+#: commit.c:193
 msgid ""
 "Support for <GIT_DIR>/info/grafts is deprecated\n"
 "and will be removed in a future Git version.\n"
@@ -1471,7 +1486,29 @@
 "\n"
 "    git config advice.graftFileDeprecated false"
 
-#: commit.c:1629
+#: commit.c:1115
+#, c-format
+msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
+msgstr ""
+"Подаването „%s“ е с недоверен подпис от GPG, който твърди, че е на „%s“."
+
+#: commit.c:1118
+#, c-format
+msgid "Commit %s has a bad GPG signature allegedly by %s."
+msgstr ""
+"Подаването „%s“ е с неправилен подпис от GPG, който твърди, че е на „%s“."
+
+#: commit.c:1121
+#, c-format
+msgid "Commit %s does not have a GPG signature."
+msgstr "Подаването „%s“ е без подпис от GPG."
+
+#: commit.c:1124
+#, c-format
+msgid "Commit %s has a good GPG signature by %s\n"
+msgstr "Подаването „%s“ е с коректен подпис от GPG на „%s“.\n"
+
+#: commit.c:1378
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1481,74 +1518,90 @@
 "Може да поправите подаването заедно със съобщението или може да\n"
 "зададете ползваното кодиране в настройката „i18n.commitencoding“.\n"
 
-#: commit-graph.c:83
+#: commit-graph.c:108
 #, c-format
 msgid "graph file %s is too small"
 msgstr "файлът с гра̀фа на подаванията „%s“ е твърде малък"
 
-#: commit-graph.c:90
+#: commit-graph.c:115
 #, c-format
 msgid "graph signature %X does not match signature %X"
 msgstr "отпечатъкът на гра̀фа с подаванията %X не съвпада с %X"
 
-#: commit-graph.c:97
+#: commit-graph.c:122
 #, c-format
 msgid "graph version %X does not match version %X"
 msgstr "версията на гра̀фа с подаванията %X не съвпада с %X"
 
-#: commit-graph.c:104
+#: commit-graph.c:129
 #, c-format
 msgid "hash version %X does not match version %X"
 msgstr "версията на отпечатъка на гра̀фа с подаванията %X не съвпада с %X"
 
-#: commit-graph.c:128
+#: commit-graph.c:153
 #, c-format
 msgid "improper chunk offset %08x%08x"
 msgstr "неправилно отместване на откъс: %08x%08x"
 
-#: commit-graph.c:164
+#: commit-graph.c:189
 #, c-format
 msgid "chunk id %08x appears multiple times"
 msgstr "откъсът %08x се явява многократно"
 
-#: commit-graph.c:261
+#: commit-graph.c:308
 #, c-format
 msgid "could not find commit %s"
 msgstr "подаването „%s“ не може да бъде открито"
 
-#: commit-graph.c:565 builtin/pack-objects.c:2568
+#: commit-graph.c:617 builtin/pack-objects.c:2652
 #, c-format
 msgid "unable to get type of object %s"
 msgstr "видът на обекта „%s“ не може да бъде определен"
 
-#: commit-graph.c:730
+#: commit-graph.c:651
+msgid "Annotating commits in commit graph"
+msgstr "Анотиране на подаванията в гра̀фа"
+
+#: commit-graph.c:691
+msgid "Computing commit graph generation numbers"
+msgstr "Изчисляване на номерата на поколенията в гра̀фа с подаванията"
+
+#: commit-graph.c:803 commit-graph.c:826 commit-graph.c:852
+msgid "Finding commits for commit graph"
+msgstr "Откриване на подаванията в гра̀фа"
+
+#: commit-graph.c:812
 #, c-format
 msgid "error adding pack %s"
 msgstr "грешка при добавяне на пакетен файл „%s“"
 
-#: commit-graph.c:732
+#: commit-graph.c:814
 #, c-format
 msgid "error opening index for %s"
 msgstr "грешка при отваряне на индекса на „%s“"
 
-#: commit-graph.c:773
+#: commit-graph.c:868
 #, c-format
 msgid "the commit graph format cannot write %d commits"
 msgstr "форматът на гра̀фа с подаванията не може да запише %d подавания"
 
-#: commit-graph.c:800
+#: commit-graph.c:895
 msgid "too many commits to write graph"
 msgstr "прекалено много подавания за записване на гра̀фа"
 
-#: commit-graph.c:806
+#: commit-graph.c:902 midx.c:769
 #, c-format
 msgid "unable to create leading directories of %s"
 msgstr "родителските директории на „%s“ не могат да бъдат създадени"
 
-#: commit-graph.c:904
+#: commit-graph.c:1002
 msgid "the commit-graph file has incorrect checksum and is likely corrupt"
 msgstr "графът с подаванията е с грешна сума за проверка — вероятно е повреден"
 
+#: commit-graph.c:1046
+msgid "Verifying commits in commit graph"
+msgstr "Проверка на подаванията в гра̀фа"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "паметта свърши"
@@ -1591,7 +1644,7 @@
 msgid "key does not contain variable name: %s"
 msgstr "ключът не съдържа име на променлива: „%s“"
 
-#: config.c:378 sequencer.c:2206
+#: config.c:378 sequencer.c:2296
 #, c-format
 msgid "invalid key: %s"
 msgstr "неправилен ключ: „%s“"
@@ -1713,17 +1766,17 @@
 msgid "invalid mode for object creation: %s"
 msgstr "неправилен режим за създаването на обекти: %s"
 
-#: config.c:1403
+#: config.c:1395
 #, c-format
 msgid "malformed value for %s"
 msgstr "неправилна стойност за „%s“"
 
-#: config.c:1429
+#: config.c:1421
 #, c-format
 msgid "malformed value for %s: %s"
 msgstr "неправилна стойност за „%s“: „%s“"
 
-#: config.c:1430
+#: config.c:1422
 msgid "must be one of nothing, matching, simple, upstream or current"
 msgstr ""
 "трябва да е една от следните стойности: „nothing“ (без изтласкване при липса "
@@ -1731,139 +1784,139 @@
 "„simple“ (клонът със същото име, от който се издърпва), „upstream“ (клонът, "
 "от който се издърпва) или „current“ (клонът със същото име)"
 
-#: config.c:1489 builtin/pack-objects.c:3279
+#: config.c:1481 builtin/pack-objects.c:3391
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "неправилно ниво на компресиране при пакетиране: %d"
 
-#: config.c:1610
+#: config.c:1602
 #, c-format
 msgid "unable to load config blob object '%s'"
 msgstr "обектът-BLOB „%s“ с конфигурации не може да се зареди"
 
-#: config.c:1613
+#: config.c:1605
 #, c-format
 msgid "reference '%s' does not point to a blob"
 msgstr "указателят „%s“ не сочи към обект-BLOB"
 
-#: config.c:1630
+#: config.c:1622
 #, c-format
 msgid "unable to resolve config blob '%s'"
 msgstr "обектът-BLOB „%s“ с конфигурации не може да бъде открит"
 
-#: config.c:1660
+#: config.c:1652
 #, c-format
 msgid "failed to parse %s"
 msgstr "„%s“ не може да бъде анализиран"
 
-#: config.c:1700
+#: config.c:1705
 msgid "unable to parse command-line config"
 msgstr "неправилни настройки от командния ред"
 
-#: config.c:2032
+#: config.c:2037
 msgid "unknown error occurred while reading the configuration files"
 msgstr "неочаквана грешка при изчитането на конфигурационните файлове"
 
-#: config.c:2202
+#: config.c:2207
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "Неправилен %s: „%s“"
 
-#: config.c:2245
+#: config.c:2250
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
 "непозната стойност „%s“ за настройката „core.untrackedCache“.  Ще се ползва "
 "стандартната стойност „keep“ (запазване)"
 
-#: config.c:2271
+#: config.c:2276
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr ""
 "стойността на „splitIndex.maxPercentChange“ трябва да е между 1 и 100, а не "
 "%d"
 
-#: config.c:2296
+#: config.c:2322
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr "неразпозната стойност „%s“ от командния ред"
 
-#: config.c:2298
+#: config.c:2324
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr "неправилна настройка „%s“ във файла „%s“ на ред №%d"
 
-#: config.c:2379
+#: config.c:2405
 #, c-format
 msgid "invalid section name '%s'"
 msgstr "неправилно име на раздел: „%s“"
 
-#: config.c:2411
+#: config.c:2437
 #, c-format
 msgid "%s has multiple values"
 msgstr "зададени са няколко стойности за „%s“"
 
-#: config.c:2440
+#: config.c:2466
 #, c-format
 msgid "failed to write new configuration file %s"
 msgstr "новият конфигурационен файл „%s“ не може да бъде запазен"
 
-#: config.c:2691 config.c:3015
+#: config.c:2717 config.c:3041
 #, c-format
 msgid "could not lock config file %s"
 msgstr "конфигурационният файл „%s“ не може да бъде заключен"
 
-#: config.c:2702
+#: config.c:2728
 #, c-format
 msgid "opening %s"
 msgstr "отваряне на „%s“"
 
-#: config.c:2737 builtin/config.c:324
+#: config.c:2763 builtin/config.c:327
 #, c-format
 msgid "invalid pattern: %s"
 msgstr "неправилен шаблон: %s"
 
-#: config.c:2762
+#: config.c:2788
 #, c-format
 msgid "invalid config file %s"
 msgstr "неправилен конфигурационен файл: „%s“"
 
-#: config.c:2775 config.c:3028
+#: config.c:2801 config.c:3054
 #, c-format
 msgid "fstat on %s failed"
 msgstr "неуспешно изпълнение на „fstat“ върху „%s“"
 
-#: config.c:2786
+#: config.c:2812
 #, c-format
 msgid "unable to mmap '%s'"
 msgstr "неуспешно изпълнение на „mmap“ върху „%s“"
 
-#: config.c:2795 config.c:3033
+#: config.c:2821 config.c:3059
 #, c-format
 msgid "chmod on %s failed"
 msgstr "неуспешна смяна на права с „chmod“ върху „%s“"
 
-#: config.c:2880 config.c:3130
+#: config.c:2906 config.c:3156
 #, c-format
 msgid "could not write config file %s"
 msgstr "конфигурационният файл „%s“ не може да бъде записан"
 
-#: config.c:2914
+#: config.c:2940
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "„%s“ не може да се зададе да е „%s“"
 
-#: config.c:2916 builtin/remote.c:781
+#: config.c:2942 builtin/remote.c:782
 #, c-format
 msgid "could not unset '%s'"
 msgstr "„%s“ не може да се премахне"
 
-#: config.c:3006
+#: config.c:3032
 #, c-format
 msgid "invalid section name: %s"
 msgstr "неправилно име на раздел: %s"
 
-#: config.c:3173
+#: config.c:3199
 #, c-format
 msgid "missing value for '%s'"
 msgstr "липсва стойност за „%s“"
@@ -1917,7 +1970,7 @@
 msgid "repository on the other end cannot be shallow"
 msgstr "отсрещното хранилище не може да е плитко"
 
-#: connect.c:310 fetch-pack.c:183 builtin/archive.c:63
+#: connect.c:310 fetch-pack.c:182 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "отдалечена грешка: %s"
@@ -2037,7 +2090,7 @@
 msgid "unable to fork"
 msgstr "неуспешно създаване на процес"
 
-#: connected.c:68 builtin/fsck.c:203 builtin/prune.c:146
+#: connected.c:68 builtin/fsck.c:202 builtin/prune.c:147
 msgid "Checking connectivity"
 msgstr "Проверка на връзката"
 
@@ -2179,12 +2232,12 @@
 msgid "true/false are no valid working-tree-encodings"
 msgstr "„true“/„false“ не може да са кодирания на работното дърво"
 
-#: convert.c:1402 convert.c:1436
+#: convert.c:1398 convert.c:1432
 #, c-format
 msgid "%s: clean filter '%s' failed"
 msgstr "%s: неуспешно изпълнение на декодиращ филтър „%s“"
 
-#: convert.c:1480
+#: convert.c:1476
 #, c-format
 msgid "%s: smudge filter %s failed"
 msgstr "%s: неуспешно изпълнение на кодиращ филтър „%s“"
@@ -2257,12 +2310,38 @@
 msgstr[0] "преди %<PRIuMAX> година"
 msgstr[1] "преди %<PRIuMAX> години"
 
+#: delta-islands.c:268
+msgid "Propagating island marks"
+msgstr "Разпространяване на границите на групите"
+
+#: delta-islands.c:286
+#, c-format
+msgid "bad tree object %s"
+msgstr "неправилен обект-дърво: %s"
+
+#: delta-islands.c:330
+#, c-format
+msgid "failed to load island regex for '%s': %s"
+msgstr "регулярният израз на групата за „%s“, не може да бъде зареден: „%s“"
+
+#: delta-islands.c:386
+#, c-format
+msgid "island regex from config has too many capture groups (max=%d)"
+msgstr ""
+"регулярният израз на групата в конфигурационния файл съдържа повече от "
+"максимално поддържаните (%d) прихващащи групи"
+
+#: delta-islands.c:462
+#, c-format
+msgid "Marked %d islands, done.\n"
+msgstr "Отбелязани са %d групи, работата приключи.\n"
+
 #: diffcore-order.c:24
 #, c-format
 msgid "failed to read orderfile '%s'"
 msgstr "файлът с подредбата на съответствията „%s“ не може да бъде прочетен"
 
-#: diffcore-rename.c:536
+#: diffcore-rename.c:544
 msgid "Performing inexact rename detection"
 msgstr "Търсене на преименувания на обекти съчетани с промени"
 
@@ -2319,27 +2398,27 @@
 "Грешки в настройката „diff.dirstat“:\n"
 "%s"
 
-#: diff.c:4096
+#: diff.c:4140
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr ""
 "външната програма за разлики завърши неуспешно.  Спиране на работата при „%s“"
 
-#: diff.c:4427
+#: diff.c:4482
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr ""
 "Опциите „--name-only“, „--name-status“, „--check“ и „-s“ са несъвместими "
 "една с друга"
 
-#: diff.c:4430
+#: diff.c:4485
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "Опциите „-G“, „-S“ и „--find-object“ са несъвместими една с друга"
 
-#: diff.c:4508
+#: diff.c:4563
 msgid "--follow requires exactly one pathspec"
 msgstr "Опцията „--follow“ изисква точно един път"
 
-#: diff.c:4674
+#: diff.c:4729
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -2348,68 +2427,68 @@
 "Неразпознат параметър към опцията „--dirstat/-X“:\n"
 "%s"
 
-#: diff.c:4688
+#: diff.c:4743
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Неразпознат параметър към опцията „--submodule“: „%s“"
 
-#: diff.c:5766
+#: diff.c:5823
 msgid "inexact rename detection was skipped due to too many files."
 msgstr ""
 "търсенето на преименувания на обекти съчетани с промени се прескача поради "
 "многото файлове."
 
-#: diff.c:5769
+#: diff.c:5826
 msgid "only found copies from modified paths due to too many files."
 msgstr ""
 "установени са точните копия на променените пътища поради многото файлове."
 
-#: diff.c:5772
+#: diff.c:5829
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
 msgstr "задайте променливата „%s“ да е поне %d и отново изпълнете командата."
 
-#: dir.c:569
+#: dir.c:576
 #, c-format
 msgid "pathspec '%s' did not match any file(s) known to git"
 msgstr "пътят „%s“ не съвпада с никой файл в git"
 
-#: dir.c:958
+#: dir.c:965
 #, c-format
 msgid "cannot use %s as an exclude file"
 msgstr "„%s“ не може да се ползва за игнорираните файлове (като gitignore)"
 
-#: dir.c:1873
+#: dir.c:1880
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "директорията „%s“ не може да бъде отворена"
 
-#: dir.c:2115
+#: dir.c:2122
 msgid "failed to get kernel name and information"
 msgstr "името и версията на ядрото не бяха получени"
 
-#: dir.c:2239
+#: dir.c:2246
 msgid "untracked cache is disabled on this system or location"
 msgstr ""
 "кешът за неследените файлове е изключен на тази система или местоположение"
 
-#: dir.c:3037
+#: dir.c:3047
 #, c-format
 msgid "index file corrupt in repo %s"
 msgstr "файлът с индекса е повреден в хранилището „%s“"
 
-#: dir.c:3082 dir.c:3087
+#: dir.c:3092 dir.c:3097
 #, c-format
 msgid "could not create directories for %s"
 msgstr "директориите за „%s“ не може да бъдат създадени"
 
-#: dir.c:3116
+#: dir.c:3126
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "директорията на git не може да се мигрира от „%s“ до „%s“"
 
-#: editor.c:61
+#: editor.c:73
 #, c-format
 msgid "hint: Waiting for your editor to close the file...%c"
 msgstr "Подсказка: чака се редакторът ви да затвори файла …%c"
@@ -2418,7 +2497,7 @@
 msgid "Filtering content"
 msgstr "Филтриране на съдържанието"
 
-#: entry.c:437
+#: entry.c:465
 #, c-format
 msgid "could not stat file '%s'"
 msgstr "неуспешно изпълнение на „stat“ върху файла „%s“"
@@ -2442,78 +2521,78 @@
 msgid "Remote with no URL"
 msgstr "Липсва адрес за отдалеченото хранилище"
 
-#: fetch-pack.c:152
+#: fetch-pack.c:151
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack: очаква се плитък списък"
 
-#: fetch-pack.c:164
+#: fetch-pack.c:163
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr ""
 "git fetch-pack: очаква се „ACK“/„NAK“, а бе получен изчистващ пакет „flush“"
 
-#: fetch-pack.c:184
+#: fetch-pack.c:183
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr "git fetch-pack: очаква се „ACK“/„NAK“, а бе получено „%s“"
 
-#: fetch-pack.c:254
+#: fetch-pack.c:253
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "опцията „--stateless-rpc“ изисква  „multi_ack_detailed“"
 
-#: fetch-pack.c:342 fetch-pack.c:1257
+#: fetch-pack.c:347 fetch-pack.c:1277
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "неправилен плитък ред: „%s“"
 
-#: fetch-pack.c:348 fetch-pack.c:1263
+#: fetch-pack.c:353 fetch-pack.c:1283
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "неправилен неплитък ред: „%s“"
 
-#: fetch-pack.c:350 fetch-pack.c:1265
+#: fetch-pack.c:355 fetch-pack.c:1285
 #, c-format
 msgid "object not found: %s"
 msgstr "обектът „%s“ липсва"
 
-#: fetch-pack.c:353 fetch-pack.c:1268
+#: fetch-pack.c:358 fetch-pack.c:1288
 #, c-format
 msgid "error in object: %s"
 msgstr "грешка в обекта: „%s“"
 
-#: fetch-pack.c:355 fetch-pack.c:1270
+#: fetch-pack.c:360 fetch-pack.c:1290
 #, c-format
 msgid "no shallow found: %s"
 msgstr "не е открит плитък обект: %s"
 
-#: fetch-pack.c:358 fetch-pack.c:1273
+#: fetch-pack.c:363 fetch-pack.c:1293
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "очаква се плитък или не обект, а бе получено: „%s“"
 
-#: fetch-pack.c:399
+#: fetch-pack.c:404
 #, c-format
 msgid "got %s %d %s"
 msgstr "получено бе %s %d %s"
 
-#: fetch-pack.c:416
+#: fetch-pack.c:421
 #, c-format
 msgid "invalid commit %s"
 msgstr "неправилно подаване: „%s“"
 
-#: fetch-pack.c:447
+#: fetch-pack.c:452
 msgid "giving up"
 msgstr "преустановяване"
 
-#: fetch-pack.c:459 progress.c:229
+#: fetch-pack.c:464 progress.c:229
 msgid "done"
 msgstr "действието завърши"
 
-#: fetch-pack.c:471
+#: fetch-pack.c:476
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "получено бе %s (%d) %s"
 
-#: fetch-pack.c:517
+#: fetch-pack.c:522
 #, c-format
 msgid "Marking %s as complete"
 msgstr "Отбелязване на „%s“ като пълно"
@@ -2581,7 +2660,7 @@
 msgid "Server supports ofs-delta"
 msgstr "Сървърът поддържа „ofs-delta“"
 
-#: fetch-pack.c:971 fetch-pack.c:1150
+#: fetch-pack.c:971 fetch-pack.c:1158
 msgid "Server supports filter"
 msgstr "Сървърът поддържа филтри"
 
@@ -2602,85 +2681,96 @@
 msgid "Server does not support --deepen"
 msgstr "Сървърът не поддържа опцията „--deepen“"
 
-#: fetch-pack.c:1004
+#: fetch-pack.c:1008
 msgid "no common commits"
 msgstr "няма общи подавания"
 
-#: fetch-pack.c:1016 fetch-pack.c:1393
+#: fetch-pack.c:1020 fetch-pack.c:1418
 msgid "git fetch-pack: fetch failed."
 msgstr "git fetch-pack: неуспешно доставяне."
 
-#: fetch-pack.c:1145
+#: fetch-pack.c:1153
 msgid "Server does not support shallow requests"
 msgstr "Сървърът не поддържа плитки заявки"
 
-#: fetch-pack.c:1191
+#: fetch-pack.c:1199
 #, c-format
 msgid "error reading section header '%s'"
 msgstr "грешка при прочитане на заглавната част на раздел „%s“"
 
-#: fetch-pack.c:1197
+#: fetch-pack.c:1205
 #, c-format
 msgid "expected '%s', received '%s'"
 msgstr "очаква се „%s“, а бе получено „%s“"
 
-#: fetch-pack.c:1236
+#: fetch-pack.c:1244
 #, c-format
 msgid "unexpected acknowledgment line: '%s'"
 msgstr "неочакван ред за потвърждение: „%s“"
 
-#: fetch-pack.c:1241
+#: fetch-pack.c:1249
 #, c-format
 msgid "error processing acks: %d"
 msgstr "грешка при обработка на потвържденията: %d"
 
-#: fetch-pack.c:1278
+#: fetch-pack.c:1259
+msgid "expected packfile to be sent after 'ready'"
+msgstr ""
+"очакваше се пакетният файл да бъде изпратен след отговор за готовност (ready)"
+
+#: fetch-pack.c:1261
+msgid "expected no other sections to be sent after no 'ready'"
+msgstr ""
+"очакваше се след липса на отговор за готовност (ready) да не се се пращат "
+"други раздели"
+
+#: fetch-pack.c:1298
 #, c-format
 msgid "error processing shallow info: %d"
 msgstr "грешка при обработка на информация за дълбочината/плиткостта: %d"
 
-#: fetch-pack.c:1294
+#: fetch-pack.c:1314
 #, c-format
 msgid "expected wanted-ref, got '%s'"
 msgstr "очаква се искан указател, а бе получено: „%s“"
 
-#: fetch-pack.c:1304
+#: fetch-pack.c:1324
 #, c-format
 msgid "unexpected wanted-ref: '%s'"
 msgstr "неочакван искан указател: „%s“"
 
-#: fetch-pack.c:1308
+#: fetch-pack.c:1328
 #, c-format
 msgid "error processing wanted refs: %d"
 msgstr "грешка при обработката на исканите указатели: %d"
 
-#: fetch-pack.c:1603
+#: fetch-pack.c:1642
 msgid "no matching remote head"
 msgstr "не може да бъде открит подходящ връх от отдалеченото хранилище"
 
-#: fetch-pack.c:1621 builtin/clone.c:664
+#: fetch-pack.c:1660 builtin/clone.c:664
 msgid "remote did not send all necessary objects"
 msgstr "отдалеченото хранилище не изпрати всички необходими обекти."
 
-#: fetch-pack.c:1647
+#: fetch-pack.c:1686
 #, c-format
 msgid "no such remote ref %s"
 msgstr "такъв отдалечен указател няма: %s"
 
-#: fetch-pack.c:1650
+#: fetch-pack.c:1689
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr "Сървърът не позволява заявка за необявен „%s“"
 
-#: gpg-interface.c:253
+#: gpg-interface.c:318
 msgid "gpg failed to sign the data"
 msgstr "Програмата „gpg“ не подписа данните."
 
-#: gpg-interface.c:279
+#: gpg-interface.c:344
 msgid "could not create temporary file"
 msgstr "не може да се създаде временен файл"
 
-#: gpg-interface.c:282
+#: gpg-interface.c:347
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr "Програмата не успя да запише самостоятелния подпис в „%s“"
@@ -2690,18 +2780,18 @@
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "прескачане на неправилния цвят „%.*s“ в „log.graphColors“"
 
-#: grep.c:2115
+#: grep.c:2113
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "„%s“: файлът сочен от „%s“ не може да бъде прочетен"
 
-#: grep.c:2132 setup.c:164 builtin/clone.c:410 builtin/diff.c:81
+#: grep.c:2130 setup.c:164 builtin/clone.c:410 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "не може да бъде получена информация чрез „stat“ за „%s“"
 
-#: grep.c:2143
+#: grep.c:2141
 #, c-format
 msgid "'%s': short read"
 msgstr "„%s“: изчитането върна по-малко байтове от очакваното"
@@ -2758,29 +2848,41 @@
 msgid "Low-level Commands / Internal Helpers"
 msgstr "Команди от ниско ниво/Допълнителни инструменти"
 
-#: help.c:293
+#: help.c:296
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "налични команди на git от „%s“"
 
-#: help.c:300
+#: help.c:303
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "команди на git от други директории от „$PATH“"
 
-#: help.c:309
+#: help.c:312
 msgid "These are common Git commands used in various situations:"
 msgstr "Това са най-често използваните команди на Git:"
 
-#: help.c:358 git.c:90
+#: help.c:361 git.c:90
 #, c-format
 msgid "unsupported command listing type '%s'"
 msgstr "неподдържан списък от команди „%s“"
 
-#: help.c:405
+#: help.c:408
 msgid "The common Git guides are:"
 msgstr "Популярните въведения в Git са:"
 
-#: help.c:552
+#: help.c:517
+msgid "See 'git help <command>' to read about a specific subcommand"
+msgstr "За повече информация за КОМАНДА изпълнете „git help КОМАНДА“"
+
+#: help.c:522
+msgid "External commands"
+msgstr "Външни команди"
+
+#: help.c:530
+msgid "Command aliases"
+msgstr "Псевдоними на командите"
+
+#: help.c:594
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -2789,36 +2891,36 @@
 "Изглежда, че „%s“ е команда на git, но тя не може да\n"
 "бъде изпълнена.  Вероятно пакетът „git-%s“ е повреден."
 
-#: help.c:611
+#: help.c:653
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Странно, изглежда, че на системата ви няма нито една команда на git."
 
-#: help.c:633
+#: help.c:675
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr ""
 "ПРЕДУПРЕЖДЕНИЕ: Пробвахте да изпълните команда на Git на име „%s“, а такава "
 "не съществува."
 
-#: help.c:638
+#: help.c:680
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr ""
 "Изпълнението автоматично продължава, като се счита, че имате предвид „%s“."
 
-#: help.c:643
+#: help.c:685
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr ""
 "Изпълнението автоматично ще продължи след %0.1f сек., като се счита, че "
 "имате предвид „%s“."
 
-#: help.c:651
+#: help.c:693
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: „%s“ не е команда на git.  Погледнете изхода от „git --help“."
 
-#: help.c:655
+#: help.c:697
 msgid ""
 "\n"
 "The most similar command is"
@@ -2832,16 +2934,16 @@
 "\n"
 "Най-близките команди са"
 
-#: help.c:670
+#: help.c:712
 msgid "git version [<options>]"
 msgstr "git version [ОПЦИЯ…]"
 
-#: help.c:738
+#: help.c:780
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s — %s"
 
-#: help.c:742
+#: help.c:784
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2855,7 +2957,7 @@
 "\n"
 "Команди с подобно име са:"
 
-#: ident.c:342
+#: ident.c:345
 msgid ""
 "\n"
 "*** Please tell me who you are.\n"
@@ -2882,46 +2984,50 @@
 "хранилище.\n"
 "\n"
 
-#: ident.c:366
+#: ident.c:369
 msgid "no email was given and auto-detection is disabled"
 msgstr "липсва адрес за е-поща, а автоматичното отгатване е изключено"
 
-#: ident.c:371
+#: ident.c:374
 #, c-format
 msgid "unable to auto-detect email address (got '%s')"
 msgstr ""
 "адресът за е-поща не може да бъде отгатнат (най-доброто предположение бе "
 "„%s“)"
 
-#: ident.c:381
+#: ident.c:384
 msgid "no name was given and auto-detection is disabled"
 msgstr "липсва име, а автоматичното отгатване е изключено"
 
-#: ident.c:387
+#: ident.c:390
 #, c-format
 msgid "unable to auto-detect name (got '%s')"
 msgstr "името не може да бъде отгатнато (най-доброто предположение бе „%s“)"
 
-#: ident.c:395
+#: ident.c:398
 #, c-format
 msgid "empty ident name (for <%s>) not allowed"
 msgstr "не може да се ползва празно име като идентификатор (за <%s>)"
 
-#: ident.c:401
+#: ident.c:404
 #, c-format
 msgid "name consists only of disallowed characters: %s"
 msgstr "името съдържа само непозволени знаци: „%s“"
 
-#: ident.c:416 builtin/commit.c:600
+#: ident.c:419 builtin/commit.c:606
 #, c-format
 msgid "invalid date format: %s"
 msgstr "неправилен формат на дата: %s"
 
-#: list-objects-filter-options.c:36
+#: list-objects-filter-options.c:35
 msgid "multiple filter-specs cannot be combined"
 msgstr "не може да комбинирате множество филтри"
 
-#: list-objects-filter-options.c:126
+#: list-objects-filter-options.c:58
+msgid "only 'tree:0' is supported"
+msgstr "поддържа се единствено „tree:0“"
+
+#: list-objects-filter-options.c:137
 msgid "cannot change partial clone promisor remote"
 msgstr "не може да промените хранилището-гарант на непълно хранилище"
 
@@ -2949,129 +3055,129 @@
 msgid "Unable to create '%s.lock': %s"
 msgstr "Файлът-ключалка „%s.lock“ не може да бъде създаден: %s"
 
-#: merge.c:40
+#: merge.c:41
 msgid "failed to read the cache"
 msgstr "кешът не може да бъде прочетен"
 
-#: merge.c:105 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:380
-#: builtin/checkout.c:608 builtin/clone.c:763
+#: merge.c:107 rerere.c:720 builtin/am.c:1899 builtin/am.c:1933
+#: builtin/checkout.c:387 builtin/checkout.c:708 builtin/clone.c:764
 msgid "unable to write new index file"
 msgstr "неуспешно записване на новия индекс"
 
-#: merge-recursive.c:303
+#: merge-recursive.c:323
 msgid "(bad commit)\n"
 msgstr "(лошо подаване)\n"
 
-#: merge-recursive.c:325
+#: merge-recursive.c:345
 #, c-format
 msgid "add_cacheinfo failed for path '%s'; merge aborting."
 msgstr ""
 "неуспешно изпълнение на „add_cacheinfo“ за пътя „%s“.  Сливането е "
 "преустановено."
 
-#: merge-recursive.c:333
+#: merge-recursive.c:353
 #, c-format
 msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
 msgstr ""
 "неуспешно изпълнение на „add_cacheinfo“ за обновяването на пътя „%s“.  "
 "Сливането е преустановено."
 
-#: merge-recursive.c:415
+#: merge-recursive.c:435
 msgid "error building trees"
 msgstr "грешка при изграждане на дърветата"
 
-#: merge-recursive.c:886
+#: merge-recursive.c:906
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "грешка при създаването на пътя „%s“%s"
 
-#: merge-recursive.c:897
+#: merge-recursive.c:917
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "Изтриване на „%s“, за да се освободи място за поддиректория\n"
 
-#: merge-recursive.c:911 merge-recursive.c:930
+#: merge-recursive.c:931 merge-recursive.c:950
 msgid ": perhaps a D/F conflict?"
 msgstr ": възможно е да има конфликт директория/файл."
 
-#: merge-recursive.c:920
+#: merge-recursive.c:940
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr ""
 "преустановяване на действието, за да не се изтрие неследеният файл „%s“"
 
-#: merge-recursive.c:962 builtin/cat-file.c:39
+#: merge-recursive.c:982 builtin/cat-file.c:39
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "обектът „%s“ (%s) не може да бъде прочетен"
 
-#: merge-recursive.c:964
+#: merge-recursive.c:984
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "обектът „%s“ (%s) се очакваше да е BLOB, а не е"
 
-#: merge-recursive.c:988
+#: merge-recursive.c:1008
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr "„%s“ не може да се отвори: %s"
 
-#: merge-recursive.c:999
+#: merge-recursive.c:1019
 #, c-format
 msgid "failed to symlink '%s': %s"
 msgstr "неуспешно създаване на символната връзка „%s“: %s"
 
-#: merge-recursive.c:1004
+#: merge-recursive.c:1024
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr ""
 "не е ясно какво да се прави с обекта „%2$s“ (%3$s) с права за достъп „%1$06o“"
 
-#: merge-recursive.c:1191
+#: merge-recursive.c:1212
 #, c-format
 msgid "Failed to merge submodule %s (not checked out)"
 msgstr "Неуспешно сливане на подмодула „%s“ (не е изтеглен)"
 
-#: merge-recursive.c:1198
+#: merge-recursive.c:1219
 #, c-format
 msgid "Failed to merge submodule %s (commits not present)"
 msgstr "Неуспешно сливане на подмодула „%s“ (няма подавания)"
 
-#: merge-recursive.c:1205
+#: merge-recursive.c:1226
 #, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr ""
 "Подмодулът „%s“ не може да бъде слят (базата за сливане не предшества "
 "подаванията)"
 
-#: merge-recursive.c:1213 merge-recursive.c:1225
+#: merge-recursive.c:1234 merge-recursive.c:1246
 #, c-format
 msgid "Fast-forwarding submodule %s to the following commit:"
 msgstr "Превъртане на подмодула „%s“ до следното подаване:"
 
-#: merge-recursive.c:1216 merge-recursive.c:1228
+#: merge-recursive.c:1237 merge-recursive.c:1249
 #, c-format
 msgid "Fast-forwarding submodule %s"
 msgstr "Превъртане на подмодула „%s“"
 
-#: merge-recursive.c:1250
+#: merge-recursive.c:1271
 #, c-format
 msgid "Failed to merge submodule %s (merge following commits not found)"
 msgstr ""
 "Неуспешно сливане на подмодула „%s“ (липсва сливането, което се предшества "
 "от подаванията)"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1275
 #, c-format
 msgid "Failed to merge submodule %s (not fast-forward)"
 msgstr "Неуспешно сливане на подмодула „%s“ (не е превъртане)"
 
-#: merge-recursive.c:1255
+#: merge-recursive.c:1276
 msgid "Found a possible merge resolution for the submodule:\n"
 msgstr ""
 "Открито е сливане, което може да решава проблема със сливането на "
 "подмодула:\n"
 
-#: merge-recursive.c:1258
+#: merge-recursive.c:1279
 #, c-format
 msgid ""
 "If this is correct simply add it to the index for example\n"
@@ -3087,31 +3193,31 @@
 "\n"
 "Това приема предложеното.\n"
 
-#: merge-recursive.c:1267
+#: merge-recursive.c:1288
 #, c-format
 msgid "Failed to merge submodule %s (multiple merges found)"
 msgstr "Неуспешно сливане на подмодула „%s“ (открити са множество сливания)"
 
-#: merge-recursive.c:1326
+#: merge-recursive.c:1358
 msgid "Failed to execute internal merge"
 msgstr "Неуспешно вътрешно сливане"
 
-#: merge-recursive.c:1331
+#: merge-recursive.c:1363
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "„%s“ не може да се добави в базата с данни"
 
-#: merge-recursive.c:1363
+#: merge-recursive.c:1395
 #, c-format
 msgid "Auto-merging %s"
 msgstr "Автоматично сливане на „%s“"
 
-#: merge-recursive.c:1434
+#: merge-recursive.c:1416
 #, c-format
 msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
 msgstr "Грешка: за да не се изтрие неследеният файл „%s“, се записва в „%s“."
 
-#: merge-recursive.c:1501
+#: merge-recursive.c:1483
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -3120,7 +3226,7 @@
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ в %s.  Версия %s на „%s“ "
 "е оставена в дървото."
 
-#: merge-recursive.c:1506
+#: merge-recursive.c:1488
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -3129,7 +3235,7 @@
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ е преименуван на „%s“ в "
 "%s.  Версия %s на „%s“ е оставена в дървото."
 
-#: merge-recursive.c:1513
+#: merge-recursive.c:1495
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -3138,7 +3244,7 @@
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ в %s.  Версия %s на „%s“ "
 "е оставена в дървото: %s."
 
-#: merge-recursive.c:1518
+#: merge-recursive.c:1500
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -3147,33 +3253,33 @@
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ е преименуван на „%s“ в "
 "%s.  Версия %s на „%s“ е оставена в дървото: %s."
 
-#: merge-recursive.c:1552
+#: merge-recursive.c:1534
 msgid "rename"
 msgstr "преименуване"
 
-#: merge-recursive.c:1552
+#: merge-recursive.c:1534
 msgid "renamed"
 msgstr "преименуван"
 
-#: merge-recursive.c:1606 merge-recursive.c:1762 merge-recursive.c:2394
-#: merge-recursive.c:3129
+#: merge-recursive.c:1588 merge-recursive.c:1737 merge-recursive.c:2369
+#: merge-recursive.c:3124
 #, c-format
 msgid "Refusing to lose dirty file at %s"
 msgstr "Преустановяване на действието, за да не се изгуби промененият „%s“"
 
-#: merge-recursive.c:1620
+#: merge-recursive.c:1602
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "„%s“ е директория в „%s“, затова се добавя като „%s“"
 
-#: merge-recursive.c:1625
+#: merge-recursive.c:1607
 #, c-format
 msgid "Refusing to lose untracked file at %s; adding as %s instead"
 msgstr ""
 "Преустановяване на действието, за да не се изгуби неследеният файл „%s“.  "
 "Вместо него се добавя „%s“"
 
-#: merge-recursive.c:1651
+#: merge-recursive.c:1633
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -3182,29 +3288,29 @@
 "КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон "
 "„%s“, а „%s“ е преименуван на „%s“ в „%s“/%s."
 
-#: merge-recursive.c:1656
+#: merge-recursive.c:1638
 msgid " (left unresolved)"
 msgstr " (некоригиран конфликт)"
 
-#: merge-recursive.c:1720
+#: merge-recursive.c:1699
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 "КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон "
 "„%s“, а „%s“ е преименуван на „%s“ в „%s“"
 
-#: merge-recursive.c:1759
+#: merge-recursive.c:1734
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "Преименуване на „%s“ на „%s“, а „%s“ на „%s“"
 
-#: merge-recursive.c:1771
+#: merge-recursive.c:1746
 #, c-format
 msgid "Refusing to lose untracked file at %s, even though it's in the way."
 msgstr ""
 "Отказ да се загуби неследеният файл „%s“, защото е на място, където пречи."
 
-#: merge-recursive.c:1977
+#: merge-recursive.c:1952
 #, c-format
 msgid ""
 "CONFLICT (directory rename split): Unclear where to place %s because "
@@ -3215,7 +3321,7 @@
 "постави „%s“, защото няколко нови директории поделят съдържанието на "
 "директория „%s“, като никоя не съдържа мнозинство от файловете ѝ."
 
-#: merge-recursive.c:2009
+#: merge-recursive.c:1984
 #, c-format
 msgid ""
 "CONFLICT (implicit dir rename): Existing file/dir at %s in the way of "
@@ -3224,7 +3330,7 @@
 "КОНФЛИКТ (косвено преименуване на директория): следният файл или директория "
 "„%s“ не позволяват косвеното преименуване на следния път/ища: %s."
 
-#: merge-recursive.c:2019
+#: merge-recursive.c:1994
 #, c-format
 msgid ""
 "CONFLICT (implicit dir rename): Cannot map more than one path to %s; "
@@ -3234,7 +3340,7 @@
 "съответства на „%s“.  Косвено преименуване на директория води до поставянето "
 "на тези пътища там: %s."
 
-#: merge-recursive.c:2111
+#: merge-recursive.c:2086
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
@@ -3243,7 +3349,7 @@
 "КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон "
 "„%s“, а „%s“ е преименуван на „%s“ в „%s“"
 
-#: merge-recursive.c:2356
+#: merge-recursive.c:2331
 #, c-format
 msgid ""
 "WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
@@ -3252,89 +3358,89 @@
 "ПРЕДУПРЕЖДЕНИЕ: прескачане на преименуването на „%s“ на „%s“ в „%s“, защото "
 "„%s“ също е с променено име."
 
-#: merge-recursive.c:2762
+#: merge-recursive.c:2737
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr ""
 "КОНФЛИКТ (преименуване/добавяне): „%s“ е преименуван на „%s“ в клон „%s“, а "
 "„%s“ е добавен в „%s“"
 
-#: merge-recursive.c:2777
+#: merge-recursive.c:2763
 #, c-format
 msgid "Adding merged %s"
 msgstr "Добавяне на слетия „%s“"
 
-#: merge-recursive.c:2784 merge-recursive.c:3132
+#: merge-recursive.c:2770 merge-recursive.c:3127
 #, c-format
 msgid "Adding as %s instead"
 msgstr "Добавяне като „%s“"
 
-#: merge-recursive.c:2941
+#: merge-recursive.c:2934
 #, c-format
 msgid "cannot read object %s"
 msgstr "обектът „%s“ не може да се прочете"
 
-#: merge-recursive.c:2944
+#: merge-recursive.c:2937
 #, c-format
 msgid "object %s is not a blob"
 msgstr "обектът „%s“ не е BLOB"
 
-#: merge-recursive.c:3013
+#: merge-recursive.c:3006
 msgid "modify"
 msgstr "промяна"
 
-#: merge-recursive.c:3013
+#: merge-recursive.c:3006
 msgid "modified"
 msgstr "променен"
 
-#: merge-recursive.c:3024
+#: merge-recursive.c:3017
 msgid "content"
 msgstr "съдържание"
 
-#: merge-recursive.c:3031
+#: merge-recursive.c:3024
 msgid "add/add"
 msgstr "добавяне/добавяне"
 
-#: merge-recursive.c:3076
+#: merge-recursive.c:3071
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "Прескачане на „%s“ (слетият резултат е идентичен със сегашния)"
 
-#: merge-recursive.c:3098 git-submodule.sh:865
+#: merge-recursive.c:3093 git-submodule.sh:858
 msgid "submodule"
 msgstr "ПОДМОДУЛ"
 
-#: merge-recursive.c:3099
+#: merge-recursive.c:3094
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "КОНФЛИКТ (%s): Конфликт при сливане на „%s“"
 
-#: merge-recursive.c:3221
+#: merge-recursive.c:3216
 #, c-format
 msgid "Removing %s"
 msgstr "Изтриване на „%s“"
 
-#: merge-recursive.c:3247
+#: merge-recursive.c:3242
 msgid "file/directory"
 msgstr "файл/директория"
 
-#: merge-recursive.c:3253
+#: merge-recursive.c:3248
 msgid "directory/file"
 msgstr "директория/файл"
 
-#: merge-recursive.c:3260
+#: merge-recursive.c:3255
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 "КОНФЛИКТ (%s): Съществува директория на име „%s“ в „%s“.  Добавяне на „%s“ "
 "като „%s“"
 
-#: merge-recursive.c:3269
+#: merge-recursive.c:3264
 #, c-format
 msgid "Adding %s"
 msgstr "Добавяне на „%s“"
 
-#: merge-recursive.c:3303
+#: merge-recursive.c:3300
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -3343,40 +3449,179 @@
 "Сливането ще презапише локалните промени на тези файлове:\n"
 "    %s"
 
-#: merge-recursive.c:3314
+#: merge-recursive.c:3311
 msgid "Already up to date!"
 msgstr "Вече е обновено!"
 
-#: merge-recursive.c:3323
+#: merge-recursive.c:3320
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "неуспешно сливане на дърветата „%s“ и „%s“"
 
-#: merge-recursive.c:3422
+#: merge-recursive.c:3419
 msgid "Merging:"
 msgstr "Сливане:"
 
-#: merge-recursive.c:3435
+#: merge-recursive.c:3432
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "открит е %u общ предшественик:"
 msgstr[1] "открити са %u общи предшественици:"
 
-#: merge-recursive.c:3474
+#: merge-recursive.c:3471
 msgid "merge returned no commit"
 msgstr "сливането не върна подаване"
 
-#: merge-recursive.c:3540
+#: merge-recursive.c:3537
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "Неуспешен анализ на обекта „%s“"
 
-#: merge-recursive.c:3556 builtin/merge.c:689 builtin/merge.c:846
+#: merge-recursive.c:3553 builtin/merge.c:691 builtin/merge.c:849
 msgid "Unable to write index."
 msgstr "Индексът не може да бъде прочетен"
 
-#: notes-merge.c:274
+#: midx.c:65
+#, c-format
+msgid "multi-pack-index file %s is too small"
+msgstr "файлът с индекса за множество пакети „%s“ е твърде малък"
+
+#: midx.c:81
+#, c-format
+msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
+msgstr "отпечатъкът на индекса за множество пакети 0x%08x не съвпада с 0x%08x"
+
+#: midx.c:86
+#, c-format
+msgid "multi-pack-index version %d not recognized"
+msgstr "непозната версия на индекс за множество пакети — %d"
+
+#: midx.c:91
+#, c-format
+msgid "hash version %u does not match"
+msgstr "версията на отпечатъка %u не съвпада"
+
+#: midx.c:105
+msgid "invalid chunk offset (too large)"
+msgstr "неправилно (прекалено голямо) отместване на откъс"
+
+#: midx.c:129
+msgid "terminating multi-pack-index chunk id appears earlier than expected"
+msgstr ""
+"идентификаторът за краен откъс на индекс за множество пакети се явява по-"
+"рано от очакваното"
+
+#: midx.c:142
+msgid "multi-pack-index missing required pack-name chunk"
+msgstr "липсва откъс (pack-name) от индекс за множество пакети"
+
+#: midx.c:144
+msgid "multi-pack-index missing required OID fanout chunk"
+msgstr "липсва откъс (OID fanout) от индекс за множество пакети"
+
+#: midx.c:146
+msgid "multi-pack-index missing required OID lookup chunk"
+msgstr "липсва откъс (OID lookup) от индекс за множество пакети"
+
+#: midx.c:148
+msgid "multi-pack-index missing required object offsets chunk"
+msgstr "липсва откъс за отместванията на обекти от индекс за множество пакети"
+
+#: midx.c:162
+#, c-format
+msgid "multi-pack-index pack names out of order: '%s' before '%s'"
+msgstr ""
+"неправилна подредба на имената в индекс за множество пакети: „%s“ се появи "
+"преди „%s“"
+
+#: midx.c:205
+#, c-format
+msgid "bad pack-int-id: %u (%u total packs)"
+msgstr ""
+"неправилен идентификатор на пакет (pack-int-id): %u (от общо %u пакети)"
+
+#: midx.c:246
+msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
+msgstr ""
+"индексът за множество пакети съдържа 64-битови отмествания, но размерът на "
+"„off_t“ е недостатъчен"
+
+#: midx.c:271
+msgid "error preparing packfile from multi-pack-index"
+msgstr ""
+"грешка при създаването на пакетен файл на базата на индекс за множество "
+"пакети"
+
+#: midx.c:407
+#, c-format
+msgid "failed to add packfile '%s'"
+msgstr "пакетният файл „%s“ не може да бъде добавен"
+
+#: midx.c:413
+#, c-format
+msgid "failed to open pack-index '%s'"
+msgstr "индексът за пакети „%s“ не може да бъде отворен"
+
+#: midx.c:507
+#, c-format
+msgid "failed to locate object %d in packfile"
+msgstr "обект %d в пакетния файл липсва"
+
+#: midx.c:943
+#, c-format
+msgid "failed to clear multi-pack-index at %s"
+msgstr "индексът за множество пакети не може да бъде изчистен при „%s“"
+
+#: midx.c:981
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"неправилна подредба на откъси (OID fanout): fanout[%d] = %<PRIx32> > "
+"%<PRIx32> = fanout[%d]"
+
+#: midx.c:992
+#, c-format
+msgid "oid lookup out of order: oid[%d] = %s >= %s = oid[%d]"
+msgstr ""
+"неправилна подредба на откъси (OID lookup): oid[%d] = %s >= %s = oid[%d]"
+
+#: midx.c:996
+msgid "Verifying object offsets"
+msgstr "Проверка на отместването на обекти"
+
+#: midx.c:1004
+#, c-format
+msgid "failed to load pack entry for oid[%d] = %s"
+msgstr "записът в пакета за обекта oid[%d] = %s не може да бъде зареден"
+
+#: midx.c:1010
+#, c-format
+msgid "failed to load pack-index for packfile %s"
+msgstr "индексът на пакета „%s“ не може да бъде зареден"
+
+#: midx.c:1019
+#, c-format
+msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
+msgstr "неправилно отместване на обект за oid[%d] = %s: %<PRIx64> != %<PRIx64>"
+
+#: name-hash.c:532
+#, c-format
+msgid "unable to create lazy_dir thread: %s"
+msgstr "не може да се създаде нишка за директории: %s"
+
+#: name-hash.c:554
+#, c-format
+msgid "unable to create lazy_name thread: %s"
+msgstr "не може да се създаде нишка за имена: %s"
+
+#: name-hash.c:560
+#, c-format
+msgid "unable to join lazy_name thread: %s"
+msgstr "не може да се изчака нишка за имена: %s"
+
+#: notes-merge.c:275
 #, c-format
 msgid ""
 "You have not concluded your previous notes merge (%s exists).\n"
@@ -3393,7 +3638,7 @@
 "\n"
 "    git notes merge --abort"
 
-#: notes-merge.c:281
+#: notes-merge.c:282
 #, c-format
 msgid "You have not concluded your notes merge (%s exists)."
 msgstr ""
@@ -3449,19 +3694,19 @@
 msgid "sha1 mismatch %s"
 msgstr "разлика в SHA1: „%s“"
 
-#: packfile.c:563
+#: packfile.c:607
 msgid "offset before end of packfile (broken .idx?)"
 msgstr ""
 "отместване преди края на пакетния файл (възможно е индексът да е повреден)"
 
-#: packfile.c:1745
+#: packfile.c:1864
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr ""
 "отместване преди началото на индекса на пакетния файл „%s“ (възможно е "
 "индексът да е повреден)"
 
-#: packfile.c:1749
+#: packfile.c:1868
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr ""
@@ -3494,17 +3739,17 @@
 msgid "-NUM"
 msgstr "-ЧИСЛО"
 
-#: parse-options-cb.c:44
+#: parse-options-cb.c:37
 #, c-format
 msgid "malformed expiration date '%s'"
 msgstr "неправилна дата на срок: „%s“"
 
-#: parse-options-cb.c:112
+#: parse-options-cb.c:109
 #, c-format
 msgid "malformed object name '%s'"
 msgstr "неправилно име на обект „%s“"
 
-#: path.c:892
+#: path.c:894
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "Не могат да се дадат права за запис в директорията „%s“ на групата"
@@ -3623,34 +3868,47 @@
 msgid "protocol error: bad line length %d"
 msgstr "протоколна грешка: неправилна дължина на ред: %d"
 
+#: preload-index.c:118
+msgid "Refreshing index"
+msgstr "Обновяване на индекса"
+
+#: preload-index.c:137
+#, c-format
+msgid "unable to create threaded lstat: %s"
+msgstr "не може да се създаде нишка за изпълнението на „lstat“: %s"
+
 #: pretty.c:962
 msgid "unable to parse --pretty format"
 msgstr "аргументът към опцията „--pretty“ не може да се анализира"
 
-#: range-diff.c:48
+#: range-diff.c:56
 msgid "could not start `log`"
 msgstr "командата за журнала с подавания „log“ не може да се стартира"
 
-#: range-diff.c:51
+#: range-diff.c:59
 msgid "could not read `log` output"
 msgstr ""
 "изходът от командата за журнала с подавания „log“ не може да се прочете"
 
-#: range-diff.c:66 sequencer.c:4540
+#: range-diff.c:74 sequencer.c:4764
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "подаването „%s“ не може да бъде анализирано"
 
-#: range-diff.c:196
+#: range-diff.c:224
 msgid "failed to generate diff"
 msgstr "неуспешно търсене на разлика"
 
-#: range-diff.c:421 range-diff.c:423
+#: range-diff.c:455 range-diff.c:457
 #, c-format
 msgid "could not parse log for '%s'"
 msgstr "журналът с подаванията на „%s“ не може да бъде анализиран"
 
-#: read-cache.c:1579
+#: read-cache.c:1490
+msgid "Refresh index"
+msgstr "Обновяване на индекса"
+
+#: read-cache.c:1604
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -3659,7 +3917,7 @@
 "Зададена е неправилна стойност на настройката „index.version“.\n"
 "Ще се ползва версия %i"
 
-#: read-cache.c:1589
+#: read-cache.c:1614
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -3669,135 +3927,269 @@
 "„GIT_INDEX_VERSION“.\n"
 "Ще се ползва версия %i"
 
-#: read-cache.c:2580 sequencer.c:4503 wrapper.c:658 builtin/merge.c:1083
+#: read-cache.c:1792
+#, c-format
+msgid "malformed name field in the index, near path '%s'"
+msgstr "неправилно име на поле в индекса, близо до пътя „%s“"
+
+#: read-cache.c:1960 rerere.c:565 rerere.c:599 rerere.c:1111 builtin/add.c:458
+#: builtin/check-ignore.c:177 builtin/checkout.c:289 builtin/checkout.c:585
+#: builtin/checkout.c:953 builtin/clean.c:954 builtin/commit.c:343
+#: builtin/diff-tree.c:115 builtin/grep.c:489 builtin/mv.c:144
+#: builtin/reset.c:244 builtin/rm.c:270 builtin/submodule--helper.c:329
+msgid "index file corrupt"
+msgstr "файлът с индекса е повреден"
+
+#: read-cache.c:2101
+#, c-format
+msgid "unable to create load_cache_entries thread: %s"
+msgstr "не може да се създаде нишка за зареждане на обектите от кеша: %s"
+
+#: read-cache.c:2114
+#, c-format
+msgid "unable to join load_cache_entries thread: %s"
+msgstr "не може да се изчака нишка за зареждане на обектите от кеша: %s"
+
+#: read-cache.c:2201
+#, c-format
+msgid "unable to create load_index_extensions thread: %s"
+msgstr ""
+"не може да се създаде нишка за зареждане на разширенията на индекса: %s"
+
+#: read-cache.c:2228
+#, c-format
+msgid "unable to join load_index_extensions thread: %s"
+msgstr ""
+"не може да се създаде нишка за зареждане на разширенията на индекса: %s"
+
+#: read-cache.c:2982 sequencer.c:4727 wrapper.c:658 builtin/merge.c:1086
 #, c-format
 msgid "could not close '%s'"
 msgstr "„%s“ не може да се затвори"
 
-#: read-cache.c:2653 sequencer.c:2113 sequencer.c:3374
+#: read-cache.c:3055 sequencer.c:2203 sequencer.c:3592
 #, c-format
 msgid "could not stat '%s'"
 msgstr "неуспешно изпълнение на „stat“ върху „%s“"
 
-#: read-cache.c:2666
+#: read-cache.c:3068
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "не може да се отвори директорията на git: %s"
 
-#: read-cache.c:2678
+#: read-cache.c:3080
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "неуспешно изтриване на „%s“"
 
+#: rebase-interactive.c:10
+msgid ""
+"\n"
+"Commands:\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"b, break = stop here (continue rebase later with 'git rebase --continue')\n"
+"d, drop <commit> = remove commit\n"
+"l, label <label> = label current HEAD with a name\n"
+"t, reset <label> = reset HEAD to a label\n"
+"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
+".       create a merge commit using the original merge commit's\n"
+".       message (or the oneline, if no original merge commit was\n"
+".       specified). Use -c <commit> to reword the commit message.\n"
+"\n"
+"These lines can be re-ordered; they are executed from top to bottom.\n"
+msgstr ""
+"\n"
+"Команди:\n"
+" p, pick ПОДАВАНЕ   — прилагане на подаването\n"
+" r, reword ПОДАВАНЕ — прилагане на подаването, но смяна на съобщението му\n"
+" e, edit ПОДАВАНЕ   — прилагане на подаването и спиране при него за още "
+"промени\n"
+" s, squash ПОДАВАНЕ — вкарване на подаването в предходното му\n"
+" f, fixup ПОДАВАНЕ  — вкарване на подаването в предходното му, без смяна на\n"
+"                      съобщението\n"
+" x, exec ПОДАВАНЕ   — изпълнение на команда към обвивката: останалата част "
+"на\n"
+"                      реда\n"
+" b, break           — спиране (може да продължите пребазирането с командата\n"
+"                      „git rebase --continue“)\n"
+" d, drop ПОДАВАНЕ   — прескачане на подаването\n"
+" l, label ЕТИКЕТ    — задаване на етикет на указаното от HEAD\n"
+" t, reset ЕТИКЕТ    — зануляване на HEAD към ЕТИКЕТа\n"
+" m, merge [-C ПОДАВАНЕ | -c ПОДАВАНЕ] ЕТИКЕТ [# ЕДИН_РЕД]\n"
+"                    — създаване на подаване със сливане със съобщението от\n"
+"                      първоначалното подаване (или съобщението от ЕДИН_РЕД,\n"
+"                      ако не е зададено подаване със сливане.  С опцията\n"
+"                      „-c ПОДАВАНЕ“, може да смените съобщението.\n"
+"\n"
+"Може да променяте последователността на редовете — те се изпълняват\n"
+"последователно отгоре-надолу.\n"
+
+#: rebase-interactive.c:31 git-rebase--preserve-merges.sh:173
+msgid ""
+"\n"
+"Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
+msgstr ""
+"\n"
+"Не изтривайте редове.  Подаванията могат да се прескачат с командата "
+"„drop“.\n"
+
+#: rebase-interactive.c:34 git-rebase--preserve-merges.sh:177
+msgid ""
+"\n"
+"If you remove a line here THAT COMMIT WILL BE LOST.\n"
+msgstr ""
+"\n"
+"Ако изтриете ред, съответстващото му подаване ще бъде ИЗТРИТО.\n"
+
+#: rebase-interactive.c:40 git-rebase--preserve-merges.sh:816
+msgid ""
+"\n"
+"You are editing the todo file of an ongoing interactive rebase.\n"
+"To continue rebase after editing, run:\n"
+"    git rebase --continue\n"
+"\n"
+msgstr ""
+"\n"
+"В момента редактирате файла с командите на текущото интерактивно "
+"пребазиране.\n"
+"За да продължите пребазирането след това, изпълнете:\n"
+"    git rebase --continue\n"
+"\n"
+
+#: rebase-interactive.c:45 git-rebase--preserve-merges.sh:893
+msgid ""
+"\n"
+"However, if you remove everything, the rebase will be aborted.\n"
+"\n"
+msgstr ""
+"\n"
+"Ако изтриете всичко, пребазирането ще бъде преустановено.\n"
+"\n"
+
+#: rebase-interactive.c:51 git-rebase--preserve-merges.sh:900
+msgid "Note that empty commits are commented out"
+msgstr "Празните подавания са коментирани"
+
+#: rebase-interactive.c:62 rebase-interactive.c:75 sequencer.c:2186
+#: sequencer.c:4505 sequencer.c:4561 sequencer.c:4836
+#, c-format
+msgid "could not read '%s'."
+msgstr "от „%s“ не може да се чете."
+
 #: refs.c:192
 #, c-format
 msgid "%s does not point to a valid object!"
 msgstr "„%s“ не сочи към позволен обект!"
 
-#: refs.c:579
+#: refs.c:583
 #, c-format
 msgid "ignoring dangling symref %s"
 msgstr "игнориране на указател на обект извън клон „%s“"
 
-#: refs.c:581 ref-filter.c:2067
+#: refs.c:585 ref-filter.c:1951
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "игнориране на повредения указател „%s“"
 
-#: refs.c:685
+#: refs.c:711
 #, c-format
 msgid "could not open '%s' for writing: %s"
 msgstr "„%s“ не може да бъде отворен за запис: %s"
 
-#: refs.c:695 refs.c:746
+#: refs.c:721 refs.c:772
 #, c-format
 msgid "could not read ref '%s'"
 msgstr "указателят „%s“ не може да се прочете"
 
-#: refs.c:701
+#: refs.c:727
 #, c-format
 msgid "ref '%s' already exists"
 msgstr "указателят „%s“ вече съществува"
 
-#: refs.c:706
+#: refs.c:732
 #, c-format
 msgid "unexpected object ID when writing '%s'"
 msgstr "неочакван идентификатор на обект при записването на „%s“"
 
-#: refs.c:714 sequencer.c:385 sequencer.c:2366 sequencer.c:2492
-#: sequencer.c:2506 sequencer.c:2733 sequencer.c:4501 sequencer.c:4564
+#: refs.c:740 sequencer.c:394 sequencer.c:2510 sequencer.c:2636
+#: sequencer.c:2650 sequencer.c:2877 sequencer.c:4725 sequencer.c:4788
 #: wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "в „%s“ не може да се пише"
 
-#: refs.c:741 sequencer.c:4499 sequencer.c:4558 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:780
+#: refs.c:767 sequencer.c:4723 sequencer.c:4782 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:728
 #, c-format
 msgid "could not open '%s' for writing"
 msgstr "„%s“ не може да бъде отворен за запис"
 
-#: refs.c:748
+#: refs.c:774
 #, c-format
 msgid "unexpected object ID when deleting '%s'"
 msgstr "неочакван идентификатор на обект при изтриването на „%s“"
 
-#: refs.c:879
+#: refs.c:905
 #, c-format
 msgid "log for ref %s has gap after %s"
 msgstr "има пропуски в журнала с подаванията за указателя „%s“ след „%s“"
 
-#: refs.c:885
+#: refs.c:911
 #, c-format
 msgid "log for ref %s unexpectedly ended on %s"
 msgstr "журналът с подаванията за указателя „%s“ свършва неочаквано след „%s“"
 
-#: refs.c:943
+#: refs.c:969
 #, c-format
 msgid "log for %s is empty"
 msgstr "журналът с подаванията за указателя „%s“ е празен"
 
-#: refs.c:1035
+#: refs.c:1061
 #, c-format
 msgid "refusing to update ref with bad name '%s'"
 msgstr "указател не може да се обнови с грешно име „%s“"
 
-#: refs.c:1111
+#: refs.c:1137
 #, c-format
 msgid "update_ref failed for ref '%s': %s"
 msgstr "неуспешно обновяване на указателя „%s“: %s"
 
-#: refs.c:1853
+#: refs.c:1911
 #, c-format
 msgid "multiple updates for ref '%s' not allowed"
 msgstr "не са позволени повече от една промени на указателя „%s“"
 
-#: refs.c:1885
+#: refs.c:1943
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "обновяванията на указатели са забранени в среди под карантина"
 
-#: refs.c:1981 refs.c:2011
+#: refs.c:2039 refs.c:2069
 #, c-format
 msgid "'%s' exists; cannot create '%s'"
 msgstr "„%s“ съществува, не може да се създаде „%s“"
 
-#: refs.c:1987 refs.c:2022
+#: refs.c:2045 refs.c:2080
 #, c-format
 msgid "cannot process '%s' and '%s' at the same time"
 msgstr "невъзможно е едновременно да се обработват „%s“ и „%s“"
 
-#: refs/files-backend.c:1191
+#: refs/files-backend.c:1228
 #, c-format
 msgid "could not remove reference %s"
 msgstr "Указателят „%s“ не може да бъде изтрит"
 
-#: refs/files-backend.c:1205 refs/packed-backend.c:1532
+#: refs/files-backend.c:1242 refs/packed-backend.c:1532
 #: refs/packed-backend.c:1542
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "Указателят „%s“ не може да бъде изтрит: %s"
 
-#: refs/files-backend.c:1208 refs/packed-backend.c:1545
+#: refs/files-backend.c:1245 refs/packed-backend.c:1545
 #, c-format
 msgid "could not delete references: %s"
 msgstr "Указателите не може да бъдат изтрити: %s"
@@ -3807,191 +4199,197 @@
 msgid "invalid refspec '%s'"
 msgstr "неправилен указател: „%s“"
 
-#: ref-filter.c:38 wt-status.c:1850
+#: ref-filter.c:39 wt-status.c:1855
 msgid "gone"
 msgstr "изтрит"
 
-#: ref-filter.c:39
+#: ref-filter.c:40
 #, c-format
 msgid "ahead %d"
 msgstr "напред с %d"
 
-#: ref-filter.c:40
+#: ref-filter.c:41
 #, c-format
 msgid "behind %d"
 msgstr "назад с %d"
 
-#: ref-filter.c:41
+#: ref-filter.c:42
 #, c-format
 msgid "ahead %d, behind %d"
 msgstr "напред с %d, назад с %d"
 
-#: ref-filter.c:137
+#: ref-filter.c:138
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "очакван формат: %%(color:ЦВЯТ)"
 
-#: ref-filter.c:139
+#: ref-filter.c:140
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "непознат цвят: %%(color:%s)"
 
-#: ref-filter.c:161
+#: ref-filter.c:162
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "очаква се цяло число за „refname:lstrip=%s“"
 
-#: ref-filter.c:165
+#: ref-filter.c:166
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "очаква се цяло число за „refname:rstrip=%s“"
 
-#: ref-filter.c:167
+#: ref-filter.c:168
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "непознат аргумент за „%%(%s)“: %s"
 
-#: ref-filter.c:222
+#: ref-filter.c:223
 #, c-format
 msgid "%%(objecttype) does not take arguments"
 msgstr "%%(objecttype) не приема аргументи"
 
-#: ref-filter.c:234
+#: ref-filter.c:235
 #, c-format
 msgid "%%(objectsize) does not take arguments"
 msgstr "%%(objectsize) не приема аргументи"
 
-#: ref-filter.c:246
+#: ref-filter.c:247
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body) не приема аргументи"
 
-#: ref-filter.c:255
+#: ref-filter.c:256
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject) не приема аргументи"
 
-#: ref-filter.c:275
+#: ref-filter.c:278
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "непознат аргумент „%%(trailers)“: %s"
 
-#: ref-filter.c:304
+#: ref-filter.c:307
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "очаква се положителна стойност за „contents:lines=%s“"
 
-#: ref-filter.c:306
+#: ref-filter.c:309
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "непознат аргумент за %%(contents): %s"
 
-#: ref-filter.c:321
+#: ref-filter.c:324
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "очаква се положителна стойност за „objectname:short=%s“"
 
-#: ref-filter.c:325
+#: ref-filter.c:328
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "непознат аргумент за %%(objectname): %s"
 
-#: ref-filter.c:355
+#: ref-filter.c:358
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "очакван формат: %%(align:ШИРОЧИНА,ПОЗИЦИЯ)"
 
-#: ref-filter.c:367
+#: ref-filter.c:370
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "непозната позиция: %s"
 
-#: ref-filter.c:374
+#: ref-filter.c:377
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "непозната широчина: %s"
 
-#: ref-filter.c:383
+#: ref-filter.c:386
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "непознат аргумент за %%(align): %s"
 
-#: ref-filter.c:391
+#: ref-filter.c:394
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr "очаква се положителна широчина с лексемата „%%(align)“"
 
-#: ref-filter.c:409
+#: ref-filter.c:412
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "непознат аргумент за „%%(if)“: %s"
 
-#: ref-filter.c:505
+#: ref-filter.c:508
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr "неправилно име на обект: „%.*s“"
 
-#: ref-filter.c:532
+#: ref-filter.c:535
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "непознато име на обект: „%.*s“"
 
-#: ref-filter.c:656
+#: ref-filter.c:539
+#, c-format
+msgid ""
+"not a git repository, but the field '%.*s' requires access to object data"
+msgstr "не е хранилище на git, а полето „%.*s“ изисква достъп данни на обектни"
+
+#: ref-filter.c:663
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "формат: лексемата %%(if) е използвана без съответната ѝ %%(then)"
 
-#: ref-filter.c:719
+#: ref-filter.c:726
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "формат: лексемата %%(then) е използвана без съответната ѝ %%(if)"
 
-#: ref-filter.c:721
+#: ref-filter.c:728
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr "формат: лексемата %%(then) е използвана повече от един път"
 
-#: ref-filter.c:723
+#: ref-filter.c:730
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "формат: лексемата %%(then) е използвана след %%(else)"
 
-#: ref-filter.c:751
+#: ref-filter.c:758
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "формат: лексемата %%(else) е използвана без съответната ѝ %%(if)"
 
-#: ref-filter.c:753
+#: ref-filter.c:760
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "формат: лексемата %%(else) е използвана без съответната ѝ %%(then)"
 
-#: ref-filter.c:755
+#: ref-filter.c:762
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr "формат: лексемата %%(else) е използвана повече от един път"
 
-#: ref-filter.c:770
+#: ref-filter.c:777
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr "формат: лексемата %%(end) е използвана без съответната ѝ"
 
-#: ref-filter.c:827
+#: ref-filter.c:834
 #, c-format
 msgid "malformed format string %s"
 msgstr "неправилен форматиращ низ „%s“"
 
-#: ref-filter.c:1416
+#: ref-filter.c:1424
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(извън клон, пребазиране на „%s“)"
 
-#: ref-filter.c:1419
+#: ref-filter.c:1427
 #, c-format
 msgid "(no branch, rebasing detached HEAD %s)"
 msgstr "(извън клон, пребазиране на несвързан указател „HEAD“ при „%s“)"
 
-#: ref-filter.c:1422
+#: ref-filter.c:1430
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(извън клон, двоично търсене от „%s“)"
@@ -3999,7 +4397,7 @@
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1430
+#: ref-filter.c:1438
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(Указателят „HEAD“ не е свързан и е при „%s“)"
@@ -4007,144 +4405,144 @@
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1437
+#: ref-filter.c:1445
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "Указателят „HEAD“ не е свързан и е отделѐн от „%s“"
 
-#: ref-filter.c:1441
+#: ref-filter.c:1449
 msgid "(no branch)"
 msgstr "(извън клон)"
 
-#: ref-filter.c:1475 ref-filter.c:1623
+#: ref-filter.c:1483 ref-filter.c:1638
 #, c-format
 msgid "missing object %s for %s"
 msgstr "обектът „%s“ липсва за „%s“"
 
-#: ref-filter.c:1483
+#: ref-filter.c:1491
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "неуспешно анализиране чрез „parse_object_buffer“ на „%s“ за „%s“"
 
-#: ref-filter.c:1980
+#: ref-filter.c:1857
 #, c-format
 msgid "malformed object at '%s'"
 msgstr "обект със сгрешен формат при „%s“"
 
-#: ref-filter.c:2062
+#: ref-filter.c:1946
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "игнориране на указателя с грешно име „%s“"
 
-#: ref-filter.c:2340
+#: ref-filter.c:2232
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "грешка във форма̀та: липсва лексемата %%(end)"
 
-#: ref-filter.c:2444
+#: ref-filter.c:2338
 #, c-format
 msgid "malformed object name %s"
 msgstr "неправилно име на обект „%s“"
 
-#: remote.c:606
+#: remote.c:607
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "Невъзможно е да се доставят едновременно и „%s“, и „%s“ към „%s“"
 
-#: remote.c:610
+#: remote.c:611
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "„%s“ обикновено следи „%s“, а не „%s“"
 
-#: remote.c:614
+#: remote.c:615
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "„%s“ следи както „%s“, така и „%s“"
 
-#: remote.c:622
+#: remote.c:623
 msgid "Internal error"
 msgstr "Вътрешна грешка"
 
-#: remote.c:1536 remote.c:1637
+#: remote.c:1569 remote.c:1670
 msgid "HEAD does not point to a branch"
 msgstr "Указателят „HEAD“ не сочи към клон"
 
-#: remote.c:1545
+#: remote.c:1578
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "няма клон на име „%s“"
 
-#: remote.c:1548
+#: remote.c:1581
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr "не е зададен клон-източник за клона „%s“"
 
-#: remote.c:1554
+#: remote.c:1587
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "клонът-източник „%s“ не е съхранен като следящ клон"
 
-#: remote.c:1569
+#: remote.c:1602
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr ""
 "липсва локален следящ клон за местоположението за изтласкване „%s“ в "
 "хранилището „%s“"
 
-#: remote.c:1581
+#: remote.c:1614
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "няма информация клонът „%s“ да следи някой друг"
 
-#: remote.c:1591
+#: remote.c:1624
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "указателят за изтласкване на „%s“ не включва „%s“"
 
-#: remote.c:1604
+#: remote.c:1637
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "указателят за изтласкване не включва цел („push.default“ е „nothing“)"
 
-#: remote.c:1626
+#: remote.c:1659
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr "простото (simple) изтласкване не съответства на една цел"
 
-#: remote.c:1951
+#: remote.c:1935
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "Този клон следи „%s“, но следеният клон е изтрит.\n"
 
-#: remote.c:1955
+#: remote.c:1939
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "  (за да коригирате това, използвайте „git branch --unset-upstream“)\n"
 
-#: remote.c:1958
+#: remote.c:1942
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr "Клонът е актуализиран към „%s“.\n"
 
-#: remote.c:1962
+#: remote.c:1946
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr "Клонът ви и „%s“ сочат към различни подавания.\n"
 
-#: remote.c:1965
+#: remote.c:1949
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr "  (за повече информация ползвайте „%s“)\n"
 
-#: remote.c:1969
+#: remote.c:1953
 #, 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] "Клонът ви е с %2$d подаване пред „%1$s“.\n"
 msgstr[1] "Клонът ви е с %2$d подавания пред „%1$s“.\n"
 
-#: remote.c:1975
+#: remote.c:1959
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (публикувайте локалните си промени чрез „git push“)\n"
 
-#: remote.c:1978
+#: remote.c:1962
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -4152,11 +4550,11 @@
 msgstr[0] "Клонът ви е с %2$d подаване зад „%1$s“ и може да бъде превъртян.\n"
 msgstr[1] "Клонът ви е с %2$d подавания зад „%1$s“ и може да бъде превъртян.\n"
 
-#: remote.c:1986
+#: remote.c:1970
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (обновете локалния си клон чрез „git pull“)\n"
 
-#: remote.c:1989
+#: remote.c:1973
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -4171,43 +4569,149 @@
 "Текущият клон се е отделил от „%s“,\n"
 "двата имат съответно по %d и %d несъвпадащи подавания.\n"
 
-#: remote.c:1999
+#: remote.c:1983
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (слейте отдалечения клон в локалния чрез „git pull“)\n"
 
-#: replace-object.c:20
+#: replace-object.c:21
 #, c-format
 msgid "bad replace ref name: %s"
 msgstr "неправилно име на указател за замяна: „%s“"
 
-#: replace-object.c:29
+#: replace-object.c:30
 #, c-format
 msgid "duplicate replace ref: %s"
 msgstr "повтарящ се указател за замяна: „%s“"
 
-#: replace-object.c:72
+#: replace-object.c:73
 #, c-format
 msgid "replace depth too high for object %s"
 msgstr "дълбочината на замяна е прекалено голяма за обекта: „%s“"
 
-#: revision.c:2305
+#: rerere.c:217 rerere.c:226 rerere.c:229
+msgid "corrupt MERGE_RR"
+msgstr "повреден „MERGE_RR“ (запис за коригиране на конфликт)"
+
+#: rerere.c:264 rerere.c:269
+msgid "unable to write rerere record"
+msgstr "приложеното коригиране на конфликт не може да бъде записано"
+
+#: rerere.c:485 rerere.c:692 sequencer.c:3136 sequencer.c:3162
+#, c-format
+msgid "could not write '%s'"
+msgstr "„%s“ не може да се запише"
+
+#: rerere.c:495
+#, c-format
+msgid "there were errors while writing '%s' (%s)"
+msgstr "грешки при записването на „%s“ (%s)"
+
+#: rerere.c:498
+#, c-format
+msgid "failed to flush '%s'"
+msgstr "грешка при изчистването на буферите при записването на „%s“"
+
+#: rerere.c:503 rerere.c:1039
+#, c-format
+msgid "could not parse conflict hunks in '%s'"
+msgstr "парчетата с конфликти в „%s“ не може да се анализират"
+
+#: rerere.c:684
+#, c-format
+msgid "failed utime() on '%s'"
+msgstr "неуспешно задаване на време на достъп/създаване чрез „utime“ на „%s“"
+
+#: rerere.c:694
+#, c-format
+msgid "writing '%s' failed"
+msgstr "неуспешен запис на „%s“"
+
+#: rerere.c:714
+#, c-format
+msgid "Staged '%s' using previous resolution."
+msgstr ""
+"„%s“ е добавен към индекса с преизползване на запазена корекция при сливане"
+
+#: rerere.c:753
+#, c-format
+msgid "Recorded resolution for '%s'."
+msgstr "Корекцията на конфликта при сливане на „%s“ е запазена."
+
+#: rerere.c:788
+#, c-format
+msgid "Resolved '%s' using previous resolution."
+msgstr ""
+"Конфликтът при сливане на „%s“ е коригиран с преизползване на предишна "
+"корекция."
+
+#: rerere.c:803
+#, c-format
+msgid "cannot unlink stray '%s'"
+msgstr "излишният обект „%s“ не може да се изтрие"
+
+#: rerere.c:807
+#, c-format
+msgid "Recorded preimage for '%s'"
+msgstr "Предварителният вариант на „%s“ е запазен"
+
+#: rerere.c:881 submodule.c:1763 builtin/submodule--helper.c:1413
+#: builtin/submodule--helper.c:1423
+#, c-format
+msgid "could not create directory '%s'"
+msgstr "Директорията „%s“ не може да бъде създадена"
+
+#: rerere.c:1057
+#, c-format
+msgid "failed to update conflicted state in '%s'"
+msgstr "конфликтът в „%s“ не може да се обнови"
+
+#: rerere.c:1068 rerere.c:1075
+#, c-format
+msgid "no remembered resolution for '%s'"
+msgstr "липсва запазена корекция на конфликт при „%s“"
+
+#: rerere.c:1077
+#, c-format
+msgid "cannot unlink '%s'"
+msgstr "„%s“ не може да се изтрие"
+
+#: rerere.c:1087
+#, c-format
+msgid "Updated preimage for '%s'"
+msgstr "Предварителният вариант на „%s“ е обновен"
+
+#: rerere.c:1096
+#, c-format
+msgid "Forgot resolution for '%s'\n"
+msgstr "Запазената корекция на конфликт при „%s“ е премахната\n"
+
+#: rerere.c:1199
+msgid "unable to open rr-cache directory"
+msgstr "директорията „rr-cache“ не може да се отвори"
+
+#: revision.c:2324
 msgid "your current branch appears to be broken"
 msgstr "Текущият клон е повреден"
 
-#: revision.c:2308
+#: revision.c:2327
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr "Текущият клон „%s“ е без подавания "
 
-#: revision.c:2505
+#: revision.c:2523
 msgid "--first-parent is incompatible with --bisect"
 msgstr "опциите „--first-parent“ и „--bisect“ са несъвместими"
 
-#: run-command.c:728
+#: run-command.c:740
 msgid "open /dev/null failed"
 msgstr "неуспешно отваряне на „/dev/null“"
 
-#: run-command.c:1271
+#: run-command.c:1229
+#, c-format
+msgid "cannot create async thread: %s"
+msgstr "не може да се създаде асинхронна нишка: %s"
+
+#: run-command.c:1293
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -4234,15 +4738,15 @@
 msgid "remote unpack failed: %s"
 msgstr "неуспешно отдалечено разпакетиране: %s"
 
-#: send-pack.c:309
+#: send-pack.c:308
 msgid "failed to sign the push certificate"
 msgstr "сертификатът за изтласкване не може да бъде подписан"
 
-#: send-pack.c:422
+#: send-pack.c:421
 msgid "the receiving end does not support --signed push"
 msgstr "отсрещната страна не поддържа изтласкване с опцията „--signed“"
 
-#: send-pack.c:424
+#: send-pack.c:423
 msgid ""
 "not sending a push certificate since the receiving end does not support --"
 "signed push"
@@ -4250,42 +4754,42 @@
 "отсрещната страна не поддържа изтласкване с опцията „--signed“, затова не се "
 "използва сертификат"
 
-#: send-pack.c:436
+#: send-pack.c:435
 msgid "the receiving end does not support --atomic push"
 msgstr "получаващата страна не поддържа изтласкване с опцията „--atomic“"
 
-#: send-pack.c:441
+#: send-pack.c:440
 msgid "the receiving end does not support push options"
 msgstr "отсрещната страна не поддържа опции при изтласкване"
 
-#: sequencer.c:177
+#: sequencer.c:183
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr "несъществуващ режим на изчистване „%s“ на съобщение при подаване"
 
-#: sequencer.c:278
+#: sequencer.c:287
 #, c-format
 msgid "could not delete '%s'"
 msgstr "„%s“ не може да бъде изтрит"
 
-#: sequencer.c:304
+#: sequencer.c:313
 msgid "revert"
 msgstr "отмяна"
 
-#: sequencer.c:306
+#: sequencer.c:315
 msgid "cherry-pick"
 msgstr "отбиране"
 
-#: sequencer.c:308
+#: sequencer.c:317
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:310
+#: sequencer.c:319
 #, c-format
 msgid "unknown action: %d"
 msgstr "неизвестно действие: %d"
 
-#: sequencer.c:367
+#: sequencer.c:376
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -4293,7 +4797,7 @@
 "след коригирането на конфликтите, отбележете съответните\n"
 "пътища с „git add ПЪТ…“ или „git rm ПЪТ…“."
 
-#: sequencer.c:370
+#: sequencer.c:379
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -4303,39 +4807,39 @@
 "пътища с „git add ПЪТ…“ или „git rm ПЪТ…“, след което\n"
 "подайте резултата с командата „git commit'“."
 
-#: sequencer.c:383 sequencer.c:2488
+#: sequencer.c:392 sequencer.c:2632
 #, c-format
 msgid "could not lock '%s'"
 msgstr "„%s“ не може да се заключи"
 
-#: sequencer.c:390
+#: sequencer.c:399
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "краят на ред не може да се запише в „%s“"
 
-#: sequencer.c:395 sequencer.c:2371 sequencer.c:2494 sequencer.c:2508
-#: sequencer.c:2741
+#: sequencer.c:404 sequencer.c:2515 sequencer.c:2638 sequencer.c:2652
+#: sequencer.c:2885
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "„%s“ не може да се завърши"
 
-#: sequencer.c:418 sequencer.c:816 sequencer.c:1505 sequencer.c:2391
-#: sequencer.c:2723 sequencer.c:2827 builtin/am.c:260 builtin/commit.c:740
-#: builtin/merge.c:1081
+#: sequencer.c:427 sequencer.c:921 sequencer.c:1594 sequencer.c:2535
+#: sequencer.c:2867 sequencer.c:2974 builtin/am.c:260 builtin/commit.c:746
+#: builtin/merge.c:1084 builtin/rebase.c:152
 #, c-format
 msgid "could not read '%s'"
 msgstr "файлът „%s“ не може да бъде прочетен"
 
-#: sequencer.c:444
+#: sequencer.c:453
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "локалните ви промени ще бъдат презаписани при %s."
 
-#: sequencer.c:448
+#: sequencer.c:457
 msgid "commit your changes or stash them to proceed."
 msgstr "подайте или скатайте промените, за да продължите"
 
-#: sequencer.c:477
+#: sequencer.c:486
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s: превъртане"
@@ -4343,35 +4847,70 @@
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:566
+#: sequencer.c:575
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: новият индекс не може да бъде запазен"
 
-#: sequencer.c:582
+#: sequencer.c:591
 msgid "unable to update cache tree"
 msgstr "дървото на кеша не може да бъде обновено"
 
-#: sequencer.c:595
+#: sequencer.c:604
 msgid "could not resolve HEAD commit"
 msgstr "подаването, сочено от указателя „HEAD“, не може да бъде открито"
 
-#: sequencer.c:723 sequencer.c:740
+#: sequencer.c:684
 #, c-format
-msgid "could not parse '%s' (looking for '%s')"
-msgstr "„%s“ не може да се анализира (търси се „%s“)"
+msgid "no key present in '%.*s'"
+msgstr "в „%.*s“ няма ключове"
 
-#: sequencer.c:731
+#: sequencer.c:695
 #, c-format
-msgid "bad quoting on %s value in '%s'"
-msgstr "лошо цитиране на стойността на „%s“ в „%s“"
+msgid "unable to dequote value of '%s'"
+msgstr "цитирането на стойността на „%s“ не може да бъде изчистено"
+
+#: sequencer.c:732 wrapper.c:227 wrapper.c:397 builtin/am.c:719
+#: builtin/am.c:811 builtin/merge.c:1081
+#, c-format
+msgid "could not open '%s' for reading"
+msgstr "файлът не може да бъде прочетен: „%s“"
+
+#: sequencer.c:742
+msgid "'GIT_AUTHOR_NAME' already given"
+msgstr "настройката за автор „GIT_AUTHOR_NAME“ вече е зададена"
 
 #: sequencer.c:747
+msgid "'GIT_AUTHOR_EMAIL' already given"
+msgstr "настройката за е-поща „GIT_AUTHOR_EMAIL“ вече е зададена"
+
+#: sequencer.c:752
+msgid "'GIT_AUTHOR_DATE' already given"
+msgstr "настройката за дата „GIT_AUTHOR_DATE“ вече е зададена"
+
+#: sequencer.c:756
+#, c-format
+msgid "unknown variable '%s'"
+msgstr "непозната променлива „%s“"
+
+#: sequencer.c:761
+msgid "missing 'GIT_AUTHOR_NAME'"
+msgstr "настройката за автор „GIT_AUTHOR_NAME“ липсва"
+
+#: sequencer.c:763
+msgid "missing 'GIT_AUTHOR_EMAIL'"
+msgstr "настройката за е-поща „GIT_AUTHOR_EMAIL“ липсва"
+
+#: sequencer.c:765
+msgid "missing 'GIT_AUTHOR_DATE'"
+msgstr "настройката за дата „GIT_AUTHOR_DATE“ липсва"
+
+#: sequencer.c:825
 #, c-format
 msgid "invalid date format '%s' in '%s'"
 msgstr "неправилен формат на дата „%s“ в „%s“"
 
-#: sequencer.c:761
+#: sequencer.c:842
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -4400,17 +4939,17 @@
 "\n"
 "    git rebase --continue\n"
 
-#: sequencer.c:830
+#: sequencer.c:935
 msgid "writing root commit"
 msgstr "запазване на начално подаване"
 
-#: sequencer.c:1055
+#: sequencer.c:1142
 msgid "'prepare-commit-msg' hook failed"
 msgstr ""
 "неуспешно изпълнение на куката при промяна на съобщението при подаване "
 "(prepare-commit-msg)"
 
-#: sequencer.c:1062
+#: sequencer.c:1149
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -4439,7 +4978,7 @@
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:1075
+#: sequencer.c:1162
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -4465,316 +5004,311 @@
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:1115
+#: sequencer.c:1202
 msgid "couldn't look up newly created commit"
 msgstr "току що създаденото подаване не може да бъде открито"
 
-#: sequencer.c:1117
+#: sequencer.c:1204
 msgid "could not parse newly created commit"
 msgstr "току що създаденото подаване не може да бъде анализирано"
 
-#: sequencer.c:1163
+#: sequencer.c:1250
 msgid "unable to resolve HEAD after creating commit"
 msgstr ""
 "състоянието сочено от указателя „HEAD“ не може да бъде открито след "
 "подаването"
 
-#: sequencer.c:1165
+#: sequencer.c:1252
 msgid "detached HEAD"
 msgstr "несвързан връх „HEAD“"
 
-#: sequencer.c:1169
+#: sequencer.c:1256
 msgid " (root-commit)"
 msgstr " (начално подаване)"
 
-#: sequencer.c:1190
+#: sequencer.c:1277
 msgid "could not parse HEAD"
 msgstr "указателят „HEAD“ не може да бъде анализиран"
 
-#: sequencer.c:1192
+#: sequencer.c:1279
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "указателят „HEAD“ „%s“ сочи към нещо, което не е подаване!"
 
-#: sequencer.c:1196 builtin/commit.c:1528
+#: sequencer.c:1283 builtin/commit.c:1543
 msgid "could not parse HEAD commit"
 msgstr "върховото подаване „HEAD“ не може да бъде прочетено"
 
-#: sequencer.c:1247 sequencer.c:1845
+#: sequencer.c:1334 sequencer.c:1934
 msgid "unable to parse commit author"
 msgstr "авторът на подаването не може да бъде анализиран"
 
-#: sequencer.c:1257 builtin/am.c:1632 builtin/merge.c:675
+#: sequencer.c:1344 builtin/am.c:1585 builtin/merge.c:677
 msgid "git write-tree failed to write a tree"
 msgstr "Командата „git write-tree“ не успя да запише обект-дърво"
 
-#: sequencer.c:1274 sequencer.c:1329
+#: sequencer.c:1361 sequencer.c:1416
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr "съобщението за подаване не може да бъде прочетено от „%s“"
 
-#: sequencer.c:1296 builtin/am.c:1653 builtin/commit.c:1631 builtin/merge.c:855
-#: builtin/merge.c:880
+#: sequencer.c:1383 builtin/am.c:1606 builtin/commit.c:1646 builtin/merge.c:858
+#: builtin/merge.c:883
 msgid "failed to write commit object"
 msgstr "обектът за подаването не може да бъде записан"
 
-#: sequencer.c:1356
+#: sequencer.c:1443
 #, c-format
 msgid "could not parse commit %s"
 msgstr "подаването „%s“ не може да бъде анализирано"
 
-#: sequencer.c:1361
+#: sequencer.c:1448
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr "родителското подаване „%s“ не може да бъде анализирано"
 
-#: sequencer.c:1457 sequencer.c:1565
+#: sequencer.c:1546 sequencer.c:1654
 #, c-format
 msgid "unknown command: %d"
 msgstr "непозната команда: %d"
 
-#: sequencer.c:1512 sequencer.c:1537
+#: sequencer.c:1601 sequencer.c:1626
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "Това е обединение от %d подавания"
 
-#: sequencer.c:1522 sequencer.c:4520
+#: sequencer.c:1611 sequencer.c:4744
 msgid "need a HEAD to fixup"
 msgstr "За вкарване в предходното подаване ви трябва указател „HEAD“"
 
-#: sequencer.c:1524 sequencer.c:2768
+#: sequencer.c:1613 sequencer.c:2912
 msgid "could not read HEAD"
 msgstr "указателят „HEAD“ не може да се прочете"
 
-#: sequencer.c:1526
+#: sequencer.c:1615
 msgid "could not read HEAD's commit message"
 msgstr ""
 "съобщението за подаване към указателя „HEAD“ не може да бъде прочетено: %s"
 
-#: sequencer.c:1532
+#: sequencer.c:1621
 #, c-format
 msgid "cannot write '%s'"
 msgstr "„%s“ не може да се запази"
 
-#: sequencer.c:1539 git-rebase--preserve-merges.sh:441
+#: sequencer.c:1628 git-rebase--preserve-merges.sh:441
 msgid "This is the 1st commit message:"
 msgstr "Това е 1-то съобщение при подаване:"
 
-#: sequencer.c:1547
+#: sequencer.c:1636
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "съобщението за подаване към „%s“ не може да бъде прочетено"
 
-#: sequencer.c:1554
+#: sequencer.c:1643
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "Това е съобщение при подаване №%d:"
 
-#: sequencer.c:1560
+#: sequencer.c:1649
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr "Съобщение при подаване №%d ще бъде прескочено:"
 
-#: sequencer.c:1643
+#: sequencer.c:1732
 msgid "your index file is unmerged."
 msgstr "индексът не е слят."
 
-#: sequencer.c:1650
+#: sequencer.c:1739
 msgid "cannot fixup root commit"
 msgstr "началното подаване не може да се вкара в предходното му"
 
-#: sequencer.c:1669
+#: sequencer.c:1758
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr "подаването „%s“ е сливане, но не е дадена опцията „-m“"
 
-#: sequencer.c:1677
+#: sequencer.c:1766
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "подаването „%s“ няма родител %d"
 
-#: sequencer.c:1681
+#: sequencer.c:1770
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr "указано е базово подаване, но подаването „%s“ не е сливане."
 
-#: sequencer.c:1687
+#: sequencer.c:1776
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "неуспешно извличане на съобщението за подаване на „%s“"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1706
+#: sequencer.c:1795
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: неразпозната стойност за родителското подаване „%s“"
 
-#: sequencer.c:1771
+#: sequencer.c:1860
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "„%s“ не може да се преименува на „%s“"
 
-#: sequencer.c:1826
+#: sequencer.c:1915
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "подаването „%s“… не може да бъде отменено: „%s“"
 
-#: sequencer.c:1827
+#: sequencer.c:1916
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "подаването „%s“… не може да бъде приложено: „%s“"
 
-#: sequencer.c:1885
+#: sequencer.c:1974
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: неуспешно изчитане на индекса"
 
-#: sequencer.c:1892
+#: sequencer.c:1981
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s: неуспешно обновяване на индекса"
 
-#: sequencer.c:1972
+#: sequencer.c:2062
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "„%s“ не приема аргументи: „%s“"
 
-#: sequencer.c:1981
+#: sequencer.c:2071
 #, c-format
 msgid "missing arguments for %s"
 msgstr "„%s“ изисква аргументи"
 
-#: sequencer.c:2040
+#: sequencer.c:2130
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "неправилен ред %d: %.*s"
 
-#: sequencer.c:2048
+#: sequencer.c:2138
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr "Без предишно подаване не може да се изпълни „%s“"
 
-#: sequencer.c:2096 sequencer.c:4277 sequencer.c:4333
-#, c-format
-msgid "could not read '%s'."
-msgstr "от „%s“ не може да се чете."
-
-#: sequencer.c:2119
+#: sequencer.c:2209
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr "коригирайте това чрез „git rebase --edit-todo“."
 
-#: sequencer.c:2121
+#: sequencer.c:2211
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "неизползваем файл с описание на предстоящите действия: „%s“"
 
-#: sequencer.c:2126
+#: sequencer.c:2216
 msgid "no commits parsed."
 msgstr "никое от подаванията не може да се разпознае."
 
-#: sequencer.c:2137
+#: sequencer.c:2227
 msgid "cannot cherry-pick during a revert."
 msgstr ""
 "по време на отмяна на подаване не може да се извърши отбиране на подаване."
 
-#: sequencer.c:2139
+#: sequencer.c:2229
 msgid "cannot revert during a cherry-pick."
 msgstr "по време на отбиране не може да се извърши отмяна на подаване."
 
-#: sequencer.c:2209
+#: sequencer.c:2299
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "неправилна стойност за „%s“: „%s“"
 
-#: sequencer.c:2285
+#: sequencer.c:2380
 msgid "unusable squash-onto"
 msgstr "подаването, в което другите да се вкарат, не може да се използва"
 
-#: sequencer.c:2301
+#: sequencer.c:2396
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr "неправилен файл с опции: „%s“"
 
-#: sequencer.c:2335 sequencer.c:3775
+#: sequencer.c:2479 sequencer.c:4005
 msgid "empty commit set passed"
 msgstr "зададено е празно множество от подавания"
 
-#: sequencer.c:2343
+#: sequencer.c:2487
 msgid "a cherry-pick or revert is already in progress"
 msgstr ""
 "в момента вече се извършва отбиране на подавания или пребазиране на клона"
 
-#: sequencer.c:2344
+#: sequencer.c:2488
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "използвайте „git cherry-pick (--continue | --quit | --abort)“"
 
-#: sequencer.c:2347
+#: sequencer.c:2491
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "директорията за секвенсора „%s“ не може да бъде създадена"
 
-#: sequencer.c:2361
+#: sequencer.c:2505
 msgid "could not lock HEAD"
 msgstr "указателят „HEAD“ не може да се заключи"
 
-#: sequencer.c:2416 sequencer.c:3543
+#: sequencer.c:2560 sequencer.c:3761
 msgid "no cherry-pick or revert in progress"
 msgstr ""
 "в момента не се извършва отбиране на подавания или пребазиране на клона"
 
-#: sequencer.c:2418
+#: sequencer.c:2562
 msgid "cannot resolve HEAD"
 msgstr "Подаването сочено от указателя „HEAD“ не може да бъде открито"
 
-#: sequencer.c:2420 sequencer.c:2455
+#: sequencer.c:2564 sequencer.c:2599
 msgid "cannot abort from a branch yet to be born"
 msgstr ""
 "действието не може да бъде преустановено, когато сте на клон, който тепърва "
 "предстои да бъде създаден"
 
-#: sequencer.c:2441 builtin/grep.c:721
+#: sequencer.c:2585 builtin/grep.c:721
 #, c-format
 msgid "cannot open '%s'"
 msgstr "„%s“ не може да бъде отворен"
 
-#: sequencer.c:2443
+#: sequencer.c:2587
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "„%s“ не може да бъде прочетен: %s"
 
-#: sequencer.c:2444
+#: sequencer.c:2588
 msgid "unexpected end of file"
 msgstr "неочакван край на файл"
 
-#: sequencer.c:2450
+#: sequencer.c:2594
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr ""
 "запазеният преди започването на отбирането файл за указателя „HEAD“ — „%s“ е "
 "повреден"
 
-#: sequencer.c:2461
+#: sequencer.c:2605
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr ""
 "Изглежда указателят „HEAD“ е променен.  Проверете към какво сочи.\n"
 "Не се правят промени."
 
-#: sequencer.c:2565 sequencer.c:3461
+#: sequencer.c:2709 sequencer.c:3679
 #, c-format
 msgid "could not update %s"
 msgstr "„%s“ не може да се обнови"
 
-#: sequencer.c:2603 sequencer.c:3441
+#: sequencer.c:2747 sequencer.c:3659
 msgid "cannot read HEAD"
 msgstr "указателят „HEAD“ не може да бъде прочетен"
 
-#: sequencer.c:2618
+#: sequencer.c:2762
 #, c-format
 msgid "unable to copy '%s' to '%s'"
 msgstr "„%s“ не може да се копира като „%s“"
 
-#: sequencer.c:2626
+#: sequencer.c:2770
 #, c-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -4793,26 +5327,27 @@
 "\n"
 "    git rebase --continue\n"
 
-#: sequencer.c:2636
+#: sequencer.c:2780
 #, c-format
 msgid "Could not apply %s... %.*s"
 msgstr "Подаването „%s“… не може да бъде приложено: „%.*s“"
 
-#: sequencer.c:2643
+#: sequencer.c:2787
 #, c-format
 msgid "Could not merge %.*s"
 msgstr "Невъзможно сливане на „%.*s“"
 
-#: sequencer.c:2654 sequencer.c:2658 builtin/difftool.c:640
+#: sequencer.c:2798 sequencer.c:2802 builtin/difftool.c:640
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "„%s“ не може да се копира като „%s“"
 
-#: sequencer.c:2680 sequencer.c:3095
+#: sequencer.c:2824 sequencer.c:3242 builtin/rebase.c:580 builtin/rebase.c:1019
+#: builtin/rebase.c:1372 builtin/rebase.c:1426
 msgid "could not read index"
 msgstr "индексът не може да бъде прочетен"
 
-#: sequencer.c:2685
+#: sequencer.c:2829
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -4827,11 +5362,11 @@
 "    git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2691
+#: sequencer.c:2835
 msgid "and made changes to the index and/or the working tree\n"
 msgstr "и промени индекса и/или работното дърво\n"
 
-#: sequencer.c:2697
+#: sequencer.c:2841
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -4848,81 +5383,76 @@
 "    git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2758
+#: sequencer.c:2902
 #, c-format
 msgid "illegal label name: '%.*s'"
 msgstr "неправилно име на етикет: „%.*s“"
 
-#: sequencer.c:2810
+#: sequencer.c:2954
 msgid "writing fake root commit"
 msgstr "запазване на фалшиво начално подаване"
 
-#: sequencer.c:2815
+#: sequencer.c:2959
 msgid "writing squash-onto"
 msgstr "запазване на подаването, в което другите да се вкарат"
 
-#: sequencer.c:2850
+#: sequencer.c:2997 builtin/rebase.c:585 builtin/rebase.c:591
 #, c-format
 msgid "failed to find tree of %s"
 msgstr "дървото, сочено от „%s“, не може да бъде открито"
 
-#: sequencer.c:2868
+#: sequencer.c:3015 builtin/rebase.c:604
 msgid "could not write index"
 msgstr "индексът не може да бъде записан"
 
-#: sequencer.c:2895
+#: sequencer.c:3042
 #, c-format
 msgid "could not resolve '%s'"
 msgstr "„%s“ не може да бъде открит"
 
-#: sequencer.c:2921
+#: sequencer.c:3068
 msgid "cannot merge without a current revision"
 msgstr "без текущо подаване не може да се слива"
 
-#: sequencer.c:2943
+#: sequencer.c:3090
 #, c-format
 msgid "unable to parse '%.*s'"
 msgstr "„%.*s“ не може да се анализира"
 
-#: sequencer.c:2952
+#: sequencer.c:3099
 #, c-format
 msgid "nothing to merge: '%.*s'"
 msgstr "няма нищо за сливане: „%.*s“"
 
-#: sequencer.c:2964
+#: sequencer.c:3111
 msgid "octopus merge cannot be executed on top of a [new root]"
 msgstr "върху начално подаване не може да се извърши множествено сливане"
 
-#: sequencer.c:2979
+#: sequencer.c:3126
 #, c-format
 msgid "could not get commit message of '%s'"
 msgstr "съобщението за подаване към „%s“ не може да бъде получено"
 
-#: sequencer.c:2989 sequencer.c:3015
-#, c-format
-msgid "could not write '%s'"
-msgstr "„%s“ не може да се запише"
-
-#: sequencer.c:3127
+#: sequencer.c:3274
 #, c-format
 msgid "could not even attempt to merge '%.*s'"
 msgstr "сливането на „%.*s“ не може даже да започне"
 
-#: sequencer.c:3143
+#: sequencer.c:3290
 msgid "merge: Unable to write new index file"
 msgstr "сливане: новият индекс не може да бъде запазен"
 
-#: sequencer.c:3211
+#: sequencer.c:3358 builtin/rebase.c:268
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "Автоматично скатаното е приложено.\n"
 
-#: sequencer.c:3223
+#: sequencer.c:3370
 #, c-format
 msgid "cannot store %s"
 msgstr "„%s“ не може да бъде запазен"
 
-#: sequencer.c:3226 git-rebase.sh:188
+#: sequencer.c:3373 builtin/rebase.c:284
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -4933,7 +5463,31 @@
 "надеждно скатани.  Можете да пробвате да ги приложите чрез „git stash pop“\n"
 "или да ги изхвърлите чрез „git stash drop“, когато поискате.\n"
 
-#: sequencer.c:3257
+#: sequencer.c:3427
+#, c-format
+msgid "could not checkout %s"
+msgstr "„%s“ не може да се изтегли"
+
+#: sequencer.c:3441
+#, c-format
+msgid "%s: not a valid OID"
+msgstr "„%s“ е неправилен идентификатор на обект"
+
+#: sequencer.c:3446 git-rebase--preserve-merges.sh:724
+msgid "could not detach HEAD"
+msgstr "указателят „HEAD“ не може да се отдели"
+
+#: sequencer.c:3461
+#, c-format
+msgid "Stopped at HEAD\n"
+msgstr "Бе спряно при „HEAD“\n"
+
+#: sequencer.c:3463
+#, c-format
+msgid "Stopped at %s\n"
+msgstr "Бе спряно при „%s“\n"
+
+#: sequencer.c:3471
 #, c-format
 msgid ""
 "Could not execute the todo command\n"
@@ -4956,48 +5510,48 @@
 "    git rebase --edit-todo\n"
 "    git rebase --continue\n"
 
-#: sequencer.c:3325
+#: sequencer.c:3543
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "Спиране при „%s“…  %.*s\n"
 
-#: sequencer.c:3404
+#: sequencer.c:3622
 #, c-format
 msgid "unknown command %d"
 msgstr "непозната команда %d"
 
-#: sequencer.c:3449
+#: sequencer.c:3667
 msgid "could not read orig-head"
 msgstr "указателят за „orig-head“ не може да се прочете"
 
-#: sequencer.c:3454 sequencer.c:4517
+#: sequencer.c:3672 sequencer.c:4741
 msgid "could not read 'onto'"
 msgstr "указателят за „onto“ не може да се прочете"
 
-#: sequencer.c:3468
+#: sequencer.c:3686
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "„HEAD“ не може да бъде обновен до „%s“"
 
-#: sequencer.c:3554
+#: sequencer.c:3772
 msgid "cannot rebase: You have unstaged changes."
 msgstr "не може да пребазирате, защото има промени, които не са в индекса."
 
-#: sequencer.c:3563
+#: sequencer.c:3781
 msgid "cannot amend non-existing commit"
 msgstr "несъществуващо подаване не може да се поправи"
 
-#: sequencer.c:3565
+#: sequencer.c:3783
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "неправилен файл: „%s“"
 
-#: sequencer.c:3567
+#: sequencer.c:3785
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "неправилно съдържание: „%s“"
 
-#: sequencer.c:3570
+#: sequencer.c:3788
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -5007,47 +5561,47 @@
 "В работното дърво има неподадени промени.  Първо ги подайте, а след това\n"
 "отново изпълнете „git rebase --continue“."
 
-#: sequencer.c:3595 sequencer.c:3633
+#: sequencer.c:3824 sequencer.c:3862
 #, c-format
 msgid "could not write file: '%s'"
 msgstr "файлът „%s“ не може да бъде записан"
 
-#: sequencer.c:3648
+#: sequencer.c:3877
 msgid "could not remove CHERRY_PICK_HEAD"
 msgstr "указателят „CHERRY_PICK_HEAD“ не може да бъде изтрит"
 
-#: sequencer.c:3655
+#: sequencer.c:3884
 msgid "could not commit staged changes."
 msgstr "промените в индекса не могат да бъдат подадени."
 
-#: sequencer.c:3752
+#: sequencer.c:3982
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: не може да се отбере „%s“"
 
-#: sequencer.c:3756
+#: sequencer.c:3986
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: неправилна версия"
 
-#: sequencer.c:3791
+#: sequencer.c:4021
 msgid "can't revert as initial commit"
 msgstr "първоначалното подаване не може да бъде отменено"
 
-#: sequencer.c:4238
+#: sequencer.c:4466
 msgid "make_script: unhandled options"
 msgstr "make_script: неподдържани опции"
 
-#: sequencer.c:4241
+#: sequencer.c:4469
 msgid "make_script: error preparing revisions"
 msgstr "make_script: грешка при подготовката на версии"
 
-#: sequencer.c:4281 sequencer.c:4337
+#: sequencer.c:4509 sequencer.c:4565 sequencer.c:4840
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "неуспешно изтриване на списъка за изпълнение: „%s“"
 
-#: sequencer.c:4396
+#: sequencer.c:4620
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
@@ -5055,7 +5609,7 @@
 "Непозната стойност „%s“ за настройката „rebase.missingCommitsCheck“.  "
 "Настройката се прескача."
 
-#: sequencer.c:4466
+#: sequencer.c:4690
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -5064,7 +5618,7 @@
 "Предупреждение: някои подавания може да са пропуснати.\n"
 "Пропуснати подавания (новите са най-отгоре):\n"
 
-#: sequencer.c:4473
+#: sequencer.c:4697
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -5081,7 +5635,7 @@
 "предупреждение)\n"
 "или „error“ (считане за грешка).\n"
 
-#: sequencer.c:4486
+#: sequencer.c:4710
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -5092,7 +5646,31 @@
 "continue“ след това.\n"
 "Може и да преустановите пребазирането с командата „git rebase --abort“.\n"
 
-#: sequencer.c:4660
+#: sequencer.c:4848 sequencer.c:4886
+msgid "nothing to do"
+msgstr "няма какво да се прави"
+
+#: sequencer.c:4852
+#, c-format
+msgid "Rebase %s onto %s (%d command)"
+msgid_plural "Rebase %s onto %s (%d commands)"
+msgstr[0] "Пребазиране на „%s“ върху „%s“ (%d команди)"
+msgstr[1] "Пребазиране на „%s“ върху „%s“ (%d команда)"
+
+#: sequencer.c:4864
+#, c-format
+msgid "could not copy '%s' to '%s'."
+msgstr "„%s“ не може да се копира като „%s“."
+
+#: sequencer.c:4868 sequencer.c:4897
+msgid "could not transform the todo list"
+msgstr "файлът с командите не може да се обработи"
+
+#: sequencer.c:4900
+msgid "could not skip unnecessary pick commands"
+msgstr "излишните команди за отбиране не бяха прескочени"
+
+#: sequencer.c:4983
 msgid "the script was already rearranged."
 msgstr "скриптът вече е преподреден."
 
@@ -5151,86 +5729,86 @@
 msgid "this operation must be run in a work tree"
 msgstr "тази команда трябва да се изпълни в работно дърво"
 
-#: setup.c:503
+#: setup.c:527
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Очаква се версия на хранилището на git <= %d, а не %d"
 
-#: setup.c:511
+#: setup.c:535
 msgid "unknown repository extensions found:"
 msgstr "открити са непознати разширения в хранилището:"
 
-#: setup.c:530
+#: setup.c:554
 #, c-format
 msgid "error opening '%s'"
 msgstr "„%s“ не може да се отвори"
 
-#: setup.c:532
+#: setup.c:556
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr "прекалено голям файл „.git“: „%s“"
 
-#: setup.c:534
+#: setup.c:558
 #, c-format
 msgid "error reading %s"
 msgstr "грешка при прочитане на „%s“"
 
-#: setup.c:536
+#: setup.c:560
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "неправилен формат на gitfile: %s"
 
-#: setup.c:538
+#: setup.c:562
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "липсва път в gitfile: „%s“"
 
-#: setup.c:540
+#: setup.c:564
 #, c-format
 msgid "not a git repository: %s"
 msgstr "не е хранилище на Git: %s"
 
-#: setup.c:639
+#: setup.c:663
 #, c-format
 msgid "'$%s' too big"
 msgstr "„%s“ е прекалено голям"
 
-#: setup.c:653
+#: setup.c:677
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "не е хранилище на git: „%s“"
 
-#: setup.c:682 setup.c:684 setup.c:715
+#: setup.c:706 setup.c:708 setup.c:739
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "не може да се влезе в директорията „%s“"
 
-#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
+#: setup.c:711 setup.c:767 setup.c:777 setup.c:816 setup.c:824 setup.c:839
 msgid "cannot come back to cwd"
 msgstr "процесът не може да се върне към предишната работна директория"
 
-#: setup.c:813
+#: setup.c:837
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr ""
 "нито тази, нито която и да е от по-горните директории, не е хранилище на "
 "git: %s"
 
-#: setup.c:824
+#: setup.c:848
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr "не може да бъде получена информация чрез „stat“ за „%*s%s%s“"
 
-#: setup.c:1054
+#: setup.c:1078
 msgid "Unable to read current working directory"
 msgstr "Текущата работна директория не може да бъде прочетена"
 
-#: setup.c:1066 setup.c:1072
+#: setup.c:1090 setup.c:1096
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "не може да се влезе в директорията „%s“"
 
-#: setup.c:1085
+#: setup.c:1109
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
@@ -5241,7 +5819,7 @@
 "Git работи в рамките на една файлова система, защото променливата на средата "
 "„GIT_DISCOVERY_ACROSS_FILESYSTEM“ не е зададена."
 
-#: setup.c:1168
+#: setup.c:1192
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
@@ -5251,15 +5829,15 @@
 "(0%.3o).\n"
 "Собственикът на файла трябва да има права за писане и четене."
 
-#: setup.c:1211
+#: setup.c:1235
 msgid "open /dev/null or dup failed"
 msgstr "неуспешно изпълнение на „open“ или „dup“ върху „/dev/null“"
 
-#: setup.c:1226
+#: setup.c:1250
 msgid "fork failed"
 msgstr "неуспешно създаване на процес чрез „fork“"
 
-#: setup.c:1231
+#: setup.c:1255
 msgid "setsid failed"
 msgstr "неуспешно изпълнение на „setsid“"
 
@@ -5339,12 +5917,12 @@
 msgid "object file %s is empty"
 msgstr "файлът с обектите „%s“ е празен"
 
-#: sha1-file.c:1093 sha1-file.c:2206
+#: sha1-file.c:1093 sha1-file.c:2215
 #, c-format
 msgid "corrupt loose object '%s'"
 msgstr "непакетираният обект „%s“ е повреден"
 
-#: sha1-file.c:1095 sha1-file.c:2210
+#: sha1-file.c:1095 sha1-file.c:2219
 #, c-format
 msgid "garbage at end of loose object '%s'"
 msgstr "грешни данни в края на непакетирания обект „%s“"
@@ -5443,7 +6021,7 @@
 msgid "confused by unstable object source data for %s"
 msgstr "грешка поради нестабилния източник данни за обектите „%s“"
 
-#: sha1-file.c:1685 builtin/pack-objects.c:899
+#: sha1-file.c:1685 builtin/pack-objects.c:918
 #, c-format
 msgid "failed utime() on %s"
 msgstr "неуспешно задаване на време на достъп/създаване чрез „utime“ на „%s“"
@@ -5461,76 +6039,76 @@
 msgid "corrupt tag"
 msgstr "повреден етикет"
 
-#: sha1-file.c:1906
+#: sha1-file.c:1912
 #, c-format
 msgid "read error while indexing %s"
 msgstr "грешка при четене по време на индексиране на „%s“"
 
-#: sha1-file.c:1909
+#: sha1-file.c:1915
 #, c-format
 msgid "short read while indexing %s"
 msgstr "непълно прочитане по време на индексиране на „%s“"
 
-#: sha1-file.c:1980 sha1-file.c:1989
+#: sha1-file.c:1988 sha1-file.c:1997
 #, c-format
 msgid "%s: failed to insert into database"
 msgstr "„%s“ не може да се вмъкне в базата от данни"
 
-#: sha1-file.c:1995
+#: sha1-file.c:2003
 #, c-format
 msgid "%s: unsupported file type"
 msgstr "неподдържан вид файл: „%s“"
 
-#: sha1-file.c:2019
+#: sha1-file.c:2027
 #, c-format
 msgid "%s is not a valid object"
 msgstr "„%s“ е неправилен обект"
 
-#: sha1-file.c:2021
+#: sha1-file.c:2029
 #, c-format
 msgid "%s is not a valid '%s' object"
 msgstr "„%s“ е неправилен обект от вид „%s“"
 
-#: sha1-file.c:2048 builtin/index-pack.c:158
+#: sha1-file.c:2056 builtin/index-pack.c:154
 #, c-format
 msgid "unable to open %s"
 msgstr "обектът „%s“ не може да бъде отворен"
 
-#: sha1-file.c:2217 sha1-file.c:2269
+#: sha1-file.c:2226 sha1-file.c:2278
 #, c-format
 msgid "sha1 mismatch for %s (expected %s)"
 msgstr "неправилна сума по SHA1 за „%s“ (трябва да е %s)"
 
-#: sha1-file.c:2241
+#: sha1-file.c:2250
 #, c-format
 msgid "unable to mmap %s"