Merge branch 'ak/git-pm-typofix'

Typofix in comments.

* ak/git-pm-typofix:
  Git.pm: two minor typo fixes
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines
index 894546d..7636199 100644
--- a/Documentation/CodingGuidelines
+++ b/Documentation/CodingGuidelines
@@ -328,9 +328,14 @@
 
  - When you come up with an API, document it.
 
- - The first #include in C files, except in platform specific
-   compat/ implementations, should be git-compat-util.h or another
-   header file that includes it, such as cache.h or builtin.h.
+ - The first #include in C files, except in platform specific compat/
+   implementations, must be either "git-compat-util.h", "cache.h" or
+   "builtin.h".  You do not have to include more than one of these.
+
+ - A C file must directly include the header files that declare the
+   functions and the types it uses, except for the functions and types
+   that are made available to it by including one of the header files
+   it must include by the previous rule.
 
  - If you are planning a new command, consider writing it in shell
    or perl first, so that changes in semantics can be easily
@@ -413,6 +418,29 @@
  - Say what the error is first ("cannot open %s", not "%s: cannot open")
 
 
+Externally Visible Names
+
+ - For configuration variable names, follow the existing convention:
+
+   . The section name indicates the affected subsystem.
+
+   . The subsection name, if any, indicates which of an unbounded set
+     of things to set the value for.
+
+   . The variable name describes the effect of tweaking this knob.
+
+   The section and variable names that consist of multiple words are
+   formed by concatenating the words without punctuations (e.g. `-`),
+   and are broken using bumpyCaps in documentation as a hint to the
+   reader.
+
+   When choosing the variable namespace, do not use variable name for
+   specifying possibly unbounded set of things, most notably anything
+   an end user can freely come up with (e.g. branch names).  Instead,
+   use subsection names or variable values, like the existing variable
+   branch.<name>.description does.
+
+
 Writing Documentation:
 
  Most (if not all) of the documentation pages are written in the
@@ -441,6 +469,10 @@
    --sort=<key>
    --abbrev[=<n>]
 
+ If a placeholder has multiple words, they are separated by dashes:
+   <new-branch-name>
+   --template=<template-directory>
+
  Possibility of multiple occurrences is indicated by three dots:
    <file>...
    (One or more of <file>.)
@@ -457,12 +489,12 @@
    (Zero or more of <patch>.  Note that the dots are inside, not
    outside the brackets.)
 
- Multiple alternatives are indicated with vertical bar:
+ Multiple alternatives are indicated with vertical bars:
    [-q | --quiet]
    [--utf8 | --no-utf8]
 
  Parentheses are used for grouping:
-   [(<rev>|<range>)...]
+   [(<rev> | <range>)...]
    (Any number of either <rev> or <range>.  Parens are needed to make
    it clear that "..." pertains to both <rev> and <range>.)
 
diff --git a/Documentation/RelNotes/2.3.1.txt b/Documentation/RelNotes/2.3.1.txt
new file mode 100644
index 0000000..cf96186
--- /dev/null
+++ b/Documentation/RelNotes/2.3.1.txt
@@ -0,0 +1,52 @@
+Git v2.3.1 Release Notes
+========================
+
+Fixes since v2.3
+----------------
+
+ * The interactive "show a list and let the user choose from it"
+   interface "add -i" used showed and prompted to the user even when
+   the candidate list was empty, against which the only "choice" the
+   user could have made was to choose nothing.
+
+ * "git apply --whitespace=fix" used to under-allocate the memory
+   when the fix resulted in a longer text than the original patch.
+
+ * "git log --help" used to show rev-list options that are irrelevant
+   to the "log" command.
+
+ * The error message from "git commit", when a non-existing author
+   name was given as value to the "--author=" parameter, has been
+   reworded to avoid misunderstanding.
+
+ * A broken pack .idx file in the receiving repository prevented the
+   dumb http transport from fetching a good copy of it from the other
+   side.
+
+ * The documentation incorrectly said that C(opy) and R(ename) are the
+   only ones that can be followed by the score number in the output in
+   the --raw format.
+
+ * Fix a misspelled conditional that is always true.
+
+ * Code to read branch name from various files in .git/ directory
+   would have misbehaved if the code to write them left an empty file.
+
+ * The "git push" documentation made the "--repo=<there>" option
+   easily misunderstood.
+
+ * After attempting and failing a password-less authentication
+   (e.g. kerberos), libcURL refuses to fall back to password based
+   Basic authentication without a bit of help/encouragement.
+
+ * Setting diff.submodule to 'log' made "git format-patch" produce
+   broken patches.
+
+ * "git rerere" (invoked internally from many mergy operations) did
+   not correctly signal errors when told to update the working tree
+   files and failed to do so for whatever reason.
+
+ * "git blame HEAD -- missing" failed to correctly say "HEAD" when it
+   tried to say "No such path 'missing' in HEAD".
+
+Also contains typofixes, documentation updates and trivial code clean-ups.
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 04e2a71..440784c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -683,14 +683,13 @@
 	for abbreviated object names to stay unique for sufficiently long
 	time.
 
-add.ignore-errors::
 add.ignoreErrors::
+add.ignore-errors (deprecated)::
 	Tells 'git add' to continue adding files when some files cannot be
 	added due to indexing errors. Equivalent to the '--ignore-errors'
-	option of linkgit:git-add[1].  Older versions of Git accept only
-	`add.ignore-errors`, which does not follow the usual naming
-	convention for configuration variables.  Newer versions of Git
-	honor `add.ignoreErrors` as well.
+	option of linkgit:git-add[1].  `add.ignore-errors` is deprecated,
+	as it does not follow the usual naming convention for configuration
+	variables.
 
 alias.*::
 	Command aliases for the linkgit:git[1] command wrapper - e.g.
@@ -1960,7 +1959,7 @@
 	true. You should not generally need to turn this off unless
 	you are debugging pack bitmaps.
 
-pack.writebitmaps::
+pack.writebitmaps (deprecated)::
 	This is a deprecated synonym for `repack.writeBitmaps`.
 
 pack.writeBitmapHashCache::
@@ -2094,6 +2093,11 @@
 	successful rebase might result in non-trivial conflicts.
 	Defaults to false.
 
+receive.advertiseatomic::
+	By default, git-receive-pack will advertise the atomic push
+	capability to its clients. If you don't want to this capability
+	to be advertised, set this variable to false.
+
 receive.autogc::
 	By default, git-receive-pack will run "git-gc --auto" after
 	receiving data from git-push and updating refs.  You can stop
@@ -2153,11 +2157,15 @@
 	message. Defaults to "refuse".
 +
 Another option is "updateInstead" which will update the working
-directory (must be clean) if pushing into the current branch. This option is
+tree if pushing into the current branch.  This option is
 intended for synchronizing working directories when one side is not easily
 accessible via interactive ssh (e.g. a live web site, hence the requirement
 that the working directory be clean). This mode also comes in handy when
 developing inside a VM to test and fix code on different Operating Systems.
++
+By default, "updateInstead" will refuse the push if the working tree or
+the index have any difference from the HEAD, but the `push-to-checkout`
+hook can be used to customize this.  See linkgit:githooks[5].
 
 receive.denyNonFastForwards::
 	If set to true, git-receive-pack will deny a ref update which is
@@ -2297,7 +2305,7 @@
 	See linkgit:git-send-email[1] for description.  Note that this
 	setting is not subject to the 'identity' mechanism.
 
-sendemail.smtpssl::
+sendemail.smtpssl (deprecated)::
 	Deprecated alias for 'sendemail.smtpencryption = ssl'.
 
 sendemail.smtpsslcertpath::
@@ -2337,7 +2345,7 @@
 sendemail.xmailer::
 	See linkgit:git-send-email[1] for description.
 
-sendemail.signedoffcc::
+sendemail.signedoffcc (deprecated)::
 	Deprecated alias for 'sendemail.signedoffbycc'.
 
 showbranch.default::
diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
index 15c7e79..85b0890 100644
--- a/Documentation/diff-format.txt
+++ b/Documentation/diff-format.txt
@@ -66,7 +66,8 @@
 
 Status letters C and R are always followed by a score (denoting the
 percentage of similarity between the source and target of the move or
-copy), and are the only ones to be so.
+copy).  Status letter M may be followed by a score (denoting the
+percentage of dissimilarity) for file rewrites.
 
 <sha1> is shown as all 0's if a file is new on the filesystem
 and it is out of sync with the index.
diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt
index 6ab5f94..a1664b9 100644
--- a/Documentation/git-p4.txt
+++ b/Documentation/git-p4.txt
@@ -241,6 +241,9 @@
 	Use a client spec to find the list of interesting files in p4.
 	See the "CLIENT SPEC" section below.
 
+-/ <path>::
+	Exclude selected depot paths when cloning or syncing.
+
 Clone options
 ~~~~~~~~~~~~~
 These options can be used in an initial 'clone', along with the 'sync'
@@ -254,9 +257,6 @@
 --bare::
 	Perform a bare clone.  See linkgit:git-clone[1].
 
--/ <path>::
-	Exclude selected depot paths when cloning.
-
 Submit options
 ~~~~~~~~~~~~~~
 These options can be used to modify 'git p4 submit' behavior.
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index b17283a..e1a46a7 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -9,7 +9,7 @@
 SYNOPSIS
 --------
 [verse]
-'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
+'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
 	   [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose]
 	   [-u | --set-upstream] [--signed]
 	   [--force-with-lease[=<refname>[:<expect>]]]
@@ -136,6 +136,11 @@
 	logged.  See linkgit:git-receive-pack[1] for the details
 	on the receiving end.
 
+--[no-]atomic::
+	Use an atomic transaction on the remote side if available.
+	Either all refs are updated, or on error, no refs are updated.
+	If the server does not support atomic pushes the push will fail.
+
 --receive-pack=<git-receive-pack>::
 --exec=<git-receive-pack>::
 	Path to the 'git-receive-pack' program on the remote
@@ -214,22 +219,8 @@
 `<refspec>...` section above for details.
 
 --repo=<repository>::
-	This option is only relevant if no <repository> argument is
-	passed in the invocation. In this case, 'git push' derives the
-	remote name from the current branch: If it tracks a remote
-	branch, then that remote repository is pushed to. Otherwise,
-	the name "origin" is used. For this latter case, this option
-	can be used to override the name "origin". In other words,
-	the difference between these two commands
-+
---------------------------
-git push public         #1
-git push --repo=public  #2
---------------------------
-+
-is that #1 always pushes to "public" whereas #2 pushes to "public"
-only if the current branch does not track a remote branch. This is
-useful if you write an alias or script around 'git push'.
+	This option is equivalent to the <repository> argument. If both
+	are specified, the command-line argument takes precedence.
 
 -u::
 --set-upstream::
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index cb103c8..a77607b 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -130,17 +130,25 @@
 
 'set-url'::
 
-Changes URL remote points to. Sets first URL remote points to matching
+Changes URLs for the remote. Sets first URL for remote <name> that matches
 regex <oldurl> (first URL if no <oldurl> is given) to <newurl>. If
-<oldurl> doesn't match any URL, error occurs and nothing is changed.
+<oldurl> doesn't match any URL, an error occurs and nothing is changed.
 +
 With '--push', push URLs are manipulated instead of fetch URLs.
 +
-With '--add', instead of changing some URL, new URL is added.
+With '--add', instead of changing existing URLs, new URL is added.
 +
-With '--delete', instead of changing some URL, all URLs matching
-regex <url> are deleted. Trying to delete all non-push URLs is an
-error.
+With '--delete', instead of changing existing URLs, all URLs matching
+regex <url> are deleted for remote <name>.  Trying to delete all
+non-push URLs is an error.
++
+Note that the push URL and the fetch URL, even though they can
+be set differently, must still refer to the same place.  What you
+pushed to the push URL should be what you would see if you
+immediately fetched from the fetch URL.  If you are trying to
+fetch from one place (e.g. your upstream) and push to another (e.g.
+your publishing repository), use two separate remotes.
+
 
 'show'::
 
diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index 2a0de42..45c7725 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -9,7 +9,7 @@
 SYNOPSIS
 --------
 [verse]
-'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]
+'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> [<ref>...]
 
 DESCRIPTION
 -----------
@@ -62,6 +62,11 @@
 	Send a "thin" pack, which records objects in deltified form based
 	on objects not included in the pack to reduce network traffic.
 
+--atomic::
+	Use an atomic transaction for updating the refs. If any of the refs
+	fails to update then the entire push will fail without changing any
+	refs.
+
 <host>::
 	A remote host to house the repository.  When this
 	part is specified, 'git-receive-pack' is invoked via
diff --git a/Documentation/git.txt b/Documentation/git.txt
index eadbd05..b37f1ab 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -43,9 +43,10 @@
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v2.3.0/git.html[documentation for release 2.3]
+* link:v2.3.1/git.html[documentation for release 2.3.1]
 
 * release notes for
+  link:RelNotes/2.3.1.txt[2.3.1],
   link:RelNotes/2.3.0.txt[2.3].
 
 * link:v2.2.2/git.html[documentation for release 2.2.2]
diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt
index 9ef2469..7ba0ac9 100644
--- a/Documentation/githooks.txt
+++ b/Documentation/githooks.txt
@@ -341,6 +341,36 @@
 'git send-pack' on the other end, so you can simply `echo` messages
 for the user.
 
+push-to-checkout
+~~~~~~~~~~~~~~~~
+
+This hook is invoked by 'git-receive-pack' on the remote repository,
+which happens when a 'git push' is done on a local repository, when
+the push tries to update the branch that is currently checked out
+and the `receive.denyCurrentBranch` configuration variable is set to
+`updateInstead`.  Such a push by default is refused if the working
+tree and the index of the remote repository has any difference from
+the currently checked out commit; when both the working tree and the
+index match the current commit, they are updated to match the newly
+pushed tip of the branch.  This hook is to be used to override the
+default behaviour.
+
+The hook receives the commit with which the tip of the current
+branch is going to be updated.  It can exit with a non-zero status
+to refuse the push (when it does so, it must not modify the index or
+the working tree).  Or it can make any necessary changes to the
+working tree and to the index to bring them to the desired state
+when the tip of the current branch is updated to the new commit, and
+exit with a zero status.
+
+For example, the hook can simply run `git read-tree -u -m HEAD "$1"`
+in order to emulate 'git fetch' that is run in the reverse direction
+with `git push`, as the two-tree form of `read-tree -u -m` is
+essentially the same as `git checkout` that switches branches while
+keeping the local changes in the working tree that do not interfere
+with the difference between the branches.
+
+
 pre-auto-gc
 ~~~~~~~~~~~
 
diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt
index 8569e29..74aa01a 100644
--- a/Documentation/pretty-options.txt
+++ b/Documentation/pretty-options.txt
@@ -3,9 +3,13 @@
 
 	Pretty-print the contents of the commit logs in a given format,
 	where '<format>' can be one of 'oneline', 'short', 'medium',
-	'full', 'fuller', 'email', 'raw' and 'format:<string>'.  See
-	the "PRETTY FORMATS" section for some additional details for each
-	format.  When omitted, the format defaults to 'medium'.
+	'full', 'fuller', 'email', 'raw', 'format:<string>'
+	and 'tformat:<string>'.  When '<format>' is none of the above,
+	and has '%placeholder' in it, it acts as if
+	'--pretty=tformat:<format>' were given.
++
+See the "PRETTY FORMATS" section for some additional details for each
+format.  When '=<format>' part is omitted, it defaults to 'medium'.
 +
 Note: you can specify the default pretty format in the repository
 configuration (see linkgit:git-config[1]).
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 2984f40..4ed8587 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -66,6 +66,10 @@
 	Limit the commits output to ones that match all given `--grep`,
 	instead of ones that match at least one.
 
+--invert-grep::
+	Limit the commits output to ones with log message that do not
+	match the pattern specified with `--grep=<pattern>`.
+
 -i::
 --regexp-ignore-case::
 	Match the regular expression limiting patterns without regard to letter
@@ -172,11 +176,6 @@
 	Pretend as if all objects mentioned by reflogs are listed on the
 	command line as `<commit>`.
 
---indexed-objects::
-	Pretend as if all trees and blobs used by the index are listed
-	on the command line.  Note that you probably want to use
-	`--objects`, too.
-
 --ignore-missing::
 	Upon seeing an invalid object name in the input, pretend as if
 	the bad input was not given.
@@ -644,6 +643,7 @@
 
 These options are mostly targeted for packing of Git repositories.
 
+ifdef::git-rev-list[]
 --objects::
 	Print the object IDs of any object referenced by the listed
 	commits.  `--objects foo ^bar` thus means ``send me
@@ -662,9 +662,15 @@
 	commits at the cost of increased time.  This is used instead of
 	`--objects-edge` to build ``thin'' packs for shallow repositories.
 
+--indexed-objects::
+	Pretend as if all trees and blobs used by the index are listed
+	on the command line.  Note that you probably want to use
+	`--objects`, too.
+
 --unpacked::
 	Only useful with `--objects`; print the object IDs that are not
 	in packs.
+endif::git-rev-list[]
 
 --no-walk[=(sorted|unsorted)]::
 	Only show the given commits, but do not traverse their ancestors.
diff --git a/Documentation/technical/api-error-handling.txt b/Documentation/technical/api-error-handling.txt
new file mode 100644
index 0000000..fc68db1
--- /dev/null
+++ b/Documentation/technical/api-error-handling.txt
@@ -0,0 +1,75 @@
+Error reporting in git
+======================
+
+`die`, `usage`, `error`, and `warning` report errors of various
+kinds.
+
+- `die` is for fatal application errors.  It prints a message to
+  the user and exits with status 128.
+
+- `usage` is for errors in command line usage.  After printing its
+  message, it exits with status 129.  (See also `usage_with_options`
+  in the link:api-parse-options.html[parse-options API].)
+
+- `error` is for non-fatal library errors.  It prints a message
+  to the user and returns -1 for convenience in signaling the error
+  to the caller.
+
+- `warning` is for reporting situations that probably should not
+  occur but which the user (and Git) can continue to work around
+  without running into too many problems.  Like `error`, it
+  returns -1 after reporting the situation to the caller.
+
+Customizable error handlers
+---------------------------
+
+The default behavior of `die` and `error` is to write a message to
+stderr and then exit or return as appropriate.  This behavior can be
+overridden using `set_die_routine` and `set_error_routine`.  For
+example, "git daemon" uses set_die_routine to write the reason `die`
+was called to syslog before exiting.
+
+Library errors
+--------------
+
+Functions return a negative integer on error.  Details beyond that
+vary from function to function:
+
+- Some functions return -1 for all errors.  Others return a more
+  specific value depending on how the caller might want to react
+  to the error.
+
+- Some functions report the error to stderr with `error`,
+  while others leave that for the caller to do.
+
+- errno is not meaningful on return from most functions (except
+  for thin wrappers for system calls).
+
+Check the function's API documentation to be sure.
+
+Caller-handled errors
+---------------------
+
+An increasing number of functions take a parameter 'struct strbuf *err'.
+On error, such functions append a message about what went wrong to the
+'err' strbuf.  The message is meant to be complete enough to be passed
+to `die` or `error` as-is.  For example:
+
+	if (ref_transaction_commit(transaction, &err))
+		die("%s", err.buf);
+
+The 'err' parameter will be untouched if no error occured, so multiple
+function calls can be chained:
+
+	t = ref_transaction_begin(&err);
+	if (!t ||
+	    ref_transaction_update(t, "HEAD", ..., &err) ||
+	    ret_transaction_commit(t, &err))
+		die("%s", err.buf);
+
+The 'err' parameter must be a pointer to a valid strbuf.  To silence
+a message, pass a strbuf that is explicitly ignored:
+
+	if (thing_that_can_fail_in_an_ignorable_way(..., &err))
+		/* This failure is okay. */
+		strbuf_reset(&err);
diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt
deleted file mode 100644
index cca6543..0000000
--- a/Documentation/technical/api-strbuf.txt
+++ /dev/null
@@ -1,351 +0,0 @@
-strbuf API
-==========
-
-strbuf's are meant to be used with all the usual C string and memory
-APIs. Given that the length of the buffer is known, it's often better to
-use the mem* functions than a str* one (memchr vs. strchr e.g.).
-Though, one has to be careful about the fact that str* functions often
-stop on NULs and that strbufs may have embedded NULs.
-
-A strbuf is NUL terminated for convenience, but no function in the
-strbuf API actually relies on the string being free of NULs.
-
-strbufs have some invariants that are very important to keep in mind:
-
-. The `buf` member is never NULL, so it can be used in any usual C
-string operations safely. strbuf's _have_ to be initialized either by
-`strbuf_init()` or by `= STRBUF_INIT` before the invariants, though.
-+
-Do *not* assume anything on what `buf` really is (e.g. if it is
-allocated memory or not), use `strbuf_detach()` to unwrap a memory
-buffer from its strbuf shell in a safe way. That is the sole supported
-way. This will give you a malloced buffer that you can later `free()`.
-+
-However, it is totally safe to modify anything in the string pointed by
-the `buf` member, between the indices `0` and `len-1` (inclusive).
-
-. The `buf` member is a byte array that has at least `len + 1` bytes
-  allocated. The extra byte is used to store a `'\0'`, allowing the
-  `buf` member to be a valid C-string. Every strbuf function ensure this
-  invariant is preserved.
-+
-NOTE: It is OK to "play" with the buffer directly if you work it this
-      way:
-+
-----
-strbuf_grow(sb, SOME_SIZE); <1>
-strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
-----
-<1> Here, the memory array starting at `sb->buf`, and of length
-`strbuf_avail(sb)` is all yours, and you can be sure that
-`strbuf_avail(sb)` is at least `SOME_SIZE`.
-+
-NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`.
-+
-Doing so is safe, though if it has to be done in many places, adding the
-missing API to the strbuf module is the way to go.
-+
-WARNING: Do _not_ assume that the area that is yours is of size `alloc
-- 1` even if it's true in the current implementation. Alloc is somehow a
-"private" member that should not be messed with. Use `strbuf_avail()`
-instead.
-
-Data structures
----------------
-
-* `struct strbuf`
-
-This is the string buffer structure. The `len` member can be used to
-determine the current length of the string, and `buf` member provides
-access to the string itself.
-
-Functions
----------
-
-* Life cycle
-
-`strbuf_init`::
-
-	Initialize the structure. The second parameter can be zero or a bigger
-	number to allocate memory, in case you want to prevent further reallocs.
-
-`strbuf_release`::
-
-	Release a string buffer and the memory it used. You should not use the
-	string buffer after using this function, unless you initialize it again.
-
-`strbuf_detach`::
-
-	Detach the string from the strbuf and returns it; you now own the
-	storage the string occupies and it is your responsibility from then on
-	to release it with `free(3)` when you are done with it.
-
-`strbuf_attach`::
-
-	Attach a string to a buffer. You should specify the string to attach,
-	the current length of the string and the amount of allocated memory.
-	The amount must be larger than the string length, because the string you
-	pass is supposed to be a NUL-terminated string.  This string _must_ be
-	malloc()ed, and after attaching, the pointer cannot be relied upon
-	anymore, and neither be free()d directly.
-
-`strbuf_swap`::
-
-	Swap the contents of two string buffers.
-
-* Related to the size of the buffer
-
-`strbuf_avail`::
-
-	Determine the amount of allocated but unused memory.
-
-`strbuf_grow`::
-
-	Ensure that at least this amount of unused memory is available after
-	`len`. This is used when you know a typical size for what you will add
-	and want to avoid repetitive automatic resizing of the underlying buffer.
-	This is never a needed operation, but can be critical for performance in
-	some cases.
-
-`strbuf_setlen`::
-
-	Set the length of the buffer to a given value. This function does *not*
-	allocate new memory, so you should not perform a `strbuf_setlen()` to a
-	length that is larger than `len + strbuf_avail()`. `strbuf_setlen()` is
-	just meant as a 'please fix invariants from this strbuf I just messed
-	with'.
-
-`strbuf_reset`::
-
-	Empty the buffer by setting the size of it to zero.
-
-* Related to the contents of the buffer
-
-`strbuf_trim`::
-
-	Strip whitespace from the beginning and end of a string.
-	Equivalent to performing `strbuf_rtrim()` followed by `strbuf_ltrim()`.
-
-`strbuf_rtrim`::
-
-	Strip whitespace from the end of a string.
-
-`strbuf_ltrim`::
-
-	Strip whitespace from the beginning of a string.
-
-`strbuf_reencode`::
-
-	Replace the contents of the strbuf with a reencoded form.  Returns -1
-	on error, 0 on success.
-
-`strbuf_tolower`::
-
-	Lowercase each character in the buffer using `tolower`.
-
-`strbuf_cmp`::
-
-	Compare two buffers. Returns an integer less than, equal to, or greater
-	than zero if the first buffer is found, respectively, to be less than,
-	to match, or be greater than the second buffer.
-
-* Adding data to the buffer
-
-NOTE: All of the functions in this section will grow the buffer as necessary.
-If they fail for some reason other than memory shortage and the buffer hadn't
-been allocated before (i.e. the `struct strbuf` was set to `STRBUF_INIT`),
-then they will free() it.
-
-`strbuf_addch`::
-
-	Add a single character to the buffer.
-
-`strbuf_addchars`::
-
-	Add a character the specified number of times to the buffer.
-
-`strbuf_insert`::
-
-	Insert data to the given position of the buffer. The remaining contents
-	will be shifted, not overwritten.
-
-`strbuf_remove`::
-
-	Remove given amount of data from a given position of the buffer.
-
-`strbuf_splice`::
-
-	Remove the bytes between `pos..pos+len` and replace it with the given
-	data.
-
-`strbuf_add_commented_lines`::
-
-	Add a NUL-terminated string to the buffer. Each line will be prepended
-	by a comment character and a blank.
-
-`strbuf_add`::
-
-	Add data of given length to the buffer.
-
-`strbuf_addstr`::
-
-Add a NUL-terminated string to the buffer.
-+
-NOTE: This function will *always* be implemented as an inline or a macro
-that expands to:
-+
-----
-strbuf_add(..., s, strlen(s));
-----
-+
-Meaning that this is efficient to write things like:
-+
-----
-strbuf_addstr(sb, "immediate string");
-----
-
-`strbuf_addbuf`::
-
-	Copy the contents of another buffer at the end of the current one.
-
-`strbuf_adddup`::
-
-	Copy part of the buffer from a given position till a given length to the
-	end of the buffer.
-
-`strbuf_expand`::
-
-	This function can be used to expand a format string containing
-	placeholders. To that end, it parses the string and calls the specified
-	function for every percent sign found.
-+
-The callback function is given a pointer to the character after the `%`
-and a pointer to the struct strbuf.  It is expected to add the expanded
-version of the placeholder to the strbuf, e.g. to add a newline
-character if the letter `n` appears after a `%`.  The function returns
-the length of the placeholder recognized and `strbuf_expand()` skips
-over it.
-+
-The format `%%` is automatically expanded to a single `%` as a quoting
-mechanism; callers do not need to handle the `%` placeholder themselves,
-and the callback function will not be invoked for this placeholder.
-+
-All other characters (non-percent and not skipped ones) are copied
-verbatim to the strbuf.  If the callback returned zero, meaning that the
-placeholder is unknown, then the percent sign is copied, too.
-+
-In order to facilitate caching and to make it possible to give
-parameters to the callback, `strbuf_expand()` passes a context pointer,
-which can be used by the programmer of the callback as she sees fit.
-
-`strbuf_expand_dict_cb`::
-
-	Used as callback for `strbuf_expand()`, expects an array of
-	struct strbuf_expand_dict_entry as context, i.e. pairs of
-	placeholder and replacement string.  The array needs to be
-	terminated by an entry with placeholder set to NULL.
-
-`strbuf_addbuf_percentquote`::
-
-	Append the contents of one strbuf to another, quoting any
-	percent signs ("%") into double-percents ("%%") in the
-	destination. This is useful for literal data to be fed to either
-	strbuf_expand or to the *printf family of functions.
-
-`strbuf_humanise_bytes`::
-
-	Append the given byte size as a human-readable string (i.e. 12.23 KiB,
-	3.50 MiB).
-
-`strbuf_addf`::
-
-	Add a formatted string to the buffer.
-
-`strbuf_commented_addf`::
-
-	Add a formatted string prepended by a comment character and a
-	blank to the buffer.
-
-`strbuf_fread`::
-
-	Read a given size of data from a FILE* pointer to the buffer.
-+
-NOTE: The buffer is rewound if the read fails. If -1 is returned,
-`errno` must be consulted, like you would do for `read(3)`.
-`strbuf_read()`, `strbuf_read_file()` and `strbuf_getline()` has the
-same behaviour as well.
-
-`strbuf_read`::
-
-	Read the contents of a given file descriptor. The third argument can be
-	used to give a hint about the file size, to avoid reallocs.
-
-`strbuf_read_file`::
-
-	Read the contents of a file, specified by its path. The third argument
-	can be used to give a hint about the file size, to avoid reallocs.
-
-`strbuf_readlink`::
-
-	Read the target of a symbolic link, specified by its path.  The third
-	argument can be used to give a hint about the size, to avoid reallocs.
-
-`strbuf_getline`::
-
-	Read a line from a FILE *, overwriting the existing contents
-	of the strbuf. The second argument specifies the line
-	terminator character, typically `'\n'`.
-	Reading stops after the terminator or at EOF.  The terminator
-	is removed from the buffer before returning.  Returns 0 unless
-	there was nothing left before EOF, in which case it returns `EOF`.
-
-`strbuf_getwholeline`::
-
-	Like `strbuf_getline`, but keeps the trailing terminator (if
-	any) in the buffer.
-
-`strbuf_getwholeline_fd`::
-
-	Like `strbuf_getwholeline`, but operates on a file descriptor.
-	It reads one character at a time, so it is very slow.  Do not
-	use it unless you need the correct position in the file
-	descriptor.
-
-`strbuf_getcwd`::
-
-	Set the buffer to the path of the current working directory.
-
-`strbuf_add_absolute_path`
-
-	Add a path to a buffer, converting a relative path to an
-	absolute one in the process.  Symbolic links are not
-	resolved.
-
-`stripspace`::
-
-	Strip whitespace from a buffer. The second parameter controls if
-	comments are considered contents to be removed or not.
-
-`strbuf_split_buf`::
-`strbuf_split_str`::
-`strbuf_split_max`::
-`strbuf_split`::
-
-	Split a string or strbuf into a list of strbufs at a specified
-	terminator character.  The returned substrings include the
-	terminator characters.  Some of these functions take a `max`
-	parameter, which, if positive, limits the output to that
-	number of substrings.
-
-`strbuf_list_free`::
-
-	Free a list of strbufs (for example, the return values of the
-	`strbuf_split()` functions).
-
-`launch_editor`::
-
-	Launch the user preferred editor to edit a file and fill the buffer
-	with the file's contents upon the user completing their editing. The
-	third argument can be used to set the environment which the editor is
-	run in. If the buffer is NULL the editor is launched as usual but the
-	file's contents are not read into the buffer upon completion.
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index 6d5424c..4f8a7bf 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -18,8 +18,9 @@
 and server advertised.  As a consequence of these rules, server MUST
 NOT advertise capabilities it does not understand.
 
-The 'report-status', 'delete-refs', 'quiet', and 'push-cert' capabilities
-are sent and recognized by the receive-pack (push to server) process.
+The 'atomic', 'report-status', 'delete-refs', 'quiet', and 'push-cert'
+capabilities are sent and recognized by the receive-pack (push to server)
+process.
 
 The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
 by both upload-pack and receive-pack protocols.  The 'agent' capability
@@ -244,6 +245,14 @@
 reporting if the local progress reporting is also being suppressed
 (e.g., via `push -q`, or if stderr does not go to a tty).
 
+atomic
+------
+
+If the server sends the 'atomic' capability it is capable of accepting
+atomic pushes. If the pushing client requests this capability, the server
+will update the refs in one atomic transaction. Either all refs are
+updated or none.
+
 allow-tip-sha1-in-want
 ----------------------
 
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 780064a..0407788 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.3.0
+DEF_VER=v2.3.1
 
 LF='
 '
diff --git a/Makefile b/Makefile
index c44eb3a..44f1dd1 100644
--- a/Makefile
+++ b/Makefile
@@ -348,6 +348,15 @@
 #
 # Define NO_HMAC_CTX_CLEANUP if your OpenSSL is version 0.9.6b or earlier to
 # cleanup the HMAC context with the older HMAC_cleanup function.
+#
+# Define USE_PARENS_AROUND_GETTEXT_N to "yes" if your compiler happily
+# compiles the following initialization:
+#
+#   static const char s[] = ("FOO");
+#
+# and define it to "no" if you need to remove the parentheses () around the
+# constant.  The default is "auto", which means to use parentheses if your
+# compiler is detected to support it.
 
 GIT-VERSION-FILE: FORCE
 	@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -955,6 +964,14 @@
 	BASIC_CFLAGS += -Dsocklen_t=$(SOCKLEN_T)
 endif
 
+ifeq (yes,$(USE_PARENS_AROUND_GETTEXT_N))
+	BASIC_CFLAGS += -DUSE_PARENS_AROUND_GETTEXT_N=1
+else
+ifeq (no,$(USE_PARENS_AROUND_GETTEXT_N))
+	BASIC_CFLAGS += -DUSE_PARENS_AROUND_GETTEXT_N=0
+endif
+endif
+
 ifeq ($(uname_S),Darwin)
 	ifndef NO_FINK
 		ifeq ($(shell test -d /sw/lib && echo y),y)
@@ -1035,13 +1052,13 @@
 	REMOTE_CURL_NAMES = $(REMOTE_CURL_PRIMARY) $(REMOTE_CURL_ALIASES)
 	PROGRAM_OBJS += http-fetch.o
 	PROGRAMS += $(REMOTE_CURL_NAMES)
-	curl_check := $(shell (echo 070908; curl-config --vernum) 2>/dev/null | sort -r | sed -ne 2p)
+	curl_check := $(shell (echo 070908; curl-config --vernum | sed -e '/^70[BC]/s/^/0/') 2>/dev/null | sort -r | sed -ne 2p)
 	ifeq "$(curl_check)" "070908"
 		ifndef NO_EXPAT
 			PROGRAM_OBJS += http-push.o
 		endif
 	endif
-	curl_check := $(shell (echo 072200; curl-config --vernum) 2>/dev/null | sort -r | sed -ne 2p)
+	curl_check := $(shell (echo 072200; curl-config --vernum | sed -e '/^70[BC]/s/^/0/') 2>/dev/null | sort -r | sed -ne 2p)
 	ifeq "$(curl_check)" "072200"
 		USE_CURL_FOR_IMAP_SEND = YesPlease
 	endif
diff --git a/RelNotes b/RelNotes
deleted file mode 120000
index 9257c74..0000000
--- a/RelNotes
+++ /dev/null
@@ -1 +0,0 @@
-Documentation/RelNotes/2.3.0.txt
\ No newline at end of file
diff --git a/RelNotes b/RelNotes
new file mode 100644
index 0000000..8dae3d4
--- /dev/null
+++ b/RelNotes
@@ -0,0 +1,171 @@
+Git ???? Release Notes
+======================
+
+Updates since v2.3
+------------------
+
+Ports
+
+
+UI, Workflows & Features
+
+ * The command usage info strings given by "git cmd -h" and in
+   documentation have been tweaked for consistency.
+
+ * The "sync" subcommand of "git p4" now allows users to exclude
+   subdirectories like its "clone" subcommand does.
+
+ * "git log --invert-grep --grep=WIP" will show only commits that do
+   not have the string "WIP" in their messages.
+
+ * "git push" has been taught a "--atomic" option that makes push to
+   update more than one ref an "all-or-none" affair.
+
+ * Extending the "push to deploy" added in 2.3, the behaviour of "git
+   push" when updating the branch that is checked out can now be
+   tweaked by push-to-checkout hook.
+
+ * Using environment variable LANGUAGE and friends on the client side,
+   HTTP-based transports now send Accept-Language when making requests.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * Implementation of N_() macro has been updated slightly to help us
+   detect mistakes.
+
+ * Implementation of "reflog expire" has been restructured to fit the
+   reflogs better with the recently updated ref API.
+
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v2.3
+----------------
+
+Unless otherwise noted, all the fixes since v2.3 in the maintenance
+track are contained in this release (see the maintenance releases'
+notes for details).
+
+ * "git blame HEAD -- missing" failed to correctly say "HEAD" when it
+   tried to say "No such path 'missing' in HEAD".
+   (merge a46442f jk/blame-commit-label later to maint).
+
+ * "git rerere" (invoked internally from many mergy operations) did
+   not correctly signal errors when told to update the working tree
+   files and failed to do so for whatever reason.
+   (merge 89ea903 jn/rerere-fail-on-auto-update-failure later to maint).
+
+ * Setting diff.submodule to 'log' made "git format-patch" produce
+   broken patches.
+   (merge 339de50 dk/format-patch-ignore-diff-submodule later to maint).
+
+ * After attempting and failing a password-less authentication
+   (e.g. kerberos), libcURL refuses to fall back to password based
+   Basic authentication without a bit of help/encouragement.
+   (merge 4dbe664 bc/http-fallback-to-password-after-krb-fails later to maint).
+
+ * The "git push" documentation made the "--repo=<there>" option
+   easily misunderstood.
+   (merge 57b92a7 mg/push-repo-option-doc later to maint).
+
+ * Code to read branch name from various files in .git/ directory
+   would have misbehaved if the code to write them left an empty file.
+   (merge 66ec904 jk/status-read-branch-name-fix later to maint).
+
+ * A misspelled conditional that is always true has been fixed.
+   (merge 94ee8e2 jk/remote-curl-an-array-in-struct-cannot-be-null later to maint).
+
+ * The documentation incorrectly said that C(opy) and R(ename) are the
+   only ones that can be followed by the score number in the output in
+   the --raw format.
+   (merge ac1c2d9 jc/diff-format-doc later to maint).
+
+ * A broken pack .idx file in the receiving repository prevented the
+   dumb http transport from fetching a good copy of it from the other
+   side.
+   (merge 8b9c2dd jk/dumb-http-idx-fetch-fix later to maint).
+
+ * The error message from "git commit", when a non-existing author
+   name was given as value to the "--author=" parameter, has been
+   reworded to avoid misunderstanding.
+   (merge 1044b1f mg/commit-author-no-match-malformed-message later to maint).
+
+ * "git log --help" used to show rev-list options that are irrelevant
+   to the "log" command.
+   (merge 3cab02d jc/doc-log-rev-list-options later to maint).
+
+ * "git apply --whitespace=fix" used to under-allocate the memory when
+   the fix resulted in a longer text than the original patch.
+   (merge 407a792 jc/apply-ws-fix-expands later to maint).
+
+ * The interactive "show a list and let the user choose from it"
+   interface "add -i" used showed and prompted to the user even when
+   the candidate list was empty, against which the only "choice" the
+   user could have made was to choose nothing.
+   (merge a9c4641 ak/add-i-empty-candidates later to maint).
+
+ * The insn sheet "git rebase -i" creates did not fully honor
+   core.abbrev settings.
+   (merge edb72d5 ks/rebase-i-abbrev later to maint).
+
+ * "git fetch" over a remote-helper that cannot respond to "list"
+   command could not fetch from a symbolic reference e.g. HEAD.
+   (merge 33cae54 mh/deref-symref-over-helper-transport later to maint).
+
+ * "git push --signed" gave an incorrectly worded error message when
+   the other side did not support the capability.
+   (merge 45917f0 jc/push-cert later to maint).
+
+ * We didn't format an integer that wouldn't fit in "int" but in
+   "uintmax_t" correctly.
+   (merge d306f3d jk/decimal-width-for-uintmax later to maint).
+
+ * Reading configuration from a blob object, when it ends with a lone
+   CR, use to confuse the configuration parser.
+   (merge 1d0655c jk/config-no-ungetc-eof later to maint).
+
+ * The pack bitmap support did not build with older versions of GCC.
+   (merge bd4e882 jk/pack-bitmap later to maint).
+
+ * The documentation wasn't clear that "remote.<nick>.pushURL" and
+   "remote.<nick>.URL" are there to name the same repository accessed
+   via different transports, not two separate repositories.
+   (merge 697f652 jc/remote-set-url-doc later to maint).
+
+ * Older GnuPG implementations may not correctly import the keyring
+   material we prepare for the tests to use.
+   (merge 1f985d6 ch/new-gpg-drops-rfc-1991 later to maint).
+
+ * The credential helper for Windows (in contrib/) used to mishandle
+   a user name with an at-sign in it.
+   (merge 13d261e av/wincred-with-at-in-username-fix later to maint).
+
+ * Longstanding configuration variable naming rules has been added to
+   the documentation.
+   (merge 35840a3 jc/conf-var-doc later to maint).
+
+ * An earlier workaround to squelch unhelpful deprecation warnings
+   from the complier on Mac OSX unnecessarily set minimum required
+   version of the OS, which the user might want to raise (or lower)
+   for other reasons.
+   (merge 88c03eb es/squelch-openssl-warnings-on-macosx later to maint).
+
+ * Certain older vintages of cURL give irregular output from
+   "curl-config --vernum", which confused our build system.
+   (merge 3af6792 tc/curl-vernum-output-broken-in-7.11 later to maint).
+
+ * In v2.2.0, we broke "git prune" that runs in a repository that
+   borrows from an alternate object store.
+   (merge b0a4264 jk/prune-mtime later to maint).
+
+ * "git submodule add" failed to squash "path/to/././submodule" to
+   "path/to/submodule".
+   (merge 8196e72 ps/submodule-sanitize-path-upon-add later to maint).
+
+ * "git merge-file" did not work correctly in a subdirectory.
+   (merge 204a8ff ab/merge-file-prefix later to maint).
+
+ * "git blame" died, trying to free an uninitialized piece of memory.
+   (merge e600592 es/blame-commit-info-fix later to maint).
diff --git a/advice.c b/advice.c
index 3b8bf3c..575bec2 100644
--- a/advice.c
+++ b/advice.c
@@ -105,7 +105,7 @@
 	"state without impacting any branches by performing another checkout.\n\n"
 	"If you want to create a new branch to retain commits you create, you may\n"
 	"do so (now or later) by using -b with the checkout command again. Example:\n\n"
-	"  git checkout -b new_branch_name\n\n";
+	"  git checkout -b <new-branch-name>\n\n";
 
 	fprintf(stderr, fmt, new_name);
 }
diff --git a/archive.c b/archive.c
index 9e30246..96057ed 100644
--- a/archive.c
+++ b/archive.c
@@ -8,9 +8,9 @@
 #include "dir.h"
 
 static char const * const archive_usage[] = {
-	N_("git archive [options] <tree-ish> [<path>...]"),
+	N_("git archive [<options>] <tree-ish> [<path>...]"),
 	N_("git archive --list"),
-	N_("git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]"),
+	N_("git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]"),
 	N_("git archive --remote <repo> [--exec <cmd>] --list"),
 	NULL
 };
diff --git a/attr.c b/attr.c
index cd54697..1f9eebd 100644
--- a/attr.c
+++ b/attr.c
@@ -32,9 +32,12 @@
 	struct git_attr *next;
 	unsigned h;
 	int attr_nr;
+	int maybe_macro;
+	int maybe_real;
 	char name[FLEX_ARRAY];
 };
 static int attr_nr;
+static int cannot_trust_maybe_real;
 
 static struct git_attr_check *check_all_attr;
 static struct git_attr *(git_attr_hash[HASHSIZE]);
@@ -95,6 +98,8 @@
 	a->h = hval;
 	a->next = git_attr_hash[pos];
 	a->attr_nr = attr_nr++;
+	a->maybe_macro = 0;
+	a->maybe_real = 0;
 	git_attr_hash[pos] = a;
 
 	REALLOC_ARRAY(check_all_attr, attr_nr);
@@ -244,9 +249,10 @@
 		      sizeof(*res) +
 		      sizeof(struct attr_state) * num_attr +
 		      (is_macro ? 0 : namelen + 1));
-	if (is_macro)
+	if (is_macro) {
 		res->u.attr = git_attr_internal(name, namelen);
-	else {
+		res->u.attr->maybe_macro = 1;
+	} else {
 		char *p = (char *)&(res->state[num_attr]);
 		memcpy(p, name, namelen);
 		res->u.pat.pattern = p;
@@ -266,6 +272,10 @@
 	/* Second pass to fill the attr_states */
 	for (cp = states, i = 0; *cp; i++) {
 		cp = parse_attr(src, lineno, cp, &(res->state[i]));
+		if (!is_macro)
+			res->state[i].attr->maybe_real = 1;
+		if (res->state[i].attr->maybe_macro)
+			cannot_trust_maybe_real = 1;
 	}
 
 	return res;
@@ -681,13 +691,14 @@
 	return rem;
 }
 
-static int macroexpand_one(int attr_nr, int rem)
+static int macroexpand_one(int nr, int rem)
 {
 	struct attr_stack *stk;
 	struct match_attr *a = NULL;
 	int i;
 
-	if (check_all_attr[attr_nr].value != ATTR__TRUE)
+	if (check_all_attr[nr].value != ATTR__TRUE ||
+	    !check_all_attr[nr].attr->maybe_macro)
 		return rem;
 
 	for (stk = attr_stack; !a && stk; stk = stk->prev)
@@ -695,7 +706,7 @@
 			struct match_attr *ma = stk->attrs[i];
 			if (!ma->is_macro)
 				continue;
-			if (ma->u.attr->attr_nr == attr_nr)
+			if (ma->u.attr->attr_nr == nr)
 				a = ma;
 		}
 
@@ -706,10 +717,13 @@
 }
 
 /*
- * Collect all attributes for path into the array pointed to by
- * check_all_attr.
+ * Collect attributes for path into the array pointed to by
+ * check_all_attr. If num is non-zero, only attributes in check[] are
+ * collected. Otherwise all attributes are collected.
  */
-static void collect_all_attrs(const char *path)
+static void collect_some_attrs(const char *path, int num,
+			       struct git_attr_check *check)
+
 {
 	struct attr_stack *stk;
 	int i, pathlen, rem, dirlen;
@@ -732,6 +746,19 @@
 	prepare_attr_stack(path, dirlen);
 	for (i = 0; i < attr_nr; i++)
 		check_all_attr[i].value = ATTR__UNKNOWN;
+	if (num && !cannot_trust_maybe_real) {
+		rem = 0;
+		for (i = 0; i < num; i++) {
+			if (!check[i].attr->maybe_real) {
+				struct git_attr_check *c;
+				c = check_all_attr + check[i].attr->attr_nr;
+				c->value = ATTR__UNSET;
+				rem++;
+			}
+		}
+		if (rem == num)
+			return;
+	}
 
 	rem = attr_nr;
 	for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
@@ -742,7 +769,7 @@
 {
 	int i;
 
-	collect_all_attrs(path);
+	collect_some_attrs(path, num, check);
 
 	for (i = 0; i < num; i++) {
 		const char *value = check_all_attr[check[i].attr->attr_nr].value;
@@ -758,7 +785,7 @@
 {
 	int i, count, j;
 
-	collect_all_attrs(path);
+	collect_some_attrs(path, 0, NULL);
 
 	/* Count the number of attributes that are set. */
 	count = 0;
diff --git a/builtin/add.c b/builtin/add.c
index 1074e32..3390933 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -19,7 +19,7 @@
 #include "argv-array.h"
 
 static const char * const builtin_add_usage[] = {
-	N_("git add [options] [--] <pathspec>..."),
+	N_("git add [<options>] [--] <pathspec>..."),
 	NULL
 };
 static int patch_interactive, add_interactive, edit_interactive;
diff --git a/builtin/apply.c b/builtin/apply.c
index 0aad912..955cc79 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -55,7 +55,7 @@
 static int line_termination = '\n';
 static unsigned int p_context = UINT_MAX;
 static const char * const apply_usage[] = {
-	N_("git apply [options] [<patch>...]"),
+	N_("git apply [<options>] [<patch>...]"),
 	NULL
 };
 
@@ -657,11 +657,6 @@
 	return line + len - end;
 }
 
-static char *null_strdup(const char *s)
-{
-	return s ? xstrdup(s) : NULL;
-}
-
 static char *find_name_common(const char *line, const char *def,
 			      int p_value, const char *end, int terminate)
 {
@@ -684,10 +679,10 @@
 			start = line;
 	}
 	if (!start)
-		return squash_slash(null_strdup(def));
+		return squash_slash(xstrdup_or_null(def));
 	len = line - start;
 	if (!len)
-		return squash_slash(null_strdup(def));
+		return squash_slash(xstrdup_or_null(def));
 
 	/*
 	 * Generally we prefer the shorter name, especially
@@ -909,7 +904,7 @@
 			patch->old_name = name;
 		} else {
 			patch->old_name = name;
-			patch->new_name = null_strdup(name);
+			patch->new_name = xstrdup_or_null(name);
 		}
 	}
 	if (!name)
@@ -998,7 +993,7 @@
 {
 	patch->is_delete = 1;
 	free(patch->old_name);
-	patch->old_name = null_strdup(patch->def_name);
+	patch->old_name = xstrdup_or_null(patch->def_name);
 	return gitdiff_oldmode(line, patch);
 }
 
@@ -1006,7 +1001,7 @@
 {
 	patch->is_new = 1;
 	free(patch->new_name);
-	patch->new_name = null_strdup(patch->def_name);
+	patch->new_name = xstrdup_or_null(patch->def_name);
 	return gitdiff_newmode(line, patch);
 }
 
@@ -2235,6 +2230,12 @@
 		ctx++;
 	}
 
+	if (postlen
+	    ? postlen < new - postimage->buf
+	    : postimage->len < new - postimage->buf)
+		die("BUG: caller miscounted postlen: asked %d, orig = %d, used = %d",
+		    (int)postlen, (int) postimage->len, (int)(new - postimage->buf));
+
 	/* Fix the length of the whole thing */
 	postimage->len = new - postimage->buf;
 	postimage->nr -= reduced;
@@ -2390,10 +2391,27 @@
 
 	/*
 	 * The hunk does not apply byte-by-byte, but the hash says
-	 * it might with whitespace fuzz. We haven't been asked to
+	 * it might with whitespace fuzz. We weren't asked to
 	 * ignore whitespace, we were asked to correct whitespace
 	 * errors, so let's try matching after whitespace correction.
 	 *
+	 * While checking the preimage against the target, whitespace
+	 * errors in both fixed, we count how large the corresponding
+	 * postimage needs to be.  The postimage prepared by
+	 * apply_one_fragment() has whitespace errors fixed on added
+	 * lines already, but the common lines were propagated as-is,
+	 * which may become longer when their whitespace errors are
+	 * fixed.
+	 */
+
+	/* First count added lines in postimage */
+	postlen = 0;
+	for (i = 0; i < postimage->nr; i++) {
+		if (!(postimage->line[i].flag & LINE_COMMON))
+			postlen += postimage->line[i].len;
+	}
+
+	/*
 	 * The preimage may extend beyond the end of the file,
 	 * but in this loop we will only handle the part of the
 	 * preimage that falls within the file.
@@ -2401,7 +2419,6 @@
 	strbuf_init(&fixed, preimage->len + 1);
 	orig = preimage->buf;
 	target = img->buf + try;
-	postlen = 0;
 	for (i = 0; i < preimage_limit; i++) {
 		size_t oldlen = preimage->line[i].len;
 		size_t tgtlen = img->line[try_lno + i].len;
@@ -2429,7 +2446,10 @@
 		match = (tgtfix.len == fixed.len - fixstart &&
 			 !memcmp(tgtfix.buf, fixed.buf + fixstart,
 					     fixed.len - fixstart));
-		postlen += tgtfix.len;
+
+		/* Add the length if this is common with the postimage */
+		if (preimage->line[i].flag & LINE_COMMON)
+			postlen += tgtfix.len;
 
 		strbuf_release(&tgtfix);
 		if (!match)
diff --git a/builtin/blame.c b/builtin/blame.c
index 303e217..06484c2 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -27,12 +27,12 @@
 #include "line-range.h"
 #include "line-log.h"
 
-static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
+static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] file");
 
 static const char *blame_opt_usage[] = {
 	blame_usage,
 	"",
-	N_("[rev-opts] are documented in git-rev-list(1)"),
+	N_("<rev-opts> are documented in git-rev-list(1)"),
 	NULL
 };
 
@@ -2085,7 +2085,6 @@
 
 	for (e = sb->ent; e; e = e->next) {
 		struct origin *suspect = e->suspect;
-		struct commit_info ci;
 		int num;
 
 		if (compute_auto_abbrev)
@@ -2096,6 +2095,7 @@
 		if (longest_file < num)
 			longest_file = num;
 		if (!(suspect->commit->object.flags & METAINFO_SHOWN)) {
+			struct commit_info ci;
 			suspect->commit->object.flags |= METAINFO_SHOWN;
 			get_commit_info(suspect->commit, &ci, 1);
 			if (*option & OUTPUT_SHOW_EMAIL)
@@ -2104,6 +2104,7 @@
 				num = utf8_strwidth(ci.author.buf);
 			if (longest_author < num)
 				longest_author = num;
+			commit_info_destroy(&ci);
 		}
 		num = e->s_lno + e->num_lines;
 		if (longest_src_lines < num)
@@ -2113,8 +2114,6 @@
 			longest_dst_lines = num;
 		if (largest_score < ent_score(sb, e))
 			largest_score = ent_score(sb, e);
-
-		commit_info_destroy(&ci);
 	}
 	max_orig_digits = decimal_width(longest_src_lines);
 	max_digits = decimal_width(longest_dst_lines);
@@ -2390,7 +2389,7 @@
 	return commit;
 }
 
-static const char *prepare_final(struct scoreboard *sb)
+static char *prepare_final(struct scoreboard *sb)
 {
 	int i;
 	const char *final_commit_name = NULL;
@@ -2415,10 +2414,10 @@
 		sb->final = (struct commit *) obj;
 		final_commit_name = revs->pending.objects[i].name;
 	}
-	return final_commit_name;
+	return xstrdup_or_null(final_commit_name);
 }
 
-static const char *prepare_initial(struct scoreboard *sb)
+static char *prepare_initial(struct scoreboard *sb)
 {
 	int i;
 	const char *final_commit_name = NULL;
@@ -2445,7 +2444,7 @@
 	}
 	if (!final_commit_name)
 		die("No commit to dig down to?");
-	return final_commit_name;
+	return xstrdup(final_commit_name);
 }
 
 static int blame_copy_callback(const struct option *option, const char *arg, int unset)
@@ -2489,7 +2488,7 @@
 	struct origin *o;
 	struct blame_entry *ent = NULL;
 	long dashdash_pos, lno;
-	const char *final_commit_name = NULL;
+	char *final_commit_name = NULL;
 	enum object_type type;
 
 	static struct string_list range_list;
@@ -2786,6 +2785,8 @@
 
 	assign_blame(&sb, opt);
 
+	free(final_commit_name);
+
 	if (incremental)
 		return 0;
 
diff --git a/builtin/branch.c b/builtin/branch.c
index dc6f0b2..6a25957 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -21,10 +21,10 @@
 #include "wt-status.h"
 
 static const char * const builtin_branch_usage[] = {
-	N_("git branch [options] [-r | -a] [--merged | --no-merged]"),
-	N_("git branch [options] [-l] [-f] <branchname> [<start-point>]"),
-	N_("git branch [options] [-r] (-d | -D) <branchname>..."),
-	N_("git branch [options] (-m | -M) [<oldbranch>] <newbranch>"),
+	N_("git branch [<options>] [-r | -a] [--merged | --no-merged]"),
+	N_("git branch [<options>] [-l] [-f] <branch-name> [<start-point>]"),
+	N_("git branch [<options>] [-r] (-d | -D) <branch-name>..."),
+	N_("git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"),
 	NULL
 };
 
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 31b133b..df99df4 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -323,8 +323,8 @@
 }
 
 static const char * const cat_file_usage[] = {
-	N_("git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"),
-	N_("git cat-file (--batch|--batch-check) < <list_of_objects>"),
+	N_("git cat-file (-t | -s | -e | -p | <type> | --textconv) <object>"),
+	N_("git cat-file (--batch | --batch-check) < <list-of-objects>"),
 	NULL
 };
 
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 5600ec3..21d2bed 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -8,8 +8,8 @@
 static int cached_attrs;
 static int stdin_paths;
 static const char * const check_attr_usage[] = {
-N_("git check-attr [-a | --all | attr...] [--] pathname..."),
-N_("git check-attr --stdin [-z] [-a | --all | attr...] < <list-of-paths>"),
+N_("git check-attr [-a | --all | <attr>...] [--] <pathname>..."),
+N_("git check-attr --stdin [-z] [-a | --all | <attr>...] < <list-of-paths>"),
 NULL
 };
 
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index 594463a..dc8d97c 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -7,8 +7,8 @@
 
 static int quiet, verbose, stdin_paths, show_non_matching, no_index;
 static const char * const check_ignore_usage[] = {
-"git check-ignore [options] pathname...",
-"git check-ignore [options] --stdin < <list-of-paths>",
+"git check-ignore [<options>] <pathname>...",
+"git check-ignore [<options>] --stdin < <list-of-paths>",
 NULL
 };
 
diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c
index 8f4d809..eaaea54 100644
--- a/builtin/check-mailmap.c
+++ b/builtin/check-mailmap.c
@@ -5,7 +5,7 @@
 
 static int use_stdin;
 static const char * const check_mailmap_usage[] = {
-N_("git check-mailmap [options] <contact>..."),
+N_("git check-mailmap [<options>] <contact>..."),
 NULL
 };
 
diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
index 28a7320..fd915d5 100644
--- a/builtin/check-ref-format.c
+++ b/builtin/check-ref-format.c
@@ -8,7 +8,7 @@
 #include "strbuf.h"
 
 static const char builtin_check_ref_format_usage[] =
-"git check-ref-format [--normalize] [options] <refname>\n"
+"git check-ref-format [--normalize] [<options>] <refname>\n"
 "   or: git check-ref-format --branch <branchname-shorthand>";
 
 /*
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index 031780f..9ca2da1 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -123,7 +123,7 @@
 }
 
 static const char * const builtin_checkout_index_usage[] = {
-	N_("git checkout-index [options] [--] [<file>...]"),
+	N_("git checkout-index [<options>] [--] [<file>...]"),
 	NULL
 };
 
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 52d6cbb..3e141fc 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -22,8 +22,8 @@
 #include "argv-array.h"
 
 static const char * const checkout_usage[] = {
-	N_("git checkout [options] <branch>"),
-	N_("git checkout [options] [<branch>] -- <file>..."),
+	N_("git checkout [<options>] <branch>"),
+	N_("git checkout [<options>] [<branch>] -- <file>..."),
 	NULL,
 };
 
@@ -746,7 +746,7 @@
 			_(
 			"If you want to keep them by creating a new branch, "
 			"this may be a good time\nto do so with:\n\n"
-			" git branch new_branch_name %s\n\n"),
+			" git branch <new-branch-name> %s\n\n"),
 			find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
 }
 
@@ -1127,7 +1127,7 @@
 		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'")),
+				N_("second guess 'git checkout <no-such-branch>'")),
 		OPT_END(),
 	};
 
diff --git a/builtin/clone.c b/builtin/clone.c
index 316c75d..9572467 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -34,7 +34,7 @@
  *
  */
 static const char * const builtin_clone_usage[] = {
-	N_("git clone [options] [--] <repo> [<dir>]"),
+	N_("git clone [<options>] [--] <repo> [<dir>]"),
 	NULL
 };
 
diff --git a/builtin/column.c b/builtin/column.c
index 7581852..449413c 100644
--- a/builtin/column.c
+++ b/builtin/column.c
@@ -6,7 +6,7 @@
 #include "column.h"
 
 static const char * const builtin_column_usage[] = {
-	N_("git column [options]"),
+	N_("git column [<options>]"),
 	NULL
 };
 static unsigned int colopts;
diff --git a/builtin/commit.c b/builtin/commit.c
index 7d90c35..6055c76 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -34,12 +34,12 @@
 #include "mailmap.h"
 
 static const char * const builtin_commit_usage[] = {
-	N_("git commit [options] [--] <pathspec>..."),
+	N_("git commit [<options>] [--] <pathspec>..."),
 	NULL
 };
 
 static const char * const builtin_status_usage[] = {
-	N_("git status [options] [--] <pathspec>..."),
+	N_("git status [<options>] [--] <pathspec>..."),
 	NULL
 };
 
@@ -559,20 +559,14 @@
 	*buf = val;
 }
 
-static char *envdup(const char *var)
-{
-	const char *val = getenv(var);
-	return val ? xstrdup(val) : NULL;
-}
-
 static void determine_author_info(struct strbuf *author_ident)
 {
 	char *name, *email, *date;
 	struct ident_split author;
 
-	name = envdup("GIT_AUTHOR_NAME");
-	email = envdup("GIT_AUTHOR_EMAIL");
-	date = envdup("GIT_AUTHOR_DATE");
+	name = xstrdup_or_null(getenv("GIT_AUTHOR_NAME"));
+	email = xstrdup_or_null(getenv("GIT_AUTHOR_EMAIL"));
+	date = xstrdup_or_null(getenv("GIT_AUTHOR_DATE"));
 
 	if (author_message) {
 		struct ident_split ident;
@@ -1056,7 +1050,7 @@
 		clear_mailmap(&mailmap);
 		return strbuf_detach(&buf, NULL);
 	}
-	die(_("No existing author found with '%s'"), name);
+	die(_("--author '%s' is not 'Name <email>' and matches no existing author"), name);
 }
 
 
diff --git a/builtin/config.c b/builtin/config.c
index 15a7bea..d32c532 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -5,7 +5,7 @@
 #include "urlmatch.h"
 
 static const char *const builtin_config_usage[] = {
-	N_("git config [options]"),
+	N_("git config [<options>]"),
 	NULL
 };
 
diff --git a/builtin/describe.c b/builtin/describe.c
index 9103193..e00a75b 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -14,8 +14,8 @@
 #define MAX_TAGS	(FLAG_BITS - 1)
 
 static const char * const describe_usage[] = {
-	N_("git describe [options] <commit-ish>*"),
-	N_("git describe [options] --dirty"),
+	N_("git describe [<options>] [<commit-ish>...]"),
+	N_("git describe [<options>] --dirty"),
 	NULL
 };
 
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 9200069..8ed2eb8 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -11,7 +11,7 @@
 #include "submodule.h"
 
 static const char diff_files_usage[] =
-"git diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
+"git diff-files [-q] [-0 | -1 | -2 | -3 | -c | --cc] [<common-diff-options>] [<path>...]"
 COMMON_DIFF_OPTIONS_HELP;
 
 int cmd_diff_files(int argc, const char **argv, const char *prefix)
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index ce15b23..d979824 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -7,7 +7,7 @@
 
 static const char diff_cache_usage[] =
 "git diff-index [-m] [--cached] "
-"[<common diff options>] <tree-ish> [<path>...]"
+"[<common-diff-options>] <tree-ish> [<path>...]"
 COMMON_DIFF_OPTIONS_HELP;
 
 int cmd_diff_index(int argc, const char **argv, const char *prefix)
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 1c4ad62..12b683d 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -82,7 +82,7 @@
 
 static const char diff_tree_usage[] =
 "git diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] "
-"[<common diff options>] <tree-ish> [<tree-ish>] [<path>...]\n"
+"[<common-diff-options>] <tree-ish> [<tree-ish>] [<path>...]\n"
 "  -r            diff recursively\n"
 "  --root        include the initial commit as diff against /dev/null\n"
 COMMON_DIFF_OPTIONS_HELP;
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 1262b40..4a6b340 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -6,7 +6,7 @@
 #include "sha1-array.h"
 
 static const char fetch_pack_usage[] =
-"git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] "
+"git fetch-pack [--all] [--stdin] [--quiet | -q] [--keep | -k] [--thin] "
 "[--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] "
 "[--no-progress] [--diag-url] [-v] [<host>:]<directory> [<refs>...]";
 
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7b84d35..75a55e5 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -11,7 +11,6 @@
 #include "run-command.h"
 #include "parse-options.h"
 #include "sigchain.h"
-#include "transport.h"
 #include "submodule.h"
 #include "connected.h"
 #include "argv-array.h"
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index af7919e..1d962dc 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -10,7 +10,7 @@
 #include "gpg-interface.h"
 
 static const char * const fmt_merge_msg_usage[] = {
-	N_("git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]"),
+	N_("git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]"),
 	NULL
 };
 
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index a0123f6..19be78a 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -1061,7 +1061,7 @@
 }
 
 static char const * const for_each_ref_usage[] = {
-	N_("git for-each-ref [options] [<pattern>]"),
+	N_("git for-each-ref [<options>] [<pattern>]"),
 	NULL
 };
 
diff --git a/builtin/fsck.c b/builtin/fsck.c
index a27515a..0c75786 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -600,7 +600,7 @@
 }
 
 static char const * const fsck_usage[] = {
-	N_("git fsck [options] [<object>...]"),
+	N_("git fsck [<options>] [<object>...]"),
 	NULL
 };
 
diff --git a/builtin/gc.c b/builtin/gc.c
index 005adbe..5c634af 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -21,7 +21,7 @@
 #define FAILED_RUN "failed to run %s"
 
 static const char * const builtin_gc_usage[] = {
-	N_("git gc [options]"),
+	N_("git gc [<options>]"),
 	NULL
 };
 
diff --git a/builtin/grep.c b/builtin/grep.c
index 4063882..9262b73 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -20,7 +20,7 @@
 #include "pathspec.h"
 
 static char const * const grep_usage[] = {
-	N_("git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"),
+	N_("git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"),
 	NULL
 };
 
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 6158363..207b90c 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -79,7 +79,7 @@
 int cmd_hash_object(int argc, const char **argv, const char *prefix)
 {
 	static const char * const hash_object_usage[] = {
-		N_("git hash-object [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] <file>..."),
+		N_("git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] [--] <file>..."),
 		N_("git hash-object  --stdin-paths < <list-of-paths>"),
 		NULL
 	};
diff --git a/builtin/help.c b/builtin/help.c
index e78c135..6133fe4 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -49,7 +49,7 @@
 };
 
 static const char * const builtin_help_usage[] = {
-	N_("git help [--all] [--guides] [--man|--web|--info] [command]"),
+	N_("git help [--all] [--guides] [--man | --web | --info] [<command>]"),
 	NULL
 };
 
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 9966522..6723d39 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -472,7 +472,7 @@
 }
 
 static const char *const init_db_usage[] = {
-	N_("git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [directory]"),
+	N_("git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [<directory>]"),
 	NULL
 };
 
diff --git a/builtin/log.c b/builtin/log.c
index 923ffe7..dd8f3fc 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -39,7 +39,7 @@
 
 static const char * const builtin_log_usage[] = {
 	N_("git log [<options>] [<revision range>] [[--] <path>...]"),
-	N_("git show [options] <object>..."),
+	N_("git show [<options>] <object>..."),
 	NULL
 };
 
@@ -705,7 +705,7 @@
 		return 0;
 	}
 	if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff") ||
-	    !strcmp(var, "color.ui")) {
+	    !strcmp(var, "color.ui") || !strcmp(var, "diff.submodule")) {
 		return 0;
 	}
 	if (!strcmp(var, "format.numbered")) {
@@ -1023,7 +1023,7 @@
 }
 
 static const char * const builtin_format_patch_usage[] = {
-	N_("git format-patch [options] [<since> | <revision range>]"),
+	N_("git format-patch [<options>] [<since> | <revision-range>]"),
 	NULL
 };
 
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 99cee20..914054d 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -398,7 +398,7 @@
 }
 
 static const char * const ls_files_usage[] = {
-	N_("git ls-files [options] [<file>...]"),
+	N_("git ls-files [<options>] [<file>...]"),
 	NULL
 };
 
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index b2a4b92..4554dbc 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -5,7 +5,7 @@
 
 static const char ls_remote_usage[] =
 "git ls-remote [--heads] [--tags]  [-u <exec> | --upload-pack <exec>]\n"
-"                     [-q|--quiet] [--exit-code] [--get-url] [<repository> [<refs>...]]";
+"                     [-q | --quiet] [--exit-code] [--get-url] [<repository> [<refs>...]]";
 
 /*
  * Is there one among the list of patterns that match the tail part
diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c
index c8a47c1..999a525 100644
--- a/builtin/mailinfo.c
+++ b/builtin/mailinfo.c
@@ -1031,7 +1031,7 @@
 }
 
 static const char mailinfo_usage[] =
-	"git mailinfo [-k|-b] [-m | --message-id] [-u | --encoding=<encoding> | -n] [--scissors | --no-scissors] msg patch < mail >info";
+	"git mailinfo [-k | -b] [-m | --message-id] [-u | --encoding=<encoding> | -n] [--scissors | --no-scissors] <msg> <patch> < mail >info";
 
 int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index fdebef6..08a8217 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -26,8 +26,8 @@
 }
 
 static const char * const merge_base_usage[] = {
-	N_("git merge-base [-a|--all] <commit> <commit>..."),
-	N_("git merge-base [-a|--all] --octopus <commit>..."),
+	N_("git merge-base [-a | --all] <commit> <commit>..."),
+	N_("git merge-base [-a | --all] --octopus <commit>..."),
 	N_("git merge-base --independent <commit>..."),
 	N_("git merge-base --is-ancestor <commit> <commit>"),
 	N_("git merge-base --fork-point <ref> [<commit>]"),
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index 844f84f..ea8093f 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -5,7 +5,7 @@
 #include "parse-options.h"
 
 static const char *const merge_file_usage[] = {
-	N_("git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file file2"),
+	N_("git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> <orig-file> <file2>"),
 	NULL
 };
 
@@ -42,7 +42,7 @@
 			    N_("for conflicts, use this marker size")),
 		OPT__QUIET(&quiet, N_("do not warn about conflicts")),
 		OPT_CALLBACK('L', NULL, names, N_("name"),
-			     N_("set labels for file1/orig_file/file2"), &label_cb),
+			     N_("set labels for file1/orig-file/file2"), &label_cb),
 		OPT_END(),
 	};
 
@@ -90,7 +90,8 @@
 
 	if (ret >= 0) {
 		const char *filename = argv[0];
-		FILE *f = to_stdout ? stdout : fopen(filename, "wb");
+		const char *fpath = prefix_filename(prefix, prefixlen, argv[0]);
+		FILE *f = to_stdout ? stdout : fopen(fpath, "wb");
 
 		if (!f)
 			ret = error("Could not open %s for writing", filename);
diff --git a/builtin/merge-index.c b/builtin/merge-index.c
index b416d92..1a1eafa 100644
--- a/builtin/merge-index.c
+++ b/builtin/merge-index.c
@@ -75,7 +75,7 @@
 	signal(SIGCHLD, SIG_DFL);
 
 	if (argc < 3)
-		usage("git merge-index [-o] [-q] <merge-program> (-a | [--] <filename>*)");
+		usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])");
 
 	read_cache();
 
diff --git a/builtin/merge.c b/builtin/merge.c
index c638fd5..3b0f8f9 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -42,8 +42,8 @@
 };
 
 static const char * const builtin_merge_usage[] = {
-	N_("git merge [options] [<commit>...]"),
-	N_("git merge [options] <msg> HEAD <commit>"),
+	N_("git merge [<options>] [<commit>...]"),
+	N_("git merge [<options>] <msg> HEAD <commit>"),
 	N_("git merge --abort"),
 	NULL
 };
diff --git a/builtin/mv.c b/builtin/mv.c
index 563d05b..d1d4316 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -12,7 +12,7 @@
 #include "submodule.h"
 
 static const char * const builtin_mv_usage[] = {
-	N_("git mv [options] <source>... <destination>"),
+	N_("git mv [<options>] <source>... <destination>"),
 	NULL
 };
 
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 3c8f319..9736d44 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -252,9 +252,9 @@
 }
 
 static char const * const name_rev_usage[] = {
-	N_("git name-rev [options] <commit>..."),
-	N_("git name-rev [options] --all"),
-	N_("git name-rev [options] --stdin"),
+	N_("git name-rev [<options>] <commit>..."),
+	N_("git name-rev [<options>] --all"),
+	N_("git name-rev [<options>] --stdin"),
 	NULL
 };
 
diff --git a/builtin/notes.c b/builtin/notes.c
index a9f37d0..63f95fc 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -21,18 +21,18 @@
 #include "notes-utils.h"
 
 static const char * const git_notes_usage[] = {
-	N_("git notes [--ref <notes_ref>] [list [<object>]]"),
-	N_("git notes [--ref <notes_ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
-	N_("git notes [--ref <notes_ref>] copy [-f] <from-object> <to-object>"),
-	N_("git notes [--ref <notes_ref>] append [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
-	N_("git notes [--ref <notes_ref>] edit [--allow-empty] [<object>]"),
-	N_("git notes [--ref <notes_ref>] show [<object>]"),
-	N_("git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>"),
+	N_("git notes [--ref <notes-ref>] [list [<object>]]"),
+	N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+	N_("git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"),
+	N_("git notes [--ref <notes-ref>] append [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+	N_("git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"),
+	N_("git notes [--ref <notes-ref>] show [<object>]"),
+	N_("git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"),
 	N_("git notes merge --commit [-v | -q]"),
 	N_("git notes merge --abort [-v | -q]"),
-	N_("git notes [--ref <notes_ref>] remove [<object>...]"),
-	N_("git notes [--ref <notes_ref>] prune [-n | -v]"),
-	N_("git notes [--ref <notes_ref>] get-ref"),
+	N_("git notes [--ref <notes-ref>] remove [<object>...]"),
+	N_("git notes [--ref <notes-ref>] prune [-n | -v]"),
+	N_("git notes [--ref <notes-ref>] get-ref"),
 	NULL
 };
 
@@ -68,7 +68,7 @@
 };
 
 static const char * const git_notes_merge_usage[] = {
-	N_("git notes merge [<options>] <notes_ref>"),
+	N_("git notes merge [<options>] <notes-ref>"),
 	N_("git notes merge --commit [<options>]"),
 	N_("git notes merge --abort [<options>]"),
 	NULL
@@ -951,7 +951,7 @@
 	const char *override_notes_ref = NULL;
 	struct option options[] = {
 		OPT_STRING(0, "ref", &override_notes_ref, N_("notes-ref"),
-			   N_("use notes from <notes_ref>")),
+			   N_("use notes from <notes-ref>")),
 		OPT_END()
 	};
 
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index 649c3aa..d0532f6 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -11,7 +11,7 @@
 #define BLKSIZE 512
 
 static const char pack_redundant_usage[] =
-"git pack-redundant [ --verbose ] [ --alt-odb ] < --all | <.pack filename> ...>";
+"git pack-redundant [--verbose] [--alt-odb] (--all | <filename.pack>...)";
 
 static int load_all_packs, verbose, alt_odb;
 
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index b20b1ec..39f9a55 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -3,7 +3,7 @@
 #include "refs.h"
 
 static char const * const pack_refs_usage[] = {
-	N_("git pack-refs [options]"),
+	N_("git pack-refs [<options>]"),
 	NULL
 };
 
diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c
index f24a2c2..7cf900e 100644
--- a/builtin/prune-packed.c
+++ b/builtin/prune-packed.c
@@ -4,7 +4,7 @@
 #include "parse-options.h"
 
 static const char * const prune_packed_usage[] = {
-	N_("git prune-packed [-n|--dry-run] [-q|--quiet]"),
+	N_("git prune-packed [-n | --dry-run] [-q | --quiet]"),
 	NULL
 };
 
diff --git a/builtin/push.c b/builtin/push.c
index 12f5e69..fc771a9 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -487,6 +487,7 @@
 	int flags = 0;
 	int tags = 0;
 	int rc;
+	int atomic = 0;
 	const char *repo = NULL;	/* default repository */
 	struct option options[] = {
 		OPT__VERBOSITY(&verbosity),
@@ -518,6 +519,7 @@
 		OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
 			TRANSPORT_PUSH_FOLLOW_TAGS),
 		OPT_BIT(0, "signed", &flags, N_("GPG sign the push"), TRANSPORT_PUSH_CERT),
+		OPT_BOOL(0, "atomic", &atomic, N_("request atomic transaction on remote side")),
 		OPT_END()
 	};
 
@@ -533,6 +535,9 @@
 	if (tags)
 		add_refspec("refs/tags/*");
 
+	if (atomic)
+		flags |= TRANSPORT_PUSH_ATOMIC;
+
 	if (argc > 0) {
 		repo = argv[0];
 		set_refspecs(argv + 1, argc - 1, repo);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 8266c1f..e0ce78e 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -38,9 +38,11 @@
 static int transfer_fsck_objects = -1;
 static int receive_unpack_limit = -1;
 static int transfer_unpack_limit = -1;
+static int advertise_atomic_push = 1;
 static int unpack_limit = 100;
 static int report_status;
 static int use_sideband;
+static int use_atomic;
 static int quiet;
 static int prefer_ofs_delta = 1;
 static int auto_update_server_info;
@@ -67,6 +69,7 @@
 static const char *nonce_status;
 static long nonce_stamp_slop;
 static unsigned long nonce_stamp_slop_limit;
+static struct ref_transaction *transaction;
 
 static enum deny_action parse_deny_action(const char *var, const char *value)
 {
@@ -160,6 +163,11 @@
 		return 0;
 	}
 
+	if (strcmp(var, "receive.advertiseatomic") == 0) {
+		advertise_atomic_push = git_config_bool(var, value);
+		return 0;
+	}
+
 	return git_default_config(var, value, cb);
 }
 
@@ -175,6 +183,8 @@
 
 		strbuf_addstr(&cap,
 			      "report-status delete-refs side-band-64k quiet");
+		if (advertise_atomic_push)
+			strbuf_addstr(&cap, " atomic");
 		if (prefer_ofs_delta)
 			strbuf_addstr(&cap, " ofs-delta");
 		if (push_cert_nonce)
@@ -733,7 +743,9 @@
 	return 0;
 }
 
-static const char *update_worktree(unsigned char *sha1)
+static const char *push_to_deploy(unsigned char *sha1,
+				  struct argv_array *env,
+				  const char *work_tree)
 {
 	const char *update_refresh[] = {
 		"update-index", "-q", "--ignore-submodules", "--refresh", NULL
@@ -748,67 +760,85 @@
 	const char *read_tree[] = {
 		"read-tree", "-u", "-m", NULL, NULL
 	};
+	struct child_process child = CHILD_PROCESS_INIT;
+
+	child.argv = update_refresh;
+	child.env = env->argv;
+	child.dir = work_tree;
+	child.no_stdin = 1;
+	child.stdout_to_stderr = 1;
+	child.git_cmd = 1;
+	if (run_command(&child))
+		return "Up-to-date check failed";
+
+	/* run_command() does not clean up completely; reinitialize */
+	child_process_init(&child);
+	child.argv = diff_files;
+	child.env = env->argv;
+	child.dir = work_tree;
+	child.no_stdin = 1;
+	child.stdout_to_stderr = 1;
+	child.git_cmd = 1;
+	if (run_command(&child))
+		return "Working directory has unstaged changes";
+
+	child_process_init(&child);
+	child.argv = diff_index;
+	child.env = env->argv;
+	child.no_stdin = 1;
+	child.no_stdout = 1;
+	child.stdout_to_stderr = 0;
+	child.git_cmd = 1;
+	if (run_command(&child))
+		return "Working directory has staged changes";
+
+	read_tree[3] = sha1_to_hex(sha1);
+	child_process_init(&child);
+	child.argv = read_tree;
+	child.env = env->argv;
+	child.dir = work_tree;
+	child.no_stdin = 1;
+	child.no_stdout = 1;
+	child.stdout_to_stderr = 0;
+	child.git_cmd = 1;
+	if (run_command(&child))
+		return "Could not update working tree to new HEAD";
+
+	return NULL;
+}
+
+static const char *push_to_checkout_hook = "push-to-checkout";
+
+static const char *push_to_checkout(unsigned char *sha1,
+				    struct argv_array *env,
+				    const char *work_tree)
+{
+	argv_array_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree));
+	if (run_hook_le(env->argv, push_to_checkout_hook,
+			sha1_to_hex(sha1), NULL))
+		return "push-to-checkout hook declined";
+	else
+		return NULL;
+}
+
+static const char *update_worktree(unsigned char *sha1)
+{
+	const char *retval;
 	const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
 	struct argv_array env = ARGV_ARRAY_INIT;
-	struct child_process child = CHILD_PROCESS_INIT;
 
 	if (is_bare_repository())
 		return "denyCurrentBranch = updateInstead needs a worktree";
 
 	argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
 
-	child.argv = update_refresh;
-	child.env = env.argv;
-	child.dir = work_tree;
-	child.no_stdin = 1;
-	child.stdout_to_stderr = 1;
-	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
-		return "Up-to-date check failed";
-	}
-
-	/* run_command() does not clean up completely; reinitialize */
-	child_process_init(&child);
-	child.argv = diff_files;
-	child.env = env.argv;
-	child.dir = work_tree;
-	child.no_stdin = 1;
-	child.stdout_to_stderr = 1;
-	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
-		return "Working directory has unstaged changes";
-	}
-
-	child_process_init(&child);
-	child.argv = diff_index;
-	child.env = env.argv;
-	child.no_stdin = 1;
-	child.no_stdout = 1;
-	child.stdout_to_stderr = 0;
-	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
-		return "Working directory has staged changes";
-	}
-
-	read_tree[3] = sha1_to_hex(sha1);
-	child_process_init(&child);
-	child.argv = read_tree;
-	child.env = env.argv;
-	child.dir = work_tree;
-	child.no_stdin = 1;
-	child.no_stdout = 1;
-	child.stdout_to_stderr = 0;
-	child.git_cmd = 1;
-	if (run_command(&child)) {
-		argv_array_clear(&env);
-		return "Could not update working tree to new HEAD";
-	}
+	if (!find_hook(push_to_checkout_hook))
+		retval = push_to_deploy(sha1, &env, work_tree);
+	else
+		retval = push_to_checkout(sha1, &env, work_tree);
 
 	argv_array_clear(&env);
-	return NULL;
+	return retval;
 }
 
 static const char *update(struct command *cmd, struct shallow_info *si)
@@ -910,6 +940,7 @@
 	}
 
 	if (is_null_sha1(new_sha1)) {
+		struct strbuf err = STRBUF_INIT;
 		if (!parse_object(old_sha1)) {
 			old_sha1 = NULL;
 			if (ref_exists(name)) {
@@ -919,35 +950,36 @@
 				cmd->did_not_exist = 1;
 			}
 		}
-		if (delete_ref(namespaced_name, old_sha1, 0)) {
-			rp_error("failed to delete %s", name);
+		if (ref_transaction_delete(transaction,
+					   namespaced_name,
+					   old_sha1,
+					   0, old_sha1 != NULL,
+					   "push", &err)) {
+			rp_error("%s", err.buf);
+			strbuf_release(&err);
 			return "failed to delete";
 		}
+		strbuf_release(&err);
 		return NULL; /* good */
 	}
 	else {
 		struct strbuf err = STRBUF_INIT;
-		struct ref_transaction *transaction;
-
 		if (shallow_update && si->shallow_ref[cmd->index] &&
 		    update_shallow_ref(cmd, si))
 			return "shallow error";
 
-		transaction = ref_transaction_begin(&err);
-		if (!transaction ||
-		    ref_transaction_update(transaction, namespaced_name,
-					   new_sha1, old_sha1, 0, 1, "push",
-					   &err) ||
-		    ref_transaction_commit(transaction, &err)) {
-			ref_transaction_free(transaction);
-
+		if (ref_transaction_update(transaction,
+					   namespaced_name,
+					   new_sha1, old_sha1,
+					   0, 1, "push",
+					   &err)) {
 			rp_error("%s", err.buf);
 			strbuf_release(&err);
+
 			return "failed to update ref";
 		}
-
-		ref_transaction_free(transaction);
 		strbuf_release(&err);
+
 		return NULL; /* good */
 	}
 }
@@ -1131,11 +1163,105 @@
 	}
 }
 
+static int should_process_cmd(struct command *cmd)
+{
+	return !cmd->error_string && !cmd->skip_update;
+}
+
+static void warn_if_skipped_connectivity_check(struct command *commands,
+					       struct shallow_info *si)
+{
+	struct command *cmd;
+	int checked_connectivity = 1;
+
+	for (cmd = commands; cmd; cmd = cmd->next) {
+		if (should_process_cmd(cmd) && si->shallow_ref[cmd->index]) {
+			error("BUG: connectivity check has not been run on ref %s",
+			      cmd->ref_name);
+			checked_connectivity = 0;
+		}
+	}
+	if (!checked_connectivity)
+		die("BUG: connectivity check skipped???");
+}
+
+static void execute_commands_non_atomic(struct command *commands,
+					struct shallow_info *si)
+{
+	struct command *cmd;
+	struct strbuf err = STRBUF_INIT;
+
+	for (cmd = commands; cmd; cmd = cmd->next) {
+		if (!should_process_cmd(cmd))
+			continue;
+
+		transaction = ref_transaction_begin(&err);
+		if (!transaction) {
+			rp_error("%s", err.buf);
+			strbuf_reset(&err);
+			cmd->error_string = "transaction failed to start";
+			continue;
+		}
+
+		cmd->error_string = update(cmd, si);
+
+		if (!cmd->error_string
+		    && ref_transaction_commit(transaction, &err)) {
+			rp_error("%s", err.buf);
+			strbuf_reset(&err);
+			cmd->error_string = "failed to update ref";
+		}
+		ref_transaction_free(transaction);
+	}
+	strbuf_release(&err);
+}
+
+static void execute_commands_atomic(struct command *commands,
+					struct shallow_info *si)
+{
+	struct command *cmd;
+	struct strbuf err = STRBUF_INIT;
+	const char *reported_error = "atomic push failure";
+
+	transaction = ref_transaction_begin(&err);
+	if (!transaction) {
+		rp_error("%s", err.buf);
+		strbuf_reset(&err);
+		reported_error = "transaction failed to start";
+		goto failure;
+	}
+
+	for (cmd = commands; cmd; cmd = cmd->next) {
+		if (!should_process_cmd(cmd))
+			continue;
+
+		cmd->error_string = update(cmd, si);
+
+		if (cmd->error_string)
+			goto failure;
+	}
+
+	if (ref_transaction_commit(transaction, &err)) {
+		rp_error("%s", err.buf);
+		reported_error = "atomic transaction failed";
+		goto failure;
+	}
+	goto cleanup;
+
+failure:
+	for (cmd = commands; cmd; cmd = cmd->next)
+		if (!cmd->error_string)
+			cmd->error_string = reported_error;
+
+cleanup:
+	ref_transaction_free(transaction);
+	strbuf_release(&err);
+}
+
 static void execute_commands(struct command *commands,
 			     const char *unpacker_error,
 			     struct shallow_info *si)
 {
-	int checked_connectivity;
 	struct command *cmd;
 	unsigned char sha1[20];
 	struct iterate_data data;
@@ -1166,27 +1292,13 @@
 	free(head_name_to_free);
 	head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL);
 
-	checked_connectivity = 1;
-	for (cmd = commands; cmd; cmd = cmd->next) {
-		if (cmd->error_string)
-			continue;
+	if (use_atomic)
+		execute_commands_atomic(commands, si);
+	else
+		execute_commands_non_atomic(commands, si);
 
-		if (cmd->skip_update)
-			continue;
-
-		cmd->error_string = update(cmd, si);
-		if (shallow_update && !cmd->error_string &&
-		    si->shallow_ref[cmd->index]) {
-			error("BUG: connectivity check has not been run on ref %s",
-			      cmd->ref_name);
-			checked_connectivity = 0;
-		}
-	}
-
-	if (shallow_update && !checked_connectivity)
-		error("BUG: run 'git fsck' for safety.\n"
-		      "If there are errors, try to remove "
-		      "the reported refs above");
+	if (shallow_update)
+		warn_if_skipped_connectivity_check(commands, si);
 }
 
 static struct command **queue_command(struct command **tail,
@@ -1268,6 +1380,9 @@
 				use_sideband = LARGE_PACKET_MAX;
 			if (parse_feature_request(feature_list, "quiet"))
 				quiet = 1;
+			if (advertise_atomic_push
+			    && parse_feature_request(feature_list, "atomic"))
+				use_atomic = 1;
 		}
 
 		if (!strcmp(line, "push-cert")) {
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 2d85d26..49c64f9 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -22,18 +22,13 @@
 
 struct cmd_reflog_expire_cb {
 	struct rev_info revs;
-	int dry_run;
 	int stalefix;
-	int rewrite;
-	int updateref;
-	int verbose;
 	unsigned long expire_total;
 	unsigned long expire_unreachable;
 	int recno;
 };
 
-struct expire_reflog_cb {
-	FILE *newlog;
+struct expire_reflog_policy_cb {
 	enum {
 		UE_NORMAL,
 		UE_ALWAYS,
@@ -41,14 +36,16 @@
 	} unreachable_expire_kind;
 	struct commit_list *mark_list;
 	unsigned long mark_limit;
-	struct cmd_reflog_expire_cb *cmd;
-	unsigned char last_kept_sha1[20];
+	struct cmd_reflog_expire_cb cmd;
+	struct commit *tip_commit;
+	struct commit_list *tips;
 };
 
 struct collected_reflog {
 	unsigned char sha1[20];
 	char reflog[FLEX_ARRAY];
 };
+
 struct collect_reflog_cb {
 	struct collected_reflog **e;
 	int alloc;
@@ -220,7 +217,7 @@
  * the expire_limit and queue them back, so that the caller can call
  * us again to restart the traversal with longer expire_limit.
  */
-static void mark_reachable(struct expire_reflog_cb *cb)
+static void mark_reachable(struct expire_reflog_policy_cb *cb)
 {
 	struct commit *commit;
 	struct commit_list *pending;
@@ -259,7 +256,7 @@
 	cb->mark_list = leftover;
 }
 
-static int unreachable(struct expire_reflog_cb *cb, struct commit *commit, unsigned char *sha1)
+static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit, unsigned char *sha1)
 {
 	/*
 	 * We may or may not have the commit yet - if not, look it
@@ -288,55 +285,39 @@
 	return !(commit->object.flags & REACHABLE);
 }
 
-static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
-		const char *email, unsigned long timestamp, int tz,
-		const char *message, void *cb_data)
+/*
+ * Return true iff the specified reflog entry should be expired.
+ */
+static int should_expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
+				    const char *email, unsigned long timestamp, int tz,
+				    const char *message, void *cb_data)
 {
-	struct expire_reflog_cb *cb = cb_data;
+	struct expire_reflog_policy_cb *cb = cb_data;
 	struct commit *old, *new;
 
-	if (timestamp < cb->cmd->expire_total)
-		goto prune;
-
-	if (cb->cmd->rewrite)
-		osha1 = cb->last_kept_sha1;
+	if (timestamp < cb->cmd.expire_total)
+		return 1;
 
 	old = new = NULL;
-	if (cb->cmd->stalefix &&
+	if (cb->cmd.stalefix &&
 	    (!keep_entry(&old, osha1) || !keep_entry(&new, nsha1)))
-		goto prune;
+		return 1;
 
-	if (timestamp < cb->cmd->expire_unreachable) {
+	if (timestamp < cb->cmd.expire_unreachable) {
 		if (cb->unreachable_expire_kind == UE_ALWAYS)
-			goto prune;
+			return 1;
 		if (unreachable(cb, old, osha1) || unreachable(cb, new, nsha1))
-			goto prune;
+			return 1;
 	}
 
-	if (cb->cmd->recno && --(cb->cmd->recno) == 0)
-		goto prune;
+	if (cb->cmd.recno && --(cb->cmd.recno) == 0)
+		return 1;
 
-	if (cb->newlog) {
-		char sign = (tz < 0) ? '-' : '+';
-		int zone = (tz < 0) ? (-tz) : tz;
-		fprintf(cb->newlog, "%s %s %s %lu %c%04d\t%s",
-			sha1_to_hex(osha1), sha1_to_hex(nsha1),
-			email, timestamp, sign, zone,
-			message);
-		hashcpy(cb->last_kept_sha1, nsha1);
-	}
-	if (cb->cmd->verbose)
-		printf("keep %s", message);
-	return 0;
- prune:
-	if (!cb->newlog)
-		printf("would prune %s", message);
-	else if (cb->cmd->verbose)
-		printf("prune %s", message);
 	return 0;
 }
 
-static int push_tip_to_list(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+static int push_tip_to_list(const char *refname, const unsigned char *sha1,
+			    int flags, void *cb_data)
 {
 	struct commit_list **list = cb_data;
 	struct commit *tip_commit;
@@ -349,104 +330,56 @@
 	return 0;
 }
 
-static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, void *cb_data)
+static void reflog_expiry_prepare(const char *refname,
+				  const unsigned char *sha1,
+				  void *cb_data)
 {
-	struct cmd_reflog_expire_cb *cmd = cb_data;
-	struct expire_reflog_cb cb;
-	struct ref_lock *lock;
-	char *log_file, *newlog_path = NULL;
-	struct commit *tip_commit;
-	struct commit_list *tips;
-	int status = 0;
+	struct expire_reflog_policy_cb *cb = cb_data;
 
-	memset(&cb, 0, sizeof(cb));
-
-	/*
-	 * we take the lock for the ref itself to prevent it from
-	 * getting updated.
-	 */
-	lock = lock_any_ref_for_update(ref, sha1, 0, NULL);
-	if (!lock)
-		return error("cannot lock ref '%s'", ref);
-	log_file = git_pathdup("logs/%s", ref);
-	if (!reflog_exists(ref))
-		goto finish;
-	if (!cmd->dry_run) {
-		newlog_path = git_pathdup("logs/%s.lock", ref);
-		cb.newlog = fopen(newlog_path, "w");
-	}
-
-	cb.cmd = cmd;
-
-	if (!cmd->expire_unreachable || !strcmp(ref, "HEAD")) {
-		tip_commit = NULL;
-		cb.unreachable_expire_kind = UE_HEAD;
+	if (!cb->cmd.expire_unreachable || !strcmp(refname, "HEAD")) {
+		cb->tip_commit = NULL;
+		cb->unreachable_expire_kind = UE_HEAD;
 	} else {
-		tip_commit = lookup_commit_reference_gently(sha1, 1);
-		if (!tip_commit)
-			cb.unreachable_expire_kind = UE_ALWAYS;
+		cb->tip_commit = lookup_commit_reference_gently(sha1, 1);
+		if (!cb->tip_commit)
+			cb->unreachable_expire_kind = UE_ALWAYS;
 		else
-			cb.unreachable_expire_kind = UE_NORMAL;
+			cb->unreachable_expire_kind = UE_NORMAL;
 	}
 
-	if (cmd->expire_unreachable <= cmd->expire_total)
-		cb.unreachable_expire_kind = UE_ALWAYS;
+	if (cb->cmd.expire_unreachable <= cb->cmd.expire_total)
+		cb->unreachable_expire_kind = UE_ALWAYS;
 
-	cb.mark_list = NULL;
-	tips = NULL;
-	if (cb.unreachable_expire_kind != UE_ALWAYS) {
-		if (cb.unreachable_expire_kind == UE_HEAD) {
+	cb->mark_list = NULL;
+	cb->tips = NULL;
+	if (cb->unreachable_expire_kind != UE_ALWAYS) {
+		if (cb->unreachable_expire_kind == UE_HEAD) {
 			struct commit_list *elem;
-			for_each_ref(push_tip_to_list, &tips);
-			for (elem = tips; elem; elem = elem->next)
-				commit_list_insert(elem->item, &cb.mark_list);
+			for_each_ref(push_tip_to_list, &cb->tips);
+			for (elem = cb->tips; elem; elem = elem->next)
+				commit_list_insert(elem->item, &cb->mark_list);
 		} else {
-			commit_list_insert(tip_commit, &cb.mark_list);
+			commit_list_insert(cb->tip_commit, &cb->mark_list);
 		}
-		cb.mark_limit = cmd->expire_total;
-		mark_reachable(&cb);
+		cb->mark_limit = cb->cmd.expire_total;
+		mark_reachable(cb);
 	}
+}
 
-	for_each_reflog_ent(ref, expire_reflog_ent, &cb);
+static void reflog_expiry_cleanup(void *cb_data)
+{
+	struct expire_reflog_policy_cb *cb = cb_data;
 
-	if (cb.unreachable_expire_kind != UE_ALWAYS) {
-		if (cb.unreachable_expire_kind == UE_HEAD) {
+	if (cb->unreachable_expire_kind != UE_ALWAYS) {
+		if (cb->unreachable_expire_kind == UE_HEAD) {
 			struct commit_list *elem;
-			for (elem = tips; elem; elem = elem->next)
+			for (elem = cb->tips; elem; elem = elem->next)
 				clear_commit_marks(elem->item, REACHABLE);
-			free_commit_list(tips);
+			free_commit_list(cb->tips);
 		} else {
-			clear_commit_marks(tip_commit, REACHABLE);
+			clear_commit_marks(cb->tip_commit, REACHABLE);
 		}
 	}
- finish:
-	if (cb.newlog) {
-		if (fclose(cb.newlog)) {
-			status |= error("%s: %s", strerror(errno),
-					newlog_path);
-			unlink(newlog_path);
-		} else if (cmd->updateref &&
-			(write_in_full(lock->lock_fd,
-				sha1_to_hex(cb.last_kept_sha1), 40) != 40 ||
-			 write_str_in_full(lock->lock_fd, "\n") != 1 ||
-			 close_ref(lock) < 0)) {
-			status |= error("Couldn't write %s",
-					lock->lk->filename.buf);
-			unlink(newlog_path);
-		} else if (rename(newlog_path, log_file)) {
-			status |= error("cannot rename %s to %s",
-					newlog_path, log_file);
-			unlink(newlog_path);
-		} else if (cmd->updateref && commit_ref(lock)) {
-			status |= error("Couldn't set %s", lock->ref_name);
-		} else {
-			adjust_shared_perm(log_file);
-		}
-	}
-	free(newlog_path);
-	free(log_file);
-	unlock_ref(lock);
-	return status;
 }
 
 static int collect_reflog(const char *ref, const unsigned char *sha1, int unused, void *cb_data)
@@ -590,10 +523,11 @@
 
 static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
 {
-	struct cmd_reflog_expire_cb cb;
+	struct expire_reflog_policy_cb cb;
 	unsigned long now = time(NULL);
 	int i, status, do_all;
 	int explicit_expiry = 0;
+	unsigned int flags = 0;
 
 	default_reflog_expire_unreachable = now - 30 * 24 * 3600;
 	default_reflog_expire = now - 90 * 24 * 3600;
@@ -603,33 +537,33 @@
 	do_all = status = 0;
 	memset(&cb, 0, sizeof(cb));
 
-	cb.expire_total = default_reflog_expire;
-	cb.expire_unreachable = default_reflog_expire_unreachable;
+	cb.cmd.expire_total = default_reflog_expire;
+	cb.cmd.expire_unreachable = default_reflog_expire_unreachable;
 
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 		if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
-			cb.dry_run = 1;
+			flags |= EXPIRE_REFLOGS_DRY_RUN;
 		else if (starts_with(arg, "--expire=")) {
-			if (parse_expiry_date(arg + 9, &cb.expire_total))
+			if (parse_expiry_date(arg + 9, &cb.cmd.expire_total))
 				die(_("'%s' is not a valid timestamp"), arg);
 			explicit_expiry |= EXPIRE_TOTAL;
 		}
 		else if (starts_with(arg, "--expire-unreachable=")) {
-			if (parse_expiry_date(arg + 21, &cb.expire_unreachable))
+			if (parse_expiry_date(arg + 21, &cb.cmd.expire_unreachable))
 				die(_("'%s' is not a valid timestamp"), arg);
 			explicit_expiry |= EXPIRE_UNREACH;
 		}
 		else if (!strcmp(arg, "--stale-fix"))
-			cb.stalefix = 1;
+			cb.cmd.stalefix = 1;
 		else if (!strcmp(arg, "--rewrite"))
-			cb.rewrite = 1;
+			flags |= EXPIRE_REFLOGS_REWRITE;
 		else if (!strcmp(arg, "--updateref"))
-			cb.updateref = 1;
+			flags |= EXPIRE_REFLOGS_UPDATE_REF;
 		else if (!strcmp(arg, "--all"))
 			do_all = 1;
 		else if (!strcmp(arg, "--verbose"))
-			cb.verbose = 1;
+			flags |= EXPIRE_REFLOGS_VERBOSE;
 		else if (!strcmp(arg, "--")) {
 			i++;
 			break;
@@ -645,12 +579,12 @@
 	 * even in older repository.  We cannot trust what's reachable
 	 * from reflog if the repository was pruned with older git.
 	 */
-	if (cb.stalefix) {
-		init_revisions(&cb.revs, prefix);
-		if (cb.verbose)
+	if (cb.cmd.stalefix) {
+		init_revisions(&cb.cmd.revs, prefix);
+		if (flags & EXPIRE_REFLOGS_VERBOSE)
 			printf("Marking reachable objects...");
-		mark_reachable_objects(&cb.revs, 0, 0, NULL);
-		if (cb.verbose)
+		mark_reachable_objects(&cb.cmd.revs, 0, 0, NULL);
+		if (flags & EXPIRE_REFLOGS_VERBOSE)
 			putchar('\n');
 	}
 
@@ -662,8 +596,12 @@
 		for_each_reflog(collect_reflog, &collected);
 		for (i = 0; i < collected.nr; i++) {
 			struct collected_reflog *e = collected.e[i];
-			set_reflog_expiry_param(&cb, explicit_expiry, e->reflog);
-			status |= expire_reflog(e->reflog, e->sha1, 0, &cb);
+			set_reflog_expiry_param(&cb.cmd, explicit_expiry, e->reflog);
+			status |= reflog_expire(e->reflog, e->sha1, flags,
+						reflog_expiry_prepare,
+						should_expire_reflog_ent,
+						reflog_expiry_cleanup,
+						&cb);
 			free(e);
 		}
 		free(collected.e);
@@ -676,8 +614,12 @@
 			status |= error("%s points nowhere!", argv[i]);
 			continue;
 		}
-		set_reflog_expiry_param(&cb, explicit_expiry, ref);
-		status |= expire_reflog(ref, sha1, 0, &cb);
+		set_reflog_expiry_param(&cb.cmd, explicit_expiry, ref);
+		status |= reflog_expire(ref, sha1, flags,
+					reflog_expiry_prepare,
+					should_expire_reflog_ent,
+					reflog_expiry_cleanup,
+					&cb);
 	}
 	return status;
 }
@@ -686,29 +628,30 @@
 		const char *email, unsigned long timestamp, int tz,
 		const char *message, void *cb_data)
 {
-	struct cmd_reflog_expire_cb *cb = cb_data;
-	if (!cb->expire_total || timestamp < cb->expire_total)
-		cb->recno++;
+	struct expire_reflog_policy_cb *cb = cb_data;
+	if (!cb->cmd.expire_total || timestamp < cb->cmd.expire_total)
+		cb->cmd.recno++;
 	return 0;
 }
 
 static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
 {
-	struct cmd_reflog_expire_cb cb;
+	struct expire_reflog_policy_cb cb;
 	int i, status = 0;
+	unsigned int flags = 0;
 
 	memset(&cb, 0, sizeof(cb));
 
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 		if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
-			cb.dry_run = 1;
+			flags |= EXPIRE_REFLOGS_DRY_RUN;
 		else if (!strcmp(arg, "--rewrite"))
-			cb.rewrite = 1;
+			flags |= EXPIRE_REFLOGS_REWRITE;
 		else if (!strcmp(arg, "--updateref"))
-			cb.updateref = 1;
+			flags |= EXPIRE_REFLOGS_UPDATE_REF;
 		else if (!strcmp(arg, "--verbose"))
-			cb.verbose = 1;
+			flags |= EXPIRE_REFLOGS_VERBOSE;
 		else if (!strcmp(arg, "--")) {
 			i++;
 			break;
@@ -740,15 +683,19 @@
 
 		recno = strtoul(spec + 2, &ep, 10);
 		if (*ep == '}') {
-			cb.recno = -recno;
+			cb.cmd.recno = -recno;
 			for_each_reflog_ent(ref, count_reflog_ent, &cb);
 		} else {
-			cb.expire_total = approxidate(spec + 2);
+			cb.cmd.expire_total = approxidate(spec + 2);
 			for_each_reflog_ent(ref, count_reflog_ent, &cb);
-			cb.expire_total = 0;
+			cb.cmd.expire_total = 0;
 		}
 
-		status |= expire_reflog(ref, sha1, 0, &cb);
+		status |= reflog_expire(ref, sha1, flags,
+					reflog_expiry_prepare,
+					should_expire_reflog_ent,
+					reflog_expiry_cleanup,
+					&cb);
 		free(ref);
 	}
 	return status;
diff --git a/builtin/remote.c b/builtin/remote.c
index b4ff468..5d3ab90 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -10,10 +10,10 @@
 
 static const char * const builtin_remote_usage[] = {
 	N_("git remote [-v | --verbose]"),
-	N_("git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>"),
+	N_("git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--mirror=<fetch|push>] <name> <url>"),
 	N_("git remote rename <old> <new>"),
 	N_("git remote remove <name>"),
-	N_("git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"),
+	N_("git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"),
 	N_("git remote [-v | --verbose] show [-n] <name>"),
 	N_("git remote prune [-n | --dry-run] <name>"),
 	N_("git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"),
diff --git a/builtin/repack.c b/builtin/repack.c
index 3f852f3..28fbc70 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -14,7 +14,7 @@
 static char *packdir, *packtmp;
 
 static const char *const git_repack_usage[] = {
-	N_("git repack [options]"),
+	N_("git repack [<options>]"),
 	NULL
 };
 
diff --git a/builtin/rerere.c b/builtin/rerere.c
index 98eb8c5..7afadd2 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -9,7 +9,7 @@
 #include "pathspec.h"
 
 static const char * const rerere_usage[] = {
-	N_("git rerere [clear | forget path... | status | remaining | diff | gc]"),
+	N_("git rerere [clear | forget <path>... | status | remaining | diff | gc]"),
 	NULL,
 };
 
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 95328b8..3626c61 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -358,7 +358,7 @@
 {
 	static int keep_dashdash = 0, stop_at_non_option = 0;
 	static char const * const parseopt_usage[] = {
-		N_("git rev-parse --parseopt [options] -- [<args>...]"),
+		N_("git rev-parse --parseopt [<options>] -- [<args>...]"),
 		NULL
 	};
 	static struct option parseopt_opts[] = {
@@ -496,9 +496,9 @@
 }
 
 static const char builtin_rev_parse_usage[] =
-N_("git rev-parse --parseopt [options] -- [<args>...]\n"
+N_("git rev-parse --parseopt [<options>] -- [<args>...]\n"
    "   or: git rev-parse --sq-quote [<arg>...]\n"
-   "   or: git rev-parse [options] [<arg>...]\n"
+   "   or: git rev-parse [<options>] [<arg>...]\n"
    "\n"
    "Run \"git rev-parse --parseopt -h\" for more information on the first usage.");
 
diff --git a/builtin/revert.c b/builtin/revert.c
index f9ed5bd..56a2c36 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -19,13 +19,13 @@
  */
 
 static const char * const revert_usage[] = {
-	N_("git revert [options] <commit-ish>..."),
+	N_("git revert [<options>] <commit-ish>..."),
 	N_("git revert <subcommand>"),
 	NULL
 };
 
 static const char * const cherry_pick_usage[] = {
-	N_("git cherry-pick [options] <commit-ish>..."),
+	N_("git cherry-pick [<options>] <commit-ish>..."),
 	N_("git cherry-pick <subcommand>"),
 	NULL
 };
diff --git a/builtin/rm.c b/builtin/rm.c
index d8a9c86..3304bff 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -14,7 +14,7 @@
 #include "pathspec.h"
 
 static const char * const builtin_rm_usage[] = {
-	N_("git rm [options] [--] <file>..."),
+	N_("git rm [<options>] [--] <file>..."),
 	NULL
 };
 
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index b564a77..b961e5a 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -13,7 +13,7 @@
 #include "sha1-array.h"
 
 static const char send_pack_usage[] =
-"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
+"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> [<ref>...]\n"
 "  --all and explicit <ref> specification are mutually exclusive.";
 
 static struct send_pack_args args;
@@ -170,6 +170,10 @@
 				args.use_thin_pack = 1;
 				continue;
 			}
+			if (!strcmp(arg, "--atomic")) {
+				args.atomic = 1;
+				continue;
+			}
 			if (!strcmp(arg, "--stateless-rpc")) {
 				args.stateless_rpc = 1;
 				continue;
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 4b7e536..c0bab6a 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -10,7 +10,7 @@
 #include "parse-options.h"
 
 static char const * const shortlog_usage[] = {
-	N_("git shortlog [<options>] [<revision range>] [[--] [<path>...]]"),
+	N_("git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"),
 	NULL
 };
 
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 365228a..f3fb5fb 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -6,11 +6,11 @@
 #include "parse-options.h"
 
 static const char* show_branch_usage[] = {
-    N_("git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order]\n"
+    N_("git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
        "		[--current] [--color[=<when>] | --no-color] [--sparse]\n"
        "		[--more=<n> | --list | --independent | --merge-base]\n"
        "		[--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]"),
-    N_("git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]"),
+    N_("git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]"),
     NULL
 };
 
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 5ba1f30..afb1030 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -7,7 +7,7 @@
 #include "parse-options.h"
 
 static const char * const show_ref_usage[] = {
-	N_("git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] "),
+	N_("git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]"),
 	N_("git show-ref --exclude-existing[=pattern] < ref-list"),
 	NULL
 };
diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c
index 29fb3f1..ce0fde7 100644
--- a/builtin/symbolic-ref.c
+++ b/builtin/symbolic-ref.c
@@ -4,8 +4,8 @@
 #include "parse-options.h"
 
 static const char * const git_symbolic_ref_usage[] = {
-	N_("git symbolic-ref [options] name [ref]"),
-	N_("git symbolic-ref -d [-q] name"),
+	N_("git symbolic-ref [<options>] <name> [<ref>]"),
+	N_("git symbolic-ref -d [-q] <name>"),
 	NULL
 };
 
diff --git a/builtin/tag.c b/builtin/tag.c
index e633f4e..6dc85a9 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -19,9 +19,9 @@
 #include "column.h"
 
 static const char * const git_tag_usage[] = {
-	N_("git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]"),
+	N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> [<head>]"),
 	N_("git tag -d <tagname>..."),
-	N_("git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>] "
+	N_("git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>]"
 		"\n\t\t[<pattern>...]"),
 	N_("git tag -v <tagname>..."),
 	NULL
diff --git a/builtin/update-index.c b/builtin/update-index.c
index b0e3dc9..5878986 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -400,7 +400,7 @@
 }
 
 static const char * const update_index_usage[] = {
-	N_("git update-index [options] [--] [<file>...]"),
+	N_("git update-index [<options>] [--] [<file>...]"),
 	NULL
 };
 
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 1993529..2497ba4 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -6,9 +6,9 @@
 #include "argv-array.h"
 
 static const char * const git_update_ref_usage[] = {
-	N_("git update-ref [options] -d <refname> [<oldval>]"),
-	N_("git update-ref [options]    <refname> <newval> [<oldval>]"),
-	N_("git update-ref [options] --stdin [-z]"),
+	N_("git update-ref [<options>] -d <refname> [<old-val>]"),
+	N_("git update-ref [<options>]    <refname> <new-val> [<old-val>]"),
+	N_("git update-ref [<options>] --stdin [-z]"),
 	NULL
 };
 
diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c
index b0f85042..ec0c4e3 100644
--- a/builtin/verify-commit.c
+++ b/builtin/verify-commit.c
@@ -14,7 +14,7 @@
 #include "gpg-interface.h"
 
 static const char * const verify_commit_usage[] = {
-		N_("git verify-commit [-v|--verbose] <commit>..."),
+		N_("git verify-commit [-v | --verbose] <commit>..."),
 		NULL
 };
 
diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c
index 7747537..c94e156 100644
--- a/builtin/verify-pack.c
+++ b/builtin/verify-pack.c
@@ -51,7 +51,7 @@
 }
 
 static const char * const verify_pack_usage[] = {
-	N_("git verify-pack [-v|--verbose] [-s|--stat-only] <pack>..."),
+	N_("git verify-pack [-v | --verbose] [-s | --stat-only] <pack>..."),
 	NULL
 };
 
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index 9cdf332..53c68fc 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -14,7 +14,7 @@
 #include "gpg-interface.h"
 
 static const char * const verify_tag_usage[] = {
-		N_("git verify-tag [-v|--verbose] <tag>..."),
+		N_("git verify-tag [-v | --verbose] <tag>..."),
 		NULL
 };
 
diff --git a/cache.h b/cache.h
index f704af5..4d02efc 100644
--- a/cache.h
+++ b/cache.h
@@ -1254,6 +1254,10 @@
  *
  * Any callback that is NULL will be ignored. Callbacks returning non-zero
  * will end the iteration.
+ *
+ * In the "buf" variant, "path" is a strbuf which will also be used as a
+ * scratch buffer, but restored to its original contents before
+ * the function returns.
  */
 typedef int each_loose_object_fn(const unsigned char *sha1,
 				 const char *path,
@@ -1269,6 +1273,11 @@
 				  each_loose_cruft_fn cruft_cb,
 				  each_loose_subdir_fn subdir_cb,
 				  void *data);
+int for_each_loose_file_in_objdir_buf(struct strbuf *path,
+				      each_loose_object_fn obj_cb,
+				      each_loose_cruft_fn cruft_cb,
+				      each_loose_subdir_fn subdir_cb,
+				      void *data);
 
 /*
  * Iterate over loose and packed objects in both the local
@@ -1498,7 +1507,7 @@
 extern int pager_in_use(void);
 extern int pager_use_color;
 extern int term_columns(void);
-extern int decimal_width(int);
+extern int decimal_width(uintmax_t);
 extern int check_pager_config(const char *cmd);
 
 extern const char *editor_program;
diff --git a/check-builtins.sh b/check-builtins.sh
index 07cff69..a0aaf3a 100755
--- a/check-builtins.sh
+++ b/check-builtins.sh
@@ -3,7 +3,7 @@
 {
 	cat <<\EOF
 sayIt:
-	$(foreach b,$(BUILT_INS),echo XXX $b YYY;)
+	$(foreach b,$(BUILT_INS),echo XXX $(b:$X=) YYY;)
 EOF
 	cat Makefile
 } |
diff --git a/commit.h b/commit.h
index 5cc1e7e..9f189cb 100644
--- a/commit.h
+++ b/commit.h
@@ -254,7 +254,6 @@
 extern int is_repository_shallow(void);
 extern struct commit_list *get_shallow_commits(struct object_array *heads,
 		int depth, int shallow_flag, int not_shallow_flag);
-extern void check_shallow_file_for_update(void);
 extern void set_alternate_shallow_file(const char *path, int override);
 extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
 				 const struct sha1_array *extra);
diff --git a/config.c b/config.c
index 752e2e2..66c0a51 100644
--- a/config.c
+++ b/config.c
@@ -73,8 +73,12 @@
 
 static int config_buf_ungetc(int c, struct config_source *conf)
 {
-	if (conf->u.buf.pos > 0)
-		return conf->u.buf.buf[--conf->u.buf.pos];
+	if (conf->u.buf.pos > 0) {
+		conf->u.buf.pos--;
+		if (conf->u.buf.buf[conf->u.buf.pos] != c)
+			die("BUG: config_buf can only ungetc the same character");
+		return c;
+	}
 
 	return EOF;
 }
@@ -235,7 +239,8 @@
 		/* DOS like systems */
 		c = cf->do_fgetc(cf);
 		if (c != '\n') {
-			cf->do_ungetc(c, cf);
+			if (c != EOF)
+				cf->do_ungetc(c, cf);
 			c = '\r';
 		}
 	}
@@ -1340,7 +1345,7 @@
 		string_list_init(&e->value_list, 1);
 		hashmap_add(&cs->config_hash, e);
 	}
-	si = string_list_append_nodup(&e->value_list, value ? xstrdup(value) : NULL);
+	si = string_list_append_nodup(&e->value_list, xstrdup_or_null(value));
 
 	ALLOC_GROW(cs->list.items, cs->list.nr + 1, cs->list.alloc);
 	l_item = &cs->list.items[cs->list.nr++];
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 8cfee95..c21190d 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1425,7 +1425,7 @@
 # Options that go well for log and shortlog (not gitk)
 __git_log_shortlog_options="
 	--author= --committer= --grep=
-	--all-match
+	--all-match --invert-grep
 "
 
 __git_log_pretty_formats="oneline short medium full fuller email raw format:"
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c
index a1d38f0..0061340 100644
--- a/contrib/credential/wincred/git-credential-wincred.c
+++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -111,14 +111,23 @@
  * Match an (optional) expected string and a delimiter in the target string,
  * consuming the matched text by updating the target pointer.
  */
-static int match_part(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim)
+
+static LPCWSTR wcsstr_last(LPCWSTR str, LPCWSTR find)
+{
+	LPCWSTR res = NULL, pos;
+	for (pos = wcsstr(str, find); pos; pos = wcsstr(pos + 1, find))
+		res = pos;
+	return res;
+}
+
+static int match_part_with_last(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim, int last)
 {
 	LPCWSTR delim_pos, start = *ptarget;
 	int len;
 
 	/* find start of delimiter (or end-of-string if delim is empty) */
 	if (*delim)
-		delim_pos = wcsstr(start, delim);
+		delim_pos = last ? wcsstr_last(start, delim) : wcsstr(start, delim);
 	else
 		delim_pos = start + wcslen(start);
 
@@ -138,6 +147,16 @@
 	return !want || (!wcsncmp(want, start, len) && !want[len]);
 }
 
+static int match_part(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim)
+{
+	return match_part_with_last(ptarget, want, delim, 0);
+}
+
+static int match_part_last(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim)
+{
+	return match_part_with_last(ptarget, want, delim, 1);
+}
+
 static int match_cred(const CREDENTIALW *cred)
 {
 	LPCWSTR target = cred->TargetName;
@@ -146,7 +165,7 @@
 
 	return match_part(&target, L"git", L":") &&
 		match_part(&target, protocol, L"://") &&
-		match_part(&target, wusername, L"@") &&
+		match_part_last(&target, wusername, L"@") &&
 		match_part(&target, host, L"/") &&
 		match_part(&target, path, L"");
 }
diff --git a/credential-store.c b/credential-store.c
index d435514..925d3f4 100644
--- a/credential-store.c
+++ b/credential-store.c
@@ -118,7 +118,7 @@
 int main(int argc, char **argv)
 {
 	const char * const usage[] = {
-		"git credential-store [options] <action>",
+		"git credential-store [<options>] <action>",
 		NULL
 	};
 	const char *op;
diff --git a/diff-lib.c b/diff-lib.c
index 875aff8..a85c497 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -101,6 +101,7 @@
 		struct cache_entry *ce = active_cache[i];
 		int changed;
 		unsigned dirty_submodule = 0;
+		const unsigned char *old_sha1, *new_sha1;
 
 		if (diff_can_quit_early(&revs->diffopt))
 			break;
@@ -224,9 +225,12 @@
 				continue;
 		}
 		oldmode = ce->ce_mode;
+		old_sha1 = ce->sha1;
+		new_sha1 = changed ? null_sha1 : ce->sha1;
 		diff_change(&revs->diffopt, oldmode, newmode,
-			    ce->sha1, (changed ? null_sha1 : ce->sha1),
-			    !is_null_sha1(ce->sha1), (changed ? 0 : !is_null_sha1(ce->sha1)),
+			    old_sha1, new_sha1,
+			    !is_null_sha1(old_sha1),
+			    !is_null_sha1(new_sha1),
 			    ce->name, 0, dirty_submodule);
 
 	}
diff --git a/ewah/ewok.h b/ewah/ewok.h
index f6ad190..13c6e20 100644
--- a/ewah/ewok.h
+++ b/ewah/ewok.h
@@ -47,7 +47,8 @@
 	return (x * 0x0101010101010101ULL) >> 56;
 }
 
-#ifdef __GNUC__
+/* __builtin_ctzll was not available until 3.4.0 */
+#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3  && __GNUC_MINOR > 3))
 #define ewah_bit_ctz64(x) __builtin_ctzll(x)
 #else
 static inline int ewah_bit_ctz64(uint64_t x)
diff --git a/fast-import.c b/fast-import.c
index d0bd285..aac2c24 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -947,9 +947,12 @@
 
 static void end_packfile(void)
 {
-	if (!pack_data)
+	static int running;
+
+	if (running || !pack_data)
 		return;
 
+	running = 1;
 	clear_delta_base_cache();
 	if (object_count) {
 		struct packed_git *new_p;
@@ -999,6 +1002,7 @@
 	}
 	free(pack_data);
 	pack_data = NULL;
+	running = 0;
 
 	/* We can't carry a delta across packfiles. */
 	strbuf_release(&last_blob.data);
diff --git a/gettext.h b/gettext.h
index 7671d09..dc1722d 100644
--- a/gettext.h
+++ b/gettext.h
@@ -63,6 +63,30 @@
 }
 
 /* Mark msgid for translation but do not translate it. */
+#if !USE_PARENS_AROUND_GETTEXT_N
 #define N_(msgid) msgid
+#else
+/*
+ * Strictly speaking, this will lead to invalid C when
+ * used this way:
+ *	static const char s[] = N_("FOO");
+ * which will expand to
+ *	static const char s[] = ("FOO");
+ * and in valid C, the initializer on the right hand side must
+ * be without the parentheses.  But many compilers do accept it
+ * as a language extension and it will allow us to catch mistakes
+ * like:
+ *	static const char *msgs[] = {
+ *		N_("one")
+ *		N_("two"),
+ *		N_("three"),
+ *		NULL
+ *	};
+ * (notice the missing comma on one of the lines) by forcing
+ * a compilation error, because parenthesised ("one") ("two")
+ * will not get silently turned into ("onetwo").
+ */
+#define N_(msgid) (msgid)
+#endif
 
 #endif
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index c725674..77876d4 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -515,6 +515,9 @@
 sub list_and_choose {
 	my ($opts, @stuff) = @_;
 	my (@chosen, @return);
+	if (!@stuff) {
+	    return @return;
+	}
 	my $i;
 	my @prefixes = find_unique_prefixes(@stuff) unless $opts->{LIST_ONLY};
 
@@ -725,6 +728,8 @@
 	if (@add) {
 		system(qw(git update-index --add --), @add);
 		say_n_paths('added', @add);
+	} else {
+		print "No untracked files.\n";
 	}
 	print "\n";
 }
diff --git a/git-bisect.sh b/git-bisect.sh
index 2fc07ac..ae3fec2 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -127,7 +127,7 @@
 		if test "z$mode" != "z--no-checkout"
 		then
 			git checkout "$start_head" -- ||
-			die "$(eval_gettext "Checking out '\$start_head' failed. Try 'git bisect reset <validbranch>'.")"
+			die "$(eval_gettext "Checking out '\$start_head' failed. Try 'git bisect reset <valid-branch>'.")"
 		fi
 	else
 		# Get rev from where we start.
diff --git a/git-compat-util.h b/git-compat-util.h
index eb9b0ff..3455c5e 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -212,12 +212,15 @@
 #endif
 
 #ifndef NO_OPENSSL
+#ifdef __APPLE__
 #define __AVAILABILITY_MACROS_USES_AVAILABILITY 0
-#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
+#include <AvailabilityMacros.h>
+#undef DEPRECATED_ATTRIBUTE
+#define DEPRECATED_ATTRIBUTE
+#undef __AVAILABILITY_MACROS_USES_AVAILABILITY
+#endif
 #include <openssl/ssl.h>
 #include <openssl/err.h>
-#undef MAC_OS_X_VERSION_MIN_REQUIRED
-#undef __AVAILABILITY_MACROS_USES_AVAILABILITY
 #ifdef NO_HMAC_CTX_CLEANUP
 #define HMAC_CTX_cleanup HMAC_cleanup
 #endif
@@ -678,6 +681,11 @@
 
 #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))
 
+static inline char *xstrdup_or_null(const char *str)
+{
+	return str ? xstrdup(str) : NULL;
+}
+
 static inline size_t xsize_t(off_t len)
 {
 	if (len > (size_t) len)
@@ -870,4 +878,8 @@
 #define gmtime_r git_gmtime_r
 #endif
 
+#if !defined(USE_PARENS_AROUND_GETTEXT_N) && defined(__GNUC__)
+#define USE_PARENS_AROUND_GETTEXT_N 1
+#endif
+
 #endif
diff --git a/git-p4.py b/git-p4.py
index ff132b2..549022e 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -1442,7 +1442,7 @@
             print "  " + self.clientPath
             print
             print "To submit, use \"p4 submit\" to write a new description,"
-            print "or \"p4 submit -i %s\" to use the one prepared by" \
+            print "or \"p4 submit -i <%s\" to use the one prepared by" \
                   " \"git p4\"." % fileName
             print "You can delete the file \"%s\" when finished." % fileName
 
@@ -1915,7 +1915,10 @@
                 optparse.make_option("--keep-path", dest="keepRepoPath", action='store_true',
                                      help="Keep entire BRANCH/DIR/SUBDIR prefix during import"),
                 optparse.make_option("--use-client-spec", dest="useClientSpec", action='store_true',
-                                     help="Only sync files that are included in the Perforce Client Spec")
+                                     help="Only sync files that are included in the Perforce Client Spec"),
+                optparse.make_option("-/", dest="cloneExclude",
+                                     action="append", type="string",
+                                     help="exclude depot path"),
         ]
         self.description = """Imports from Perforce into a git repository.\n
     example:
@@ -1950,6 +1953,12 @@
         if gitConfig("git-p4.syncFromOrigin") == "false":
             self.syncWithOrigin = False
 
+    # This is required for the "append" cloneExclude action
+    def ensure_value(self, attr, value):
+        if not hasattr(self, attr) or getattr(self, attr) is None:
+            setattr(self, attr, value)
+        return getattr(self, attr)
+
     # Force a checkpoint in fast-import and wait for it to finish
     def checkpoint(self):
         self.gitStream.write("checkpoint\n\n")
@@ -3101,9 +3110,6 @@
             optparse.make_option("--destination", dest="cloneDestination",
                                  action='store', default=None,
                                  help="where to leave result of the clone"),
-            optparse.make_option("-/", dest="cloneExclude",
-                                 action="append", type="string",
-                                 help="exclude depot path"),
             optparse.make_option("--bare", dest="cloneBare",
                                  action="store_true", default=False),
         ]
@@ -3111,12 +3117,6 @@
         self.needsGit = False
         self.cloneBare = False
 
-    # This is required for the "append" cloneExclude action
-    def ensure_value(self, attr, value):
-        if not hasattr(self, attr) or getattr(self, attr) is None:
-            setattr(self, attr, value)
-        return getattr(self, attr)
-
     def defaultDestination(self, args):
         ## TODO: use common prefix of args?
         depotPath = args[0]
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index c6a4629..c96b984 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -961,14 +961,13 @@
 	revisions=$onto...$orig_head
 	shortrevisions=$shorthead
 fi
-git rev-list $merges_option --pretty=oneline --abbrev-commit \
-	--abbrev=7 --reverse --left-right --topo-order \
+git rev-list $merges_option --pretty=oneline --reverse --left-right --topo-order \
 	$revisions ${restrict_revision+^$restrict_revision} | \
 	sed -n "s/^>//p" |
-while read -r shortsha1 rest
+while read -r sha1 rest
 do
 
-	if test -z "$keep_empty" && is_empty_commit $shortsha1 && ! is_merge_commit $shortsha1
+	if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
 	then
 		comment_out="$comment_char "
 	else
@@ -977,9 +976,8 @@
 
 	if test t != "$preserve_merges"
 	then
-		printf '%s\n' "${comment_out}pick $shortsha1 $rest" >>"$todo"
+		printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
 	else
-		sha1=$(git rev-parse $shortsha1)
 		if test -z "$rebase_root"
 		then
 			preserve=t
@@ -996,7 +994,7 @@
 		if test f = "$preserve"
 		then
 			touch "$rewritten"/$sha1
-			printf '%s\n' "${comment_out}pick $shortsha1 $rest" >>"$todo"
+			printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
 		fi
 	fi
 done
@@ -1020,8 +1018,8 @@
 			# just the history of its first-parent for others that will
 			# be rebasing on top of it
 			git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$dropped"/$rev
-			short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
-			sane_grep -v "^[a-z][a-z]* $short" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
+			sha1=$(git rev-list -1 $rev)
+			sane_grep -v "^[a-z][a-z]* $sha1" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
 			rm "$rewritten"/$rev
 		fi
 	done
@@ -1054,6 +1052,7 @@
 	return 2
 
 cp "$todo" "$todo".backup
+collapse_todo_ids
 git_sequence_editor "$todo" ||
 	die_abort "Could not execute editor"
 
diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh
index a9c75a2..752c763 100755
--- a/git-remote-testgit.sh
+++ b/git-remote-testgit.sh
@@ -1,7 +1,13 @@
 #!/bin/sh
 # Copyright (c) 2012 Felipe Contreras
 
-alias=$1
+# The first argument can be a url when the fetch/push command was a url
+# instead of a configured remote. In this case, use a generic alias.
+if test "$1" = "testgit::$2"; then
+	alias=_
+else
+	alias=$1
+fi
 url=$2
 
 dir="$GIT_DIR/testgit/$alias"
diff --git a/git-send-email.perl b/git-send-email.perl
index 3092ab3..848f176 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -752,6 +752,7 @@
 		print "    $f\n";
 	}
 	$auto_8bit_encoding = ask("Which 8bit encoding should I declare [UTF-8]? ",
+				  valid_re => qr/.{4}/, confirm_only => 1,
 				  default => "UTF-8");
 }
 
diff --git a/git-submodule.sh b/git-submodule.sh
index 9245abf..36797c3 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -423,7 +423,7 @@
 		sed -e '
 			s|//*|/|g
 			s|^\(\./\)*||
-			s|/\./|/|g
+			s|/\(\./\)*|/|g
 			:start
 			s|\([^/]*\)/\.\./||
 			tstart
diff --git a/git.c b/git.c
index 6b5ae6a..8c7ee9c 100644
--- a/git.c
+++ b/git.c
@@ -6,7 +6,7 @@
 const char git_usage_string[] =
 	"git [--version] [--help] [-C <path>] [-c name=value]\n"
 	"           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-	"           [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n"
+	"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
 	"           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 	"           <command> [<args>]";
 
diff --git a/grep.c b/grep.c
index 6e085f8..b58c7c6 100644
--- a/grep.c
+++ b/grep.c
@@ -1661,8 +1661,8 @@
 		      const void *identifier)
 {
 	gs->type = type;
-	gs->name = name ? xstrdup(name) : NULL;
-	gs->path = path ? xstrdup(path) : NULL;
+	gs->name = xstrdup_or_null(name);
+	gs->path = xstrdup_or_null(path);
 	gs->buf = NULL;
 	gs->size = 0;
 	gs->driver = NULL;
diff --git a/hex.c b/hex.c
index 9ebc050..cfd9d72 100644
--- a/hex.c
+++ b/hex.c
@@ -59,7 +59,7 @@
 char *sha1_to_hex(const unsigned char *sha1)
 {
 	static int bufno;
-	static char hexbuffer[4][50];
+	static char hexbuffer[4][41];
 	static const char hex[] = "0123456789abcdef";
 	char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
 	int i;
diff --git a/http.c b/http.c
index 040f362..0153fb0 100644
--- a/http.c
+++ b/http.c
@@ -62,12 +62,17 @@
 
 static struct credential cert_auth = CREDENTIAL_INIT;
 static int ssl_cert_password_required;
+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
+static unsigned long http_auth_methods = CURLAUTH_ANY;
+#endif
 
 static struct curl_slist *pragma_header;
 static struct curl_slist *no_pragma_header;
 
 static struct active_request_slot *active_queue_head;
 
+static char *cached_accept_language;
+
 size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
 {
 	size_t size = eltsize * nmemb;
@@ -114,6 +119,37 @@
 	return eltsize * nmemb;
 }
 
+static void closedown_active_slot(struct active_request_slot *slot)
+{
+	active_requests--;
+	slot->in_use = 0;
+}
+
+static void finish_active_slot(struct active_request_slot *slot)
+{
+	closedown_active_slot(slot);
+	curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);
+
+	if (slot->finished != NULL)
+		(*slot->finished) = 1;
+
+	/* Store slot results so they can be read after the slot is reused */
+	if (slot->results != NULL) {
+		slot->results->curl_result = slot->curl_result;
+		slot->results->http_code = slot->http_code;
+#if LIBCURL_VERSION_NUM >= 0x070a08
+		curl_easy_getinfo(slot->curl, CURLINFO_HTTPAUTH_AVAIL,
+				  &slot->results->auth_avail);
+#else
+		slot->results->auth_avail = 0;
+#endif
+	}
+
+	/* Run callback if appropriate */
+	if (slot->callback_func != NULL)
+		slot->callback_func(slot->callback_data);
+}
+
 #ifdef USE_CURL_MULTI
 static void process_curl_messages(void)
 {
@@ -369,7 +405,9 @@
 
 	if (curl_http_proxy) {
 		curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
+#if LIBCURL_VERSION_NUM >= 0x070a07
 		curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+#endif
 	}
 
 	set_curl_keepalive(result);
@@ -515,6 +553,9 @@
 		cert_auth.password = NULL;
 	}
 	ssl_cert_password_required = 0;
+
+	free(cached_accept_language);
+	cached_accept_language = NULL;
 }
 
 struct active_request_slot *get_active_slot(void)
@@ -580,6 +621,9 @@
 	curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
+	curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
+#endif
 	if (http_auth.password)
 		init_curl_http_auth(slot->curl);
 
@@ -730,12 +774,6 @@
 #endif
 }
 
-static void closedown_active_slot(struct active_request_slot *slot)
-{
-	active_requests--;
-	slot->in_use = 0;
-}
-
 static void release_active_slot(struct active_request_slot *slot)
 {
 	closedown_active_slot(slot);
@@ -752,31 +790,6 @@
 #endif
 }
 
-void finish_active_slot(struct active_request_slot *slot)
-{
-	closedown_active_slot(slot);
-	curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);
-
-	if (slot->finished != NULL)
-		(*slot->finished) = 1;
-
-	/* Store slot results so they can be read after the slot is reused */
-	if (slot->results != NULL) {
-		slot->results->curl_result = slot->curl_result;
-		slot->results->http_code = slot->http_code;
-#if LIBCURL_VERSION_NUM >= 0x070a08
-		curl_easy_getinfo(slot->curl, CURLINFO_HTTPAUTH_AVAIL,
-				  &slot->results->auth_avail);
-#else
-		slot->results->auth_avail = 0;
-#endif
-	}
-
-	/* Run callback if appropriate */
-	if (slot->callback_func != NULL)
-		slot->callback_func(slot->callback_data);
-}
-
 void finish_all_active_slots(void)
 {
 	struct active_request_slot *slot = active_queue_head;
@@ -839,7 +852,7 @@
 	return strbuf_detach(&buf, NULL);
 }
 
-int handle_curl_result(struct slot_results *results)
+static int handle_curl_result(struct slot_results *results)
 {
 	/*
 	 * If we see a failing http code with CURLE_OK, we have turned off
@@ -870,6 +883,9 @@
 			credential_reject(&http_auth);
 			return HTTP_NOAUTH;
 		} else {
+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
+			http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE;
+#endif
 			return HTTP_REAUTH;
 		}
 	} else {
@@ -986,6 +1002,143 @@
 		strbuf_addstr(charset, "ISO-8859-1");
 }
 
+
+/*
+ * Guess the user's preferred languages from the value in LANGUAGE environment
+ * variable and LC_MESSAGES locale category if NO_GETTEXT is not defined.
+ *
+ * The result can be a colon-separated list like "ko:ja:en".
+ */
+static const char *get_preferred_languages(void)
+{
+	const char *retval;
+
+	retval = getenv("LANGUAGE");
+	if (retval && *retval)
+		return retval;
+
+#ifndef NO_GETTEXT
+	retval = setlocale(LC_MESSAGES, NULL);
+	if (retval && *retval &&
+		strcmp(retval, "C") &&
+		strcmp(retval, "POSIX"))
+		return retval;
+#endif
+
+	return NULL;
+}
+
+static void write_accept_language(struct strbuf *buf)
+{
+	/*
+	 * MAX_DECIMAL_PLACES must not be larger than 3. If it is larger than
+	 * that, q-value will be smaller than 0.001, the minimum q-value the
+	 * HTTP specification allows. See
+	 * http://tools.ietf.org/html/rfc7231#section-5.3.1 for q-value.
+	 */
+	const int MAX_DECIMAL_PLACES = 3;
+	const int MAX_LANGUAGE_TAGS = 1000;
+	const int MAX_ACCEPT_LANGUAGE_HEADER_SIZE = 4000;
+	char **language_tags = NULL;
+	int num_langs = 0;
+	const char *s = get_preferred_languages();
+	int i;
+	struct strbuf tag = STRBUF_INIT;
+
+	/* Don't add Accept-Language header if no language is preferred. */
+	if (!s)
+		return;
+
+	/*
+	 * Split the colon-separated string of preferred languages into
+	 * language_tags array.
+	 */
+	do {
+		/* collect language tag */
+		for (; *s && (isalnum(*s) || *s == '_'); s++)
+			strbuf_addch(&tag, *s == '_' ? '-' : *s);
+
+		/* skip .codeset, @modifier and any other unnecessary parts */
+		while (*s && *s != ':')
+			s++;
+
+		if (tag.len) {
+			num_langs++;
+			REALLOC_ARRAY(language_tags, num_langs);
+			language_tags[num_langs - 1] = strbuf_detach(&tag, NULL);
+			if (num_langs >= MAX_LANGUAGE_TAGS - 1) /* -1 for '*' */
+				break;
+		}
+	} while (*s++);
+
+	/* write Accept-Language header into buf */
+	if (num_langs) {
+		int last_buf_len = 0;
+		int max_q;
+		int decimal_places;
+		char q_format[32];
+
+		/* add '*' */
+		REALLOC_ARRAY(language_tags, num_langs + 1);
+		language_tags[num_langs++] = "*"; /* it's OK; this won't be freed */
+
+		/* compute decimal_places */
+		for (max_q = 1, decimal_places = 0;
+		     max_q < num_langs && decimal_places <= MAX_DECIMAL_PLACES;
+		     decimal_places++, max_q *= 10)
+			;
+
+		sprintf(q_format, ";q=0.%%0%dd", decimal_places);
+
+		strbuf_addstr(buf, "Accept-Language: ");
+
+		for (i = 0; i < num_langs; i++) {
+			if (i > 0)
+				strbuf_addstr(buf, ", ");
+
+			strbuf_addstr(buf, language_tags[i]);
+
+			if (i > 0)
+				strbuf_addf(buf, q_format, max_q - i);
+
+			if (buf->len > MAX_ACCEPT_LANGUAGE_HEADER_SIZE) {
+				strbuf_remove(buf, last_buf_len, buf->len - last_buf_len);
+				break;
+			}
+
+			last_buf_len = buf->len;
+		}
+	}
+
+	/* free language tags -- last one is a static '*' */
+	for (i = 0; i < num_langs - 1; i++)
+		free(language_tags[i]);
+	free(language_tags);
+}
+
+/*
+ * Get an Accept-Language header which indicates user's preferred languages.
+ *
+ * Examples:
+ *   LANGUAGE= -> ""
+ *   LANGUAGE=ko:en -> "Accept-Language: ko, en; q=0.9, *; q=0.1"
+ *   LANGUAGE=ko_KR.UTF-8:sr@latin -> "Accept-Language: ko-KR, sr; q=0.9, *; q=0.1"
+ *   LANGUAGE=ko LANG=en_US.UTF-8 -> "Accept-Language: ko, *; q=0.1"
+ *   LANGUAGE= LANG=en_US.UTF-8 -> "Accept-Language: en-US, *; q=0.1"
+ *   LANGUAGE= LANG=C -> ""
+ */
+static const char *get_accept_language(void)
+{
+	if (!cached_accept_language) {
+		struct strbuf buf = STRBUF_INIT;
+		write_accept_language(&buf);
+		if (buf.len > 0)
+			cached_accept_language = strbuf_detach(&buf, NULL);
+	}
+
+	return cached_accept_language;
+}
+
 /* http_request() targets */
 #define HTTP_REQUEST_STRBUF	0
 #define HTTP_REQUEST_FILE	1
@@ -998,6 +1151,7 @@
 	struct slot_results results;
 	struct curl_slist *headers = NULL;
 	struct strbuf buf = STRBUF_INIT;
+	const char *accept_language;
 	int ret;
 
 	slot = get_active_slot();
@@ -1023,6 +1177,11 @@
 					 fwrite_buffer);
 	}
 
+	accept_language = get_accept_language();
+
+	if (accept_language)
+		headers = curl_slist_append(headers, accept_language);
+
 	strbuf_addstr(&buf, "Pragma:");
 	if (options && options->no_cache)
 		strbuf_addstr(&buf, " no-cache");
@@ -1240,7 +1399,7 @@
 	int ret;
 
 	if (has_pack_index(sha1)) {
-		new_pack = parse_pack_index(sha1, NULL);
+		new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1));
 		if (!new_pack)
 			return -1; /* parse_pack_index() already issued error message */
 		goto add_pack;
diff --git a/http.h b/http.h
index 473179b..49afe39 100644
--- a/http.h
+++ b/http.h
@@ -85,9 +85,7 @@
 extern struct active_request_slot *get_active_slot(void);
 extern int start_active_slot(struct active_request_slot *slot);
 extern void run_active_slot(struct active_request_slot *slot);
-extern void finish_active_slot(struct active_request_slot *slot);
 extern void finish_all_active_slots(void);
-extern int handle_curl_result(struct slot_results *results);
 
 /*
  * This will run one slot to completion in a blocking manner, similar to how
diff --git a/line-log.c b/line-log.c
index b7864ad..a490efe 100644
--- a/line-log.c
+++ b/line-log.c
@@ -237,7 +237,7 @@
 	range_set_release(&diff->target);
 }
 
-void line_log_data_init(struct line_log_data *r)
+static void line_log_data_init(struct line_log_data *r)
 {
 	memset(r, 0, sizeof(struct line_log_data));
 	range_set_init(&r->ranges, 0);
diff --git a/line-log.h b/line-log.h
index a9212d8..7a5c24e 100644
--- a/line-log.h
+++ b/line-log.h
@@ -54,8 +54,6 @@
 	struct diff_ranges diff;
 };
 
-extern void line_log_data_init(struct line_log_data *r);
-
 extern void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args);
 
 extern int line_log_filter(struct rev_info *rev);
diff --git a/notes.c b/notes.c
index c763a21..2be4d7f 100644
--- a/notes.c
+++ b/notes.c
@@ -1006,7 +1006,7 @@
 	t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node));
 	t->first_non_note = NULL;
 	t->prev_non_note = NULL;
-	t->ref = notes_ref ? xstrdup(notes_ref) : NULL;
+	t->ref = xstrdup_or_null(notes_ref);
 	t->combine_notes = combine_notes;
 	t->initialized = 1;
 	t->dirty = 0;
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 6a81841..365f9d9 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -60,7 +60,7 @@
 	struct ewah_bitmap *blobs;
 	struct ewah_bitmap *tags;
 
-	/* Map from SHA1 -> `stored_bitmap` for all the bitmapped comits */
+	/* Map from SHA1 -> `stored_bitmap` for all the bitmapped commits */
 	khash_sha1 *bitmaps;
 
 	/* Number of bitmapped commits */
@@ -252,6 +252,20 @@
 	return 0;
 }
 
+static char *pack_bitmap_filename(struct packed_git *p)
+{
+	char *idx_name;
+	int len;
+
+	len = strlen(p->pack_name) - strlen(".pack");
+	idx_name = xmalloc(len + strlen(".bitmap") + 1);
+
+	memcpy(idx_name, p->pack_name, len);
+	memcpy(idx_name + len, ".bitmap", strlen(".bitmap") + 1);
+
+	return idx_name;
+}
+
 static int open_pack_bitmap_1(struct packed_git *packfile)
 {
 	int fd;
@@ -322,20 +336,6 @@
 	return -1;
 }
 
-char *pack_bitmap_filename(struct packed_git *p)
-{
-	char *idx_name;
-	int len;
-
-	len = strlen(p->pack_name) - strlen(".pack");
-	idx_name = xmalloc(len + strlen(".bitmap") + 1);
-
-	memcpy(idx_name, p->pack_name, len);
-	memcpy(idx_name + len, ".bitmap", strlen(".bitmap") + 1);
-
-	return idx_name;
-}
-
 static int open_pack_bitmap(void)
 {
 	struct packed_git *p;
diff --git a/pack-bitmap.h b/pack-bitmap.h
index 487600b..0adcef7 100644
--- a/pack-bitmap.h
+++ b/pack-bitmap.h
@@ -38,7 +38,6 @@
 void count_bitmap_commit_list(uint32_t *commits, uint32_t *trees, uint32_t *blobs, uint32_t *tags);
 void traverse_bitmap_commit_list(show_reachable_fn show_reachable);
 void test_bitmap_walk(struct rev_info *revs);
-char *pack_bitmap_filename(struct packed_git *p);
 int prepare_bitmap_walk(struct rev_info *revs);
 int reuse_partial_packfile_from_bitmap(struct packed_git **packfile, uint32_t *entries, off_t *up_to);
 int rebuild_existing_bitmaps(struct packing_data *mapping, khash_sha1 *reused_bitmaps, int show_progress);
diff --git a/pager.c b/pager.c
index f6e8c33..98b2682 100644
--- a/pager.c
+++ b/pager.c
@@ -133,12 +133,12 @@
 /*
  * How many columns do we need to show this number in decimal?
  */
-int decimal_width(int number)
+int decimal_width(uintmax_t number)
 {
-	int i, width;
+	int width;
 
-	for (width = 1, i = 10; i <= number; width++)
-		i *= 10;
+	for (width = 1; number >= 10; width++)
+		number /= 10;
 	return width;
 }
 
diff --git a/prompt.c b/prompt.c
index 8181eeb..7540639 100644
--- a/prompt.c
+++ b/prompt.c
@@ -73,8 +73,3 @@
 	}
 	return r;
 }
-
-char *git_getpass(const char *prompt)
-{
-	return git_prompt(prompt, PROMPT_ASKPASS);
-}
diff --git a/prompt.h b/prompt.h
index 04f321a..e04cced 100644
--- a/prompt.h
+++ b/prompt.h
@@ -5,6 +5,5 @@
 #define PROMPT_ECHO    (1<<1)
 
 char *git_prompt(const char *prompt, int flags);
-char *git_getpass(const char *prompt);
 
 #endif /* PROMPT_H */
diff --git a/read-cache.c b/read-cache.c
index 9cff715..8d71860 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -725,7 +725,7 @@
 		unsigned int refresh_options)
 {
 	int size, len;
-	struct cache_entry *ce;
+	struct cache_entry *ce, *ret;
 
 	if (!verify_path(path)) {
 		error("Invalid path '%s'", path);
@@ -742,7 +742,13 @@
 	ce->ce_namelen = len;
 	ce->ce_mode = create_ce_mode(mode);
 
-	return refresh_cache_entry(ce, refresh_options);
+	ret = refresh_cache_entry(ce, refresh_options);
+	if (!ret) {
+		free(ce);
+		return NULL;
+	} else {
+		return ret;
+	}
 }
 
 int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)
diff --git a/refs.c b/refs.c
index ed3b2cb..ab2f2a9 100644
--- a/refs.c
+++ b/refs.c
@@ -6,6 +6,15 @@
 #include "dir.h"
 #include "string-list.h"
 
+struct ref_lock {
+	char *ref_name;
+	char *orig_ref_name;
+	struct lock_file *lk;
+	unsigned char old_sha1[20];
+	int lock_fd;
+	int force_write;
+};
+
 /*
  * How to handle various characters in refnames:
  * 0: An acceptable character for refs
@@ -1618,8 +1627,7 @@
 
 char *resolve_refdup(const char *ref, int resolve_flags, unsigned char *sha1, int *flags)
 {
-	const char *ret = resolve_ref_unsafe(ref, resolve_flags, sha1, flags);
-	return ret ? xstrdup(ret) : NULL;
+	return xstrdup_or_null(resolve_ref_unsafe(ref, resolve_flags, sha1, flags));
 }
 
 /* The argument to filter_refs */
@@ -2094,6 +2102,16 @@
 	return 0;
 }
 
+static void unlock_ref(struct ref_lock *lock)
+{
+	/* Do not free lock->lk -- atexit() still looks at them */
+	if (lock->lk)
+		rollback_lock_file(lock->lk);
+	free(lock->ref_name);
+	free(lock->orig_ref_name);
+	free(lock);
+}
+
 /* This function should make sure errno is meaningful on error */
 static struct ref_lock *verify_lock(struct ref_lock *lock,
 	const unsigned char *old_sha1, int mustexist)
@@ -2346,13 +2364,6 @@
 	return NULL;
 }
 
-struct ref_lock *lock_any_ref_for_update(const char *refname,
-					 const unsigned char *old_sha1,
-					 int flags, int *type_p)
-{
-	return lock_ref_sha1_basic(refname, old_sha1, NULL, flags, type_p);
-}
-
 /*
  * Write an entry to the packed-refs file for the specified refname.
  * If peeled is non-NULL, write it as the entry's peeled value.
@@ -2901,7 +2912,7 @@
 	return 1;
 }
 
-int close_ref(struct ref_lock *lock)
+static int close_ref(struct ref_lock *lock)
 {
 	if (close_lock_file(lock->lk))
 		return -1;
@@ -2909,7 +2920,7 @@
 	return 0;
 }
 
-int commit_ref(struct ref_lock *lock)
+static int commit_ref(struct ref_lock *lock)
 {
 	if (commit_lock_file(lock->lk))
 		return -1;
@@ -2917,16 +2928,6 @@
 	return 0;
 }
 
-void unlock_ref(struct ref_lock *lock)
-{
-	/* Do not free lock->lk -- atexit() still looks at them */
-	if (lock->lk)
-		rollback_lock_file(lock->lk);
-	free(lock->ref_name);
-	free(lock->orig_ref_name);
-	free(lock);
-}
-
 /*
  * copy the reflog message msg to buf, which has been allocated sufficiently
  * large, while cleaning up the whitespaces.  Especially, convert LF to space,
@@ -3003,15 +3004,37 @@
 	return 0;
 }
 
+static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
+			    const unsigned char *new_sha1,
+			    const char *committer, const char *msg)
+{
+	int msglen, written;
+	unsigned maxlen, len;
+	char *logrec;
+
+	msglen = msg ? strlen(msg) : 0;
+	maxlen = strlen(committer) + msglen + 100;
+	logrec = xmalloc(maxlen);
+	len = sprintf(logrec, "%s %s %s\n",
+		      sha1_to_hex(old_sha1),
+		      sha1_to_hex(new_sha1),
+		      committer);
+	if (msglen)
+		len += copy_msg(logrec + len - 1, msg) - 1;
+
+	written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
+	free(logrec);
+	if (written != len)
+		return -1;
+
+	return 0;
+}
+
 static int log_ref_write(const char *refname, const unsigned char *old_sha1,
 			 const unsigned char *new_sha1, const char *msg)
 {
-	int logfd, result, written, oflags = O_APPEND | O_WRONLY;
-	unsigned maxlen, len;
-	int msglen;
+	int logfd, result, oflags = O_APPEND | O_WRONLY;
 	char log_file[PATH_MAX];
-	char *logrec;
-	const char *committer;
 
 	if (log_all_ref_updates < 0)
 		log_all_ref_updates = !is_bare_repository();
@@ -3023,19 +3046,9 @@
 	logfd = open(log_file, oflags);
 	if (logfd < 0)
 		return 0;
-	msglen = msg ? strlen(msg) : 0;
-	committer = git_committer_info(0);
-	maxlen = strlen(committer) + msglen + 100;
-	logrec = xmalloc(maxlen);
-	len = sprintf(logrec, "%s %s %s\n",
-		      sha1_to_hex(old_sha1),
-		      sha1_to_hex(new_sha1),
-		      committer);
-	if (msglen)
-		len += copy_msg(logrec + len - 1, msg) - 1;
-	written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
-	free(logrec);
-	if (written != len) {
+	result = log_ref_write_fd(logfd, old_sha1, new_sha1,
+				  git_committer_info(0), msg);
+	if (result) {
 		int save_errno = errno;
 		close(logfd);
 		error("Unable to append to %s", log_file);
@@ -3661,31 +3674,8 @@
 			   int flags, const char *msg,
 			   struct strbuf *err)
 {
-	struct ref_update *update;
-
-	assert(err);
-
-	if (transaction->state != REF_TRANSACTION_OPEN)
-		die("BUG: create called for transaction that is not open");
-
-	if (!new_sha1 || is_null_sha1(new_sha1))
-		die("BUG: create ref with null new_sha1");
-
-	if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
-		strbuf_addf(err, "refusing to create ref with bad name %s",
-			    refname);
-		return -1;
-	}
-
-	update = add_update(transaction, refname);
-
-	hashcpy(update->new_sha1, new_sha1);
-	hashclr(update->old_sha1);
-	update->flags = flags;
-	update->have_old = 1;
-	if (msg)
-		update->msg = xstrdup(msg);
-	return 0;
+	return ref_transaction_update(transaction, refname, new_sha1,
+				      null_sha1, flags, 1, msg, err);
 }
 
 int ref_transaction_delete(struct ref_transaction *transaction,
@@ -3694,26 +3684,8 @@
 			   int flags, int have_old, const char *msg,
 			   struct strbuf *err)
 {
-	struct ref_update *update;
-
-	assert(err);
-
-	if (transaction->state != REF_TRANSACTION_OPEN)
-		die("BUG: delete called for transaction that is not open");
-
-	if (have_old && !old_sha1)
-		die("BUG: have_old is true but old_sha1 is NULL");
-
-	update = add_update(transaction, refname);
-	update->flags = flags;
-	update->have_old = have_old;
-	if (have_old) {
-		assert(!is_null_sha1(old_sha1));
-		hashcpy(update->old_sha1, old_sha1);
-	}
-	if (msg)
-		update->msg = xstrdup(msg);
-	return 0;
+	return ref_transaction_update(transaction, refname, null_sha1,
+				      old_sha1, flags, have_old, msg, err);
 }
 
 int update_ref(const char *action, const char *refname,
@@ -4009,3 +3981,129 @@
 	}
 	return 0;
 }
+
+struct expire_reflog_cb {
+	unsigned int flags;
+	reflog_expiry_should_prune_fn *should_prune_fn;
+	void *policy_cb;
+	FILE *newlog;
+	unsigned char last_kept_sha1[20];
+};
+
+static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
+			     const char *email, unsigned long timestamp, int tz,
+			     const char *message, void *cb_data)
+{
+	struct expire_reflog_cb *cb = cb_data;
+	struct expire_reflog_policy_cb *policy_cb = cb->policy_cb;
+
+	if (cb->flags & EXPIRE_REFLOGS_REWRITE)
+		osha1 = cb->last_kept_sha1;
+
+	if ((*cb->should_prune_fn)(osha1, nsha1, email, timestamp, tz,
+				   message, policy_cb)) {
+		if (!cb->newlog)
+			printf("would prune %s", message);
+		else if (cb->flags & EXPIRE_REFLOGS_VERBOSE)
+			printf("prune %s", message);
+	} else {
+		if (cb->newlog) {
+			fprintf(cb->newlog, "%s %s %s %lu %+05d\t%s",
+				sha1_to_hex(osha1), sha1_to_hex(nsha1),
+				email, timestamp, tz, message);
+			hashcpy(cb->last_kept_sha1, nsha1);
+		}
+		if (cb->flags & EXPIRE_REFLOGS_VERBOSE)
+			printf("keep %s", message);
+	}
+	return 0;
+}
+
+int reflog_expire(const char *refname, const unsigned char *sha1,
+		 unsigned int flags,
+		 reflog_expiry_prepare_fn prepare_fn,
+		 reflog_expiry_should_prune_fn should_prune_fn,
+		 reflog_expiry_cleanup_fn cleanup_fn,
+		 void *policy_cb_data)
+{
+	static struct lock_file reflog_lock;
+	struct expire_reflog_cb cb;
+	struct ref_lock *lock;
+	char *log_file;
+	int status = 0;
+
+	memset(&cb, 0, sizeof(cb));
+	cb.flags = flags;
+	cb.policy_cb = policy_cb_data;
+	cb.should_prune_fn = should_prune_fn;
+
+	/*
+	 * The reflog file is locked by holding the lock on the
+	 * reference itself, plus we might need to update the
+	 * reference if --updateref was specified:
+	 */
+	lock = lock_ref_sha1_basic(refname, sha1, NULL, 0, NULL);
+	if (!lock)
+		return error("cannot lock ref '%s'", refname);
+	if (!reflog_exists(refname)) {
+		unlock_ref(lock);
+		return 0;
+	}
+
+	log_file = git_pathdup("logs/%s", refname);
+	if (!(flags & EXPIRE_REFLOGS_DRY_RUN)) {
+		/*
+		 * Even though holding $GIT_DIR/logs/$reflog.lock has
+		 * no locking implications, we use the lock_file
+		 * machinery here anyway because it does a lot of the
+		 * work we need, including cleaning up if the program
+		 * exits unexpectedly.
+		 */
+		if (hold_lock_file_for_update(&reflog_lock, log_file, 0) < 0) {
+			struct strbuf err = STRBUF_INIT;
+			unable_to_lock_message(log_file, errno, &err);
+			error("%s", err.buf);
+			strbuf_release(&err);
+			goto failure;
+		}
+		cb.newlog = fdopen_lock_file(&reflog_lock, "w");
+		if (!cb.newlog) {
+			error("cannot fdopen %s (%s)",
+			      reflog_lock.filename.buf, strerror(errno));
+			goto failure;
+		}
+	}
+
+	(*prepare_fn)(refname, sha1, cb.policy_cb);
+	for_each_reflog_ent(refname, expire_reflog_ent, &cb);
+	(*cleanup_fn)(cb.policy_cb);
+
+	if (!(flags & EXPIRE_REFLOGS_DRY_RUN)) {
+		if (close_lock_file(&reflog_lock)) {
+			status |= error("couldn't write %s: %s", log_file,
+					strerror(errno));
+		} else if ((flags & EXPIRE_REFLOGS_UPDATE_REF) &&
+			(write_in_full(lock->lock_fd,
+				sha1_to_hex(cb.last_kept_sha1), 40) != 40 ||
+			 write_str_in_full(lock->lock_fd, "\n") != 1 ||
+			 close_ref(lock) < 0)) {
+			status |= error("couldn't write %s",
+					lock->lk->filename.buf);
+			rollback_lock_file(&reflog_lock);
+		} else if (commit_lock_file(&reflog_lock)) {
+			status |= error("unable to commit reflog '%s' (%s)",
+					log_file, strerror(errno));
+		} else if ((flags & EXPIRE_REFLOGS_UPDATE_REF) && commit_ref(lock)) {
+			status |= error("couldn't set %s", lock->ref_name);
+		}
+	}
+	free(log_file);
+	unlock_ref(lock);
+	return status;
+
+ failure:
+	rollback_lock_file(&reflog_lock);
+	free(log_file);
+	unlock_ref(lock);
+	return -1;
+}
diff --git a/refs.h b/refs.h
index 405c657..afa3c4d 100644
--- a/refs.h
+++ b/refs.h
@@ -1,15 +1,6 @@
 #ifndef REFS_H
 #define REFS_H
 
-struct ref_lock {
-	char *ref_name;
-	char *orig_ref_name;
-	struct lock_file *lk;
-	unsigned char old_sha1[20];
-	int lock_fd;
-	int force_write;
-};
-
 /*
  * A ref_transaction represents a collection of ref updates
  * that should succeed or fail together.
@@ -189,8 +180,7 @@
 extern int peel_ref(const char *refname, unsigned char *sha1);
 
 /*
- * Flags controlling lock_any_ref_for_update(), ref_transaction_update(),
- * ref_transaction_create(), etc.
+ * Flags controlling ref_transaction_update(), ref_transaction_create(), etc.
  * REF_NODEREF: act on the ref directly, instead of dereferencing
  *              symbolic references.
  * REF_DELETING: tolerate broken refs
@@ -199,21 +189,6 @@
  */
 #define REF_NODEREF	0x01
 #define REF_DELETING	0x02
-/*
- * This function sets errno to something meaningful on failure.
- */
-extern struct ref_lock *lock_any_ref_for_update(const char *refname,
-						const unsigned char *old_sha1,
-						int flags, int *type_p);
-
-/** Close the file descriptor owned by a lock and return the status */
-extern int close_ref(struct ref_lock *lock);
-
-/** Close and commit the ref locked by the lock */
-extern int commit_ref(struct ref_lock *lock);
-
-/** Release any lock taken but not written. **/
-extern void unlock_ref(struct ref_lock *lock);
 
 /*
  * Setup reflog before using. Set errno to something meaningful on failure.
@@ -291,7 +266,7 @@
 
 /*
  * Add a reference update to transaction.  new_sha1 is the value that
- * the reference should have after the update, or zeros if it should
+ * the reference should have after the update, or null_sha1 if it should
  * be deleted.  If have_old is true, then old_sha1 holds the value
  * that the reference should have had before the update, or zeros if
  * it must not have existed beforehand.
@@ -361,4 +336,50 @@
 extern int parse_hide_refs_config(const char *var, const char *value, const char *);
 extern int ref_is_hidden(const char *);
 
+enum expire_reflog_flags {
+	EXPIRE_REFLOGS_DRY_RUN = 1 << 0,
+	EXPIRE_REFLOGS_UPDATE_REF = 1 << 1,
+	EXPIRE_REFLOGS_VERBOSE = 1 << 2,
+	EXPIRE_REFLOGS_REWRITE = 1 << 3
+};
+
+/*
+ * The following interface is used for reflog expiration. The caller
+ * calls reflog_expire(), supplying it with three callback functions,
+ * of the following types. The callback functions define the
+ * expiration policy that is desired.
+ *
+ * reflog_expiry_prepare_fn -- Called once after the reference is
+ *     locked.
+ *
+ * reflog_expiry_should_prune_fn -- Called once for each entry in the
+ *     existing reflog. It should return true iff that entry should be
+ *     pruned.
+ *
+ * reflog_expiry_cleanup_fn -- Called once before the reference is
+ *     unlocked again.
+ */
+typedef void reflog_expiry_prepare_fn(const char *refname,
+				      const unsigned char *sha1,
+				      void *cb_data);
+typedef int reflog_expiry_should_prune_fn(unsigned char *osha1,
+					  unsigned char *nsha1,
+					  const char *email,
+					  unsigned long timestamp, int tz,
+					  const char *message, void *cb_data);
+typedef void reflog_expiry_cleanup_fn(void *cb_data);
+
+/*
+ * Expire reflog entries for the specified reference. sha1 is the old
+ * value of the reference. flags is a combination of the constants in
+ * enum expire_reflog_flags. The three function pointers are described
+ * above. On success, return zero.
+ */
+extern int reflog_expire(const char *refname, const unsigned char *sha1,
+			 unsigned int flags,
+			 reflog_expiry_prepare_fn prepare_fn,
+			 reflog_expiry_should_prune_fn should_prune_fn,
+			 reflog_expiry_cleanup_fn cleanup_fn,
+			 void *policy_cb_data);
+
 #endif /* REFS_H */
diff --git a/remote-curl.c b/remote-curl.c
index dd63bc2..deb4bfe 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -760,7 +760,7 @@
 
 	for (i = 0; i < nr_heads; i++) {
 		struct ref *ref = to_fetch[i];
-		if (!ref->name || !*ref->name)
+		if (!*ref->name)
 			die("cannot fetch by sha1 over smart http");
 		packet_buf_write(&preamble, "%s %s\n",
 				 sha1_to_hex(ref->old_sha1), ref->name);
@@ -962,6 +962,8 @@
 	struct strbuf buf = STRBUF_INIT;
 	int nongit;
 
+	git_setup_gettext();
+
 	git_extract_argv0_path(argv[0]);
 	setup_git_directory_gently(&nongit);
 	if (argc < 2) {
diff --git a/remote.c b/remote.c
index 5b9c693..68901b0 100644
--- a/remote.c
+++ b/remote.c
@@ -975,8 +975,8 @@
 	cpy = xmalloc(sizeof(struct ref) + len + 1);
 	memcpy(cpy, ref, sizeof(struct ref) + len + 1);
 	cpy->next = NULL;
-	cpy->symref = ref->symref ? xstrdup(ref->symref) : NULL;
-	cpy->remote_status = ref->remote_status ? xstrdup(ref->remote_status) : NULL;
+	cpy->symref = xstrdup_or_null(ref->symref);
+	cpy->remote_status = xstrdup_or_null(ref->remote_status);
 	cpy->peer_ref = copy_ref(ref->peer_ref);
 	return cpy;
 }
@@ -2156,7 +2156,7 @@
 /*
  * Compare-and-swap
  */
-void clear_cas_option(struct push_cas_option *cas)
+static void clear_cas_option(struct push_cas_option *cas)
 {
 	int i;
 
diff --git a/remote.h b/remote.h
index 8b62efd..02d66ce 100644
--- a/remote.h
+++ b/remote.h
@@ -115,7 +115,8 @@
 		REF_STATUS_REJECT_SHALLOW,
 		REF_STATUS_UPTODATE,
 		REF_STATUS_REMOTE_REJECT,
-		REF_STATUS_EXPECTING_REPORT
+		REF_STATUS_EXPECTING_REPORT,
+		REF_STATUS_ATOMIC_PUSH_FAILED
 	} status;
 	char *remote_status;
 	struct ref *peer_ref; /* when renaming */
@@ -260,7 +261,6 @@
 
 extern int parseopt_push_cas_option(const struct option *, const char *arg, int unset);
 extern int parse_push_cas_option(struct push_cas_option *, const char *arg, int unset);
-extern void clear_cas_option(struct push_cas_option *);
 
 extern int is_empty_cas(const struct push_cas_option *);
 void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);
diff --git a/rerere.c b/rerere.c
index 1b0555f..31644de 100644
--- a/rerere.c
+++ b/rerere.c
@@ -477,27 +477,23 @@
 
 static struct lock_file index_lock;
 
-static int update_paths(struct string_list *update)
+static void update_paths(struct string_list *update)
 {
 	int i;
-	int fd = hold_locked_index(&index_lock, 0);
-	int status = 0;
 
-	if (fd < 0)
-		return -1;
+	hold_locked_index(&index_lock, 1);
 
 	for (i = 0; i < update->nr; i++) {
 		struct string_list_item *item = &update->items[i];
-		if (add_file_to_cache(item->string, ADD_CACHE_IGNORE_ERRORS))
-			status = -1;
+		if (add_file_to_cache(item->string, 0))
+			exit(128);
 	}
 
-	if (!status && active_cache_changed) {
+	if (active_cache_changed) {
 		if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK))
 			die("Unable to write new index file");
-	} else if (fd >= 0)
+	} else
 		rollback_lock_file(&index_lock);
-	return status;
 }
 
 static int do_plain_rerere(struct string_list *rr, int fd)
diff --git a/revision.c b/revision.c
index 86406a2..66520c6 100644
--- a/revision.c
+++ b/revision.c
@@ -2017,6 +2017,8 @@
 		grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter);
 	} else if (!strcmp(arg, "--all-match")) {
 		revs->grep_filter.all_match = 1;
+	} else if (!strcmp(arg, "--invert-grep")) {
+		revs->invert_grep = 1;
 	} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
 		if (strcmp(optarg, "none"))
 			git_log_output_encoding = xstrdup(optarg);
@@ -2915,7 +2917,7 @@
 				     (char *)message, strlen(message));
 	strbuf_release(&buf);
 	unuse_commit_buffer(commit, message);
-	return retval;
+	return opt->invert_grep ? !retval : retval;
 }
 
 static inline int want_ancestry(const struct rev_info *revs)
@@ -2968,6 +2970,61 @@
 	return commit_show;
 }
 
+define_commit_slab(saved_parents, struct commit_list *);
+
+#define EMPTY_PARENT_LIST ((struct commit_list *)-1)
+
+/*
+ * You may only call save_parents() once per commit (this is checked
+ * for non-root commits).
+ */
+static void save_parents(struct rev_info *revs, struct commit *commit)
+{
+	struct commit_list **pp;
+
+	if (!revs->saved_parents_slab) {
+		revs->saved_parents_slab = xmalloc(sizeof(struct saved_parents));
+		init_saved_parents(revs->saved_parents_slab);
+	}
+
+	pp = saved_parents_at(revs->saved_parents_slab, commit);
+
+	/*
+	 * When walking with reflogs, we may visit the same commit
+	 * several times: once for each appearance in the reflog.
+	 *
+	 * In this case, save_parents() will be called multiple times.
+	 * We want to keep only the first set of parents.  We need to
+	 * store a sentinel value for an empty (i.e., NULL) parent
+	 * list to distinguish it from a not-yet-saved list, however.
+	 */
+	if (*pp)
+		return;
+	if (commit->parents)
+		*pp = copy_commit_list(commit->parents);
+	else
+		*pp = EMPTY_PARENT_LIST;
+}
+
+static void free_saved_parents(struct rev_info *revs)
+{
+	if (revs->saved_parents_slab)
+		clear_saved_parents(revs->saved_parents_slab);
+}
+
+struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit)
+{
+	struct commit_list *parents;
+
+	if (!revs->saved_parents_slab)
+		return commit->parents;
+
+	parents = *saved_parents_at(revs->saved_parents_slab, commit);
+	if (parents == EMPTY_PARENT_LIST)
+		return NULL;
+	return parents;
+}
+
 enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
 {
 	enum commit_action action = get_commit_action(revs, commit);
@@ -3267,54 +3324,3 @@
 	fputs(mark, stdout);
 	putchar(' ');
 }
-
-define_commit_slab(saved_parents, struct commit_list *);
-
-#define EMPTY_PARENT_LIST ((struct commit_list *)-1)
-
-void save_parents(struct rev_info *revs, struct commit *commit)
-{
-	struct commit_list **pp;
-
-	if (!revs->saved_parents_slab) {
-		revs->saved_parents_slab = xmalloc(sizeof(struct saved_parents));
-		init_saved_parents(revs->saved_parents_slab);
-	}
-
-	pp = saved_parents_at(revs->saved_parents_slab, commit);
-
-	/*
-	 * When walking with reflogs, we may visit the same commit
-	 * several times: once for each appearance in the reflog.
-	 *
-	 * In this case, save_parents() will be called multiple times.
-	 * We want to keep only the first set of parents.  We need to
-	 * store a sentinel value for an empty (i.e., NULL) parent
-	 * list to distinguish it from a not-yet-saved list, however.
-	 */
-	if (*pp)
-		return;
-	if (commit->parents)
-		*pp = copy_commit_list(commit->parents);
-	else
-		*pp = EMPTY_PARENT_LIST;
-}
-
-struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit)
-{
-	struct commit_list *parents;
-
-	if (!revs->saved_parents_slab)
-		return commit->parents;
-
-	parents = *saved_parents_at(revs->saved_parents_slab, commit);
-	if (parents == EMPTY_PARENT_LIST)
-		return NULL;
-	return parents;
-}
-
-void free_saved_parents(struct rev_info *revs)
-{
-	if (revs->saved_parents_slab)
-		clear_saved_parents(revs->saved_parents_slab);
-}
diff --git a/revision.h b/revision.h
index 033a244..0ea8b4e 100644
--- a/revision.h
+++ b/revision.h
@@ -169,6 +169,8 @@
 
 	/* Filter by commit log message */
 	struct grep_opt	grep_filter;
+	/* Negate the match of grep_filter */
+	int invert_grep;
 
 	/* Display history graph */
 	struct git_graph *graph;
@@ -298,18 +300,14 @@
 	rewrite_parent_fn_t rewrite_parent);
 
 /*
- * Save a copy of the parent list, and return the saved copy.  This is
- * used by the log machinery to retrieve the original parents when
- * commit->parents has been modified by history simpification.
- *
- * You may only call save_parents() once per commit (this is checked
- * for non-root commits).
+ * The log machinery saves the original parent list so that
+ * get_saved_parents() can later tell what the real parents of the
+ * commits are, when commit->parents has been modified by history
+ * simpification.
  *
  * get_saved_parents() will transparently return commit->parents if
  * history simplification is off.
  */
-extern void save_parents(struct rev_info *revs, struct commit *commit);
 extern struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit);
-extern void free_saved_parents(struct rev_info *revs);
 
 #endif
diff --git a/send-pack.c b/send-pack.c
index 25947d7..9d2b0c5 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -193,10 +193,13 @@
 	for_each_commit_graft(advertise_shallow_grafts_cb, sb);
 }
 
-static int ref_update_to_be_sent(const struct ref *ref, const struct send_pack_args *args)
+#define CHECK_REF_NO_PUSH -1
+#define CHECK_REF_STATUS_REJECTED -2
+#define CHECK_REF_UPTODATE -3
+static int check_to_send_update(const struct ref *ref, const struct send_pack_args *args)
 {
 	if (!ref->peer_ref && !args->send_mirror)
-		return 0;
+		return CHECK_REF_NO_PUSH;
 
 	/* Check for statuses set by set_ref_status_for_push() */
 	switch (ref->status) {
@@ -206,10 +209,11 @@
 	case REF_STATUS_REJECT_NEEDS_FORCE:
 	case REF_STATUS_REJECT_STALE:
 	case REF_STATUS_REJECT_NODELETE:
+		return CHECK_REF_STATUS_REJECTED;
 	case REF_STATUS_UPTODATE:
-		return 0;
+		return CHECK_REF_UPTODATE;
 	default:
-		return 1;
+		return 0;
 	}
 }
 
@@ -253,7 +257,7 @@
 	strbuf_addstr(&cert, "\n");
 
 	for (ref = remote_refs; ref; ref = ref->next) {
-		if (!ref_update_to_be_sent(ref, args))
+		if (check_to_send_update(ref, args) < 0)
 			continue;
 		update_seen = 1;
 		strbuf_addf(&cert, "%s %s %s\n",
@@ -281,6 +285,29 @@
 	return update_seen;
 }
 
+
+static int atomic_push_failure(struct send_pack_args *args,
+			       struct ref *remote_refs,
+			       struct ref *failing_ref)
+{
+	struct ref *ref;
+	/* Mark other refs as failed */
+	for (ref = remote_refs; ref; ref = ref->next) {
+		if (!ref->peer_ref && !args->send_mirror)
+			continue;
+
+		switch (ref->status) {
+		case REF_STATUS_EXPECTING_REPORT:
+			ref->status = REF_STATUS_ATOMIC_PUSH_FAILED;
+			continue;
+		default:
+			break; /* do nothing */
+		}
+	}
+	return error("atomic push failed for ref %s. status: %d\n",
+		     failing_ref->name, failing_ref->status);
+}
+
 int send_pack(struct send_pack_args *args,
 	      int fd[], struct child_process *conn,
 	      struct ref *remote_refs,
@@ -297,6 +324,8 @@
 	int use_sideband = 0;
 	int quiet_supported = 0;
 	int agent_supported = 0;
+	int use_atomic = 0;
+	int atomic_supported = 0;
 	unsigned cmds_sent = 0;
 	int ret;
 	struct async demux;
@@ -317,6 +346,8 @@
 		agent_supported = 1;
 	if (server_supports("no-thin"))
 		args->use_thin_pack = 0;
+	if (server_supports("atomic"))
+		atomic_supported = 1;
 	if (args->push_cert) {
 		int len;
 
@@ -331,6 +362,10 @@
 			"Perhaps you should specify a branch such as 'master'.\n");
 		return 0;
 	}
+	if (args->atomic && !atomic_supported)
+		die(_("server does not support --atomic push"));
+
+	use_atomic = atomic_supported && args->atomic;
 
 	if (status_report)
 		strbuf_addstr(&cap_buf, " report-status");
@@ -338,6 +373,8 @@
 		strbuf_addstr(&cap_buf, " side-band-64k");
 	if (quiet_supported && (args->quiet || !args->progress))
 		strbuf_addstr(&cap_buf, " quiet");
+	if (use_atomic)
+		strbuf_addstr(&cap_buf, " atomic");
 	if (agent_supported)
 		strbuf_addf(&cap_buf, " agent=%s", git_user_agent_sanitized());
 
@@ -362,9 +399,21 @@
 	 * the pack data.
 	 */
 	for (ref = remote_refs; ref; ref = ref->next) {
-		if (!ref_update_to_be_sent(ref, args))
+		switch (check_to_send_update(ref, args)) {
+		case 0: /* no error */
+			break;
+		case CHECK_REF_STATUS_REJECTED:
+			/*
+			 * When we know the server would reject a ref update if
+			 * we were to send it and we're trying to send the refs
+			 * atomically, abort the whole operation.
+			 */
+			if (use_atomic)
+				return atomic_push_failure(args, remote_refs, ref);
+			/* Fallthrough for non atomic case. */
+		default:
 			continue;
-
+		}
 		if (!ref->deletion)
 			need_pack_data = 1;
 
@@ -383,7 +432,7 @@
 		if (args->dry_run || args->push_cert)
 			continue;
 
-		if (!ref_update_to_be_sent(ref, args))
+		if (check_to_send_update(ref, args) < 0)
 			continue;
 
 		old_hex = sha1_to_hex(ref->old_sha1);
diff --git a/send-pack.h b/send-pack.h
index 5635457..b664648 100644
--- a/send-pack.h
+++ b/send-pack.h
@@ -13,7 +13,8 @@
 		use_ofs_delta:1,
 		dry_run:1,
 		push_cert:1,
-		stateless_rpc:1;
+		stateless_rpc:1,
+		atomic:1;
 };
 
 int send_pack(struct send_pack_args *args,
diff --git a/sha1_file.c b/sha1_file.c
index 30995e6..69a60ec 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3359,31 +3359,42 @@
 	return r;
 }
 
-int for_each_loose_file_in_objdir(const char *path,
+int for_each_loose_file_in_objdir_buf(struct strbuf *path,
 			    each_loose_object_fn obj_cb,
 			    each_loose_cruft_fn cruft_cb,
 			    each_loose_subdir_fn subdir_cb,
 			    void *data)
 {
-	struct strbuf buf = STRBUF_INIT;
-	size_t baselen;
+	size_t baselen = path->len;
 	int r = 0;
 	int i;
 
-	strbuf_addstr(&buf, path);
-	strbuf_addch(&buf, '/');
-	baselen = buf.len;
-
 	for (i = 0; i < 256; i++) {
-		strbuf_addf(&buf, "%02x", i);
-		r = for_each_file_in_obj_subdir(i, &buf, obj_cb, cruft_cb,
+		strbuf_addf(path, "/%02x", i);
+		r = for_each_file_in_obj_subdir(i, path, obj_cb, cruft_cb,
 						subdir_cb, data);
-		strbuf_setlen(&buf, baselen);
+		strbuf_setlen(path, baselen);
 		if (r)
 			break;
 	}
 
+	return r;
+}
+
+int for_each_loose_file_in_objdir(const char *path,
+				  each_loose_object_fn obj_cb,
+				  each_loose_cruft_fn cruft_cb,
+				  each_loose_subdir_fn subdir_cb,
+				  void *data)
+{
+	struct strbuf buf = STRBUF_INIT;
+	int r;
+
+	strbuf_addstr(&buf, path);
+	r = for_each_loose_file_in_objdir_buf(&buf, obj_cb, cruft_cb,
+					      subdir_cb, data);
 	strbuf_release(&buf);
+
 	return r;
 }
 
@@ -3396,9 +3407,16 @@
 			      void *vdata)
 {
 	struct loose_alt_odb_data *data = vdata;
-	return for_each_loose_file_in_objdir(alt->base,
-					     data->cb, NULL, NULL,
-					     data->data);
+	struct strbuf buf = STRBUF_INIT;
+	int r;
+
+	/* copy base not including trailing '/' */
+	strbuf_add(&buf, alt->base, alt->name - alt->base - 1);
+	r = for_each_loose_file_in_objdir_buf(&buf,
+					      data->cb, NULL, NULL,
+					      data->data);
+	strbuf_release(&buf);
+	return r;
 }
 
 int for_each_loose_object(each_loose_object_fn cb, void *data)
diff --git a/shallow.c b/shallow.c
index cdd0775..d8bf40a 100644
--- a/shallow.c
+++ b/shallow.c
@@ -22,7 +22,7 @@
 	if (alternate_shallow_file && !override)
 		return;
 	free(alternate_shallow_file);
-	alternate_shallow_file = path ? xstrdup(path) : NULL;
+	alternate_shallow_file = xstrdup_or_null(path);
 }
 
 int register_shallow(const unsigned char *sha1)
@@ -137,7 +137,7 @@
 	return result;
 }
 
-void check_shallow_file_for_update(void)
+static void check_shallow_file_for_update(void)
 {
 	if (is_shallow == -1)
 		die("BUG: shallow must be initialized by now");
diff --git a/strbuf.h b/strbuf.h
index 652b6c4..1883494 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -1,22 +1,112 @@
 #ifndef STRBUF_H
 #define STRBUF_H
 
-/* See Documentation/technical/api-strbuf.txt */
+/**
+ * strbuf's are meant to be used with all the usual C string and memory
+ * APIs. Given that the length of the buffer is known, it's often better to
+ * use the mem* functions than a str* one (memchr vs. strchr e.g.).
+ * Though, one has to be careful about the fact that str* functions often
+ * stop on NULs and that strbufs may have embedded NULs.
+ *
+ * A strbuf is NUL terminated for convenience, but no function in the
+ * strbuf API actually relies on the string being free of NULs.
+ *
+ * strbufs have some invariants that are very important to keep in mind:
+ *
+ *  - The `buf` member is never NULL, so it can be used in any usual C
+ *    string operations safely. strbuf's _have_ to be initialized either by
+ *    `strbuf_init()` or by `= STRBUF_INIT` before the invariants, though.
+ *
+ *    Do *not* assume anything on what `buf` really is (e.g. if it is
+ *    allocated memory or not), use `strbuf_detach()` to unwrap a memory
+ *    buffer from its strbuf shell in a safe way. That is the sole supported
+ *    way. This will give you a malloced buffer that you can later `free()`.
+ *
+ *    However, it is totally safe to modify anything in the string pointed by
+ *    the `buf` member, between the indices `0` and `len-1` (inclusive).
+ *
+ *  - The `buf` member is a byte array that has at least `len + 1` bytes
+ *    allocated. The extra byte is used to store a `'\0'`, allowing the
+ *    `buf` member to be a valid C-string. Every strbuf function ensure this
+ *    invariant is preserved.
+ *
+ *    NOTE: It is OK to "play" with the buffer directly if you work it this
+ *    way:
+ *
+ *        strbuf_grow(sb, SOME_SIZE); <1>
+ *        strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
+ *
+ *    <1> Here, the memory array starting at `sb->buf`, and of length
+ *    `strbuf_avail(sb)` is all yours, and you can be sure that
+ *    `strbuf_avail(sb)` is at least `SOME_SIZE`.
+ *
+ *    NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`.
+ *
+ *    Doing so is safe, though if it has to be done in many places, adding the
+ *    missing API to the strbuf module is the way to go.
+ *
+ *    WARNING: Do _not_ assume that the area that is yours is of size `alloc
+ *    - 1` even if it's true in the current implementation. Alloc is somehow a
+ *    "private" member that should not be messed with. Use `strbuf_avail()`
+ *    instead.
+*/
 
-extern char strbuf_slopbuf[];
+/**
+ * Data Structures
+ * ---------------
+ */
+
+/**
+ * This is the string buffer structure. The `len` member can be used to
+ * determine the current length of the string, and `buf` member provides
+ * access to the string itself.
+ */
 struct strbuf {
 	size_t alloc;
 	size_t len;
 	char *buf;
 };
 
+extern char strbuf_slopbuf[];
 #define STRBUF_INIT  { 0, 0, strbuf_slopbuf }
 
-/*----- strbuf life cycle -----*/
+/**
+ * Life Cycle Functions
+ * --------------------
+ */
+
+/**
+ * Initialize the structure. The second parameter can be zero or a bigger
+ * number to allocate memory, in case you want to prevent further reallocs.
+ */
 extern void strbuf_init(struct strbuf *, size_t);
+
+/**
+ * Release a string buffer and the memory it used. You should not use the
+ * string buffer after using this function, unless you initialize it again.
+ */
 extern void strbuf_release(struct strbuf *);
+
+/**
+ * Detach the string from the strbuf and returns it; you now own the
+ * storage the string occupies and it is your responsibility from then on
+ * to release it with `free(3)` when you are done with it.
+ */
 extern char *strbuf_detach(struct strbuf *, size_t *);
+
+/**
+ * Attach a string to a buffer. You should specify the string to attach,
+ * the current length of the string and the amount of allocated memory.
+ * The amount must be larger than the string length, because the string you
+ * pass is supposed to be a NUL-terminated string.  This string _must_ be
+ * malloc()ed, and after attaching, the pointer cannot be relied upon
+ * anymore, and neither be free()d directly.
+ */
 extern void strbuf_attach(struct strbuf *, void *, size_t, size_t);
+
+/**
+ * Swap the contents of two string buffers.
+ */
 static inline void strbuf_swap(struct strbuf *a, struct strbuf *b)
 {
 	struct strbuf tmp = *a;
@@ -24,14 +114,36 @@
 	*b = tmp;
 }
 
-/*----- strbuf size related -----*/
+
+/**
+ * Functions related to the size of the buffer
+ * -------------------------------------------
+ */
+
+/**
+ * Determine the amount of allocated but unused memory.
+ */
 static inline size_t strbuf_avail(const struct strbuf *sb)
 {
 	return sb->alloc ? sb->alloc - sb->len - 1 : 0;
 }
 
+/**
+ * Ensure that at least this amount of unused memory is available after
+ * `len`. This is used when you know a typical size for what you will add
+ * and want to avoid repetitive automatic resizing of the underlying buffer.
+ * This is never a needed operation, but can be critical for performance in
+ * some cases.
+ */
 extern void strbuf_grow(struct strbuf *, size_t);
 
+/**
+ * Set the length of the buffer to a given value. This function does *not*
+ * allocate new memory, so you should not perform a `strbuf_setlen()` to a
+ * length that is larger than `len + strbuf_avail()`. `strbuf_setlen()` is
+ * just meant as a 'please fix invariants from this strbuf I just messed
+ * with'.
+ */
 static inline void strbuf_setlen(struct strbuf *sb, size_t len)
 {
 	if (len > (sb->alloc ? sb->alloc - 1 : 0))
@@ -39,16 +151,269 @@
 	sb->len = len;
 	sb->buf[len] = '\0';
 }
+
+/**
+ * Empty the buffer by setting the size of it to zero.
+ */
 #define strbuf_reset(sb)  strbuf_setlen(sb, 0)
 
-/*----- content related -----*/
+
+/**
+ * Functions related to the contents of the buffer
+ * -----------------------------------------------
+ */
+
+/**
+ * Strip whitespace from the beginning (`ltrim`), end (`rtrim`), or both side
+ * (`trim`) of a string.
+ */
 extern void strbuf_trim(struct strbuf *);
 extern void strbuf_rtrim(struct strbuf *);
 extern void strbuf_ltrim(struct strbuf *);
+
+/**
+ * Replace the contents of the strbuf with a reencoded form.  Returns -1
+ * on error, 0 on success.
+ */
 extern int strbuf_reencode(struct strbuf *sb, const char *from, const char *to);
+
+/**
+ * Lowercase each character in the buffer using `tolower`.
+ */
 extern void strbuf_tolower(struct strbuf *sb);
+
+/**
+ * Compare two buffers. Returns an integer less than, equal to, or greater
+ * than zero if the first buffer is found, respectively, to be less than,
+ * to match, or be greater than the second buffer.
+ */
 extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
 
+
+/**
+ * Adding data to the buffer
+ * -------------------------
+ *
+ * NOTE: All of the functions in this section will grow the buffer as
+ * necessary.  If they fail for some reason other than memory shortage and the
+ * buffer hadn't been allocated before (i.e. the `struct strbuf` was set to
+ * `STRBUF_INIT`), then they will free() it.
+ */
+
+/**
+ * Add a single character to the buffer.
+ */
+static inline void strbuf_addch(struct strbuf *sb, int c)
+{
+	strbuf_grow(sb, 1);
+	sb->buf[sb->len++] = c;
+	sb->buf[sb->len] = '\0';
+}
+
+/**
+ * Add a character the specified number of times to the buffer.
+ */
+extern void strbuf_addchars(struct strbuf *sb, int c, size_t n);
+
+/**
+ * Insert data to the given position of the buffer. The remaining contents
+ * will be shifted, not overwritten.
+ */
+extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t);
+
+/**
+ * Remove given amount of data from a given position of the buffer.
+ */
+extern void strbuf_remove(struct strbuf *, size_t pos, size_t len);
+
+/**
+ * Remove the bytes between `pos..pos+len` and replace it with the given
+ * data.
+ */
+extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
+			  const void *, size_t);
+
+/**
+ * Add a NUL-terminated string to the buffer. Each line will be prepended
+ * by a comment character and a blank.
+ */
+extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
+
+
+/**
+ * Add data of given length to the buffer.
+ */
+extern void strbuf_add(struct strbuf *, const void *, size_t);
+
+/**
+ * Add a NUL-terminated string to the buffer.
+ *
+ * NOTE: This function will *always* be implemented as an inline or a macro
+ * using strlen, meaning that this is efficient to write things like:
+ *
+ *     strbuf_addstr(sb, "immediate string");
+ *
+ */
+static inline void strbuf_addstr(struct strbuf *sb, const char *s)
+{
+	strbuf_add(sb, s, strlen(s));
+}
+
+/**
+ * Copy the contents of another buffer at the end of the current one.
+ */
+static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
+{
+	strbuf_grow(sb, sb2->len);
+	strbuf_add(sb, sb2->buf, sb2->len);
+}
+
+/**
+ * Copy part of the buffer from a given position till a given length to the
+ * end of the buffer.
+ */
+extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
+
+/**
+ * This function can be used to expand a format string containing
+ * placeholders. To that end, it parses the string and calls the specified
+ * function for every percent sign found.
+ *
+ * The callback function is given a pointer to the character after the `%`
+ * and a pointer to the struct strbuf.  It is expected to add the expanded
+ * version of the placeholder to the strbuf, e.g. to add a newline
+ * character if the letter `n` appears after a `%`.  The function returns
+ * the length of the placeholder recognized and `strbuf_expand()` skips
+ * over it.
+ *
+ * The format `%%` is automatically expanded to a single `%` as a quoting
+ * mechanism; callers do not need to handle the `%` placeholder themselves,
+ * and the callback function will not be invoked for this placeholder.
+ *
+ * All other characters (non-percent and not skipped ones) are copied
+ * verbatim to the strbuf.  If the callback returned zero, meaning that the
+ * placeholder is unknown, then the percent sign is copied, too.
+ *
+ * In order to facilitate caching and to make it possible to give
+ * parameters to the callback, `strbuf_expand()` passes a context pointer,
+ * which can be used by the programmer of the callback as she sees fit.
+ */
+typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
+extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context);
+
+/**
+ * Used as callback for `strbuf_expand()`, expects an array of
+ * struct strbuf_expand_dict_entry as context, i.e. pairs of
+ * placeholder and replacement string.  The array needs to be
+ * terminated by an entry with placeholder set to NULL.
+ */
+struct strbuf_expand_dict_entry {
+	const char *placeholder;
+	const char *value;
+};
+extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context);
+
+/**
+ * Append the contents of one strbuf to another, quoting any
+ * percent signs ("%") into double-percents ("%%") in the
+ * destination. This is useful for literal data to be fed to either
+ * strbuf_expand or to the *printf family of functions.
+ */
+extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
+
+/**
+ * Append the given byte size as a human-readable string (i.e. 12.23 KiB,
+ * 3.50 MiB).
+ */
+extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
+
+/**
+ * Add a formatted string to the buffer.
+ */
+__attribute__((format (printf,2,3)))
+extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
+
+/**
+ * Add a formatted string prepended by a comment character and a
+ * blank to the buffer.
+ */
+__attribute__((format (printf, 2, 3)))
+extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...);
+
+__attribute__((format (printf,2,0)))
+extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
+
+/**
+ * Read a given size of data from a FILE* pointer to the buffer.
+ *
+ * NOTE: The buffer is rewound if the read fails. If -1 is returned,
+ * `errno` must be consulted, like you would do for `read(3)`.
+ * `strbuf_read()`, `strbuf_read_file()` and `strbuf_getline()` has the
+ * same behaviour as well.
+ */
+extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
+
+/**
+ * Read the contents of a given file descriptor. The third argument can be
+ * used to give a hint about the file size, to avoid reallocs.  If read fails,
+ * any partial read is undone.
+ */
+extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
+
+/**
+ * Read the contents of a file, specified by its path. The third argument
+ * can be used to give a hint about the file size, to avoid reallocs.
+ */
+extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
+
+/**
+ * Read the target of a symbolic link, specified by its path.  The third
+ * argument can be used to give a hint about the size, to avoid reallocs.
+ */
+extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
+
+/**
+ * Read a line from a FILE *, overwriting the existing contents
+ * of the strbuf. The second argument specifies the line
+ * terminator character, typically `'\n'`.
+ * Reading stops after the terminator or at EOF.  The terminator
+ * is removed from the buffer before returning.  Returns 0 unless
+ * there was nothing left before EOF, in which case it returns `EOF`.
+ */
+extern int strbuf_getline(struct strbuf *, FILE *, int);
+
+/**
+ * Like `strbuf_getline`, but keeps the trailing terminator (if
+ * any) in the buffer.
+ */
+extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
+
+/**
+ * Like `strbuf_getwholeline`, but operates on a file descriptor.
+ * It reads one character at a time, so it is very slow.  Do not
+ * use it unless you need the correct position in the file
+ * descriptor.
+ */
+extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
+
+/**
+ * Set the buffer to the path of the current working directory.
+ */
+extern int strbuf_getcwd(struct strbuf *sb);
+
+/**
+ * Add a path to a buffer, converting a relative path to an
+ * absolute one in the process.  Symbolic links are not
+ * resolved.
+ */
+extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
+
+/**
+ * Strip whitespace from a buffer. The second parameter controls if
+ * comments are considered contents to be removed or not.
+ */
+extern void stripspace(struct strbuf *buf, int skip_comments);
+
 static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
 {
 	if (strip_suffix_mem(sb->buf, &sb->len, suffix)) {
@@ -58,7 +423,7 @@
 		return 0;
 }
 
-/*
+/**
  * Split str (of length slen) at the specified terminator character.
  * Return a null-terminated array of pointers to strbuf objects
  * holding the substrings.  The substrings include the terminator,
@@ -68,97 +433,53 @@
  * substring containing everything following the (max-1)th terminator
  * character).
  *
+ * The most generic form is `strbuf_split_buf`, which takes an arbitrary
+ * pointer/len buffer. The `_str` variant takes a NUL-terminated string,
+ * the `_max` variant takes a strbuf, and just `strbuf_split` is a convenience
+ * wrapper to drop the `max` parameter.
+ *
  * For lighter-weight alternatives, see string_list_split() and
  * string_list_split_in_place().
  */
 extern struct strbuf **strbuf_split_buf(const char *, size_t,
 					int terminator, int max);
 
-/*
- * Split a NUL-terminated string at the specified terminator
- * character.  See strbuf_split_buf() for more information.
- */
 static inline struct strbuf **strbuf_split_str(const char *str,
 					       int terminator, int max)
 {
 	return strbuf_split_buf(str, strlen(str), terminator, max);
 }
 
-/*
- * Split a strbuf at the specified terminator character.  See
- * strbuf_split_buf() for more information.
- */
 static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,
 						int terminator, int max)
 {
 	return strbuf_split_buf(sb->buf, sb->len, terminator, max);
 }
 
-/*
- * Split a strbuf at the specified terminator character.  See
- * strbuf_split_buf() for more information.
- */
 static inline struct strbuf **strbuf_split(const struct strbuf *sb,
 					   int terminator)
 {
 	return strbuf_split_max(sb, terminator, 0);
 }
 
-/*
+/**
  * Free a NULL-terminated list of strbufs (for example, the return
  * values of the strbuf_split*() functions).
  */
 extern void strbuf_list_free(struct strbuf **);
 
-/*----- add data in your buffer -----*/
-static inline void strbuf_addch(struct strbuf *sb, int c)
-{
-	strbuf_grow(sb, 1);
-	sb->buf[sb->len++] = c;
-	sb->buf[sb->len] = '\0';
-}
-
-extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t);
-extern void strbuf_remove(struct strbuf *, size_t pos, size_t len);
-
-/* splice pos..pos+len with given data */
-extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
-                          const void *, size_t);
-
-extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
-
-extern void strbuf_add(struct strbuf *, const void *, size_t);
-static inline void strbuf_addstr(struct strbuf *sb, const char *s)
-{
-	strbuf_add(sb, s, strlen(s));
-}
-static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
-{
-	strbuf_grow(sb, sb2->len);
-	strbuf_add(sb, sb2->buf, sb2->len);
-}
-extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
-extern void strbuf_addchars(struct strbuf *sb, int c, size_t n);
-
-typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
-extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context);
-struct strbuf_expand_dict_entry {
-	const char *placeholder;
-	const char *value;
-};
-extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context);
-extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
-
-__attribute__((format (printf,2,3)))
-extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
-__attribute__((format (printf, 2, 3)))
-extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...);
-__attribute__((format (printf,2,0)))
-extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
+/**
+ * Launch the user preferred editor to edit a file and fill the buffer
+ * with the file's contents upon the user completing their editing. The
+ * third argument can be used to set the environment which the editor is
+ * run in. If the buffer is NULL the editor is launched as usual but the
+ * file's contents are not read into the buffer upon completion.
+ */
+extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
 
 extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
 
-/*
+/**
  * Append s to sb, with the characters '<', '>', '&' and '"' converted
  * into XML entities.
  */
@@ -170,28 +491,11 @@
 		strbuf_addch(sb, '\n');
 }
 
-extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
-/* XXX: if read fails, any partial read is undone */
-extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
-extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
-extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
-extern int strbuf_getcwd(struct strbuf *sb);
-
-extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
-extern int strbuf_getline(struct strbuf *, FILE *, int);
-extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
-
-extern void stripspace(struct strbuf *buf, int skip_comments);
-extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
-
 extern int strbuf_branchname(struct strbuf *sb, const char *name);
 extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
 
 extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
 				    int reserved);
-extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
-
-extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
 
 __attribute__((format (printf,1,2)))
 extern int printf_ln(const char *fmt, ...);
@@ -200,7 +504,7 @@
 
 char *xstrdup_tolower(const char *);
 
-/*
+/**
  * Create a newly allocated string using printf format. You can do this easily
  * with a strbuf, but this provides a shortcut to save a few lines.
  */
diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh
index d88da29..db2ef22 100755
--- a/t/lib-gpg.sh
+++ b/t/lib-gpg.sh
@@ -23,6 +23,8 @@
 		# To write armored exported key to keyring:
 		#	gpg --homedir /tmp/gpghome --export-secret-keys \
 		#		--armor 0xDEADBEEF >> lib-gpg/keyring.gpg
+		#	gpg --homedir /tmp/gpghome --export \
+		#		--armor 0xDEADBEEF >> lib-gpg/keyring.gpg
 		# To export ownertrust:
 		#	gpg --homedir /tmp/gpghome --export-ownertrust \
 		#		> lib-gpg/ownertrust
@@ -34,6 +36,8 @@
 			"$TEST_DIRECTORY"/lib-gpg/keyring.gpg &&
 		gpg --homedir "${GNUPGHOME}" 2>/dev/null --import-ownertrust \
 			"$TEST_DIRECTORY"/lib-gpg/ownertrust &&
+		gpg --homedir "${GNUPGHOME}" </dev/null >/dev/null 2>&1 \
+			--sign -u committer@example.com &&
 		test_set_prereq GPG
 		;;
 	esac
diff --git a/t/lib-gpg/keyring.gpg b/t/lib-gpg/keyring.gpg
index fb1f048..d4754a1 100644
--- a/t/lib-gpg/keyring.gpg
+++ b/t/lib-gpg/keyring.gpg
@@ -86,3 +86,57 @@
 BOW78WUxzhu0YJTLKy+iKCjg5HS5dx6OC+e4aEEgfhNPCMkbvDsJjtQ=
 =hieJ
 -----END PGP PRIVATE KEY BLOCK-----
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQGiBEZnyykRBACzCPjIpTYNL7Y2tQqlEGTTDlvZcWNLjF5f7ZzuyOqNOidLUgFD
+36qch1LZLSZkShdR3Gae+bsolyjxrlFuFP0eXRPMtqK20aLw7WZvPFpEV1ThMne+
+PRJjYrvghWw3L0VVIAIZ8GXwrVBuU99uEjHEI0ojYloOvFc2jVPgSaoBvwCg48Tj
+fol2foSoJa7XUu9yAL8szg8D/RUsTzNF+I9hSRHl7MYKFMYoKEY9BDgrgAujp7YY
+8qdGsiUb0Ggyzp2kRjZFt4lpcvKhGfHn5GEjmtk+fRbD5qPfMqKFW+T0NPfYlYmL
+JJ4fs4qZ8Lx7x6iG6X51u+YNwsQuIGjMCC3CeNi3F7or651kkNYASbaQ1NROkCIN
+NudyA/0aasvoZUoNJAc2cP5Ifs6WhXMWLfMR2p2XbfKwKNYneec60usnSComcKqh
+sJVk0Gytvr3FOYVhRkXnKAbx+0W2urFP8OFVBTEKO6Ts2VygWGgneQYoHnqzwlUE
+yjOjlr+lyf7u2s/KAxpKA6jnttEdRZAmzWkhuox1wwAUkr27/bQiQyBPIE1pdHRl
+ciA8Y29tbWl0dGVyQGV4YW1wbGUuY29tPoheBBMRAgAeBQJGZ8spAhsDBgsJCAcD
+AgMVAgMDFgIBAh4BAheAAAoJEBO29R7N3kMNdB0AoL3Z/7A6tORuY8R/676oD8a/
+oHFDAJ9DXbwlcKLcykwHy0jYqajXm1iCebkCDQRGZ8tOEAgAzrl5P1Pr6CDR8mf5
+DGGzcUUM+PEroA4FLdKJ5ZaZc7qy1lmmW9vuvb6xdinwcwee2c5fdNE+iUjHV2x2
+S/dbfDzJTN/0uajZcw+xnf+KxZ0Rs4gDSs7cHXHBtA7u8ShYd4Hu7JggXpiwgfSk
+yrGQiZyLAHW2ck8H07Go8eUP8fLIeva+iPqeYQZo9BaPz92R/J6debpeY1lRkv+y
+WTq1GE3C/hxbdBAuHf2duLP2uq9kwoVdfzCRjgV1CQmMIbCrMb7vIlzIe96bb3+K
+r/+NEtmB2I3wHBXcwJMnIOnz9Zv933KNlxSbVF23BGLB+F9D7OanKymbs7Eg18fr
+mt/t/wAEDQgAtGIxGz944Pn2OtheY9JlBRuIAuVskm24/Zz03dZnk6CuEOIBb5IM
+g36GAPKcn1vsLZ0TfE1q53jNpcAAXjgngnRsCjZm1mglqPD4ZfBpl+Hhnuc80fAR
+xsUPj+5c8KP2M+Rws4moaZRjVpd3KCi3ceflT/OjwnE9DzdhslCGTMA5n8cajAs2
+oqAaQssefVf2prLQLGV9NB4Q3lFnKXdvipHMaAYAsW+iF7JkhTDVNuNGlufeSqUm
+igRBjTZXBcVd8sj8vDOCWKUfqxJyS+zRYcotn7QvpvcKAkc3ZGxntDHAIGLVp6ay
++vrkV4Ren8BjFobl25Ruy6Abw+CgnTpuwYhJBBgRAgAJBQJGZ8tOAhsMAAoJEBO2
+9R7N3kMNwewAoNBygC0NYkW6lVGqV4EJ7PHhDaSEAJwKz78u0Twtv2EL7Zy+ve4f
+mnzYApkBDQRRTJZHAQgAyYv8ZwBfMiN+Dx4pUgmzO1bThTte6BTJKbuHIDdkKT7j
+OTFY8nL68ykoLmRbzwgy83gBSVtbj8S+Eh2h0pIrAqxYYox+ziVnDjzT0hQsLvop
+wKALLx5uJ7OqXw2ckY1Ux0mOK3TCEqihUaM2l7vLx3gUcyIRZ7mwQnqSmVtO6Cj5
+65xC1U1VElFSPunpfCRZiSFscSzS4X0UUjxdL+DA1zxf/4glomQyPidaS70OVf3+
+2LX7AxldKD2Ouie9gRSRueeXigbbZzWPdNS5iN6HJ+T+YlZ1w2qjBJcOxSqZwDV7
+nIGNx+JC8jZCN7NydAhm1yO29zAVrY3LboVr9athuQARAQABtCRFcmlzIERpc2Nv
+cmRpYSA8ZGlzY29yZEBleGFtcGxlLm5ldD6JATgEEwECACIFAlFMlkcCGwMGCwkI
+BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEGEJLoW3InGJWKMH+wfn/hQ3C1X8PF8x
+pSpLtRejyNchgrewDDtvyZJjuC5YB7iIBaanuW/14ypdCLEXG1S4raoiKJHPLvux
+/MmFOuww5Yqu7dYKgcvqk4Uh3IJ+ljCk2qgqjhNo8x8qrpSAM0LCUPnOUkaHxGQC
+k+EGtg8vp7Klg6SBO/GiXdFZ5JPVOh9lbgAb1HjfyDIL8T6+duaPqwQ+y1OCdwrT
+s31frDuvt93WvgZvVIZEeLQuB/59XQzdSWLsQUG4MU6v4fJinuP+/2L8vuVrGHfe
+mUSxNmRVnll7SpMJmG0ONht0mVF2mfEfDrW08lK42xSoqTuML18Ico7tZfXMQLK3
+GusW0gi5AQ0EUUyWRwEIAKk7TxXE16jPlKO2zqKPnXB4vFw3//F0hJmXzCnP1OaU
+kwZO4dYEirhs4xdp98EJugPPtdNb0y2kOj6BQxVvLkAdNJo8phq0Q2BYM/G44Z2n
+pGZwOF04a9UTo334DIbN7k6Qnm3VfpS/CtKCUx3N/Uzy04NtwxXEUgzftwESSUu/
+gkQSG7fS+YDm6YAOB1Gqf6OjeztOK0Dj1PNzAKp8KNiUzvw3ndM6GndFaN9TZpOB
+firxBOdn7Rh23e8qiFBigbdknkwIfOdGnC3jWT/ldWO2rQQq+/85viaR1qvTh+/z
+aJpRCJMS/Fg7fBnwCqKmYKnny/gAhJy2wLdXbt39BbMAEQEAAYkBHwQYAQIACQUC
+UUyWRwIbDAAKCRBhCS6FtyJxiexxCADF5DH+HDlppwLr73EptyqS4IblopPXcn59
+bGPyBuWraCivsqZlf05QZTGahUM7jyCUE/FS25sbS5Q4SRtOC2yOnPGsSGcTjmSi
+8uZ000stes7ahHku3onxyz2YNVBRchBCENV1tAjQwHrliofdBEY8peAoOz51kmfR
+Ivs4+iQ+T3HYtwSYUKPVjizlRCdDR5nsE2KpPUFVx/9L9R3ZeCzCbYHG3Ww1pOFE
+5F24PaZ97pgoJDSd1bPH1pyFjvSM3a9v8KxWNib1E+2L5fsLDSFmrbzhMxsu5wTl
+u/FlMc4btGCUyysvoigo4OR0uXcejgvnuGhBIH4TTwjJG7w7CY7U
+=iYv/
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index fd53b57..d154d1e 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -37,7 +37,7 @@
 	test_done
 fi
 
-if ! test_have_prereq SANITY; then
+if ! test_have_prereq NOT_ROOT; then
 	test_skip_or_die $GIT_TEST_HTTPD \
 		"Cannot run httpd tests as root"
 fi
diff --git a/t/lib-terminal.sh b/t/lib-terminal.sh
index 5184549..cd220e3 100644
--- a/t/lib-terminal.sh
+++ b/t/lib-terminal.sh
@@ -1,7 +1,7 @@
 # Helpers for terminal output tests.
 
 # Catch tests which should depend on TTY but forgot to. There's no need
-# to aditionally check that the TTY prereq is set here.  If the test declared
+# to additionally check that the TTY prereq is set here.  If the test declared
 # it and we are running the test, then it must have been set.
 test_terminal () {
 	if ! test_declared_prereq TTY
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index 17e969d..9acf628 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -34,7 +34,7 @@
 	grep "fatal: cannot exec.*hello.sh" err
 '
 
-test_expect_success POSIXPERM 'unreadable directory in PATH' '
+test_expect_success POSIXPERM,SANITY 'unreadable directory in PATH' '
 	mkdir local-command &&
 	test_when_finished "chmod u+rwx local-command && rm -fr local-command" &&
 	git config alias.nitfol "!echo frotz" &&
diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh
index fdc257e..3c6791e 100755
--- a/t/t1307-config-blob.sh
+++ b/t/t1307-config-blob.sh
@@ -67,4 +67,13 @@
 	grep "HEAD:config" err
 '
 
+test_expect_success 'can parse blob ending with CR' '
+	printf "[some]key = value\\r" >config &&
+	git add config &&
+	git commit -m CR &&
+	echo value >expect &&
+	git config --blob=HEAD:config some.key >actual &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t1509-root-worktree.sh b/t/t1509-root-worktree.sh
index 335420f..b6977d4 100755
--- a/t/t1509-root-worktree.sh
+++ b/t/t1509-root-worktree.sh
@@ -98,8 +98,16 @@
 	'
 }
 
-if ! test_have_prereq POSIXPERM || ! [ -w / ]; then
-	skip_all="Dangerous test skipped. Read this test if you want to execute it"
+if ! test -w /
+then
+	skip_all="Test requiring writable / skipped. Read this test if you want to run it"
+	test_done
+fi
+
+if  test -e /refs || test -e /objects || test -e /info || test -e /hooks ||
+    test -e /.git || test -e /foo || test -e /me
+then
+	skip_all="Skip test that clobbers existing files in /"
 	test_done
 fi
 
@@ -108,8 +116,9 @@
 	test_done
 fi
 
-if [ "$UID" = 0 ]; then
-	skip_all="No you can't run this with root"
+if ! test_have_prereq NOT_ROOT
+then
+	skip_all="No you can't run this as root"
 	test_done
 fi
 
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 8197ed2..a31f7e0 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1039,4 +1039,11 @@
 	)
 '
 
+test_expect_success 'respect core.abbrev' '
+	git config core.abbrev 12 &&
+	set_cat_todo_editor &&
+	test_must_fail git rebase -i HEAD~4 >todo-list &&
+	test 4 = $(grep -c "pick [0-9a-f]\{12,\}" todo-list)
+'
+
 test_done
diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh
index 70b3a06..1814647 100755
--- a/t/t4122-apply-symlink-inside.sh
+++ b/t/t4122-apply-symlink-inside.sh
@@ -3,17 +3,10 @@
 test_description='apply to deeper directory without getting fooled with symlink'
 . ./test-lib.sh
 
-lecho () {
-	for l_
-	do
-		echo "$l_"
-	done
-}
-
 test_expect_success setup '
 
 	mkdir -p arch/i386/boot arch/x86_64 &&
-	lecho 1 2 3 4 5 >arch/i386/boot/Makefile &&
+	test_write_lines 1 2 3 4 5 >arch/i386/boot/Makefile &&
 	test_ln_s_add ../i386/boot arch/x86_64/boot &&
 	git add . &&
 	test_tick &&
@@ -22,7 +15,7 @@
 
 	rm arch/x86_64/boot &&
 	mkdir arch/x86_64/boot &&
-	lecho 2 3 4 5 6 >arch/x86_64/boot/Makefile &&
+	test_write_lines 2 3 4 5 6 >arch/x86_64/boot/Makefile &&
 	git add . &&
 	test_tick &&
 	git commit -a -m second &&
diff --git a/t/t4138-apply-ws-expansion.sh b/t/t4138-apply-ws-expansion.sh
new file mode 100755
index 0000000..0ffe33f
--- /dev/null
+++ b/t/t4138-apply-ws-expansion.sh
@@ -0,0 +1,121 @@
+#!/bin/sh
+#
+# Copyright (C) 2015 Kyle J. McKay
+#
+
+test_description='git apply test patches with whitespace expansion.'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	#
+	## create test-N, patchN.patch, expect-N files
+	#
+
+	# test 1
+	printf "\t%s\n" 1 2 3 4 5 6 >before &&
+	printf "\t%s\n" 1 2 3 >after &&
+	printf "%64s\n" a b c >>after &&
+	printf "\t%s\n" 4 5 6 >>after &&
+	git diff --no-index before after |
+		sed -e "s/before/test-1/" -e "s/after/test-1/" >patch1.patch &&
+	printf "%64s\n" 1 2 3 4 5 6 >test-1 &&
+	printf "%64s\n" 1 2 3 a b c 4 5 6 >expect-1 &&
+
+	# test 2
+	printf "\t%s\n" a b c d e f >before &&
+	printf "\t%s\n" a b c >after &&
+	n=10 &&
+	x=1 &&
+	while test $x -lt $n
+	do
+		printf "%63s%d\n" "" $x >>after
+		x=$(( $x + 1 ))
+	done &&
+	printf "\t%s\n" d e f >>after &&
+	git diff --no-index before after |
+		sed -e "s/before/test-2/" -e "s/after/test-2/" >patch2.patch &&
+	printf "%64s\n" a b c d e f >test-2 &&
+	printf "%64s\n" a b c >expect-2 &&
+	x=1 &&
+	while test $x -lt $n
+	do
+		printf "%63s%d\n" "" $x >>expect-2
+		x=$(( $x + 1 ))
+	done &&
+	printf "%64s\n" d e f >>expect-2 &&
+
+	# test 3
+	printf "\t%s\n" a b c d e f >before &&
+	printf "\t%s\n" a b c >after &&
+	n=100 &&
+	x=0 &&
+	while test $x -lt $n
+	do
+		printf "%63s%02d\n" "" $x >>after
+		x=$(( $x + 1 ))
+	done &&
+	printf "\t%s\n" d e f >>after &&
+	git diff --no-index before after |
+	sed -e "s/before/test-3/" -e "s/after/test-3/" >patch3.patch &&
+	printf "%64s\n" a b c d e f >test-3 &&
+	printf "%64s\n" a b c >expect-3 &&
+	x=0 &&
+	while test $x -lt $n
+	do
+		printf "%63s%02d\n" "" $x >>expect-3
+		x=$(( $x + 1 ))
+	done &&
+	printf "%64s\n" d e f >>expect-3 &&
+
+	# test 4
+	>before &&
+	x=0 &&
+	while test $x -lt 50
+	do
+		printf "\t%02d\n" $x >>before
+		x=$(( $x + 1 ))
+	done &&
+	cat before >after &&
+	printf "%64s\n" a b c >>after &&
+	while test $x -lt 100
+	do
+		printf "\t%02d\n" $x >>before
+		printf "\t%02d\n" $x >>after
+		x=$(( $x + 1 ))
+	done &&
+	git diff --no-index before after |
+	sed -e "s/before/test-4/" -e "s/after/test-4/" >patch4.patch &&
+	>test-4 &&
+	x=0 &&
+	while test $x -lt 50
+	do
+		printf "%63s%02d\n" "" $x >>test-4
+		x=$(( $x + 1 ))
+	done &&
+	cat test-4 >expect-4 &&
+	printf "%64s\n" a b c >>expect-4 &&
+	while test $x -lt 100
+	do
+		printf "%63s%02d\n" "" $x >>test-4
+		printf "%63s%02d\n" "" $x >>expect-4
+		x=$(( $x + 1 ))
+	done &&
+
+	git config core.whitespace tab-in-indent,tabwidth=63 &&
+	git config apply.whitespace fix
+
+'
+
+# Note that `patch` can successfully apply all patches when run
+# with the --ignore-whitespace option.
+
+for t in 1 2 3 4
+do
+	test_expect_success 'apply with ws expansion (t=$t)' '
+		git apply patch$t.patch &&
+		test_cmp test-$t expect-$t
+	'
+done
+
+test_done
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 99ab7ca..5f2b290 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -212,6 +212,21 @@
 	test_cmp expect actual
 '
 
+cat > expect << EOF
+second
+initial
+EOF
+test_expect_success 'log --invert-grep --grep' '
+	git log --pretty="tformat:%s" --invert-grep --grep=th --grep=Sec >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'log --invert-grep --grep -i' '
+	echo initial >expect &&
+	git log --pretty="tformat:%s" --invert-grep -i --grep=th --grep=Sec >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'log --grep option parsing' '
 	echo second >expect &&
 	git log -1 --pretty="tformat:%s" --grep sec >actual &&
diff --git a/t/t4255-am-submodule.sh b/t/t4255-am-submodule.sh
index 8bde7db..0ba8194 100755
--- a/t/t4255-am-submodule.sh
+++ b/t/t4255-am-submodule.sh
@@ -18,4 +18,76 @@
 KNOWN_FAILURE_NOFF_MERGE_ATTEMPTS_TO_MERGE_REMOVED_SUBMODULE_FILES=1
 test_submodule_switch "am_3way"
 
+test_expect_success 'setup diff.submodule' '
+	test_commit one &&
+	INITIAL=$(git rev-parse HEAD) &&
+
+	git init submodule &&
+	(
+		cd submodule &&
+		test_commit two &&
+		git rev-parse HEAD >../initial-submodule
+	) &&
+	git submodule add ./submodule &&
+	git commit -m first &&
+
+	(
+		cd submodule &&
+		test_commit three &&
+		git rev-parse HEAD >../first-submodule
+	) &&
+	git add submodule &&
+	git commit -m second &&
+	SECOND=$(git rev-parse HEAD) &&
+
+	(
+		cd submodule &&
+		git mv two.t four.t &&
+		git commit -m "second submodule" &&
+		git rev-parse HEAD >../second-submodule
+	) &&
+	test_commit four &&
+	git add submodule &&
+	git commit --amend --no-edit &&
+	THIRD=$(git rev-parse HEAD) &&
+	git submodule update --init
+'
+
+run_test() {
+	START_COMMIT=$1 &&
+	EXPECT=$2 &&
+	# Abort any merges in progress: the previous
+	# test may have failed, and we should clean up.
+	test_might_fail git am --abort &&
+	git reset --hard $START_COMMIT &&
+	rm -f *.patch &&
+	git format-patch -1 &&
+	git reset --hard $START_COMMIT^ &&
+	git submodule update &&
+	git am *.patch &&
+	git submodule update &&
+	git -C submodule rev-parse HEAD >actual &&
+	test_cmp $EXPECT actual
+}
+
+test_expect_success 'diff.submodule unset' '
+	test_unconfig diff.submodule &&
+	run_test $SECOND first-submodule
+'
+
+test_expect_success 'diff.submodule unset with extra file' '
+	test_unconfig diff.submodule &&
+	run_test $THIRD second-submodule
+'
+
+test_expect_success 'diff.submodule=log' '
+	test_config diff.submodule log &&
+	run_test $SECOND first-submodule
+'
+
+test_expect_success 'diff.submodule=log with extra file' '
+	test_config diff.submodule log &&
+	run_test $THIRD second-submodule
+'
+
 test_done
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index e32e46d..0794d33 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -253,4 +253,12 @@
 	test_path_is_missing .git/shallow
 '
 
+test_expect_success 'prune: handle alternate object database' '
+	test_create_repo A &&
+	git -C A commit --allow-empty -m "initial commit" &&
+	git clone --shared A B &&
+	git -C B commit --allow-empty -m "next commit" &&
+	git -C B prune
+'
+
 test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 85c7fec..e4436c1 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1434,4 +1434,67 @@
 
 '
 
+test_expect_success 'updateInstead with push-to-checkout hook' '
+	rm -fr testrepo &&
+	git init testrepo &&
+	(
+		cd testrepo &&
+		git pull .. master &&
+		git reset --hard HEAD^^ &&
+		git tag initial &&
+		git config receive.denyCurrentBranch updateInstead &&
+		write_script .git/hooks/push-to-checkout <<-\EOF
+		echo >&2 updating from $(git rev-parse HEAD)
+		echo >&2 updating to "$1"
+
+		git update-index -q --refresh &&
+		git read-tree -u -m HEAD "$1" || {
+			status=$?
+			echo >&2 read-tree failed
+			exit $status
+		}
+		EOF
+	) &&
+
+	# Try pushing into a pristine
+	git push testrepo master &&
+	(
+		cd testrepo &&
+		git diff --quiet &&
+		git diff HEAD --quiet &&
+		test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
+	) &&
+
+	# Try pushing into a repository with conflicting change
+	(
+		cd testrepo &&
+		git reset --hard initial &&
+		echo conflicting >path2
+	) &&
+	test_must_fail git push testrepo master &&
+	(
+		cd testrepo &&
+		test $(git rev-parse initial) = $(git rev-parse HEAD) &&
+		test conflicting = "$(cat path2)" &&
+		git diff-index --quiet --cached HEAD
+	) &&
+
+	# Try pushing into a repository with unrelated change
+	(
+		cd testrepo &&
+		git reset --hard initial &&
+		echo unrelated >path1 &&
+		echo irrelevant >path5 &&
+		git add path5
+	) &&
+	git push testrepo master &&
+	(
+		cd testrepo &&
+		test "$(cat path1)" = unrelated &&
+		test "$(cat path5)" = irrelevant &&
+		test "$(git diff --name-only --cached HEAD)" = path5 &&
+		test $(git -C .. rev-parse HEAD) = $(git rev-parse HEAD)
+	)
+'
+
 test_done
diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
new file mode 100755
index 0000000..3480b33
--- /dev/null
+++ b/t/t5543-atomic-push.sh
@@ -0,0 +1,194 @@
+#!/bin/sh
+
+test_description='pushing to a repository using the atomic push option'
+
+. ./test-lib.sh
+
+mk_repo_pair () {
+	rm -rf workbench upstream &&
+	test_create_repo upstream &&
+	test_create_repo workbench &&
+	(
+		cd upstream &&
+		git config receive.denyCurrentBranch warn
+	) &&
+	(
+		cd workbench &&
+		git remote add up ../upstream
+	)
+}
+
+# Compare the ref ($1) in upstream with a ref value from workbench ($2)
+# i.e. test_refs second HEAD@{2}
+test_refs () {
+	test $# = 2 &&
+	git -C upstream rev-parse --verify "$1" >expect &&
+	git -C workbench rev-parse --verify "$2" >actual &&
+	test_cmp expect actual
+}
+
+test_expect_success 'atomic push works for a single branch' '
+	mk_repo_pair &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git push --mirror up &&
+		test_commit two &&
+		git push --atomic up master
+	) &&
+	test_refs master master
+'
+
+test_expect_success 'atomic push works for two branches' '
+	mk_repo_pair &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git branch second &&
+		git push --mirror up &&
+		test_commit two &&
+		git checkout second &&
+		test_commit three &&
+		git push --atomic up master second
+	) &&
+	test_refs master master &&
+	test_refs second second
+'
+
+test_expect_success 'atomic push works in combination with --mirror' '
+	mk_repo_pair &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git checkout -b second &&
+		test_commit two &&
+		git push --atomic --mirror up
+	) &&
+	test_refs master master &&
+	test_refs second second
+'
+
+test_expect_success 'atomic push works in combination with --force' '
+	mk_repo_pair &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git branch second master &&
+		test_commit two_a &&
+		git checkout second &&
+		test_commit two_b &&
+		test_commit three_b &&
+		test_commit four &&
+		git push --mirror up &&
+		# The actual test is below
+		git checkout master &&
+		test_commit three_a &&
+		git checkout second &&
+		git reset --hard HEAD^ &&
+		git push --force --atomic up master second
+	) &&
+	test_refs master master &&
+	test_refs second second
+'
+
+# set up two branches where master can be pushed but second can not
+# (non-fast-forward). Since second can not be pushed the whole operation
+# will fail and leave master untouched.
+test_expect_success 'atomic push fails if one branch fails' '
+	mk_repo_pair &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git checkout -b second master &&
+		test_commit two &&
+		test_commit three &&
+		test_commit four &&
+		git push --mirror up &&
+		git reset --hard HEAD~2 &&
+		test_commit five &&
+		git checkout master &&
+		test_commit six &&
+		test_must_fail git push --atomic --all up
+	) &&
+	test_refs master HEAD@{7} &&
+	test_refs second HEAD@{4}
+'
+
+test_expect_success 'atomic push fails if one tag fails remotely' '
+	# prepare the repo
+	mk_repo_pair &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git checkout -b second master &&
+		test_commit two &&
+		git push --mirror up
+	) &&
+	# a third party modifies the server side:
+	(
+		cd upstream &&
+		git checkout second &&
+		git tag test_tag second
+	) &&
+	# see if we can now push both branches.
+	(
+		cd workbench &&
+		git checkout master &&
+		test_commit three &&
+		git checkout second &&
+		test_commit four &&
+		git tag test_tag &&
+		test_must_fail git push --tags --atomic up master second
+	) &&
+	test_refs master HEAD@{3} &&
+	test_refs second HEAD@{1}
+'
+
+test_expect_success 'atomic push obeys update hook preventing a branch to be pushed' '
+	mk_repo_pair &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git checkout -b second master &&
+		test_commit two &&
+		git push --mirror up
+	) &&
+	(
+		cd upstream &&
+		HOOKDIR="$(git rev-parse --git-dir)/hooks" &&
+		HOOK="$HOOKDIR/update" &&
+		mkdir -p "$HOOKDIR" &&
+		write_script "$HOOK" <<-\EOF
+			# only allow update to master from now on
+			test "$1" = "refs/heads/master"
+		EOF
+	) &&
+	(
+		cd workbench &&
+		git checkout master &&
+		test_commit three &&
+		git checkout second &&
+		test_commit four &&
+		test_must_fail git push --atomic up master second
+	) &&
+	test_refs master HEAD@{3} &&
+	test_refs second HEAD@{1}
+'
+
+test_expect_success 'atomic push is not advertised if configured' '
+	mk_repo_pair &&
+	(
+		cd upstream
+		git config receive.advertiseatomic 0
+	) &&
+	(
+		cd workbench &&
+		test_commit one &&
+		git push --mirror up &&
+		test_commit two &&
+		test_must_fail git push --atomic up master
+	) &&
+	test_refs master HEAD@{1}
+'
+
+test_done
diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
index ac71418..2731ad4 100755
--- a/t/t5550-http-fetch-dumb.sh
+++ b/t/t5550-http-fetch-dumb.sh
@@ -165,6 +165,24 @@
 	)
 '
 
+test_expect_success 'fetch can handle previously-fetched .idx files' '
+	git checkout --orphan branch1 &&
+	echo base >file &&
+	git add file &&
+	git commit -m base &&
+	git --bare init "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git &&
+	git push "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git branch1 &&
+	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git repack -d &&
+	git checkout -b branch2 branch1 &&
+	echo b2 >>file &&
+	git commit -a -m b2 &&
+	git push "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git branch2 &&
+	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git repack -d &&
+	git --bare init clone_packed_branches.git &&
+	git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch1:branch1 &&
+	git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch2:branch2
+'
+
 test_expect_success 'did not use upload-pack service' '
 	grep '/git-upload-pack' <"$HTTPD_ROOT_PATH"/access.log >act
 	: >exp
@@ -196,5 +214,47 @@
 	grep "this is the error message" stderr
 '
 
+check_language () {
+	case "$2" in
+	'')
+		>expect
+		;;
+	?*)
+		echo "Accept-Language: $1" >expect
+		;;
+	esac &&
+	GIT_CURL_VERBOSE=1 \
+	LANGUAGE=$2 \
+	git ls-remote "$HTTPD_URL/dumb/repo.git" >output 2>&1 &&
+	tr -d '\015' <output |
+	sort -u |
+	sed -ne '/^Accept-Language:/ p' >actual &&
+	test_cmp expect actual
+}
+
+test_expect_success 'git client sends Accept-Language based on LANGUAGE' '
+	check_language "ko-KR, *;q=0.9" ko_KR.UTF-8'
+
+test_expect_success 'git client sends Accept-Language correctly with unordinary LANGUAGE' '
+	check_language "ko-KR, *;q=0.9" "ko_KR:" &&
+	check_language "ko-KR, en-US;q=0.9, *;q=0.8" "ko_KR::en_US" &&
+	check_language "ko-KR, *;q=0.9" ":::ko_KR" &&
+	check_language "ko-KR, en-US;q=0.9, *;q=0.8" "ko_KR!!:en_US" &&
+	check_language "ko-KR, ja-JP;q=0.9, *;q=0.8" "ko_KR en_US:ja_JP"'
+
+test_expect_success 'git client sends Accept-Language with many preferred languages' '
+	check_language "ko-KR, en-US;q=0.9, fr-CA;q=0.8, de;q=0.7, sr;q=0.6, \
+ja;q=0.5, zh;q=0.4, sv;q=0.3, pt;q=0.2, *;q=0.1" \
+		ko_KR.EUC-KR:en_US.UTF-8:fr_CA:de.UTF-8@euro:sr@latin:ja:zh:sv:pt &&
+	check_language "ko-KR, en-US;q=0.99, fr-CA;q=0.98, de;q=0.97, sr;q=0.96, \
+ja;q=0.95, zh;q=0.94, sv;q=0.93, pt;q=0.92, nb;q=0.91, *;q=0.90" \
+		ko_KR.EUC-KR:en_US.UTF-8:fr_CA:de.UTF-8@euro:sr@latin:ja:zh:sv:pt:nb
+'
+
+test_expect_success 'git client does not send an empty Accept-Language' '
+	GIT_CURL_VERBOSE=1 LANGUAGE= git ls-remote "$HTTPD_URL/dumb/repo.git" 2>stderr &&
+	! grep "^Accept-Language:" stderr
+'
+
 stop_httpd
 test_done
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 2419407..c9d3ed1 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -281,4 +281,28 @@
 	)
 '
 
+test_expect_success 'fetch HEAD' '
+	(cd server &&
+	git checkout master &&
+	echo more >>file &&
+	git commit -a -m more
+	) &&
+	(cd local &&
+	git fetch origin HEAD
+	) &&
+	compare_refs server HEAD local FETCH_HEAD
+'
+
+test_expect_success 'fetch url' '
+	(cd server &&
+	git checkout master &&
+	echo more >>file &&
+	git commit -a -m more
+	) &&
+	(cd local &&
+	git fetch "testgit::${PWD}/../server"
+	) &&
+	compare_refs server HEAD local FETCH_HEAD
+'
+
 test_done
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index 3758961..190ee90 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -69,7 +69,8 @@
 	cp new1.txt dir/a.txt &&
 	cp orig.txt dir/o.txt &&
 	cp new2.txt dir/b.txt &&
-	( cd dir && git merge-file a.txt o.txt b.txt )
+	( cd dir && git merge-file a.txt o.txt b.txt ) &&
+	test_path_is_missing a.txt
 '
 
 cp new1.txt test.txt
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 7c88245..5811a98 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -171,6 +171,23 @@
 	test_cmp empty untracked
 '
 
+test_expect_success 'submodule add with /././ in path' '
+	echo "refs/heads/master" >expect &&
+	>empty &&
+
+	(
+		cd addtest &&
+		git submodule add "$submodurl" dotslashdotsubmod/././frotz/./ &&
+		git submodule init
+	) &&
+
+	rm -f heads head untracked &&
+	inspect addtest/dotslashdotsubmod/frotz ../../.. &&
+	test_cmp expect heads &&
+	test_cmp expect head &&
+	test_cmp empty untracked
+'
+
 test_expect_success 'submodule add with // in path' '
 	echo "refs/heads/master" >expect &&
 	>empty &&
diff --git a/t/t9817-git-p4-exclude.sh b/t/t9817-git-p4-exclude.sh
new file mode 100755
index 0000000..aac568e
--- /dev/null
+++ b/t/t9817-git-p4-exclude.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='git p4 tests for excluded paths during clone and sync'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+	start_p4d
+'
+
+# Create a repo with the structure:
+#
+#    //depot/wanted/foo
+#    //depot/discard/foo
+#
+# Check that we can exclude a subdirectory with both
+# clone and sync operations.
+
+test_expect_success 'create exclude repo' '
+	(
+		cd "$cli" &&
+		mkdir -p wanted discard &&
+		echo wanted >wanted/foo &&
+		echo discard >discard/foo &&
+		p4 add wanted/foo discard/foo &&
+		p4 submit -d "initial revision"
+	)
+'
+
+test_expect_success 'check the repo was created correctly' '
+	test_when_finished cleanup_git &&
+	git p4 clone --dest="$git" //depot/...@all &&
+	(
+		cd "$git" &&
+		test_path_is_file wanted/foo &&
+		test_path_is_file discard/foo
+	)
+'
+
+test_expect_success 'clone, excluding part of repo' '
+	test_when_finished cleanup_git &&
+	git p4 clone -//depot/discard/... --dest="$git" //depot/...@all &&
+	(
+		cd "$git" &&
+		test_path_is_file wanted/foo &&
+		test_path_is_missing discard/foo
+	)
+'
+
+test_expect_success 'clone, then sync with exclude' '
+	test_when_finished cleanup_git &&
+	git p4 clone -//depot/discard/... --dest="$git" //depot/...@all &&
+	(
+		cd "$cli" &&
+		p4 edit wanted/foo discard/foo &&
+		date >>wanted/foo &&
+		date >>discard/foo &&
+		p4 submit -d "updating" &&
+
+		cd "$git" &&
+		git p4 sync -//depot/discard/... &&
+		test_path_is_file wanted/foo &&
+		test_path_is_missing discard/foo
+	)
+'
+
+test_expect_success 'kill p4d' '
+	kill_p4d
+'
+
+test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index bb1402d..c096778 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1031,9 +1031,33 @@
 	test -x /usr/bin/time
 '
 
-# When the tests are run as root, permission tests will report that
-# things are writable when they shouldn't be.
-test -w / || test_set_prereq SANITY
+test_lazy_prereq NOT_ROOT '
+	uid=$(id -u) &&
+	test "$uid" != 0
+'
+
+# On a filesystem that lacks SANITY, a file can be deleted even if
+# the containing directory doesn't have write permissions, or a file
+# can be accessed even if the containing directory doesn't have read
+# or execute permissions, causing our tests that validate that Git
+# works sensibly in such situations.
+test_lazy_prereq SANITY '
+	mkdir SANETESTD.1 SANETESTD.2 &&
+
+	chmod +w SANETESTD.1 SANETESTD.2 &&
+	>SANETESTD.1/x 2>SANETESTD.2/x &&
+	chmod -w SANETESTD.1 &&
+	chmod -rx SANETESTD.2 ||
+	error "bug in test sript: cannot prepare SANETESTD"
+
+	! rm SANETESTD.1/x && ! test -f SANETESTD.2/x
+	status=$?
+
+	chmod +rwx SANETESTD.1 SANETESTD.2 &&
+	rm -rf SANETESTD.1 SANETESTD.2 ||
+	error "bug in test sript: cannot clean SANETESTD"
+	return $status
+'
 
 GIT_UNZIP=${GIT_UNZIP:-unzip}
 test_lazy_prereq UNZIP '
diff --git a/trailer.c b/trailer.c
index 623adeb..05b3859 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1,7 +1,6 @@
 #include "cache.h"
 #include "string-list.h"
 #include "run-command.h"
-#include "string-list.h"
 #include "commit.h"
 #include "trailer.h"
 /*
diff --git a/transport-helper.c b/transport-helper.c
index 0224687..5d99a6b 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -5,7 +5,6 @@
 #include "commit.h"
 #include "diff.h"
 #include "revision.h"
-#include "quote.h"
 #include "remote.h"
 #include "string-list.h"
 #include "thread-utils.h"
@@ -98,6 +97,8 @@
 	free(data);
 }
 
+static void standard_options(struct transport *t);
+
 static struct child_process *get_helper(struct transport *transport)
 {
 	struct helper_data *data = transport->data;
@@ -212,6 +213,7 @@
 	strbuf_release(&buf);
 	if (debug)
 		fprintf(stderr, "Debug: Capabilities complete.\n");
+	standard_options(transport);
 	return data->helper;
 }
 
@@ -339,24 +341,14 @@
 	int i;
 	struct strbuf buf = STRBUF_INIT;
 
-	standard_options(transport);
-	if (data->check_connectivity &&
-	    data->transport_options.check_self_contained_and_connected)
-		set_helper_option(transport, "check-connectivity", "true");
-
-	if (transport->cloning)
-		set_helper_option(transport, "cloning", "true");
-
-	if (data->transport_options.update_shallow)
-		set_helper_option(transport, "update-shallow", "true");
-
 	for (i = 0; i < nr_heads; i++) {
 		const struct ref *posn = to_fetch[i];
 		if (posn->status & REF_STATUS_UPTODATE)
 			continue;
 
 		strbuf_addf(&buf, "fetch %s %s\n",
-			    sha1_to_hex(posn->old_sha1), posn->name);
+			    sha1_to_hex(posn->old_sha1),
+			    posn->symref ? posn->symref : posn->name);
 	}
 
 	strbuf_addch(&buf, '\n');
@@ -454,7 +446,8 @@
 		if (posn->status & REF_STATUS_UPTODATE)
 			continue;
 
-		strbuf_addf(&buf, "import %s\n", posn->name);
+		strbuf_addf(&buf, "import %s\n",
+			    posn->symref ? posn->symref : posn->name);
 		sendline(data, &buf);
 		strbuf_reset(&buf);
 	}
@@ -487,14 +480,15 @@
 	 * fast-forward or this is a forced update.
 	 */
 	for (i = 0; i < nr_heads; i++) {
-		char *private;
+		char *private, *name;
 		posn = to_fetch[i];
 		if (posn->status & REF_STATUS_UPTODATE)
 			continue;
+		name = posn->symref ? posn->symref : posn->name;
 		if (data->refspecs)
-			private = apply_refspecs(data->refspecs, data->refspec_nr, posn->name);
+			private = apply_refspecs(data->refspecs, data->refspec_nr, name);
 		else
-			private = xstrdup(posn->name);
+			private = xstrdup(name);
 		if (private) {
 			read_ref(private, posn->old_sha1);
 			free(private);
@@ -620,6 +614,16 @@
 	if (!count)
 		return 0;
 
+	if (data->check_connectivity &&
+	    data->transport_options.check_self_contained_and_connected)
+		set_helper_option(transport, "check-connectivity", "true");
+
+	if (transport->cloning)
+		set_helper_option(transport, "cloning", "true");
+
+	if (data->transport_options.update_shallow)
+		set_helper_option(transport, "update-shallow", "true");
+
 	if (data->fetch)
 		return fetch_with_fetch(transport, nr_heads, to_fetch);
 
@@ -824,7 +828,6 @@
 		return 0;
 	}
 
-	standard_options(transport);
 	for_each_string_list_item(cas_option, &cas_options)
 		set_helper_option(transport, "cas", cas_option->string);
 
@@ -860,7 +863,7 @@
 			die("helper %s does not support dry-run", data->name);
 	} else if (flags & TRANSPORT_PUSH_CERT) {
 		if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
-			die("helper %s does not support dry-run", data->name);
+			die("helper %s does not support --signed", data->name);
 	}
 
 	if (flags & TRANSPORT_PUSH_FORCE) {
diff --git a/transport.c b/transport.c
index 08bcd3a..0694a7c 100644
--- a/transport.c
+++ b/transport.c
@@ -728,6 +728,10 @@
 						 ref->deletion ? NULL : ref->peer_ref,
 						 "remote failed to report status", porcelain);
 		break;
+	case REF_STATUS_ATOMIC_PUSH_FAILED:
+		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+						 "atomic push failed", porcelain);
+		break;
 	case REF_STATUS_OK:
 		print_ok_ref_status(ref, porcelain);
 		break;
@@ -826,6 +830,7 @@
 	args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
 	args.porcelain = !!(flags & TRANSPORT_PUSH_PORCELAIN);
 	args.push_cert = !!(flags & TRANSPORT_PUSH_CERT);
+	args.atomic = !!(flags & TRANSPORT_PUSH_ATOMIC);
 	args.url = transport->url;
 
 	ret = send_pack(&args, data->fd, data->conn, remote_refs,
diff --git a/transport.h b/transport.h
index 3e0091e..18d2cf8 100644
--- a/transport.h
+++ b/transport.h
@@ -125,6 +125,7 @@
 #define TRANSPORT_PUSH_NO_HOOK 512
 #define TRANSPORT_PUSH_FOLLOW_TAGS 1024
 #define TRANSPORT_PUSH_CERT 2048
+#define TRANSPORT_PUSH_ATOMIC 4096
 
 #define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
 #define TRANSPORT_SUMMARY(x) (int)(TRANSPORT_SUMMARY_WIDTH + strlen(x) - gettext_width(x)), (x)
diff --git a/urlmatch.c b/urlmatch.c
index 618d216..132d342 100644
--- a/urlmatch.c
+++ b/urlmatch.c
@@ -412,9 +412,9 @@
 	return 0;
 }
 
-int match_urls(const struct url_info *url,
-	       const struct url_info *url_prefix,
-	       int *exactusermatch)
+static int match_urls(const struct url_info *url,
+		      const struct url_info *url_prefix,
+		      int *exactusermatch)
 {
 	/*
 	 * url_prefix matches url if the scheme, host and port of url_prefix
diff --git a/urlmatch.h b/urlmatch.h
index b461dfd..528862a 100644
--- a/urlmatch.h
+++ b/urlmatch.h
@@ -31,7 +31,6 @@
 };
 
 extern char *url_normalize(const char *, struct url_info *);
-extern int match_urls(const struct url_info *url, const struct url_info *url_prefix, int *exactusermatch);
 
 struct urlmatch_item {
 	size_t matched_len;
diff --git a/userdiff.c b/userdiff.c
index fad52d6..2ccbee5 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -1,6 +1,5 @@
 #include "cache.h"
 #include "userdiff.h"
-#include "cache.h"
 #include "attr.h"
 
 static struct userdiff_driver *drivers;
diff --git a/walker.c b/walker.c
index f149371..483da4e 100644
--- a/walker.c
+++ b/walker.c
@@ -232,7 +232,7 @@
 			REALLOC_ARRAY(*write_ref, targets_alloc);
 		}
 		(*target)[targets] = xstrdup(tg_one);
-		(*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL;
+		(*write_ref)[targets] = xstrdup_or_null(rf_one);
 		targets++;
 	}
 	strbuf_release(&buf);
diff --git a/wrapper.c b/wrapper.c
index 007ec0d..d5a6cef 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -172,8 +172,22 @@
  * 64-bit is buggy, returning EINVAL if len >= INT_MAX; and even in
  * the absence of bugs, large chunks can result in bad latencies when
  * you decide to kill the process.
+ *
+ * We pick 8 MiB as our default, but if the platform defines SSIZE_MAX
+ * that is smaller than that, clip it to SSIZE_MAX, as a call to
+ * read(2) or write(2) larger than that is allowed to fail.  As the last
+ * resort, we allow a port to pass via CFLAGS e.g. "-DMAX_IO_SIZE=value"
+ * to override this, if the definition of SSIZE_MAX given by the platform
+ * is broken.
  */
-#define MAX_IO_SIZE (8*1024*1024)
+#ifndef MAX_IO_SIZE
+# define MAX_IO_SIZE_DEFAULT (8*1024*1024)
+# if defined(SSIZE_MAX) && (SSIZE_MAX < MAX_IO_SIZE_DEFAULT)
+#  define MAX_IO_SIZE SSIZE_MAX
+# else
+#  define MAX_IO_SIZE MAX_IO_SIZE_DEFAULT
+# endif
+#endif
 
 /*
  * xread() is the same a read(), but it automatically restarts read()
diff --git a/wt-status.c b/wt-status.c
index b54eac5..29666d0 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1140,7 +1140,7 @@
 	if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0)
 		goto got_nothing;
 
-	while (&sb.len && sb.buf[sb.len - 1] == '\n')
+	while (sb.len && sb.buf[sb.len - 1] == '\n')
 		strbuf_setlen(&sb, sb.len - 1);
 	if (!sb.len)
 		goto got_nothing;