Merge branch 'cb/maint-ls-files-error-report' into maint

* cb/maint-ls-files-error-report:
  t3005: do not assume a particular order of stdout and stderr of git-ls-files
  ls-files: fix pathspec display on error
diff --git a/.gitignore b/.gitignore
index acffdfa..8572c8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 /GIT-BUILD-OPTIONS
 /GIT-CFLAGS
+/GIT-LDFLAGS
 /GIT-GUI-VARS
 /GIT-VERSION-FILE
 /bin-wrappers/
diff --git a/Documentation/.gitignore b/Documentation/.gitignore
index 1c3a9fe..d62aebd 100644
--- a/Documentation/.gitignore
+++ b/Documentation/.gitignore
@@ -3,6 +3,7 @@
 *.[1-8]
 *.made
 *.texi
+*.pdf
 git.info
 gitman.info
 howto-index.txt
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 36989b7..18c71d7 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -232,6 +232,7 @@
 clean:
 	$(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7
 	$(RM) *.texi *.texi+ *.texi++ git.info gitman.info
+	$(RM) *.pdf
 	$(RM) howto-index.txt howto/*.html doc.dep
 	$(RM) technical/api-*.html technical/api-index.txt
 	$(RM) $(cmds_txt) *.made
diff --git a/Documentation/RelNotes/1.7.6.1.txt b/Documentation/RelNotes/1.7.6.1.txt
new file mode 100644
index 0000000..42e46ab
--- /dev/null
+++ b/Documentation/RelNotes/1.7.6.1.txt
@@ -0,0 +1,63 @@
+Git v1.7.6.1 Release Notes
+==========================
+
+Fixes since v1.7.6
+------------------
+
+ * Various codepaths that invoked zlib deflate/inflate assumed that these
+   functions can compress or uncompress more than 4GB data in one call on
+   platforms with 64-bit long, which has been corrected.
+
+ * "git unexecutable" reported that "unexecutable" was not found, even
+   though the actual error was that "unexecutable" was found but did
+   not have a proper she-bang line to be executed.
+
+ * Error exits from $PAGER were silently ignored.
+
+ * "git checkout -b <branch>" was confused when attempting to create a
+   branch whose name ends with "-g" followed by hexadecimal digits,
+   and refused to work.
+
+ * "git checkout -b <branch>" sometimes wrote a bogus reflog entry,
+   causing later "git checkout -" to fail.
+
+ * "git diff --cc" learned to correctly ignore binary files.
+
+ * "git diff -c/--cc" mishandled a deletion that resolves a conflict, and
+   looked in the working tree instead.
+
+ * "git fast-export" forgot to quote pathnames with unsafe characters
+   in its output.
+
+ * "git fetch" over smart-http transport used to abort when the
+   repository was updated between the initial connection and the
+   subsequent object transfer.
+
+ * "git fetch" did not recurse into submodules in subdirectories.
+
+ * "git ls-tree" did not error out when asked to show a corrupt tree.
+
+ * "git pull" without any argument left an extra whitespace after the
+   command name in its reflog.
+
+ * "git push --quiet" was not really quiet.
+
+ * "git rebase -i -p" incorrectly dropped commits from side branches.
+
+ * "git reset [<commit>] paths..." did not reset the index entry correctly
+   for unmerged paths.
+
+ * "git submodule add" did not allow a relative repository path when
+   the superproject did not have any default remote url.
+
+ * "git submodule foreach" failed to correctly give the standard input to
+   the user-supplied command it invoked.
+
+ * submodules that the user has never showed interest in by running
+   "git submodule init" was incorrectly marked as interesting by "git
+   submodule sync".
+
+ * "git submodule update --quiet" was not really quiet.
+
+  * "git tag -l <glob>..." did not take multiple glob patterns from the
+   command line.
diff --git a/Documentation/RelNotes/1.7.6.2.txt b/Documentation/RelNotes/1.7.6.2.txt
new file mode 100644
index 0000000..67ae414
--- /dev/null
+++ b/Documentation/RelNotes/1.7.6.2.txt
@@ -0,0 +1,8 @@
+Git v1.7.6.2 Release Notes
+==========================
+
+Fixes since v1.7.6.1
+--------------------
+
+ * v1.7.6.1 broke "git push --quiet"; it used to be a no-op against an old
+   version of Git running on the other end, but v1.7.6.1 made it abort.
diff --git a/Documentation/RelNotes/1.7.6.3.txt b/Documentation/RelNotes/1.7.6.3.txt
new file mode 100644
index 0000000..9597183
--- /dev/null
+++ b/Documentation/RelNotes/1.7.6.3.txt
@@ -0,0 +1,24 @@
+Git v1.7.6.3 Release Notes
+==========================
+
+Fixes since v1.7.6.2
+--------------------
+
+ * "git -c var=value subcmd" misparsed the custom configuration when
+   value contained an equal sign.
+
+ * "git fetch" had a major performance regression, wasting many
+   needless cycles in a repository where there is no submodules
+   present. This was especially bad, when there were many refs.
+
+ * "git reflog $refname" did not default to the "show" subcommand as
+   the documentation advertised the command to do.
+
+ * "git reset" did not leave meaningful log message in the reflog.
+
+ * "git status --ignored" did not show ignored items when there is no
+   untracked items.
+
+ * "git tag --contains $commit" was unnecessarily inefficient.
+
+Also contains minor fixes and documentation updates.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 938eccf..0dbf2c9 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -134,8 +134,7 @@
 
 (2) Generate your patch using git tools out of your commits.
 
-git based diff tools (git, Cogito, and StGIT included) generate
-unidiff which is the preferred format.
+git based diff tools generate unidiff which is the preferred format.
 
 You do not have to be afraid to use -M option to "git diff" or
 "git format-patch", if your patch involves file renames.  The
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 6b93777..ae9913b 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -344,7 +344,9 @@
 	SHA1, the date/time and the reason of the update, but
 	only when the file exists.  If this configuration
 	variable is set to true, missing "$GIT_DIR/logs/<ref>"
-	file is automatically created for branch heads.
+	file is automatically created for branch heads (i.e. under
+	refs/heads/), remote refs (i.e. under refs/remotes/),
+	note refs (i.e. under refs/notes/), and the symbolic ref HEAD.
 +
 This information can be used to determine what commit
 was the tip of a branch "2 days ago".
@@ -676,7 +678,7 @@
 browser.<tool>.cmd::
 	Specify the command to invoke the specified browser. The
 	specified command is evaluated in shell with the URLs passed
-	as arguments. (See linkgit:git-web--browse[1].)
+	as arguments. (See linkgit:git-web{litdd}browse[1].)
 
 browser.<tool>.path::
 	Override the path for the given tool that may be used to
diff --git a/Documentation/git-annotate.txt b/Documentation/git-annotate.txt
index 9eb75c3..05fd482 100644
--- a/Documentation/git-annotate.txt
+++ b/Documentation/git-annotate.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git annotate' [options] file [revision]
 
 DESCRIPTION
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index 7b7bafb..ab60a18 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git bisect' <subcommand> <options>
 
 DESCRIPTION
diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
index 205d83d..c9fdf84 100644
--- a/Documentation/git-check-ref-format.txt
+++ b/Documentation/git-check-ref-format.txt
@@ -18,9 +18,12 @@
 status if it is not.
 
 A reference is used in git to specify branches and tags.  A
-branch head is stored under the `$GIT_DIR/refs/heads` directory, and
-a tag is stored under the `$GIT_DIR/refs/tags` directory (or, if refs
-are packed by `git gc`, as entries in the `$GIT_DIR/packed-refs` file).
+branch head is stored in the `refs/heads` hierarchy, while
+a tag is stored in the `refs/tags` hierarchy of the ref namespace
+(typically in `$GIT_DIR/refs/heads` and `$GIT_DIR/refs/tags`
+directories or, as entries in file `$GIT_DIR/packed-refs`
+if refs are packed by `git gc`).
+
 git imposes the following rules on how references are named:
 
 . They can include slash `/` for hierarchical (directory)
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index 9d8fe0d..6c9c2cb 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
 
 DESCRIPTION
diff --git a/Documentation/git-cherry.txt b/Documentation/git-cherry.txt
index 79448c5..f6c19c7 100644
--- a/Documentation/git-cherry.txt
+++ b/Documentation/git-cherry.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git cherry' [-v] [<upstream> [<head> [<limit>]]]
 
 DESCRIPTION
diff --git a/Documentation/git-citool.txt b/Documentation/git-citool.txt
index 6e5c812..c7a11c3 100644
--- a/Documentation/git-citool.txt
+++ b/Documentation/git-citool.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git citool'
 
 DESCRIPTION
diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt
index f524d76..0fdb82e 100644
--- a/Documentation/git-commit-tree.txt
+++ b/Documentation/git-commit-tree.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git commit-tree' <tree> [(-p <parent commit>)...] < changelog
 
 DESCRIPTION
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 7951cb7..5cc84a1 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -284,7 +284,7 @@
 your working tree are temporarily stored to a staging area
 called the "index" with 'git add'.  A file can be
 reverted back, only in the index but not in the working tree,
-to that of the last commit with `git reset HEAD -- <file>`,
+to that of the last commit with `git reset HEAD \-- <file>`,
 which effectively reverts 'git add' and prevents the changes to
 this file from participating in the next commit.  After building
 the state to be committed incrementally with these commands,
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index a73933a..23c80ce 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git count-objects' [-v]
 
 DESCRIPTION
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index ad93a3e..7f79cec 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git cvsexportcommit' [-h] [-u] [-v] [-c] [-P] [-p] [-a] [-d cvsroot]
 	[-w cvsworkdir] [-W] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
 
diff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.txt
index 8d48194..906774f 100644
--- a/Documentation/git-diff-files.txt
+++ b/Documentation/git-diff-files.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git diff-files' [-q] [-0|-1|-2|-3|-c|--cc] [<common diff options>] [<path>...]
 
 DESCRIPTION
diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt
index 2ea22ab..c0b7c58 100644
--- a/Documentation/git-diff-index.txt
+++ b/Documentation/git-diff-index.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git diff-index' [-m] [--cached] [<common diff options>] <tree-ish> [<path>...]
 
 DESCRIPTION
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 590f410..a03515f 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git difftool' [<options>] [<commit> [<commit>]] [--] [<path>...]
 
 DESCRIPTION
diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt
index 781bd6e..a29ac02 100644
--- a/Documentation/git-fast-export.txt
+++ b/Documentation/git-fast-export.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git fast-export [options]' | 'git fast-import'
 
 DESCRIPTION
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 3f5b912..95e480e 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 frontend | 'git fast-import' [options]
 
 DESCRIPTION
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 48d4bf6..ed1bdaa 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git fetch-pack' [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]
 
 DESCRIPTION
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index 60ac8d2..b41d7c1 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -8,12 +8,10 @@
 
 SYNOPSIS
 --------
+[verse]
 'git fetch' [<options>] [<repository> [<refspec>...]]
-
 'git fetch' [<options>] <group>
-
 'git fetch' --multiple [<options>] [(<repository> | <group>)...]
-
 'git fetch' --all [<options>]
 
 
diff --git a/Documentation/git-fsck-objects.txt b/Documentation/git-fsck-objects.txt
index 90ebb8a..eec4bdb 100644
--- a/Documentation/git-fsck-objects.txt
+++ b/Documentation/git-fsck-objects.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git fsck-objects' ...
 
 DESCRIPTION
diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index 4966cb5..815afcb 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune]
 
 DESCRIPTION
diff --git a/Documentation/git-get-tar-commit-id.txt b/Documentation/git-get-tar-commit-id.txt
index 8035736..1e2a20d 100644
--- a/Documentation/git-get-tar-commit-id.txt
+++ b/Documentation/git-get-tar-commit-id.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git get-tar-commit-id' < <tarfile>
 
 
diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.txt
index 32a833e..18f713b 100644
--- a/Documentation/git-gui.txt
+++ b/Documentation/git-gui.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git gui' [<command>] [arguments]
 
 DESCRIPTION
diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt
index 42aa2b0..9e0b3f6 100644
--- a/Documentation/git-help.txt
+++ b/Documentation/git-help.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git help' [-a|--all|-i|--info|-m|--man|-w|--web] [COMMAND]
 
 DESCRIPTION
diff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.txt
index fefa752..4d42073 100644
--- a/Documentation/git-http-fetch.txt
+++ b/Documentation/git-http-fetch.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin] <commit> <url>
 
 DESCRIPTION
diff --git a/Documentation/git-http-push.txt b/Documentation/git-http-push.txt
index 82ae34b..2e67362 100644
--- a/Documentation/git-http-push.txt
+++ b/Documentation/git-http-push.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git http-push' [--all] [--dry-run] [--force] [--verbose] <url> <ref> [<ref>...]
 
 DESCRIPTION
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 4e09708..875d283 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git imap-send'
 
 
diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt
index 9f97f5a..a21e346 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--separate-git-dir <git dir>] [--shared[=<permissions>]]
 
 
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index f2777a7..9ac2bba 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
 	  [--separate-git-dir <git dir>]
 	  [--shared[=<permissions>]] [directory]
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index de5c0d3..771a356 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git log' [<options>] [<since>..<until>] [[\--] <path>...]
 
 DESCRIPTION
@@ -68,10 +69,13 @@
 	its size is not included.
 
 [\--] <path>...::
-	Show only commits that affect any of the specified paths. To
-	prevent confusion with options and branch names, paths may need
-	to be prefixed with "\-- " to separate them from options or
-	refnames.
+	Show only commits that are enough to explain how the files
+	that match the specified paths came to be.  See "History
+	Simplification" below for details and other simplification
+	modes.
++
+To prevent confusion with options and branch names, paths may need to
+be prefixed with "\-- " to separate them from options or refnames.
 
 include::rev-list-options.txt[]
 
diff --git a/Documentation/git-lost-found.txt b/Documentation/git-lost-found.txt
index adf7e1c..c406a11 100644
--- a/Documentation/git-lost-found.txt
+++ b/Documentation/git-lost-found.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git lost-found'
 
 DESCRIPTION
diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt
index ed45662..51dc325 100644
--- a/Documentation/git-mailinfo.txt
+++ b/Documentation/git-mailinfo.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n] [--scissors] <msg> <patch>
 
 
diff --git a/Documentation/git-mailsplit.txt b/Documentation/git-mailsplit.txt
index 9b2049d..4d1b871 100644
--- a/Documentation/git-mailsplit.txt
+++ b/Documentation/git-mailsplit.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git mailsplit' [-b] [-f<nn>] [-d<prec>] [--keep-cr] -o<directory> [--] [(<mbox>|<Maildir>)...]
 
 DESCRIPTION
diff --git a/Documentation/git-merge-index.txt b/Documentation/git-merge-index.txt
index 6ce5467..e0df1b3 100644
--- a/Documentation/git-merge-index.txt
+++ b/Documentation/git-merge-index.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git merge-index' [-o] [-q] <merge-program> (-a | [--] <file>*)
 
 DESCRIPTION
diff --git a/Documentation/git-merge-one-file.txt b/Documentation/git-merge-one-file.txt
index ee059de..04e803d 100644
--- a/Documentation/git-merge-one-file.txt
+++ b/Documentation/git-merge-one-file.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git merge-one-file'
 
 DESCRIPTION
diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt
index 3bfa7b4..c5f84b6 100644
--- a/Documentation/git-merge-tree.txt
+++ b/Documentation/git-merge-tree.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git merge-tree' <base-tree> <branch1> <branch2>
 
 DESCRIPTION
diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt
index 63edede..f98a41b 100644
--- a/Documentation/git-mergetool--lib.txt
+++ b/Documentation/git-mergetool--lib.txt
@@ -7,7 +7,8 @@
 
 SYNOPSIS
 --------
-'TOOL_MODE=(diff|merge) . "$(git --exec-path)/git-mergetool--lib"'
+[verse]
+'TOOL_MODE=(diff|merge) . "$(git --exec-path)/git-mergetool{litdd}lib"'
 
 DESCRIPTION
 -----------
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index 8c79ae8..3470910 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git mergetool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<file>...]
 
 DESCRIPTION
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 037ab10..65e167a 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git mktag' < signature_file
 
 DESCRIPTION
diff --git a/Documentation/git-mktree.txt b/Documentation/git-mktree.txt
index afe21be..5c6ebdf 100644
--- a/Documentation/git-mktree.txt
+++ b/Documentation/git-mktree.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git mktree' [-z] [--missing] [--batch]
 
 DESCRIPTION
diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt
index db0e030..b8db373 100644
--- a/Documentation/git-mv.txt
+++ b/Documentation/git-mv.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git mv' <options>... <args>...
 
 DESCRIPTION
diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.txt
index db9f0f7..f2869da 100644
--- a/Documentation/git-pack-redundant.txt
+++ b/Documentation/git-pack-redundant.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git pack-redundant' [ --verbose ] [ --alt-odb ] < --all | .pack filename ... >
 
 DESCRIPTION
diff --git a/Documentation/git-pack-refs.txt b/Documentation/git-pack-refs.txt
index 54b9253..a3c6677 100644
--- a/Documentation/git-pack-refs.txt
+++ b/Documentation/git-pack-refs.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git pack-refs' [--all] [--no-prune]
 
 DESCRIPTION
diff --git a/Documentation/git-parse-remote.txt b/Documentation/git-parse-remote.txt
index 02217f6..a45ea1e 100644
--- a/Documentation/git-parse-remote.txt
+++ b/Documentation/git-parse-remote.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 '. "$(git --exec-path)/git-parse-remote"'
 
 DESCRIPTION
diff --git a/Documentation/git-patch-id.txt b/Documentation/git-patch-id.txt
index 50e26f4..90268f0 100644
--- a/Documentation/git-patch-id.txt
+++ b/Documentation/git-patch-id.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git patch-id' < <patch>
 
 DESCRIPTION
diff --git a/Documentation/git-peek-remote.txt b/Documentation/git-peek-remote.txt
index a34d62f..87ea3fb 100644
--- a/Documentation/git-peek-remote.txt
+++ b/Documentation/git-peek-remote.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git peek-remote' [--upload-pack=<git-upload-pack>] [<host>:]<directory>
 
 DESCRIPTION
diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt
index 9e6202c..80dc022 100644
--- a/Documentation/git-prune-packed.txt
+++ b/Documentation/git-prune-packed.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git prune-packed' [-n|--dry-run] [-q|--quiet]
 
 
diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt
index f616a73..80d01b0 100644
--- a/Documentation/git-prune.txt
+++ b/Documentation/git-prune.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git prune' [-n] [-v] [--expire <expire>] [--] [<head>...]
 
 DESCRIPTION
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 14609cb..e1da468 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git pull' [options] [<repository> [<refspec>...]]
 
 
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 46a96f2..c45d53c 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git read-tree' [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>]
 		[-u [--exclude-per-directory=<gitignore>] | -i]]
 		[--index-output=<file>] [--no-sparse-checkout]
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 9a075bc..504945c 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -12,7 +12,6 @@
 	[<upstream>] [<branch>]
 'git rebase' [-i | --interactive] [options] --onto <newbase>
 	--root [<branch>]
-
 'git rebase' --continue | --skip | --abort
 
 DESCRIPTION
@@ -46,7 +45,7 @@
 It is possible that a merge failure will prevent this process from being
 completely automatic.  You will have to resolve any such merge failure
 and run `git rebase --continue`.  Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`.  To restore the
+that caused the merge failure with `git rebase --skip`.  To check out the
 original <branch> and remove the .git/rebase-apply working files, use the
 command `git rebase --abort` instead.
 
@@ -233,7 +232,11 @@
 	Restart the rebasing process after having resolved a merge conflict.
 
 --abort::
-	Restore the original branch and abort the rebase operation.
+	Abort the rebase operation and reset HEAD to the original
+	branch. If <branch> was provided when the rebase operation was
+	started, then HEAD will be reset to <branch>. Otherwise HEAD
+	will be reset to where it was when the rebase operation was
+	started.
 
 --skip::
 	Restart the rebasing process by skipping the current patch.
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index f34e0ae..459c085 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git-receive-pack' <directory>
 
 DESCRIPTION
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index 09057bf..976dc14 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git reflog' <subcommand> <options>
 
 DESCRIPTION
diff --git a/Documentation/git-relink.txt b/Documentation/git-relink.txt
index 9893376..3b33c99 100644
--- a/Documentation/git-relink.txt
+++ b/Documentation/git-relink.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git relink' [--safe] <dir>... <master_dir>
 
 DESCRIPTION
diff --git a/Documentation/git-remote-ext.txt b/Documentation/git-remote-ext.txt
index 68263a6..8a8e1d7 100644
--- a/Documentation/git-remote-ext.txt
+++ b/Documentation/git-remote-ext.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 git remote add <nick> "ext::<command>[ <arguments>...]"
 
 DESCRIPTION
diff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt
index 58f6ad4..930b403 100644
--- a/Documentation/git-remote-helpers.txt
+++ b/Documentation/git-remote-helpers.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git remote-<transport>' <repository> [<URL>]
 
 DESCRIPTION
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 528f34a..5a8c506 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -60,11 +60,11 @@
 +
 With `-t <branch>` option, instead of the default glob
 refspec for the remote to track all branches under
-`$GIT_DIR/remotes/<name>/`, a refspec to track only `<branch>`
+the `refs/remotes/<name>/` namespace, a refspec to track only `<branch>`
 is created.  You can give more than one `-t <branch>` to track
 multiple branches without grabbing all branches.
 +
-With `-m <master>` option, `$GIT_DIR/remotes/<name>/HEAD` is set
+With `-m <master>` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set
 up to point at remote's `<master>` branch. See also the set-head command.
 +
 When a fetch mirror is created with `\--mirror=fetch`, the refs will not
@@ -92,24 +92,25 @@
 
 'set-head'::
 
-Sets or deletes the default branch (`$GIT_DIR/remotes/<name>/HEAD`) for
+Sets or deletes the default branch (i.e. the target of the
+symbolic-ref `refs/remotes/<name>/HEAD`) for
 the named remote. Having a default branch for a remote is not required,
 but allows the name of the remote to be specified in lieu of a specific
 branch. For example, if the default branch for `origin` is set to
 `master`, then `origin` may be specified wherever you would normally
 specify `origin/master`.
 +
-With `-d`, `$GIT_DIR/remotes/<name>/HEAD` is deleted.
+With `-d`, the symbolic ref `refs/remotes/<name>/HEAD` is deleted.
 +
-With `-a`, the remote is queried to determine its `HEAD`, then
-`$GIT_DIR/remotes/<name>/HEAD` is set to the same branch. e.g., if the remote
+With `-a`, the remote is queried to determine its `HEAD`, then the
+symbolic-ref `refs/remotes/<name>/HEAD` is set to the same branch. e.g., if the remote
 `HEAD` is pointed at `next`, "`git remote set-head origin -a`" will set
-`$GIT_DIR/refs/remotes/origin/HEAD` to `refs/remotes/origin/next`. This will
+the symbolic-ref `refs/remotes/origin/HEAD` to `refs/remotes/origin/next`. This will
 only work if `refs/remotes/origin/next` already exists; if not it must be
 fetched first.
 +
-Use `<branch>` to set `$GIT_DIR/remotes/<name>/HEAD` explicitly. e.g., "git
-remote set-head origin master" will set `$GIT_DIR/refs/remotes/origin/HEAD` to
+Use `<branch>` to set the symbolic-ref `refs/remotes/<name>/HEAD` explicitly. e.g., "git
+remote set-head origin master" will set the symbolic-ref `refs/remotes/origin/HEAD` to
 `refs/remotes/origin/master`. This will only work if
 `refs/remotes/origin/master` already exists; if not it must be fetched first.
 +
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 0decee2..40af321 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [--window=<n>] [--depth=<n>]
 
 DESCRIPTION
diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt
index a0d1fa6..9ec115b 100644
--- a/Documentation/git-repo-config.txt
+++ b/Documentation/git-repo-config.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git repo-config' ...
 
 
diff --git a/Documentation/git-request-pull.txt b/Documentation/git-request-pull.txt
index 3521d8e..b99681c 100644
--- a/Documentation/git-request-pull.txt
+++ b/Documentation/git-request-pull.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git request-pull' [-p] <start> <url> [<end>]
 
 DESCRIPTION
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 52db1d8..a6253ba 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git rerere' ['clear'|'forget' <pathspec>|'diff'|'status'|'gc']
 
 DESCRIPTION
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 02c44c9..42c9676 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git rev-parse' [ --option ] <args>...
 
 DESCRIPTION
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index ac10cfb..3d0a7d1 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>...
 
 DESCRIPTION
@@ -23,7 +24,7 @@
 should see linkgit:git-reset[1], particularly the '--hard' option.  If
 you want to extract specific files as they were in another commit, you
 should see linkgit:git-checkout[1], specifically the `git checkout
-<commit> -- <filename>` syntax.  Take care with these alternatives as
+<commit> \-- <filename>` syntax.  Take care with these alternatives as
 both will discard uncommitted changes in your working directory.
 
 OPTIONS
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index 8c0554f..da0215d 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
 
 DESCRIPTION
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 5a168cf..327233c 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git send-email' [options] <file|directory|rev-list options>...
 
 
diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index 17f8f55..bd3eaa6 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]
 
 DESCRIPTION
diff --git a/Documentation/git-sh-i18n--envsubst.txt b/Documentation/git-sh-i18n--envsubst.txt
index 61e4c08..5c3ec32 100644
--- a/Documentation/git-sh-i18n--envsubst.txt
+++ b/Documentation/git-sh-i18n--envsubst.txt
@@ -1,5 +1,5 @@
-git-sh-i18n--envsubst(1)
-========================
+git-sh-i18n{litdd}envsubst(1)
+=============================
 
 NAME
 ----
@@ -10,8 +10,8 @@
 [verse]
 eval_gettext () {
 	printf "%s" "$1" | (
-		export PATH $('git sh-i18n--envsubst' --variables "$1");
-		'git sh-i18n--envsubst' "$1"
+		export PATH $('git sh-i18n{litdd}envsubst' --variables "$1");
+		'git sh-i18n{litdd}envsubst' "$1"
 	)
 }
 
@@ -22,7 +22,7 @@
 This documentation is meant for people who are studying the
 plumbing scripts and/or are writing new ones.
 
-git-sh-i18n--envsubst is Git's stripped-down copy of the GNU
+'git sh-i18n{litdd}envsubst' is Git's stripped-down copy of the GNU
 `envsubst(1)` program that comes with the GNU gettext package. It's
 used internally by linkgit:git-sh-i18n[1] to interpolate the variables
 passed to the the `eval_gettext` function.
diff --git a/Documentation/git-sh-i18n.txt b/Documentation/git-sh-i18n.txt
index 3b1f7ac..60cf49c 100644
--- a/Documentation/git-sh-i18n.txt
+++ b/Documentation/git-sh-i18n.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 '. "$(git --exec-path)/git-sh-i18n"'
 
 DESCRIPTION
@@ -34,7 +35,7 @@
 eval_gettext::
 	Currently a dummy fall-through function implemented as a wrapper
 	around `printf(1)` with variables expanded by the
-	linkgit:git-sh-i18n--envsubst[1] helper. Will be replaced by a
+	linkgit:git-sh-i18n{litdd}envsubst[1] helper. Will be replaced by a
 	real gettext implementation in a later version.
 
 GIT
diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt
index 27fd8ba..a2f346c 100644
--- a/Documentation/git-sh-setup.txt
+++ b/Documentation/git-sh-setup.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 '. "$(git --exec-path)/git-sh-setup"'
 
 DESCRIPTION
diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt
index d7d4b92..9b92506 100644
--- a/Documentation/git-shell.txt
+++ b/Documentation/git-shell.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git shell' [-c <command> <argument>]
 
 DESCRIPTION
diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt
index ee4559b..a8e77b5 100644
--- a/Documentation/git-show-branch.txt
+++ b/Documentation/git-show-branch.txt
@@ -13,7 +13,6 @@
 		[--more=<n> | --list | --independent | --merge-base]
 		[--no-name | --sha1-name] [--topics]
 		[(<rev> | <glob>)...]
-
 'git show-branch' (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]
 
 DESCRIPTION
diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.txt
index c4d99f1..2dcbbb2 100644
--- a/Documentation/git-show-index.txt
+++ b/Documentation/git-show-index.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git show-index' < idx-file
 
 
diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt
index 7f075e8..1f0e30b 100644
--- a/Documentation/git-show.txt
+++ b/Documentation/git-show.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git show' [options] <object>...
 
 DESCRIPTION
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 38cb741..3d51717 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git status' [<options>...] [--] [<pathspec>...]
 
 DESCRIPTION
@@ -69,6 +70,9 @@
 	(and suppresses the output of submodule summaries when the config option
 	`status.submodulesummary` is set).
 
+--ignored::
+	Show ignored files as well.
+
 -z::
 	Terminate entries with NUL, instead of LF.  This implies
 	the `--porcelain` output format if no other format is given.
@@ -119,7 +123,8 @@
 * 'C' = copied
 * 'U' = updated but unmerged
 
-Ignored files are not listed.
+Ignored files are not listed, unless `--ignored` option is in effect,
+in which case `XY` are `!!`.
 
     X          Y     Meaning
     -------------------------------------------------
@@ -142,6 +147,7 @@
     U           U    unmerged, both modified
     -------------------------------------------------
     ?           ?    untracked
+    !           !    ignored
     -------------------------------------------------
 
 If -b is used the short-format status is preceded by a line
diff --git a/Documentation/git-stripspace.txt b/Documentation/git-stripspace.txt
index 10509cc..b78f031 100644
--- a/Documentation/git-stripspace.txt
+++ b/Documentation/git-stripspace.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git stripspace' [-s | --strip-comments] < <stream>
 
 DESCRIPTION
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 5e7a413..0ec8574 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -78,7 +78,9 @@
 <repository> is the URL of the new submodule's origin repository.
 This may be either an absolute URL, or (if it begins with ./
 or ../), the location relative to the superproject's origin
-repository.
+repository. If the superproject doesn't have an origin configured
+the superproject is its own authoritative upstream and the current
+working directory is used instead.
 +
 <path> is the relative location for the cloned submodule to
 exist in the superproject. If <path> does not exist, then the
@@ -167,12 +169,14 @@
 
 sync::
 	Synchronizes submodules' remote URL configuration setting
-	to the value specified in .gitmodules.  This is useful when
+	to the value specified in .gitmodules. It will only affect those
+	submodules which already have an url entry in .git/config (that is the
+	case when they are initialized or freshly added). This is useful when
 	submodule URLs change upstream and you need to update your local
 	repositories accordingly.
 +
 "git submodule sync" synchronizes all submodules while
-"git submodule sync -- A" synchronizes submodule "A" only.
+"git submodule sync \-- A" synchronizes submodule "A" only.
 
 OPTIONS
 -------
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 713e523..ed5eca1 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git svn' <command> [options] [arguments]
 
 DESCRIPTION
diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt
index d7795ed..75b1ae5 100644
--- a/Documentation/git-symbolic-ref.txt
+++ b/Documentation/git-symbolic-ref.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git symbolic-ref' [-q] [-m <reason>] <name> [<ref>]
 
 DESCRIPTION
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index d82f621..fb1c0ac 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -12,7 +12,7 @@
 'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
 	<tagname> [<commit> | <object>]
 'git tag' -d <tagname>...
-'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>]
+'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>...]
 'git tag' -v <tagname>...
 
 DESCRIPTION
@@ -69,8 +69,11 @@
 	If the tag is not annotated, the commit message is displayed instead.
 
 -l <pattern>::
-	List tags with names that match the given pattern (or all if no pattern is given).
-	Typing "git tag" without arguments, also lists all tags.
+	List tags with names that match the given pattern (or all if no
+	pattern is given).  Running "git tag" without arguments also
+	lists all tags. The pattern is a shell wildcard (i.e., matched
+	using fnmatch(3)).  Multiple patterns may be given; if any of
+	them matches, the tag is shown.
 
 --contains <commit>::
 	Only list tags which contain the specified commit.
diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt
index 5f15754..95b135d 100644
--- a/Documentation/git-tar-tree.txt
+++ b/Documentation/git-tar-tree.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git tar-tree' [--remote=<repo>] <tree-ish> [ <base> ]
 
 DESCRIPTION
diff --git a/Documentation/git-unpack-file.txt b/Documentation/git-unpack-file.txt
index c49d727..e9f148a 100644
--- a/Documentation/git-unpack-file.txt
+++ b/Documentation/git-unpack-file.txt
@@ -9,6 +9,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git unpack-file' <blob>
 
 DESCRIPTION
diff --git a/Documentation/git-unpack-objects.txt b/Documentation/git-unpack-objects.txt
index dd77990..ff23494 100644
--- a/Documentation/git-unpack-objects.txt
+++ b/Documentation/git-unpack-objects.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git unpack-objects' [-n] [-q] [-r] [--strict] <pack-file
 
 
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index e25a65a..d377a35 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git update-ref' [-m <reason>] (-d <ref> [<oldvalue>] | [--no-deref] <ref> <newvalue> [<oldvalue>])
 
 DESCRIPTION
@@ -60,8 +61,9 @@
 
 Logging Updates
 ---------------
-If config parameter "core.logAllRefUpdates" is true or the file
-"$GIT_DIR/logs/<ref>" exists then `git update-ref` will append
+If config parameter "core.logAllRefUpdates" is true and the ref is one under
+"refs/heads/", "refs/remotes/", "refs/notes/", or the symbolic ref HEAD; or
+the file "$GIT_DIR/logs/<ref>" exists then `git update-ref` will append
 a line to the log file "$GIT_DIR/logs/<ref>" (dereferencing all
 symbolic refs before creating the log name) describing the change
 in ref value.  Log lines are formatted as:
diff --git a/Documentation/git-update-server-info.txt b/Documentation/git-update-server-info.txt
index 775024d..bd0e364 100644
--- a/Documentation/git-update-server-info.txt
+++ b/Documentation/git-update-server-info.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git update-server-info' [--force]
 
 DESCRIPTION
diff --git a/Documentation/git-upload-archive.txt b/Documentation/git-upload-archive.txt
index acbf634..4d52d38 100644
--- a/Documentation/git-upload-archive.txt
+++ b/Documentation/git-upload-archive.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git upload-archive' <directory>
 
 DESCRIPTION
diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.txt
index 4c0ca9d..a58e90c 100644
--- a/Documentation/git-upload-pack.txt
+++ b/Documentation/git-upload-pack.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git-upload-pack' [--strict] [--timeout=<n>] <directory>
 
 DESCRIPTION
diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt
index 6498f7c..5317cc2 100644
--- a/Documentation/git-var.txt
+++ b/Documentation/git-var.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git var' ( -l | <variable> )
 
 DESCRIPTION
diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.txt
index 7c2428d..cd23076 100644
--- a/Documentation/git-verify-pack.txt
+++ b/Documentation/git-verify-pack.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git verify-pack' [-v|--verbose] [-s|--stat-only] [--] <pack>.idx ...
 
 
diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt
index 8c9a718..5ff76e8 100644
--- a/Documentation/git-verify-tag.txt
+++ b/Documentation/git-verify-tag.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git verify-tag' <tag>...
 
 DESCRIPTION
diff --git a/Documentation/git-web--browse.txt b/Documentation/git-web--browse.txt
index 69d92fa..c2bc87b 100644
--- a/Documentation/git-web--browse.txt
+++ b/Documentation/git-web--browse.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git web{litdd}browse' [OPTIONS] URL/FILE ...
 
 DESCRIPTION
@@ -68,7 +69,7 @@
 You can explicitly provide a full path to your preferred browser by
 setting the configuration variable 'browser.<tool>.path'. For example,
 you can configure the absolute path to firefox by setting
-'browser.firefox.path'. Otherwise, 'git web--browse' assumes the tool
+'browser.firefox.path'. Otherwise, 'git web{litdd}browse' assumes the tool
 is available in PATH.
 
 browser.<tool>.cmd
diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt
index 31f3663..99388bd 100644
--- a/Documentation/git-whatchanged.txt
+++ b/Documentation/git-whatchanged.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git whatchanged' <option>...
 
 DESCRIPTION
diff --git a/Documentation/git-write-tree.txt b/Documentation/git-write-tree.txt
index e8c94c1..f22041a 100644
--- a/Documentation/git-write-tree.txt
+++ b/Documentation/git-write-tree.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git write-tree' [--missing-ok] [--prefix=<prefix>/]
 
 DESCRIPTION
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 3c7a832..3562da8 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -44,9 +44,12 @@
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.7.6/git.html[documentation for release 1.7.6]
+* link:v1.7.6.3/git.html[documentation for release 1.7.6.3]
 
 * release notes for
+  link:RelNotes/1.7.6.3.txt[1.7.6.3],
+  link:RelNotes/1.7.6.2.txt[1.7.6.2],
+  link:RelNotes/1.7.6.1.txt[1.7.6.1],
   link:RelNotes/1.7.6.txt[1.7.6].
 
 * link:v1.7.5.4/git.html[documentation for release 1.7.5.4]
@@ -523,16 +526,15 @@
 symbolic notation:
 
 HEAD::
-	indicates the head of the current branch (i.e. the
-	contents of `$GIT_DIR/HEAD`).
+	indicates the head of the current branch.
 
 <tag>::
 	a valid tag 'name'
-	(i.e. the contents of `$GIT_DIR/refs/tags/<tag>`).
+	(i.e. a `refs/tags/<tag>` reference).
 
 <head>::
 	a valid head 'name'
-	(i.e. the contents of `$GIT_DIR/refs/heads/<head>`).
+	(i.e. a `refs/heads/<head>` reference).
 
 For a more complete list of ways to spell object names, see
 "SPECIFYING REVISIONS" section in linkgit:gitrevisions[7].
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 412c55b..2bbe76b 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -79,7 +79,7 @@
 `$(prefix)/etc/gitattributes` file.
 
 Sometimes you would need to override an setting of an attribute
-for a path to `unspecified` state.  This can be done by listing
+for a path to `Unspecified` state.  This can be done by listing
 the name of the attribute prefixed with an exclamation point `!`.
 
 
@@ -868,7 +868,7 @@
 (See linkgit:git-config[1]).
 
 
-USING ATTRIBUTE MACROS
+USING MACRO ATTRIBUTES
 ----------------------
 
 You do not want any end-of-line conversions applied to, nor textual diffs
@@ -879,24 +879,27 @@
 ------------
 
 but that may become cumbersome, when you have many attributes.  Using
-attribute macros, you can specify groups of attributes set or unset at
-the same time.  The system knows a built-in attribute macro, `binary`:
+macro attributes, you can define an attribute that, when set, also
+sets or unsets a number of other attributes at the same time.  The
+system knows a built-in macro attribute, `binary`:
 
 ------------
 *.jpg binary
 ------------
 
-which is equivalent to the above.  Note that the attribute macros can only
-be "Set" (see the above example that sets "binary" macro as if it were an
-ordinary attribute --- setting it in turn unsets "text" and "diff").
+Setting the "binary" attribute also unsets the "text" and "diff"
+attributes as above.  Note that macro attributes can only be "Set",
+though setting one might have the effect of setting or unsetting other
+attributes or even returning other attributes to the "Unspecified"
+state.
 
 
-DEFINING ATTRIBUTE MACROS
+DEFINING MACRO ATTRIBUTES
 -------------------------
 
-Custom attribute macros can be defined only in the `.gitattributes` file
-at the toplevel (i.e. not in any subdirectory).  The built-in attribute
-macro "binary" is equivalent to:
+Custom macro attributes can be defined only in the `.gitattributes`
+file at the toplevel (i.e. not in any subdirectory).  The built-in
+macro attribute "binary" is equivalent to:
 
 ------------
 [attr]binary -diff -text
diff --git a/Documentation/gitcvs-migration.txt b/Documentation/gitcvs-migration.txt
index d861ec4..aeb0cdc 100644
--- a/Documentation/gitcvs-migration.txt
+++ b/Documentation/gitcvs-migration.txt
@@ -7,7 +7,8 @@
 
 SYNOPSIS
 --------
-git cvsimport *
+[verse]
+'git cvsimport' *
 
 DESCRIPTION
 -----------
diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt
index 6af29a4..370624c 100644
--- a/Documentation/gitdiffcore.txt
+++ b/Documentation/gitdiffcore.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git diff' *
 
 DESCRIPTION
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index e10ac58..a17a354 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'gitk' [<option>...] [<revs>] [--] [<path>...]
 
 DESCRIPTION
diff --git a/Documentation/gittutorial-2.txt b/Documentation/gittutorial-2.txt
index 7fe5848..f1e4422 100644
--- a/Documentation/gittutorial-2.txt
+++ b/Documentation/gittutorial-2.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 git *
 
 DESCRIPTION
diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.txt
index 0982f74..dee0505 100644
--- a/Documentation/gittutorial.txt
+++ b/Documentation/gittutorial.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 git *
 
 DESCRIPTION
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
index 1ef55ff..5e4f362 100644
--- a/Documentation/gitworkflows.txt
+++ b/Documentation/gitworkflows.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 git *
 
 
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index 8f62d1a..3595b58 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -161,8 +161,8 @@
 
 [[def_head]]head::
 	A <<def_ref,named reference>> to the <<def_commit,commit>> at the tip of a
-	<<def_branch,branch>>.  Heads are stored in
-	`$GIT_DIR/refs/heads/`, except when using packed refs. (See
+	<<def_branch,branch>>.  Heads are stored in a file in
+	`$GIT_DIR/refs/heads/` directory, except when using packed refs. (See
 	linkgit:git-pack-refs[1].)
 
 [[def_HEAD]]HEAD::
@@ -170,8 +170,8 @@
 	working tree>> is normally derived from the state of the tree
 	referred to by HEAD.  HEAD is a reference to one of the
 	<<def_head,heads>> in your repository, except when using a
-	<<def_detached_HEAD,detached HEAD>>, in which case it may
-	reference an arbitrary commit.
+	<<def_detached_HEAD,detached HEAD>>, in which case it directly
+	references an arbitrary commit.
 
 [[def_head_ref]]head ref::
 	A synonym for <<def_head,head>>.
@@ -382,8 +382,9 @@
 
 [[def_ref]]ref::
 	A 40-byte hex representation of a <<def_SHA1,SHA1>> or a name that
-	denotes a particular <<def_object,object>>. These may be stored in
-	`$GIT_DIR/refs/`.
+	denotes a particular <<def_object,object>>. They may be stored in
+	a file under `$GIT_DIR/refs/` directory, or
+	in the `$GIT_DIR/packed-refs` file.
 
 [[def_reflog]]reflog::
 	A reflog shows the local "history" of a ref.  In other words,
@@ -459,14 +460,14 @@
 	command.
 
 [[def_tag]]tag::
-	A <<def_ref,ref>> pointing to a <<def_tag_object,tag>> or
-	<<def_commit_object,commit object>>. In contrast to a <<def_head,head>>,
-	a tag is not changed by a <<def_commit,commit>>. Tags (not
-	<<def_tag_object,tag objects>>) are stored in `$GIT_DIR/refs/tags/`. A
-	git tag has nothing to do with a Lisp tag (which would be
-	called an <<def_object_type,object type>> in git's context). A
-	tag is most typically used to mark a particular point in the
-	commit ancestry <<def_chain,chain>>.
+	A <<def_ref,ref>> under `refs/tags/` namespace that points to an
+	object of an arbitrary type (typically a tag points to either a
+	<<def_tag_object,tag>> or a <<def_commit_object,commit object>>).
+	In contrast to a <<def_head,head>>, a tag is not updated by
+	the `commit` command. A git tag has nothing to do with a Lisp
+	tag (which would be called an <<def_object_type,object type>>
+	in git's context). A tag is most typically used to mark a particular
+	point in the commit ancestry <<def_chain,chain>>.
 
 [[def_tag_object]]tag object::
 	An <<def_object,object>> containing a <<def_ref,ref>> pointing to
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 62340a5..39e6207 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -313,7 +313,7 @@
 	 \   /   /   /   /
 	  `-------------'
 -----------------------------------------------------------------------
-The horizontal line of history A--P is taken to be the first parent of
+The horizontal line of history A---P is taken to be the first parent of
 each merge.  The commits are:
 
 * `I` is the initial commit, in which `foo` exists with contents
diff --git a/Documentation/technical/api-builtin.txt b/Documentation/technical/api-builtin.txt
index 5cb2b05..b0cafe8 100644
--- a/Documentation/technical/api-builtin.txt
+++ b/Documentation/technical/api-builtin.txt
@@ -49,6 +49,8 @@
 
 . Add an entry for `git-foo` to `command-list.txt`.
 
+. Add an entry for `/git-foo` to `.gitignore`.
+
 
 How a built-in is called
 ------------------------
diff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt
new file mode 100644
index 0000000..dbbea95
--- /dev/null
+++ b/Documentation/technical/api-ref-iteration.txt
@@ -0,0 +1,81 @@
+ref iteration API
+=================
+
+
+Iteration of refs is done by using an iterate function which will call a
+callback function for every ref. The callback function has this
+signature:
+
+	int handle_one_ref(const char *refname, const unsigned char *sha1,
+			   int flags, void *cb_data);
+
+There are different kinds of iterate functions which all take a
+callback of this type. The callback is then called for each found ref
+until the callback returns nonzero. The returned value is then also
+returned by the iterate function.
+
+Iteration functions
+-------------------
+
+* `head_ref()` just iterates the head ref.
+
+* `for_each_ref()` iterates all refs.
+
+* `for_each_ref_in()` iterates all refs which have a defined prefix and
+  strips that prefix from the passed variable refname.
+
+* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`,
+  `for_each_replace_ref()` iterate refs from the respective area.
+
+* `for_each_glob_ref()` iterates all refs that match the specified glob
+  pattern.
+
+* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined.
+
+* `head_ref_submodule()`, `for_each_ref_submodule()`,
+  `for_each_ref_in_submodule()`, `for_each_tag_ref_submodule()`,
+  `for_each_branch_ref_submodule()`, `for_each_remote_ref_submodule()`
+  do the same as the functions descibed above but for a specified
+  submodule.
+
+* `for_each_rawref()` can be used to learn about broken ref and symref.
+
+* `for_each_reflog()` iterates each reflog file.
+
+Submodules
+----------
+
+If you want to iterate the refs of a submodule you first need to add the
+submodules object database. You can do this by a code-snippet like
+this:
+
+	const char *path = "path/to/submodule"
+	if (!add_submodule_odb(path))
+		die("Error submodule '%s' not populated.", path);
+
+`add_submodule_odb()` will return an non-zero value on success. If you
+do not do this you will get an error for each ref that it does not point
+to a valid object.
+
+Note: As a side-effect of this you can not safely assume that all
+objects you lookup are available in superproject. All submodule objects
+will be available the same way as the superprojects objects.
+
+Example:
+--------
+
+----
+static int handle_remote_ref(const char *refname,
+		const unsigned char *sha1, int flags, void *cb_data)
+{
+	struct strbuf *output = cb_data;
+	strbuf_addf(output, "%s\n", refname);
+	return 0;
+}
+
+...
+
+	struct strbuf output = STRBUF_INIT;
+	for_each_remote_ref(handle_remote_ref, &output);
+	printf("%s", output.buf);
+----
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 369f91d..a7004c6 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -179,34 +179,36 @@
 
 Packfile Negotiation
 --------------------
-After reference and capabilities discovery, the client can decide
-to terminate the connection by sending a flush-pkt, telling the
-server it can now gracefully terminate (as happens with the ls-remote
-command) or it can enter the negotiation phase, where the client and
-server determine what the minimal packfile necessary for transport is.
+After reference and capabilities discovery, the client can decide to
+terminate the connection by sending a flush-pkt, telling the server it can
+now gracefully terminate, and disconnect, when it does not need any pack
+data. This can happen with the ls-remote command, and also can happen when
+the client already is up-to-date.
 
-Once the client has the initial list of references that the server
-has, as well as the list of capabilities, it will begin telling the
-server what objects it wants and what objects it has, so the server
-can make a packfile that only contains the objects that the client needs.
-The client will also send a list of the capabilities it wants to be in
-effect, out of what the server said it could do with the first 'want' line.
+Otherwise, it enters the negotiation phase, where the client and
+server determine what the minimal packfile necessary for transport is,
+by telling the server what objects it wants, its shallow objects
+(if any), and the maximum commit depth it wants (if any).  The client
+will also send a list of the capabilities it wants to be in effect,
+out of what the server said it could do with the first 'want' line.
 
 ----
   upload-request    =  want-list
-		       have-list
-		       compute-end
+		       *shallow-line
+		       *1depth-request
+		       flush-pkt
 
   want-list         =  first-want
 		       *additional-want
-		       flush-pkt
+
+  shallow-line      =  PKT_LINE("shallow" SP obj-id)
+
+  depth-request     =  PKT_LINE("deepen" SP depth)
 
   first-want        =  PKT-LINE("want" SP obj-id SP capability-list LF)
   additional-want   =  PKT-LINE("want" SP obj-id LF)
 
-  have-list         =  *have-line
-  have-line         =  PKT-LINE("have" SP obj-id LF)
-  compute-end       =  flush-pkt / PKT-LINE("done")
+  depth             =  1*DIGIT
 ----
 
 Clients MUST send all the obj-ids it wants from the reference
@@ -215,21 +217,64 @@
 obj-id in a 'want' command which did not appear in the response
 obtained through ref discovery.
 
-If client is requesting a shallow clone, it will now send a 'deepen'
-line with the depth it is requesting.
+The client MUST write all obj-ids which it only has shallow copies
+of (meaning that it does not have the parents of a commit) as
+'shallow' lines so that the server is aware of the limitations of
+the client's history. Clients MUST NOT mention an obj-id which
+it does not know exists on the server.
 
-Once all the "want"s (and optional 'deepen') are transferred,
-clients MUST send a flush-pkt. If the client has all the references
-on the server, client flushes and disconnects.
+The client now sends the maximum commit history depth it wants for
+this transaction, which is the number of commits it wants from the
+tip of the history, if any, as a 'deepen' line.  A depth of 0 is the
+same as not making a depth request. The client does not want to receive
+any commits beyond this depth, nor objects needed only to complete
+those commits. Commits whose parents are not received as a result are
+defined as shallow and marked as such in the server. This information
+is sent back to the client in the next step.
 
-TODO: shallow/unshallow response and document the deepen command in the ABNF.
+Once all the 'want's and 'shallow's (and optional 'deepen') are
+transferred, clients MUST send a flush-pkt, to tell the server side
+that it is done sending the list.
+
+Otherwise, if the client sent a positive depth request, the server
+will determine which commits will and will not be shallow and
+send this information to the client. If the client did not request
+a positive depth, this step is skipped.
+
+----
+  shallow-update   =  *shallow-line
+		      *unshallow-line
+		      flush-pkt
+
+  shallow-line     =  PKT-LINE("shallow" SP obj-id)
+
+  unshallow-line   =  PKT-LINE("unshallow" SP obj-id)
+----
+
+If the client has requested a positive depth, the server will compute
+the set of commits which are no deeper than the desired depth, starting
+at the client's wants. The server writes 'shallow' lines for each
+commit whose parents will not be sent as a result. The server writes
+an 'unshallow' line for each commit which the client has indicated is
+shallow, but is no longer shallow at the currently requested depth
+(that is, its parents will now be sent). The server MUST NOT mark
+as unshallow anything which the client has not indicated was shallow.
 
 Now the client will send a list of the obj-ids it has using 'have'
-lines.  In multi_ack mode, the canonical implementation will send up
-to 32 of these at a time, then will send a flush-pkt.  The canonical
-implementation will skip ahead and send the next 32 immediately,
-so that there is always a block of 32 "in-flight on the wire" at a
-time.
+lines, so the server can make a packfile that only contains the objects
+that the client needs. In multi_ack mode, the canonical implementation
+will send up to 32 of these at a time, then will send a flush-pkt. The
+canonical implementation will skip ahead and send the next 32 immediately,
+so that there is always a block of 32 "in-flight on the wire" at a time.
+
+----
+  upload-haves      =  have-list
+		       compute-end
+
+  have-list         =  *have-line
+  have-line         =  PKT-LINE("have" SP obj-id LF)
+  compute-end       =  flush-pkt / PKT-LINE("done")
+----
 
 If the server reads 'have' lines, it then will respond by ACKing any
 of the obj-ids the client said it had that the server also has. The
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index f04e4b1..b74b21f 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.6
+DEF_VER=v1.7.6.3
 
 LF='
 '
diff --git a/Makefile b/Makefile
index e40ac0c..75b407c 100644
--- a/Makefile
+++ b/Makefile
@@ -1706,7 +1706,7 @@
 	'-DGIT_MAN_PATH="$(mandir_SQ)"' \
 	'-DGIT_INFO_PATH="$(infodir_SQ)"'
 
-git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
+git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
 		$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
 
@@ -2004,17 +2004,17 @@
 	-DNDEBUG -DOVERRIDE_STRDUP -DREPLACE_SYSTEM_ALLOCATOR
 endif
 
-git-%$X: %.o $(GITLIBS)
+git-%$X: %.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
 
-git-imap-send$X: imap-send.o $(GITLIBS)
+git-imap-send$X: imap-send.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO)
 
-git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o $(GITLIBS)
+git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(CURL_LIBCURL)
-git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
+git-http-push$X: revision.o http.o http-push.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
 
@@ -2024,7 +2024,7 @@
 	ln -s $< $@ 2>/dev/null || \
 	cp $< $@
 
-$(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o $(GITLIBS)
+$(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
 
@@ -2094,6 +2094,15 @@
 		echo "$$FLAGS" >GIT-CFLAGS; \
             fi
 
+TRACK_LDFLAGS = $(subst ','\'',$(ALL_LDFLAGS))
+
+GIT-LDFLAGS: FORCE
+	@FLAGS='$(TRACK_LDFLAGS)'; \
+	    if test x"$$FLAGS" != x"`cat GIT-LDFLAGS 2>/dev/null`" ; then \
+		echo 1>&2 "    * new link flags"; \
+		echo "$$FLAGS" >GIT-LDFLAGS; \
+            fi
+
 # We need to apply sq twice, once to protect from the shell
 # that runs GIT-BUILD-OPTIONS, and then again to protect it
 # and the first level quoting from the shell that runs "echo".
@@ -2165,7 +2174,7 @@
 
 .PRECIOUS: $(TEST_OBJS)
 
-test-%$X: test-%.o $(GITLIBS)
+test-%$X: test-%.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)
 
 check-sha1:: test-sha1$X
@@ -2375,7 +2384,7 @@
 	$(MAKE) -C gitk-git clean
 	$(MAKE) -C git-gui clean
 endif
-	$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS
+	$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS
 
 .PHONY: all install clean strip
 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/RelNotes b/RelNotes
index 5fcc4ef..695f126 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.6.txt
\ No newline at end of file
+Documentation/RelNotes/1.7.6.3.txt
\ No newline at end of file
diff --git a/abspath.c b/abspath.c
index 3005aed..f9494c4 100644
--- a/abspath.c
+++ b/abspath.c
@@ -102,7 +102,8 @@
 	pwd = getenv("PWD");
 	if (pwd && strcmp(pwd, cwd)) {
 		stat(cwd, &cwd_stat);
-		if (!stat(pwd, &pwd_stat) &&
+		if ((cwd_stat.st_dev || cwd_stat.st_ino) &&
+		    !stat(pwd, &pwd_stat) &&
 		    pwd_stat.st_dev == cwd_stat.st_dev &&
 		    pwd_stat.st_ino == cwd_stat.st_ino) {
 			strlcpy(cwd, pwd, PATH_MAX);
diff --git a/archive-zip.c b/archive-zip.c
index cf28504..72d55a5 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -90,14 +90,14 @@
 static void *zlib_deflate(void *data, unsigned long size,
 		int compression_level, unsigned long *compressed_size)
 {
-	z_stream stream;
+	git_zstream stream;
 	unsigned long maxsize;
 	void *buffer;
 	int result;
 
 	memset(&stream, 0, sizeof(stream));
-	deflateInit(&stream, compression_level);
-	maxsize = deflateBound(&stream, size);
+	git_deflate_init(&stream, compression_level);
+	maxsize = git_deflate_bound(&stream, size);
 	buffer = xmalloc(maxsize);
 
 	stream.next_in = data;
@@ -106,7 +106,7 @@
 	stream.avail_out = maxsize;
 
 	do {
-		result = deflate(&stream, Z_FINISH);
+		result = git_deflate(&stream, Z_FINISH);
 	} while (result == Z_OK);
 
 	if (result != Z_STREAM_END) {
@@ -114,7 +114,7 @@
 		return NULL;
 	}
 
-	deflateEnd(&stream);
+	git_deflate_end(&stream);
 	*compressed_size = stream.total_out;
 
 	return buffer;
diff --git a/branch.c b/branch.c
index c0c865a..d62cc01 100644
--- a/branch.c
+++ b/branch.c
@@ -210,7 +210,7 @@
 			 start_name);
 
 	if (real_ref && track)
-		setup_tracking(name, real_ref, track);
+		setup_tracking(ref.buf+11, real_ref, track);
 
 	if (!dont_change_ref)
 		if (write_ref_sha1(lock, sha1, msg) < 0)
diff --git a/builtin/apply.c b/builtin/apply.c
index 530d4bb..f2edc52 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -1634,7 +1634,7 @@
 static char *inflate_it(const void *data, unsigned long size,
 			unsigned long inflated_size)
 {
-	z_stream stream;
+	git_zstream stream;
 	void *out;
 	int st;
 
diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
index ae3f281..0723cf2 100644
--- a/builtin/check-ref-format.c
+++ b/builtin/check-ref-format.c
@@ -12,8 +12,8 @@
 "   or: git check-ref-format --branch <branchname-shorthand>";
 
 /*
- * Replace each run of adjacent slashes in src with a single slash,
- * and write the result to dst.
+ * Remove leading slashes and replace each run of adjacent slashes in
+ * src with a single slash, and write the result to dst.
  *
  * This function is similar to normalize_path_copy(), but stripped down
  * to meet check_ref_format's simpler needs.
@@ -21,7 +21,7 @@
 static void collapse_slashes(char *dst, const char *src)
 {
 	char ch;
-	char prev = '\0';
+	char prev = '/';
 
 	while ((ch = *src++) != '\0') {
 		if (prev == '/' && ch == prev)
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index f1fec24..c16d82b 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -3,38 +3,6 @@
  *
  * Copyright (C) 2005 Linus Torvalds
  *
- * Careful: order of argument flags does matter. For example,
- *
- *	git checkout-index -a -f file.c
- *
- * Will first check out all files listed in the cache (but not
- * overwrite any old ones), and then force-checkout "file.c" a
- * second time (ie that one _will_ overwrite any old contents
- * with the same filename).
- *
- * Also, just doing "git checkout-index" does nothing. You probably
- * meant "git checkout-index -a". And if you want to force it, you
- * want "git checkout-index -f -a".
- *
- * Intuitiveness is not the goal here. Repeatability is. The
- * reason for the "no arguments means no work" thing is that
- * from scripts you are supposed to be able to do things like
- *
- *	find . -name '*.h' -print0 | xargs -0 git checkout-index -f --
- *
- * or:
- *
- *	find . -name '*.h' -print0 | git checkout-index -f -z --stdin
- *
- * which will force all existing *.h files to be replaced with
- * their cached copies. If an empty command line implied "all",
- * then this would force-refresh everything in the cache, which
- * was not the point.
- *
- * Oh, and the "--" is just a good idea when you know the rest
- * will be filenames. Just so that you wouldn't have a filename
- * of "-a" causing problems (not possible in the above example,
- * but get used to it in scripting!).
  */
 #include "builtin.h"
 #include "cache.h"
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a5717f1..4c20dae 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -715,10 +715,12 @@
 	unsigned char rev[20];
 	int flag;
 	memset(&old, 0, sizeof(old));
-	old.path = resolve_ref("HEAD", rev, 0, &flag);
+	old.path = xstrdup(resolve_ref("HEAD", rev, 0, &flag));
 	old.commit = lookup_commit_reference_gently(rev, 1);
-	if (!(flag & REF_ISSYMREF))
+	if (!(flag & REF_ISSYMREF)) {
+		free((char *)old.path);
 		old.path = NULL;
+	}
 
 	if (old.path && !prefixcmp(old.path, "refs/heads/"))
 		old.name = old.path + strlen("refs/heads/");
@@ -741,6 +743,7 @@
 	update_refs_for_switch(opts, &old, new);
 
 	ret = post_checkout_hook(old.commit, new->commit, 1);
+	free((char *)old.path);
 	return ret || opts->writeout_error;
 }
 
@@ -1071,7 +1074,7 @@
 		if (strbuf_check_branch_ref(&buf, opts.new_branch))
 			die(_("git checkout: we do not like '%s' as a branch name."),
 			    opts.new_branch);
-		if (!get_sha1(buf.buf, rev)) {
+		if (ref_exists(buf.buf)) {
 			opts.branch_exists = 1;
 			if (!opts.new_branch_force)
 				die(_("git checkout: branch %s already exists"),
diff --git a/builtin/clone.c b/builtin/clone.c
index f579794..5f20082 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -39,13 +39,23 @@
 
 static int option_no_checkout, option_bare, option_mirror;
 static int option_local, option_no_hardlinks, option_shared, option_recursive;
-static char *option_template, *option_reference, *option_depth;
+static char *option_template, *option_depth;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
 static const char *real_git_dir;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbosity;
 static int option_progress;
+static struct string_list option_reference;
+
+static int opt_parse_reference(const struct option *opt, const char *arg, int unset)
+{
+	struct string_list *option_reference = opt->value;
+	if (!arg)
+		return -1;
+	string_list_append(option_reference, arg);
+	return 0;
+}
 
 static struct option builtin_clone_options[] = {
 	OPT__VERBOSITY(&option_verbosity),
@@ -71,8 +81,8 @@
 		    "initialize submodules in the clone"),
 	OPT_STRING(0, "template", &option_template, "template-directory",
 		   "directory from which templates will be used"),
-	OPT_STRING(0, "reference", &option_reference, "repo",
-		   "reference repository"),
+	OPT_CALLBACK(0 , "reference", &option_reference, "repo",
+		     "reference repository", &opt_parse_reference),
 	OPT_STRING('o', "origin", &option_origin, "branch",
 		   "use <branch> instead of 'origin' to track upstream"),
 	OPT_STRING('b', "branch", &option_branch, "branch",
@@ -101,9 +111,26 @@
 	for (i = 0; i < ARRAY_SIZE(suffix); i++) {
 		const char *path;
 		path = mkpath("%s%s", repo, suffix[i]);
-		if (is_directory(path)) {
+		if (stat(path, &st))
+			continue;
+		if (S_ISDIR(st.st_mode)) {
 			*is_bundle = 0;
 			return xstrdup(absolute_path(path));
+		} else if (S_ISREG(st.st_mode) && st.st_size > 8) {
+			/* Is it a "gitfile"? */
+			char signature[8];
+			int len, fd = open(path, O_RDONLY);
+			if (fd < 0)
+				continue;
+			len = read_in_full(fd, signature, 8);
+			close(fd);
+			if (len != 8 || strncmp(signature, "gitdir: ", 8))
+				continue;
+			path = read_gitfile(path);
+			if (path) {
+				*is_bundle = 0;
+				return xstrdup(absolute_path(path));
+			}
 		}
 	}
 
@@ -197,39 +224,80 @@
 	*end = '\0';
 }
 
-static void setup_reference(const char *repo)
+static int add_one_reference(struct string_list_item *item, void *cb_data)
 {
-	const char *ref_git;
-	char *ref_git_copy;
-
+	char *ref_git;
+	struct strbuf alternate = STRBUF_INIT;
 	struct remote *remote;
 	struct transport *transport;
 	const struct ref *extra;
 
-	ref_git = real_path(option_reference);
-
-	if (is_directory(mkpath("%s/.git/objects", ref_git)))
-		ref_git = mkpath("%s/.git", ref_git);
-	else if (!is_directory(mkpath("%s/objects", ref_git)))
+	/* Beware: real_path() and mkpath() return static buffer */
+	ref_git = xstrdup(real_path(item->string));
+	if (is_directory(mkpath("%s/.git/objects", ref_git))) {
+		char *ref_git_git = xstrdup(mkpath("%s/.git", ref_git));
+		free(ref_git);
+		ref_git = ref_git_git;
+	} else if (!is_directory(mkpath("%s/objects", ref_git)))
 		die(_("reference repository '%s' is not a local directory."),
-		    option_reference);
+		    item->string);
 
-	ref_git_copy = xstrdup(ref_git);
+	strbuf_addf(&alternate, "%s/objects", ref_git);
+	add_to_alternates_file(alternate.buf);
+	strbuf_release(&alternate);
 
-	add_to_alternates_file(ref_git_copy);
-
-	remote = remote_get(ref_git_copy);
-	transport = transport_get(remote, ref_git_copy);
+	remote = remote_get(ref_git);
+	transport = transport_get(remote, ref_git);
 	for (extra = transport_get_remote_refs(transport); extra;
 	     extra = extra->next)
 		add_extra_ref(extra->name, extra->old_sha1, 0);
 
 	transport_disconnect(transport);
-
-	free(ref_git_copy);
+	free(ref_git);
+	return 0;
 }
 
-static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
+static void setup_reference(void)
+{
+	for_each_string_list(&option_reference, add_one_reference, NULL);
+}
+
+static void copy_alternates(struct strbuf *src, struct strbuf *dst,
+			    const char *src_repo)
+{
+	/*
+	 * Read from the source objects/info/alternates file
+	 * and copy the entries to corresponding file in the
+	 * destination repository with add_to_alternates_file().
+	 * Both src and dst have "$path/objects/info/alternates".
+	 *
+	 * Instead of copying bit-for-bit from the original,
+	 * we need to append to existing one so that the already
+	 * created entry via "clone -s" is not lost, and also
+	 * to turn entries with paths relative to the original
+	 * absolute, so that they can be used in the new repository.
+	 */
+	FILE *in = fopen(src->buf, "r");
+	struct strbuf line = STRBUF_INIT;
+
+	while (strbuf_getline(&line, in, '\n') != EOF) {
+		char *abs_path, abs_buf[PATH_MAX];
+		if (!line.len || line.buf[0] == '#')
+			continue;
+		if (is_absolute_path(line.buf)) {
+			add_to_alternates_file(line.buf);
+			continue;
+		}
+		abs_path = mkpath("%s/objects/%s", src_repo, line.buf);
+		normalize_path_copy(abs_buf, abs_path);
+		add_to_alternates_file(abs_buf);
+	}
+	strbuf_release(&line);
+	fclose(in);
+}
+
+static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
+				   const char *src_repo, int src_baselen)
 {
 	struct dirent *de;
 	struct stat buf;
@@ -265,7 +333,14 @@
 		}
 		if (S_ISDIR(buf.st_mode)) {
 			if (de->d_name[0] != '.')
-				copy_or_link_directory(src, dest);
+				copy_or_link_directory(src, dest,
+						       src_repo, src_baselen);
+			continue;
+		}
+
+		/* Files that cannot be copied bit-for-bit... */
+		if (!strcmp(src->buf + src_baselen, "/info/alternates")) {
+			copy_alternates(src, dest, src_repo);
 			continue;
 		}
 
@@ -288,17 +363,20 @@
 				     const char *dest_repo)
 {
 	const struct ref *ret;
-	struct strbuf src = STRBUF_INIT;
-	struct strbuf dest = STRBUF_INIT;
 	struct remote *remote;
 	struct transport *transport;
 
-	if (option_shared)
-		add_to_alternates_file(src_repo);
-	else {
+	if (option_shared) {
+		struct strbuf alt = STRBUF_INIT;
+		strbuf_addf(&alt, "%s/objects", src_repo);
+		add_to_alternates_file(alt.buf);
+		strbuf_release(&alt);
+	} else {
+		struct strbuf src = STRBUF_INIT;
+		struct strbuf dest = STRBUF_INIT;
 		strbuf_addf(&src, "%s/objects", src_repo);
 		strbuf_addf(&dest, "%s/objects", dest_repo);
-		copy_or_link_directory(&src, &dest);
+		copy_or_link_directory(&src, &dest, src_repo, src.len);
 		strbuf_release(&src);
 		strbuf_release(&dest);
 	}
@@ -521,8 +599,8 @@
 	git_config_set(key.buf, repo);
 	strbuf_reset(&key);
 
-	if (option_reference)
-		setup_reference(git_dir);
+	if (option_reference.nr)
+		setup_reference();
 
 	fetch_pattern = value.buf;
 	refspec = parse_fetch_refspec(1, &fetch_pattern);
diff --git a/builtin/describe.c b/builtin/describe.c
index 66fc291..9f63067 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -462,8 +462,21 @@
 		die(_("No names found, cannot describe anything."));
 
 	if (argc == 0) {
-		if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix))
-			dirty = NULL;
+		if (dirty) {
+			static struct lock_file index_lock;
+			int fd;
+
+			read_cache_preload(NULL);
+			refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED,
+				      NULL, NULL, NULL);
+			fd = hold_locked_index(&index_lock, 0);
+			if (0 <= fd)
+				update_index_if_able(&the_index, &index_lock);
+
+			if (!cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1,
+					    diff_index_args, prefix))
+				dirty = NULL;
+		}
 		describe("HEAD", 1);
 	} else if (dirty) {
 		die(_("--dirty is incompatible with committishes"));
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index daf1945..48bd5e6 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -16,6 +16,7 @@
 #include "string-list.h"
 #include "utf8.h"
 #include "parse-options.h"
+#include "quote.h"
 
 static const char *fast_export_usage[] = {
 	"git fast-export [rev-list-opts]",
@@ -178,6 +179,15 @@
 	return (a->status == 'R') - (b->status == 'R');
 }
 
+static void print_path(const char *path)
+{
+	int need_quote = quote_c_style(path, NULL, NULL, 0);
+	if (need_quote)
+		quote_c_style(path, NULL, stdout, 0);
+	else
+		printf("%s", path);
+}
+
 static void show_filemodify(struct diff_queue_struct *q,
 			    struct diff_options *options, void *data)
 {
@@ -195,13 +205,18 @@
 
 		switch (q->queue[i]->status) {
 		case DIFF_STATUS_DELETED:
-			printf("D %s\n", spec->path);
+			printf("D ");
+			print_path(spec->path);
+			putchar('\n');
 			break;
 
 		case DIFF_STATUS_COPIED:
 		case DIFF_STATUS_RENAMED:
-			printf("%c \"%s\" \"%s\"\n", q->queue[i]->status,
-			       ospec->path, spec->path);
+			printf("%c ", q->queue[i]->status);
+			print_path(ospec->path);
+			putchar(' ');
+			print_path(spec->path);
+			putchar('\n');
 
 			if (!hashcmp(ospec->sha1, spec->sha1) &&
 			    ospec->mode == spec->mode)
@@ -216,13 +231,15 @@
 			 * output the SHA-1 verbatim.
 			 */
 			if (no_data || S_ISGITLINK(spec->mode))
-				printf("M %06o %s %s\n", spec->mode,
-				       sha1_to_hex(spec->sha1), spec->path);
+				printf("M %06o %s ", spec->mode,
+				       sha1_to_hex(spec->sha1));
 			else {
 				struct object *object = lookup_object(spec->sha1);
-				printf("M %06o :%d %s\n", spec->mode,
-				       get_object_mark(object), spec->path);
+				printf("M %06o :%d ", spec->mode,
+				       get_object_mark(object));
 			}
+			print_path(spec->path);
+			putchar('\n');
 			break;
 
 		default:
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 4367984..3c871c2 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -395,6 +395,8 @@
 				case ACK_continue: {
 					struct commit *commit =
 						lookup_commit(result_sha1);
+					if (!commit)
+						die("invalid commit %s", sha1_to_hex(result_sha1));
 					if (args.stateless_rpc
 					 && ack == ACK_common
 					 && !(commit->object.flags & COMMON)) {
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 93c9938..e422ced 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -941,6 +941,15 @@
 	argc = parse_options(argc, argv, prefix,
 			     builtin_fetch_options, builtin_fetch_usage, 0);
 
+	if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
+		if (recurse_submodules_default) {
+			int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
+			set_config_fetch_recurse_submodules(arg);
+		}
+		gitmodules_config();
+		git_config(submodule_config, NULL);
+	}
+
 	if (all) {
 		if (argc == 1)
 			die(_("fetch --all does not take a repository argument"));
@@ -976,12 +985,6 @@
 	if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
 		const char *options[10];
 		int num_options = 0;
-		if (recurse_submodules_default) {
-			int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
-			set_config_fetch_recurse_submodules(arg);
-		}
-		gitmodules_config();
-		git_config(submodule_config, NULL);
 		add_options_to_argv(&num_options, options);
 		result = fetch_populated_submodules(num_options, options,
 						    submodule_prefix,
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index e40451f..81cdc28 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -265,7 +265,7 @@
 static void *unpack_entry_data(unsigned long offset, unsigned long size)
 {
 	int status;
-	z_stream stream;
+	git_zstream stream;
 	void *buf = xmalloc(size);
 
 	memset(&stream, 0, sizeof(stream));
@@ -355,7 +355,7 @@
 	off_t from = obj[0].idx.offset + obj[0].hdr_size;
 	unsigned long len = obj[1].idx.offset - from;
 	unsigned char *data, *inbuf;
-	z_stream stream;
+	git_zstream stream;
 	int status;
 
 	data = xmalloc(obj->size);
@@ -666,26 +666,26 @@
 
 static int write_compressed(struct sha1file *f, void *in, unsigned int size)
 {
-	z_stream stream;
+	git_zstream stream;
 	int status;
 	unsigned char outbuf[4096];
 
 	memset(&stream, 0, sizeof(stream));
-	deflateInit(&stream, zlib_compression_level);
+	git_deflate_init(&stream, zlib_compression_level);
 	stream.next_in = in;
 	stream.avail_in = size;
 
 	do {
 		stream.next_out = outbuf;
 		stream.avail_out = sizeof(outbuf);
-		status = deflate(&stream, Z_FINISH);
+		status = git_deflate(&stream, Z_FINISH);
 		sha1write(f, outbuf, sizeof(outbuf) - stream.avail_out);
 	} while (status == Z_OK);
 
 	if (status != Z_STREAM_END)
 		die("unable to deflate appended object (%d)", status);
 	size = stream.total_out;
-	deflateEnd(&stream);
+	git_deflate_end(&stream);
 	return size;
 }
 
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 025aa47..d07554c 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -347,7 +347,7 @@
 		const char *src;
 
 		if (S_ISREG(st.st_mode))
-			src = read_gitfile_gently(git_link);
+			src = read_gitfile(git_link);
 		else if (S_ISDIR(st.st_mode))
 			src = git_link;
 		else
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index f08c5b0..6b666e1 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -173,7 +173,5 @@
 	tree = parse_tree_indirect(sha1);
 	if (!tree)
 		die("not a tree object");
-	read_tree_recursive(tree, "", 0, 0, &pathspec, show_tree, NULL);
-
-	return 0;
+	return !!read_tree_recursive(tree, "", 0, 0, &pathspec, show_tree, NULL);
 }
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index f402a84..c6e2d87 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -126,13 +126,13 @@
 
 static unsigned long do_compress(void **pptr, unsigned long size)
 {
-	z_stream stream;
+	git_zstream stream;
 	void *in, *out;
 	unsigned long maxsize;
 
 	memset(&stream, 0, sizeof(stream));
-	deflateInit(&stream, pack_compression_level);
-	maxsize = deflateBound(&stream, size);
+	git_deflate_init(&stream, pack_compression_level);
+	maxsize = git_deflate_bound(&stream, size);
 
 	in = *pptr;
 	out = xmalloc(maxsize);
@@ -142,9 +142,9 @@
 	stream.avail_in = size;
 	stream.next_out = out;
 	stream.avail_out = maxsize;
-	while (deflate(&stream, Z_FINISH) == Z_OK)
+	while (git_deflate(&stream, Z_FINISH) == Z_OK)
 		; /* nothing */
-	deflateEnd(&stream);
+	git_deflate_end(&stream);
 
 	free(in);
 	return stream.total_out;
@@ -160,7 +160,7 @@
 		off_t len,
 		unsigned long expect)
 {
-	z_stream stream;
+	git_zstream stream;
 	unsigned char fakebuf[4096], *in;
 	int st;
 
@@ -187,12 +187,12 @@
 		off_t len)
 {
 	unsigned char *in;
-	unsigned int avail;
+	unsigned long avail;
 
 	while (len) {
 		in = use_pack(p, w_curs, offset, &avail);
 		if (avail > len)
-			avail = (unsigned int)len;
+			avail = (unsigned long)len;
 		sha1write(f, in, avail);
 		offset += avail;
 		len -= avail;
@@ -994,7 +994,7 @@
 		const unsigned char *base_ref = NULL;
 		struct object_entry *base_entry;
 		unsigned long used, used_0;
-		unsigned int avail;
+		unsigned long avail;
 		off_t ofs;
 		unsigned char *buf, c;
 
diff --git a/builtin/reflog.c b/builtin/reflog.c
index ebf610e..3a9c80f 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -777,6 +777,5 @@
 	if (!strcmp(argv[1], "delete"))
 		return cmd_reflog_delete(argc - 1, argv + 1, prefix);
 
-	/* Not a recognized reflog command..*/
-	usage(reflog_usage);
+	return cmd_log_reflog(argc, argv, prefix);
 }
diff --git a/builtin/remote.c b/builtin/remote.c
index 9ff1cac..1fb441c 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -1113,7 +1113,7 @@
 			url = states.remote->url;
 			url_nr = states.remote->url_nr;
 		}
-		for (i=0; i < url_nr; i++)
+		for (i = 0; i < url_nr; i++)
 			printf("  Push  URL: %s\n", url[i]);
 		if (!i)
 			printf("  Push  URL: %s\n", "(no URL)");
diff --git a/builtin/reset.c b/builtin/reset.c
index 98bca04..811e8e2 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -33,25 +33,6 @@
 	N_("mixed"), N_("soft"), N_("hard"), N_("merge"), N_("keep"), NULL
 };
 
-static char *args_to_str(const char **argv)
-{
-	char *buf = NULL;
-	unsigned long len, space = 0, nr = 0;
-
-	for (; *argv; argv++) {
-		len = strlen(*argv);
-		ALLOC_GROW(buf, nr + 1 + len, space);
-		if (nr)
-			buf[nr++] = ' ';
-		memcpy(buf + nr, *argv, len);
-		nr += len;
-	}
-	ALLOC_GROW(buf, nr + 1, space);
-	buf[nr] = '\0';
-
-	return buf;
-}
-
 static inline int is_merge(void)
 {
 	return !access(git_path("MERGE_HEAD"), F_OK);
@@ -162,7 +143,7 @@
 
 	for (i = 0; i < q->nr; i++) {
 		struct diff_filespec *one = q->queue[i]->one;
-		if (one->mode) {
+		if (one->mode && !is_null_sha1(one->sha1)) {
 			struct cache_entry *ce;
 			ce = make_cache_entry(one->mode, one->sha1, one->path,
 				0, 0);
@@ -215,14 +196,18 @@
 	return update_index_refresh(index_fd, lock, refresh_flags);
 }
 
-static void prepend_reflog_action(const char *action, char *buf, size_t size)
+static void set_reflog_message(struct strbuf *sb, const char *action,
+			       const char *rev)
 {
-	const char *sep = ": ";
 	const char *rla = getenv("GIT_REFLOG_ACTION");
-	if (!rla)
-		rla = sep = "";
-	if (snprintf(buf, size, "%s%s%s", rla, sep, action) >= size)
-		warning(_("Reflog action message too long: %.*s..."), 50, buf);
+
+	strbuf_reset(sb);
+	if (rla)
+		strbuf_addf(sb, "%s: %s", rla, action);
+	else if (rev)
+		strbuf_addf(sb, "reset: moving to %s", rev);
+	else
+		strbuf_addf(sb, "reset: %s", action);
 }
 
 static void die_if_unmerged_cache(int reset_type)
@@ -241,7 +226,7 @@
 	unsigned char sha1[20], *orig = NULL, sha1_orig[20],
 				*old_orig = NULL, sha1_old_orig[20];
 	struct commit *commit;
-	char *reflog_action, msg[1024];
+	struct strbuf msg = STRBUF_INIT;
 	const struct option options[] = {
 		OPT__QUIET(&quiet, "be quiet, only report errors"),
 		OPT_SET_INT(0, "mixed", &reset_type,
@@ -261,8 +246,6 @@
 
 	argc = parse_options(argc, argv, prefix, options, git_reset_usage,
 						PARSE_OPT_KEEP_DASHDASH);
-	reflog_action = args_to_str(argv);
-	setenv("GIT_REFLOG_ACTION", reflog_action, 0);
 
 	/*
 	 * Possible arguments are:
@@ -357,13 +340,13 @@
 		old_orig = sha1_old_orig;
 	if (!get_sha1("HEAD", sha1_orig)) {
 		orig = sha1_orig;
-		prepend_reflog_action("updating ORIG_HEAD", msg, sizeof(msg));
-		update_ref(msg, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
+		set_reflog_message(&msg, "updating ORIG_HEAD", NULL);
+		update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
 	}
 	else if (old_orig)
 		delete_ref("ORIG_HEAD", old_orig, 0);
-	prepend_reflog_action("updating HEAD", msg, sizeof(msg));
-	update_ref_status = update_ref(msg, "HEAD", sha1, orig, 0, MSG_ON_ERR);
+	set_reflog_message(&msg, "updating HEAD", rev);
+	update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0, MSG_ON_ERR);
 
 	switch (reset_type) {
 	case HARD:
@@ -380,7 +363,7 @@
 
 	remove_branch_state();
 
-	free(reflog_action);
+	strbuf_release(&msg);
 
 	return update_ref_status;
 }
diff --git a/builtin/tag.c b/builtin/tag.c
index ec926fc..667515e 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -12,11 +12,13 @@
 #include "tag.h"
 #include "run-command.h"
 #include "parse-options.h"
+#include "diff.h"
+#include "revision.h"
 
 static const char * const git_tag_usage[] = {
 	"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
 	"git tag -d <tagname>...",
-	"git tag -l [-n[<num>]] [<pattern>]",
+	"git tag -l [-n[<num>]] [<pattern>...]",
 	"git tag -v <tagname>...",
 	NULL
 };
@@ -24,17 +26,70 @@
 static char signingkey[1000];
 
 struct tag_filter {
-	const char *pattern;
+	const char **patterns;
 	int lines;
 	struct commit_list *with_commit;
 };
 
+static int match_pattern(const char **patterns, const char *ref)
+{
+	/* no pattern means match everything */
+	if (!*patterns)
+		return 1;
+	for (; *patterns; patterns++)
+		if (!fnmatch(*patterns, ref, 0))
+			return 1;
+	return 0;
+}
+
+static int in_commit_list(const struct commit_list *want, struct commit *c)
+{
+	for (; want; want = want->next)
+		if (!hashcmp(want->item->object.sha1, c->object.sha1))
+			return 1;
+	return 0;
+}
+
+static int contains_recurse(struct commit *candidate,
+			    const struct commit_list *want)
+{
+	struct commit_list *p;
+
+	/* was it previously marked as containing a want commit? */
+	if (candidate->object.flags & TMP_MARK)
+		return 1;
+	/* or marked as not possibly containing a want commit? */
+	if (candidate->object.flags & UNINTERESTING)
+		return 0;
+	/* or are we it? */
+	if (in_commit_list(want, candidate))
+		return 1;
+
+	if (parse_commit(candidate) < 0)
+		return 0;
+
+	/* Otherwise recurse and mark ourselves for future traversals. */
+	for (p = candidate->parents; p; p = p->next) {
+		if (contains_recurse(p->item, want)) {
+			candidate->object.flags |= TMP_MARK;
+			return 1;
+		}
+	}
+	candidate->object.flags |= UNINTERESTING;
+	return 0;
+}
+
+static int contains(struct commit *candidate, const struct commit_list *want)
+{
+	return contains_recurse(candidate, want);
+}
+
 static int show_reference(const char *refname, const unsigned char *sha1,
 			  int flag, void *cb_data)
 {
 	struct tag_filter *filter = cb_data;
 
-	if (!fnmatch(filter->pattern, refname, 0)) {
+	if (match_pattern(filter->patterns, refname)) {
 		int i;
 		unsigned long size;
 		enum object_type type;
@@ -47,7 +102,7 @@
 			commit = lookup_commit_reference_gently(sha1, 1);
 			if (!commit)
 				return 0;
-			if (!is_descendant_of(commit, filter->with_commit))
+			if (!contains(commit, filter->with_commit))
 				return 0;
 		}
 
@@ -88,15 +143,12 @@
 	return 0;
 }
 
-static int list_tags(const char *pattern, int lines,
+static int list_tags(const char **patterns, int lines,
 			struct commit_list *with_commit)
 {
 	struct tag_filter filter;
 
-	if (pattern == NULL)
-		pattern = "*";
-
-	filter.pattern = pattern;
+	filter.patterns = patterns;
 	filter.lines = lines;
 	filter.with_commit = with_commit;
 
@@ -425,7 +477,7 @@
 	if (list + delete + verify > 1)
 		usage_with_options(git_tag_usage, options);
 	if (list)
-		return list_tags(argv[0], lines == -1 ? 0 : lines,
+		return list_tags(argv, lines == -1 ? 0 : lines,
 				 with_commit);
 	if (lines != -1)
 		die(_("-n option is only allowed with -l."));
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index f63973c..14e04e6 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -90,7 +90,7 @@
 
 static void *get_data(unsigned long size)
 {
-	z_stream stream;
+	git_zstream stream;
 	void *buf = xmalloc(size);
 
 	memset(&stream, 0, sizeof(stream));
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 76ba1d5..835c62a 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -11,7 +11,7 @@
 
 int cmd_update_ref(int argc, const char **argv, const char *prefix)
 {
-	const char *refname, *oldval, *msg=NULL;
+	const char *refname, *oldval, *msg = NULL;
 	unsigned char sha1[20], oldsha1[20];
 	int delete = 0, no_deref = 0, flags = 0;
 	struct option options[] = {
diff --git a/cache.h b/cache.h
index d55a6bb..6b24c25 100644
--- a/cache.h
+++ b/cache.h
@@ -16,13 +16,27 @@
 #endif
 
 #include <zlib.h>
-#if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
-#define deflateBound(c,s)  ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
-#endif
+typedef struct git_zstream {
+	z_stream z;
+	unsigned long avail_in;
+	unsigned long avail_out;
+	unsigned long total_in;
+	unsigned long total_out;
+	unsigned char *next_in;
+	unsigned char *next_out;
+} git_zstream;
 
-void git_inflate_init(z_streamp strm);
-void git_inflate_end(z_streamp strm);
-int git_inflate(z_streamp strm, int flush);
+void git_inflate_init(git_zstream *);
+void git_inflate_init_gzip_only(git_zstream *);
+void git_inflate_end(git_zstream *);
+int git_inflate(git_zstream *, int flush);
+
+void git_deflate_init(git_zstream *, int level);
+void git_deflate_init_gzip(git_zstream *, int level);
+void git_deflate_end(git_zstream *);
+int git_deflate_end_gently(git_zstream *);
+int git_deflate(git_zstream *, int flush);
+unsigned long git_deflate_bound(git_zstream *, unsigned long);
 
 #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
 #define DTYPE(de)	((de)->d_type)
@@ -420,7 +434,7 @@
 extern char *get_graft_file(void);
 extern int set_git_dir(const char *path);
 extern const char *get_git_work_tree(void);
-extern const char *read_gitfile_gently(const char *path);
+extern const char *read_gitfile(const char *path);
 extern void set_git_work_tree(const char *tree);
 
 #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
@@ -1009,7 +1023,7 @@
 extern void pack_report(void);
 extern int open_pack_index(struct packed_git *);
 extern void close_pack_index(struct packed_git *);
-extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
+extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
 extern void close_pack_windows(struct packed_git *);
 extern void unuse_pack(struct pack_window **);
 extern void free_pack_by_name(const char *);
diff --git a/combine-diff.c b/combine-diff.c
index 655fa89..b11eb71 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -7,6 +7,7 @@
 #include "xdiff-interface.h"
 #include "log-tree.h"
 #include "refs.h"
+#include "userdiff.h"
 
 static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
 {
@@ -92,7 +93,9 @@
 	unsigned long *p_lno;
 };
 
-static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned long *size)
+static char *grab_blob(const unsigned char *sha1, unsigned int mode,
+		       unsigned long *size, struct userdiff_driver *textconv,
+		       const char *path)
 {
 	char *blob;
 	enum object_type type;
@@ -105,6 +108,11 @@
 		/* deleted blob */
 		*size = 0;
 		return xcalloc(1, 1);
+	} else if (textconv) {
+		struct diff_filespec *df = alloc_filespec(path);
+		fill_filespec(df, sha1, mode);
+		*size = fill_textconv(textconv, df, &blob);
+		free_filespec(df);
 	} else {
 		blob = read_sha1_file(sha1, &type, size);
 		if (type != OBJ_BLOB)
@@ -204,7 +212,9 @@
 static void combine_diff(const unsigned char *parent, unsigned int mode,
 			 mmfile_t *result_file,
 			 struct sline *sline, unsigned int cnt, int n,
-			 int num_parent, int result_deleted)
+			 int num_parent, int result_deleted,
+			 struct userdiff_driver *textconv,
+			 const char *path)
 {
 	unsigned int p_lno, lno;
 	unsigned long nmask = (1UL << n);
@@ -217,7 +227,7 @@
 	if (result_deleted)
 		return; /* result deleted */
 
-	parent_file.ptr = grab_blob(parent, mode, &sz);
+	parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
 	parent_file.size = sz;
 	memset(&xpp, 0, sizeof(xpp));
 	xpp.flags = 0;
@@ -681,8 +691,85 @@
 	puts(buf.buf);
 }
 
+static void show_combined_header(struct combine_diff_path *elem,
+				 int num_parent,
+				 int dense,
+				 struct rev_info *rev,
+				 int mode_differs,
+				 int show_file_header)
+{
+	struct diff_options *opt = &rev->diffopt;
+	int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
+	const char *a_prefix = opt->a_prefix ? opt->a_prefix : "a/";
+	const char *b_prefix = opt->b_prefix ? opt->b_prefix : "b/";
+	int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
+	const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
+	const char *c_reset = diff_get_color(use_color, DIFF_RESET);
+	const char *abb;
+	int added = 0;
+	int deleted = 0;
+	int i;
+
+	if (rev->loginfo && !rev->no_commit_id)
+		show_log(rev);
+
+	dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
+			 "", elem->path, c_meta, c_reset);
+	printf("%sindex ", c_meta);
+	for (i = 0; i < num_parent; i++) {
+		abb = find_unique_abbrev(elem->parent[i].sha1,
+					 abbrev);
+		printf("%s%s", i ? "," : "", abb);
+	}
+	abb = find_unique_abbrev(elem->sha1, abbrev);
+	printf("..%s%s\n", abb, c_reset);
+
+	if (mode_differs) {
+		deleted = !elem->mode;
+
+		/* We say it was added if nobody had it */
+		added = !deleted;
+		for (i = 0; added && i < num_parent; i++)
+			if (elem->parent[i].status !=
+			    DIFF_STATUS_ADDED)
+				added = 0;
+		if (added)
+			printf("%snew file mode %06o",
+			       c_meta, elem->mode);
+		else {
+			if (deleted)
+				printf("%sdeleted file ", c_meta);
+			printf("mode ");
+			for (i = 0; i < num_parent; i++) {
+				printf("%s%06o", i ? "," : "",
+				       elem->parent[i].mode);
+			}
+			if (elem->mode)
+				printf("..%06o", elem->mode);
+		}
+		printf("%s\n", c_reset);
+	}
+
+	if (!show_file_header)
+		return;
+
+	if (added)
+		dump_quoted_path("--- ", "", "/dev/null",
+				 c_meta, c_reset);
+	else
+		dump_quoted_path("--- ", a_prefix, elem->path,
+				 c_meta, c_reset);
+	if (deleted)
+		dump_quoted_path("+++ ", "", "/dev/null",
+				 c_meta, c_reset);
+	else
+		dump_quoted_path("+++ ", b_prefix, elem->path,
+				 c_meta, c_reset);
+}
+
 static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
-			    int dense, struct rev_info *rev)
+			    int dense, int working_tree_file,
+			    struct rev_info *rev)
 {
 	struct diff_options *opt = &rev->diffopt;
 	unsigned long result_size, cnt, lno;
@@ -691,18 +778,22 @@
 	struct sline *sline; /* survived lines */
 	int mode_differs = 0;
 	int i, show_hunks;
-	int working_tree_file = is_null_sha1(elem->sha1);
-	int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
-	const char *a_prefix, *b_prefix;
 	mmfile_t result_file;
+	struct userdiff_driver *userdiff;
+	struct userdiff_driver *textconv = NULL;
+	int is_binary;
 
 	context = opt->context;
-	a_prefix = opt->a_prefix ? opt->a_prefix : "a/";
-	b_prefix = opt->b_prefix ? opt->b_prefix : "b/";
+	userdiff = userdiff_find_by_path(elem->path);
+	if (!userdiff)
+		userdiff = userdiff_find_by_name("default");
+	if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV))
+		textconv = userdiff_get_textconv(userdiff);
 
 	/* Read the result of merge first */
 	if (!working_tree_file)
-		result = grab_blob(elem->sha1, elem->mode, &result_size);
+		result = grab_blob(elem->sha1, elem->mode, &result_size,
+				   textconv, elem->path);
 	else {
 		/* Used by diff-tree to read from the working tree */
 		struct stat st;
@@ -725,9 +816,16 @@
 		} else if (S_ISDIR(st.st_mode)) {
 			unsigned char sha1[20];
 			if (resolve_gitlink_ref(elem->path, "HEAD", sha1) < 0)
-				result = grab_blob(elem->sha1, elem->mode, &result_size);
+				result = grab_blob(elem->sha1, elem->mode,
+						   &result_size, NULL, NULL);
 			else
-				result = grab_blob(sha1, elem->mode, &result_size);
+				result = grab_blob(sha1, elem->mode,
+						   &result_size, NULL, NULL);
+		} else if (textconv) {
+			struct diff_filespec *df = alloc_filespec(elem->path);
+			fill_filespec(df, null_sha1, st.st_mode);
+			result_size = fill_textconv(textconv, df, &result);
+			free_filespec(df);
 		} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
 			size_t len = xsize_t(st.st_size);
 			ssize_t done;
@@ -777,6 +875,38 @@
 			close(fd);
 	}
 
+	for (i = 0; i < num_parent; i++) {
+		if (elem->parent[i].mode != elem->mode) {
+			mode_differs = 1;
+			break;
+		}
+	}
+
+	if (textconv)
+		is_binary = 0;
+	else if (userdiff->binary != -1)
+		is_binary = userdiff->binary;
+	else {
+		is_binary = buffer_is_binary(result, result_size);
+		for (i = 0; !is_binary && i < num_parent; i++) {
+			char *buf;
+			unsigned long size;
+			buf = grab_blob(elem->parent[i].sha1,
+					elem->parent[i].mode,
+					&size, NULL, NULL);
+			if (buffer_is_binary(buf, size))
+				is_binary = 1;
+			free(buf);
+		}
+	}
+	if (is_binary) {
+		show_combined_header(elem, num_parent, dense, rev,
+				     mode_differs, 0);
+		printf("Binary files differ\n");
+		free(result);
+		return;
+	}
+
 	for (cnt = 0, cp = result; cp < result + result_size; cp++) {
 		if (*cp == '\n')
 			cnt++;
@@ -824,71 +954,15 @@
 			combine_diff(elem->parent[i].sha1,
 				     elem->parent[i].mode,
 				     &result_file, sline,
-				     cnt, i, num_parent, result_deleted);
-		if (elem->parent[i].mode != elem->mode)
-			mode_differs = 1;
+				     cnt, i, num_parent, result_deleted,
+				     textconv, elem->path);
 	}
 
 	show_hunks = make_hunks(sline, cnt, num_parent, dense);
 
 	if (show_hunks || mode_differs || working_tree_file) {
-		const char *abb;
-		int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
-		const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
-		const char *c_reset = diff_get_color(use_color, DIFF_RESET);
-		int added = 0;
-		int deleted = 0;
-
-		if (rev->loginfo && !rev->no_commit_id)
-			show_log(rev);
-		dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
-				 "", elem->path, c_meta, c_reset);
-		printf("%sindex ", c_meta);
-		for (i = 0; i < num_parent; i++) {
-			abb = find_unique_abbrev(elem->parent[i].sha1,
-						 abbrev);
-			printf("%s%s", i ? "," : "", abb);
-		}
-		abb = find_unique_abbrev(elem->sha1, abbrev);
-		printf("..%s%s\n", abb, c_reset);
-
-		if (mode_differs) {
-			deleted = !elem->mode;
-
-			/* We say it was added if nobody had it */
-			added = !deleted;
-			for (i = 0; added && i < num_parent; i++)
-				if (elem->parent[i].status !=
-				    DIFF_STATUS_ADDED)
-					added = 0;
-			if (added)
-				printf("%snew file mode %06o",
-				       c_meta, elem->mode);
-			else {
-				if (deleted)
-					printf("%sdeleted file ", c_meta);
-				printf("mode ");
-				for (i = 0; i < num_parent; i++) {
-					printf("%s%06o", i ? "," : "",
-					       elem->parent[i].mode);
-				}
-				if (elem->mode)
-					printf("..%06o", elem->mode);
-			}
-			printf("%s\n", c_reset);
-		}
-		if (added)
-			dump_quoted_path("--- ", "", "/dev/null",
-					 c_meta, c_reset);
-		else
-			dump_quoted_path("--- ", a_prefix, elem->path,
-					 c_meta, c_reset);
-		if (deleted)
-			dump_quoted_path("+++ ", "", "/dev/null",
-					 c_meta, c_reset);
-		else
-			dump_quoted_path("+++ ", b_prefix, elem->path,
-					 c_meta, c_reset);
+		show_combined_header(elem, num_parent, dense, rev,
+				     mode_differs, 1);
 		dump_sline(sline, cnt, num_parent,
 			   DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
 	}
@@ -954,6 +1028,12 @@
 	write_name_quoted(p->path, stdout, line_termination);
 }
 
+/*
+ * The result (p->elem) is from the working tree and their
+ * parents are typically from multiple stages during a merge
+ * (i.e. diff-files) or the state in HEAD and in the index
+ * (i.e. diff-index).
+ */
 void show_combined_diff(struct combine_diff_path *p,
 		       int num_parent,
 		       int dense,
@@ -967,7 +1047,7 @@
 				  DIFF_FORMAT_NAME_STATUS))
 		show_raw_diff(p, num_parent, rev);
 	else if (opt->output_format & DIFF_FORMAT_PATCH)
-		show_patch_diff(p, num_parent, dense, rev);
+		show_patch_diff(p, num_parent, dense, 1, rev);
 }
 
 void diff_tree_combined(const unsigned char *sha1,
@@ -1035,7 +1115,7 @@
 			for (p = paths; p; p = p->next) {
 				if (p->len)
 					show_patch_diff(p, num_parent, dense,
-							rev);
+							0, rev);
 			}
 		}
 	}
diff --git a/commit.c b/commit.c
index ac337c7..913dbab 100644
--- a/commit.c
+++ b/commit.c
@@ -515,7 +515,7 @@
 
 		commit = work_item->item;
 		for (parents = commit->parents; parents ; parents = parents->next) {
-			struct commit *parent=parents->item;
+			struct commit *parent = parents->item;
 
 			if (!parent->indegree)
 				continue;
diff --git a/compat/cygwin.c b/compat/cygwin.c
index b4a51b9..ba3327f 100644
--- a/compat/cygwin.c
+++ b/compat/cygwin.c
@@ -101,7 +101,7 @@
  * and calling git_default_config() from here would break such variables.
  */
 static int native_stat = 1;
-static int core_filemode;
+static int core_filemode = 1; /* matches trust_executable_bit default */
 
 static int git_cygwin_config(const char *var, const char *value, void *cb)
 {
diff --git a/config.c b/config.c
index 113723b..49e5250 100644
--- a/config.c
+++ b/config.c
@@ -42,10 +42,10 @@
 static int git_config_parse_parameter(const char *text,
 				      config_fn_t fn, void *data)
 {
-	struct strbuf tmp = STRBUF_INIT;
 	struct strbuf **pair;
-	strbuf_addstr(&tmp, text);
-	pair = strbuf_split(&tmp, '=');
+	pair = strbuf_split_str(text, '=', 2);
+	if (!pair[0])
+		return error("bogus config parameter: %s", text);
 	if (pair[0]->len && pair[0]->buf[pair[0]->len - 1] == '=')
 		strbuf_setlen(pair[0], pair[0]->len - 1);
 	strbuf_trim(pair[0]);
@@ -856,7 +856,7 @@
 
 	switch (git_config_from_parameters(fn, data)) {
 	case -1: /* error */
-		ret--;
+		die("unable to parse command-line config");
 		break;
 	case 0: /* found nothing */
 		break;
diff --git a/connect.c b/connect.c
index 2119c3f..d2ce57f 100644
--- a/connect.c
+++ b/connect.c
@@ -192,7 +192,8 @@
  */
 static int git_tcp_connect_sock(char *host, int flags)
 {
-	int sockfd = -1, saved_errno = 0;
+	struct strbuf error_message = STRBUF_INIT;
+	int sockfd = -1;
 	const char *port = STR(DEFAULT_GIT_PORT);
 	struct addrinfo hints, *ai0, *ai;
 	int gai;
@@ -216,21 +217,15 @@
 	if (flags & CONNECT_VERBOSE)
 		fprintf(stderr, "done.\nConnecting to %s (port %s) ... ", host, port);
 
-	for (ai0 = ai; ai; ai = ai->ai_next) {
+	for (ai0 = ai; ai; ai = ai->ai_next, cnt++) {
 		sockfd = socket(ai->ai_family,
 				ai->ai_socktype, ai->ai_protocol);
-		if (sockfd < 0) {
-			saved_errno = errno;
-			continue;
-		}
-		if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
-			saved_errno = errno;
-			fprintf(stderr, "%s[%d: %s]: errno=%s\n",
-				host,
-				cnt,
-				ai_name(ai),
-				strerror(saved_errno));
-			close(sockfd);
+		if ((sockfd < 0) ||
+		    (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)) {
+			strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
+				    host, cnt, ai_name(ai), strerror(errno));
+			if (0 <= sockfd)
+				close(sockfd);
 			sockfd = -1;
 			continue;
 		}
@@ -242,11 +237,13 @@
 	freeaddrinfo(ai0);
 
 	if (sockfd < 0)
-		die("unable to connect a socket (%s)", strerror(saved_errno));
+		die("unable to connect to %s:\n%s", host, error_message.buf);
 
 	if (flags & CONNECT_VERBOSE)
 		fprintf(stderr, "done.\n");
 
+	strbuf_release(&error_message);
+
 	return sockfd;
 }
 
diff --git a/contrib/convert-objects/git-convert-objects.txt b/contrib/convert-objects/git-convert-objects.txt
index 9718abf..0565d83 100644
--- a/contrib/convert-objects/git-convert-objects.txt
+++ b/contrib/convert-objects/git-convert-objects.txt
@@ -8,6 +8,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'git-convert-objects'
 
 DESCRIPTION
diff --git a/contrib/gitview/gitview.txt b/contrib/gitview/gitview.txt
index 77c29de..9e12f97 100644
--- a/contrib/gitview/gitview.txt
+++ b/contrib/gitview/gitview.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 'gitview' [options] [args]
 
 DESCRIPTION
diff --git a/contrib/svn-fe/svn-fe.txt b/contrib/svn-fe/svn-fe.txt
index cd075b9..72ffea0 100644
--- a/contrib/svn-fe/svn-fe.txt
+++ b/contrib/svn-fe/svn-fe.txt
@@ -7,6 +7,7 @@
 
 SYNOPSIS
 --------
+[verse]
 svnadmin dump --incremental REPO | svn-fe [url] | git fast-import
 
 DESCRIPTION
diff --git a/diff-lib.c b/diff-lib.c
index 9c29293..b379759 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -379,7 +379,8 @@
 	if (cached && idx && ce_stage(idx)) {
 		struct diff_filepair *pair;
 		pair = diff_unmerge(&revs->diffopt, idx->name);
-		fill_filespec(pair->one, idx->sha1, idx->ce_mode);
+		if (tree)
+			fill_filespec(pair->one, tree->sha1, tree->ce_mode);
 		return;
 	}
 
@@ -433,8 +434,13 @@
 	if (tree == o->df_conflict_entry)
 		tree = NULL;
 
-	if (ce_path_match(idx ? idx : tree, &revs->prune_data))
+	if (ce_path_match(idx ? idx : tree, &revs->prune_data)) {
 		do_oneway_diff(o, idx, tree);
+		if (diff_can_quit_early(&revs->diffopt)) {
+			o->exiting_early = 1;
+			return -1;
+		}
+	}
 
 	return 0;
 }
diff --git a/diff.c b/diff.c
index 61bedae..9038f19 100644
--- a/diff.c
+++ b/diff.c
@@ -1839,20 +1839,20 @@
 {
 	int bound;
 	unsigned char *deflated;
-	z_stream stream;
+	git_zstream stream;
 
 	memset(&stream, 0, sizeof(stream));
-	deflateInit(&stream, zlib_compression_level);
-	bound = deflateBound(&stream, size);
+	git_deflate_init(&stream, zlib_compression_level);
+	bound = git_deflate_bound(&stream, size);
 	deflated = xmalloc(bound);
 	stream.next_out = deflated;
 	stream.avail_out = bound;
 
 	stream.next_in = (unsigned char *)data;
 	stream.avail_in = size;
-	while (deflate(&stream, Z_FINISH) == Z_OK)
+	while (git_deflate(&stream, Z_FINISH) == Z_OK)
 		; /* nothing */
-	deflateEnd(&stream);
+	git_deflate_end(&stream);
 	*result_size = stream.total_out;
 	return deflated;
 }
@@ -1984,19 +1984,7 @@
 		return NULL;
 
 	diff_filespec_load_driver(one);
-	if (!one->driver->textconv)
-		return NULL;
-
-	if (one->driver->textconv_want_cache && !one->driver->textconv_cache) {
-		struct notes_cache *c = xmalloc(sizeof(*c));
-		struct strbuf name = STRBUF_INIT;
-
-		strbuf_addf(&name, "textconv/%s", one->driver->name);
-		notes_cache_init(c, name.buf, one->driver->textconv);
-		one->driver->textconv_cache = c;
-	}
-
-	return one->driver;
+	return userdiff_get_textconv(one->driver);
 }
 
 static void builtin_diff(const char *name_a,
diff --git a/environment.c b/environment.c
index 94d58fd..2228c4e 100644
--- a/environment.c
+++ b/environment.c
@@ -91,7 +91,7 @@
 	git_dir = getenv(GIT_DIR_ENVIRONMENT);
 	git_dir = git_dir ? xstrdup(git_dir) : NULL;
 	if (!git_dir) {
-		git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+		git_dir = read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT);
 		git_dir = git_dir ? xstrdup(git_dir) : NULL;
 	}
 	if (!git_dir)
diff --git a/fast-import.c b/fast-import.c
index 78d9786..1d5e333 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1017,7 +1017,7 @@
 	unsigned char sha1[20];
 	unsigned long hdrlen, deltalen;
 	git_SHA_CTX c;
-	z_stream s;
+	git_zstream s;
 
 	hdrlen = sprintf((char *)hdr,"%s %lu", typename(type),
 		(unsigned long)dat->len) + 1;
@@ -1050,7 +1050,7 @@
 		delta = NULL;
 
 	memset(&s, 0, sizeof(s));
-	deflateInit(&s, pack_compression_level);
+	git_deflate_init(&s, pack_compression_level);
 	if (delta) {
 		s.next_in = delta;
 		s.avail_in = deltalen;
@@ -1058,11 +1058,11 @@
 		s.next_in = (void *)dat->buf;
 		s.avail_in = dat->len;
 	}
-	s.avail_out = deflateBound(&s, s.avail_in);
+	s.avail_out = git_deflate_bound(&s, s.avail_in);
 	s.next_out = out = xmalloc(s.avail_out);
-	while (deflate(&s, Z_FINISH) == Z_OK)
-		/* nothing */;
-	deflateEnd(&s);
+	while (git_deflate(&s, Z_FINISH) == Z_OK)
+		; /* nothing */
+	git_deflate_end(&s);
 
 	/* Determine if we should auto-checkpoint. */
 	if ((max_packsize && (pack_size + 60 + s.total_out) > max_packsize)
@@ -1078,14 +1078,14 @@
 			delta = NULL;
 
 			memset(&s, 0, sizeof(s));
-			deflateInit(&s, pack_compression_level);
+			git_deflate_init(&s, pack_compression_level);
 			s.next_in = (void *)dat->buf;
 			s.avail_in = dat->len;
-			s.avail_out = deflateBound(&s, s.avail_in);
+			s.avail_out = git_deflate_bound(&s, s.avail_in);
 			s.next_out = out = xrealloc(out, s.avail_out);
-			while (deflate(&s, Z_FINISH) == Z_OK)
-				/* nothing */;
-			deflateEnd(&s);
+			while (git_deflate(&s, Z_FINISH) == Z_OK)
+				; /* nothing */
+			git_deflate_end(&s);
 		}
 	}
 
@@ -1163,7 +1163,7 @@
 	off_t offset;
 	git_SHA_CTX c;
 	git_SHA_CTX pack_file_ctx;
-	z_stream s;
+	git_zstream s;
 	int status = Z_OK;
 
 	/* Determine if we should auto-checkpoint. */
@@ -1187,7 +1187,7 @@
 	crc32_begin(pack_file);
 
 	memset(&s, 0, sizeof(s));
-	deflateInit(&s, pack_compression_level);
+	git_deflate_init(&s, pack_compression_level);
 
 	hdrlen = encode_in_pack_object_header(OBJ_BLOB, len, out_buf);
 	if (out_sz <= hdrlen)
@@ -1209,7 +1209,7 @@
 			len -= n;
 		}
 
-		status = deflate(&s, len ? 0 : Z_FINISH);
+		status = git_deflate(&s, len ? 0 : Z_FINISH);
 
 		if (!s.avail_out || status == Z_STREAM_END) {
 			size_t n = s.next_out - out_buf;
@@ -1228,7 +1228,7 @@
 			die("unexpected deflate failure: %d", status);
 		}
 	}
-	deflateEnd(&s);
+	git_deflate_end(&s);
 	git_SHA1_Final(sha1, &c);
 
 	if (sha1out)
diff --git a/git-am.sh b/git-am.sh
index 6cdd591..f5afe15 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -305,7 +305,8 @@
 		msgnum=
 		;;
 	*)
-		if test -n "$parse_patch" ; then
+		if test -n "$patch_format"
+		then
 			clean_abort "Patch format $patch_format is not supported."
 		else
 			clean_abort "Patch format detection failed."
@@ -507,6 +508,8 @@
 	fi
 fi
 
+git update-index -q --refresh
+
 case "$resolved" in
 '')
 	case "$HAS_HEAD" in
diff --git a/git-compat-util.h b/git-compat-util.h
index e0bb81e..041cbdb 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -236,6 +236,7 @@
 
 /* General helper functions */
 extern void vreportf(const char *prefix, const char *err, va_list params);
+extern void vwritef(int fd, const char *prefix, const char *err, va_list params);
 extern NORETURN void usage(const char *err);
 extern NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2)));
 extern NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2)));
@@ -244,6 +245,7 @@
 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
 extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));
+extern void set_error_routine(void (*routine)(const char *err, va_list params));
 
 extern int prefixcmp(const char *str, const char *prefix);
 extern int suffixcmp(const char *str, const char *suffix);
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 962a93b..6b5f225 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -363,7 +363,7 @@
 	sed -e '1,/^$/d' <../commit | \
 		eval "$filter_msg" > ../message ||
 			die "msg filter failed: $filter_msg"
-	@SHELL_PATH@ -c "$filter_commit" "git commit-tree" \
+	workdir=$workdir @SHELL_PATH@ -c "$filter_commit" "git commit-tree" \
 		$(git write-tree) $parentstr < ../message > ../map/$commit ||
 			die "could not write rewritten commit"
 done <../revs
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index 4db9212..a79a2ec 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -38,7 +38,7 @@
 		while true; do
 			echo "$MERGED seems unchanged."
 			printf "Was the merge successful? [y/n] "
-			read answer
+			read answer || return 1
 			case "$answer" in
 			y*|Y*) status=0; break ;;
 			n*|N*) status=1; break ;;
diff --git a/git-mergetool.sh b/git-mergetool.sh
index 3aab5aa..b6d463f 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -72,7 +72,7 @@
 resolve_symlink_merge () {
     while true; do
 	printf "Use (l)ocal or (r)emote, or (a)bort? "
-	read ans
+	read ans || return 1
 	case "$ans" in
 	    [lL]*)
 		git checkout-index -f --stage=2 -- "$MERGED"
@@ -100,7 +100,7 @@
 	else
 	    printf "Use (c)reated or (d)eleted file, or (a)bort? "
 	fi
-	read ans
+	read ans || return 1
 	case "$ans" in
 	    [mMcC]*)
 		git add -- "$MERGED"
@@ -122,7 +122,7 @@
 resolve_submodule_merge () {
     while true; do
 	printf "Use (l)ocal or (r)emote, or (a)bort? "
-	read ans
+	read ans || return 1
 	case "$ans" in
 	    [lL]*)
 		if ! local_present; then
@@ -249,7 +249,7 @@
     describe_file "$remote_mode" "remote" "$REMOTE"
     if "$prompt" = true; then
 	printf "Hit return to start merge resolution tool (%s): " "$merge_tool"
-	read ans
+	read ans || return 1
     fi
 
     if base_present; then
@@ -320,7 +320,7 @@
 prompt_after_failed_merge() {
     while true; do
 	printf "Continue merging other unresolved paths (y/n) ? "
-	read ans
+	read ans || return 1
 	case "$ans" in
 
 	    [yY]*)
diff --git a/git-pull.sh b/git-pull.sh
index fb9e2df..28441ac 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -9,7 +9,7 @@
 SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
 . git-sh-setup
-set_reflog_action "pull $*"
+set_reflog_action "pull${1+ $*}"
 require_work_tree
 cd_to_toplevel
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 65690af..c6ba7c1 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -713,7 +713,6 @@
 	# parents to rewrite and skipping dropped commits would
 	# prematurely end our probe
 	merges_option=
-	first_after_upstream="$(git rev-list --reverse --first-parent $upstream..$orig_head | head -n 1)"
 else
 	merges_option="--no-merges --cherry-pick"
 fi
@@ -746,7 +745,7 @@
 			preserve=t
 			for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
 			do
-				if test -f "$rewritten"/$p -a \( $p != $onto -o $sha1 = $first_after_upstream \)
+				if test -f "$rewritten"/$p
 				then
 					preserve=f
 				fi
diff --git a/git-rebase.sh b/git-rebase.sh
index d7855ea..38cbee7 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -13,7 +13,7 @@
 It is possible that a merge failure will prevent this process from being
 completely automatic.  You will have to resolve any such merge failure
 and run git rebase --continue.  Another option is to bypass the commit
-that caused the merge failure with git rebase --skip.  To restore the
+that caused the merge failure with git rebase --skip.  To check out the
 original <branch> and remove the .git/rebase-apply working files, use the
 command git rebase --abort instead.
 
@@ -57,9 +57,9 @@
 ignore-whitespace! passed to 'git apply'
 C=!                passed to 'git apply'
  Actions:
-continue!          continue rebasing process
-abort!             abort rebasing process and restore original branch
-skip!              skip current patch and continue rebasing process
+continue!          continue
+abort!             abort and check out the original branch
+skip!              skip current patch and continue
 "
 . git-sh-setup
 set_reflog_action rebase
@@ -72,7 +72,7 @@
 resolvemsg="
 When you have resolved this problem run \"git rebase --continue\".
 If you would prefer to skip this patch, instead run \"git rebase --skip\".
-To restore the original branch and stop rebasing run \"git rebase --abort\".
+To check out the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset onto
 strategy=
diff --git a/git-submodule.sh b/git-submodule.sh
index d189a24..c94218b 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -34,7 +34,7 @@
 {
 	remote=$(get_default_remote)
 	remoteurl=$(git config "remote.$remote.url") ||
-		die "remote ($remote) does not have a url defined in .git/config"
+		remoteurl=$(pwd) # the repository is its own authoritative upstream
 	url="$1"
 	remoteurl=${remoteurl%/}
 	sep=/
@@ -121,12 +121,17 @@
 	path=$1
 	url=$2
 	reference="$3"
+	quiet=
+	if test -n "$GIT_QUIET"
+	then
+		quiet=-q
+	fi
 
 	if test -n "$reference"
 	then
-		git-clone "$reference" -n "$url" "$path"
+		git-clone $quiet "$reference" -n "$url" "$path"
 	else
-		git-clone -n "$url" "$path"
+		git-clone $quiet -n "$url" "$path"
 	fi ||
 	die "Clone of '$url' into submodule path '$path' failed"
 }
@@ -238,15 +243,6 @@
 			die "'$path' already exists and is not a valid git repo"
 		fi
 
-		case "$repo" in
-		./*|../*)
-			url=$(resolve_relative_url "$repo") || exit
-		    ;;
-		*)
-			url="$repo"
-			;;
-		esac
-		git config submodule."$path".url "$url"
 	else
 
 		module_clone "$path" "$realrepo" "$reference" || exit
@@ -260,6 +256,7 @@
 			esac
 		) || die "Unable to checkout submodule '$path'"
 	fi
+	git config submodule."$path".url "$realrepo"
 
 	git add $force "$path" ||
 	die "Failed to add submodule '$path'"
@@ -300,6 +297,10 @@
 
 	toplevel=$(pwd)
 
+	# dup stdin so that it can be restored when running the external
+	# command in the subshell (and a recursive call to this function)
+	exec 3<&0
+
 	module_list |
 	while read mode sha1 stage path
 	do
@@ -316,7 +317,7 @@
 				then
 					cmd_foreach "--recursive" "$@"
 				fi
-			) ||
+			) <&3 3<&- ||
 			die "Stopping at '$path'; script returned non-zero status."
 		fi
 	done
@@ -355,25 +356,26 @@
 	do
 		# Skip already registered paths
 		name=$(module_name "$path") || exit
-		url=$(git config submodule."$name".url)
-		test -z "$url" || continue
+		if test -z "$(git config "submodule.$name.url")"
+		then
+			url=$(git config -f .gitmodules submodule."$name".url)
+			test -z "$url" &&
+			die "No url found for submodule path '$path' in .gitmodules"
 
-		url=$(git config -f .gitmodules submodule."$name".url)
-		test -z "$url" &&
-		die "No url found for submodule path '$path' in .gitmodules"
+			# Possibly a url relative to parent
+			case "$url" in
+			./*|../*)
+				url=$(resolve_relative_url "$url") || exit
+				;;
+			esac
+			git config submodule."$name".url "$url" ||
+			die "Failed to register url for submodule path '$path'"
+		fi
 
-		# Possibly a url relative to parent
-		case "$url" in
-		./*|../*)
-			url=$(resolve_relative_url "$url") || exit
-			;;
-		esac
-
-		git config submodule."$name".url "$url" ||
-		die "Failed to register url for submodule path '$path'"
-
+		# Copy "update" setting when it is not set yet
 		upd="$(git config -f .gitmodules submodule."$name".update)"
 		test -z "$upd" ||
+		test -n "$(git config submodule."$name".update)" ||
 		git config submodule."$name".update "$upd" ||
 		die "Failed to register update mode for submodule path '$path'"
 
@@ -874,17 +876,20 @@
 			;;
 		esac
 
-		say "Synchronizing submodule url for '$name'"
-		git config submodule."$name".url "$url"
-
-		if test -e "$path"/.git
+		if git config "submodule.$name.url" >/dev/null 2>/dev/null
 		then
-		(
-			clear_local_git_env
-			cd "$path"
-			remote=$(get_default_remote)
-			git config remote."$remote".url "$url"
-		)
+			say "Synchronizing submodule url for '$name'"
+			git config submodule."$name".url "$url"
+
+			if test -e "$path"/.git
+			then
+			(
+				clear_local_git_env
+				cd "$path"
+				remote=$(get_default_remote)
+				git config remote."$remote".url "$url"
+			)
+			fi
 		fi
 	done
 }
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 81dacf2..50a835a 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -6129,7 +6129,16 @@
 	# want to be sure not to break that by serving the image as an
 	# attachment (though Firefox 3 doesn't seem to care).
 	my $sandbox = $prevent_xss &&
-		$type !~ m!^(?:text/plain|image/(?:gif|png|jpeg))(?:[ ;]|$)!;
+		$type !~ m!^(?:text/[a-z]+|image/(?:gif|png|jpeg))(?:[ ;]|$)!;
+
+	# serve text/* as text/plain
+	if ($prevent_xss &&
+	    ($type =~ m!^text/[a-z]+\b(.*)$! ||
+	     ($type =~ m!^[a-z]+/[a-z]\+xml\b(.*)$! && -T $fd))) {
+		my $rest = $1;
+		$rest = defined $rest ? $rest : '';
+		$type = "text/plain$rest";
+	}
 
 	print $cgi->header(
 		-type => $type,
diff --git a/help.c b/help.c
index 7654f1b..4219355 100644
--- a/help.c
+++ b/help.c
@@ -302,6 +302,10 @@
 #define SIMILARITY_FLOOR 7
 #define SIMILAR_ENOUGH(x) ((x) < SIMILARITY_FLOOR)
 
+static const char bad_interpreter_advice[] =
+	N_("'%s' appears to be a git command, but we were not\n"
+	"able to execute it. Maybe git-%s is broken?");
+
 const char *help_unknown_cmd(const char *cmd)
 {
 	int i, n, best_similarity = 0;
@@ -326,6 +330,14 @@
 		int cmp = 0; /* avoid compiler stupidity */
 		const char *candidate = main_cmds.names[i]->name;
 
+		/*
+		 * An exact match means we have the command, but
+		 * for some reason exec'ing it gave us ENOENT; probably
+		 * it's a bad interpreter in the #! line.
+		 */
+		if (!strcmp(candidate, cmd))
+			die(_(bad_interpreter_advice), cmd, cmd);
+
 		/* Does the candidate appear in common_cmds list? */
 		while (n < ARRAY_SIZE(common_cmds) &&
 		       (cmp = strcmp(common_cmds[n].name, candidate)) < 0)
diff --git a/http-backend.c b/http-backend.c
index 8501504..59ad7da 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -271,16 +271,13 @@
 
 static void inflate_request(const char *prog_name, int out)
 {
-	z_stream stream;
+	git_zstream stream;
 	unsigned char in_buf[8192];
 	unsigned char out_buf[8192];
 	unsigned long cnt = 0;
-	int ret;
 
 	memset(&stream, 0, sizeof(stream));
-	ret = inflateInit2(&stream, (15 + 16));
-	if (ret != Z_OK)
-		die("cannot start zlib inflater, zlib err %d", ret);
+	git_inflate_init_gzip_only(&stream);
 
 	while (1) {
 		ssize_t n = xread(0, in_buf, sizeof(in_buf));
@@ -296,7 +293,7 @@
 			stream.next_out = out_buf;
 			stream.avail_out = sizeof(out_buf);
 
-			ret = inflate(&stream, Z_NO_FLUSH);
+			ret = git_inflate(&stream, Z_NO_FLUSH);
 			if (ret != Z_OK && ret != Z_STREAM_END)
 				die("zlib error inflating request, result %d", ret);
 
@@ -311,7 +308,7 @@
 	}
 
 done:
-	inflateEnd(&stream);
+	git_inflate_end(&stream);
 	close(out);
 }
 
diff --git a/http-push.c b/http-push.c
index 28bfe76..376331a 100644
--- a/http-push.c
+++ b/http-push.c
@@ -377,15 +377,15 @@
 	unsigned long len;
 	int hdrlen;
 	ssize_t size;
-	z_stream stream;
+	git_zstream stream;
 
 	unpacked = read_sha1_file(request->obj->sha1, &type, &len);
 	hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
 
 	/* Set it up */
 	memset(&stream, 0, sizeof(stream));
-	deflateInit(&stream, zlib_compression_level);
-	size = deflateBound(&stream, len + hdrlen);
+	git_deflate_init(&stream, zlib_compression_level);
+	size = git_deflate_bound(&stream, len + hdrlen);
 	strbuf_init(&request->buffer.buf, size);
 	request->buffer.posn = 0;
 
@@ -396,15 +396,15 @@
 	/* First header.. */
 	stream.next_in = (void *)hdr;
 	stream.avail_in = hdrlen;
-	while (deflate(&stream, 0) == Z_OK)
-		/* nothing */;
+	while (git_deflate(&stream, 0) == Z_OK)
+		; /* nothing */
 
 	/* Then the data itself.. */
 	stream.next_in = unpacked;
 	stream.avail_in = len;
-	while (deflate(&stream, Z_FINISH) == Z_OK)
-		/* nothing */;
-	deflateEnd(&stream);
+	while (git_deflate(&stream, Z_FINISH) == Z_OK)
+		; /* nothing */
+	git_deflate_end(&stream);
 	free(unpacked);
 
 	request->buffer.buf.len = stream.total_out;
@@ -1655,7 +1655,7 @@
 		return error("Remote HEAD is not a symref");
 
 	/* Remote branch must not be the remote HEAD */
-	for (i=0; symref && i<MAXDEPTH; i++) {
+	for (i = 0; symref && i < MAXDEPTH; i++) {
 		if (!strcmp(remote_ref->name, symref))
 			return error("Remote branch %s is the current HEAD",
 				     remote_ref->name);
diff --git a/http.h b/http.h
index 19b7134..0bf8592 100644
--- a/http.h
+++ b/http.h
@@ -172,7 +172,7 @@
 	unsigned char sha1[20];
 	unsigned char real_sha1[20];
 	git_SHA_CTX c;
-	z_stream stream;
+	git_zstream stream;
 	int zret;
 	int rename;
 	struct active_request_slot *slot;
diff --git a/notes.c b/notes.c
index f6ce848..93e9868 100644
--- a/notes.c
+++ b/notes.c
@@ -1105,7 +1105,7 @@
 	hashcpy(l.key_sha1, object_sha1);
 	hashclr(l.val_sha1);
 	note_tree_remove(t, t->root, 0, &l);
-	if (is_null_sha1(l.val_sha1)) // no note was removed
+	if (is_null_sha1(l.val_sha1)) /* no note was removed */
 		return 1;
 	t->dirty = 1;
 	return 0;
diff --git a/pack-check.c b/pack-check.c
index a1a5216..0c19b6e 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -26,7 +26,7 @@
 	uint32_t data_crc = crc32(0, NULL, 0);
 
 	do {
-		unsigned int avail;
+		unsigned long avail;
 		void *data = use_pack(p, w_curs, offset, &avail);
 		if (avail > len)
 			avail = len;
@@ -61,7 +61,7 @@
 
 	git_SHA1_Init(&ctx);
 	do {
-		unsigned int remaining;
+		unsigned long remaining;
 		unsigned char *in = use_pack(p, w_curs, offset, &remaining);
 		offset += remaining;
 		if (!pack_sig_ofs)
diff --git a/path.c b/path.c
index 4d73cc9..6f3f5d5 100644
--- a/path.c
+++ b/path.c
@@ -139,7 +139,7 @@
 		strbuf_addch(&buf, '/');
 	strbuf_addstr(&buf, ".git");
 
-	git_dir = read_gitfile_gently(buf.buf);
+	git_dir = read_gitfile(buf.buf);
 	if (git_dir) {
 		strbuf_reset(&buf);
 		strbuf_addstr(&buf, git_dir);
diff --git a/read-cache.c b/read-cache.c
index 4ac9a03..0a64103 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1087,7 +1087,7 @@
 {
 	if (in_porcelain && *first && header_msg) {
 		printf("%s\n", header_msg);
-		*first=0;
+		*first = 0;
 	}
 	printf(fmt, name);
 }
diff --git a/refs.c b/refs.c
index b10419a..4c1fd47 100644
--- a/refs.c
+++ b/refs.c
@@ -451,7 +451,7 @@
 	memcpy(gitdir + len, "/.git", 6);
 	len += 5;
 
-	tmp = read_gitfile_gently(gitdir);
+	tmp = read_gitfile(gitdir);
 	if (tmp) {
 		free(gitdir);
 		len = strlen(tmp);
@@ -837,7 +837,7 @@
 
 static inline int bad_ref_char(int ch)
 {
-	if (((unsigned) ch) <= ' ' ||
+	if (((unsigned) ch) <= ' ' || ch == 0x7f ||
 	    ch == '~' || ch == '^' || ch == ':' || ch == '\\')
 		return 1;
 	/* 2.13 Pattern Matching Notation */
@@ -1826,6 +1826,12 @@
 	return 0;
 }
 
+int ref_exists(char *refname)
+{
+	unsigned char sha1[20];
+	return !!resolve_ref(refname, sha1, 1, NULL);
+}
+
 struct ref *find_ref_by_name(const struct ref *list, const char *name)
 {
 	for ( ; list; list = list->next)
diff --git a/refs.h b/refs.h
index 5e7a9a5..5de06e5 100644
--- a/refs.h
+++ b/refs.h
@@ -54,6 +54,7 @@
  */
 extern void add_extra_ref(const char *refname, const unsigned char *sha1, int flags);
 extern void clear_extra_refs(void);
+extern int ref_exists(char *);
 
 extern int peel_ref(const char *, unsigned char *);
 
diff --git a/remote-curl.c b/remote-curl.c
index 8ac5028..69831e9 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -473,16 +473,12 @@
 		 * the transfer time.
 		 */
 		size_t size;
-		z_stream stream;
+		git_zstream stream;
 		int ret;
 
 		memset(&stream, 0, sizeof(stream));
-		ret = deflateInit2(&stream, Z_BEST_COMPRESSION,
-				Z_DEFLATED, (15 + 16),
-				8, Z_DEFAULT_STRATEGY);
-		if (ret != Z_OK)
-			die("cannot deflate request; zlib init error %d", ret);
-		size = deflateBound(&stream, rpc->len);
+		git_deflate_init_gzip(&stream, Z_BEST_COMPRESSION);
+		size = git_deflate_bound(&stream, rpc->len);
 		gzip_body = xmalloc(size);
 
 		stream.next_in = (unsigned char *)rpc->buf;
@@ -490,11 +486,11 @@
 		stream.next_out = (unsigned char *)gzip_body;
 		stream.avail_out = size;
 
-		ret = deflate(&stream, Z_FINISH);
+		ret = git_deflate(&stream, Z_FINISH);
 		if (ret != Z_STREAM_END)
 			die("cannot deflate request; zlib deflate error %d", ret);
 
-		ret = deflateEnd(&stream);
+		ret = git_deflate_end_gently(&stream);
 		if (ret != Z_OK)
 			die("cannot deflate request; zlib end error %d", ret);
 
diff --git a/run-command.c b/run-command.c
index 70e8a24..a2796c4 100644
--- a/run-command.c
+++ b/run-command.c
@@ -77,16 +77,14 @@
 
 static NORETURN void die_child(const char *err, va_list params)
 {
-	char msg[4096];
-	int len = vsnprintf(msg, sizeof(msg), err, params);
-	if (len > sizeof(msg))
-		len = sizeof(msg);
-
-	write_in_full(child_err, "fatal: ", 7);
-	write_in_full(child_err, msg, len);
-	write_in_full(child_err, "\n", 1);
+	vwritef(child_err, "fatal: ", err, params);
 	exit(128);
 }
+
+static void error_child(const char *err, va_list params)
+{
+	vwritef(child_err, "error: ", err, params);
+}
 #endif
 
 static inline void set_cloexec(int fd)
@@ -127,9 +125,6 @@
 		if (code == 127) {
 			code = -1;
 			failed_errno = ENOENT;
-			if (!silent_exec_failure)
-				error("cannot run %s: %s", argv0,
-					strerror(ENOENT));
 		}
 	} else {
 		error("waitpid is confused (%s)", argv0);
@@ -217,6 +212,7 @@
 			set_cloexec(child_err);
 		}
 		set_die_routine(die_child);
+		set_error_routine(error_child);
 
 		close(notify_pipe[0]);
 		set_cloexec(notify_pipe[1]);
@@ -283,14 +279,14 @@
 		} else {
 			execvp(cmd->argv[0], (char *const*) cmd->argv);
 		}
-		/*
-		 * Do not check for cmd->silent_exec_failure; the parent
-		 * process will check it when it sees this exit code.
-		 */
-		if (errno == ENOENT)
+		if (errno == ENOENT) {
+			if (!cmd->silent_exec_failure)
+				error("cannot run %s: %s", cmd->argv[0],
+					strerror(ENOENT));
 			exit(127);
-		else
+		} else {
 			die_errno("cannot exec '%s'", cmd->argv[0]);
+		}
 	}
 	if (cmd->pid < 0)
 		error("cannot fork() for %s: %s", cmd->argv[0],
diff --git a/setup.c b/setup.c
index ce87900..1b06db5 100644
--- a/setup.c
+++ b/setup.c
@@ -375,7 +375,7 @@
  * Try to read the location of the git directory from the .git file,
  * return path to git directory if found.
  */
-const char *read_gitfile_gently(const char *path)
+const char *read_gitfile(const char *path)
 {
 	char *buf;
 	char *dir;
@@ -437,7 +437,7 @@
 	if (PATH_MAX - 40 < strlen(gitdirenv))
 		die("'$%s' too big", GIT_DIR_ENVIRONMENT);
 
-	gitfile = (char*)read_gitfile_gently(gitdirenv);
+	gitfile = (char*)read_gitfile(gitdirenv);
 	if (gitfile) {
 		gitfile = xstrdup(gitfile);
 		gitdirenv = gitfile;
@@ -661,7 +661,7 @@
 	if (one_filesystem)
 		current_device = get_device_or_die(".", NULL);
 	for (;;) {
-		gitfile = (char*)read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+		gitfile = (char*)read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT);
 		if (gitfile)
 			gitdirenv = gitfile = xstrdup(gitfile);
 		else {
diff --git a/sha1_file.c b/sha1_file.c
index 064a330..32268d1 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -380,7 +380,7 @@
 {
 	struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
 	int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR);
-	char *alt = mkpath("%s/objects\n", reference);
+	char *alt = mkpath("%s\n", reference);
 	write_or_die(fd, alt, strlen(alt));
 	if (commit_lock_file(lock))
 		die("could not close alternates file");
@@ -834,7 +834,7 @@
 unsigned char *use_pack(struct packed_git *p,
 		struct pack_window **w_cursor,
 		off_t offset,
-		unsigned int *left)
+		unsigned long *left)
 {
 	struct pack_window *win = *w_cursor;
 
@@ -1205,20 +1205,29 @@
 	return map;
 }
 
-static int legacy_loose_object(unsigned char *map)
+/*
+ * There used to be a second loose object header format which
+ * was meant to mimic the in-pack format, allowing for direct
+ * copy of the object data.  This format turned up not to be
+ * really worth it and we no longer write loose objects in that
+ * format.
+ */
+static int experimental_loose_object(unsigned char *map)
 {
 	unsigned int word;
 
 	/*
 	 * Is it a zlib-compressed buffer? If so, the first byte
 	 * must be 0x78 (15-bit window size, deflated), and the
-	 * first 16-bit word is evenly divisible by 31
+	 * first 16-bit word is evenly divisible by 31. If so,
+	 * we are looking at the official format, not the experimental
+	 * one.
 	 */
 	word = (map[0] << 8) + map[1];
 	if (map[0] == 0x78 && !(word % 31))
-		return 1;
-	else
 		return 0;
+	else
+		return 1;
 }
 
 unsigned long unpack_object_header_buffer(const unsigned char *buf,
@@ -1245,7 +1254,7 @@
 	return used;
 }
 
-static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
+static int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
 {
 	unsigned long size, used;
 	static const char valid_loose_object_type[8] = {
@@ -1262,37 +1271,32 @@
 	stream->next_out = buffer;
 	stream->avail_out = bufsiz;
 
-	if (legacy_loose_object(map)) {
+	if (experimental_loose_object(map)) {
+		/*
+		 * The old experimental format we no longer produce;
+		 * we can still read it.
+		 */
+		used = unpack_object_header_buffer(map, mapsize, &type, &size);
+		if (!used || !valid_loose_object_type[type])
+			return -1;
+		map += used;
+		mapsize -= used;
+
+		/* Set up the stream for the rest.. */
+		stream->next_in = map;
+		stream->avail_in = mapsize;
 		git_inflate_init(stream);
-		return git_inflate(stream, 0);
+
+		/* And generate the fake traditional header */
+		stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
+						 typename(type), size);
+		return 0;
 	}
-
-
-	/*
-	 * There used to be a second loose object header format which
-	 * was meant to mimic the in-pack format, allowing for direct
-	 * copy of the object data.  This format turned up not to be
-	 * really worth it and we don't write it any longer.  But we
-	 * can still read it.
-	 */
-	used = unpack_object_header_buffer(map, mapsize, &type, &size);
-	if (!used || !valid_loose_object_type[type])
-		return -1;
-	map += used;
-	mapsize -= used;
-
-	/* Set up the stream for the rest.. */
-	stream->next_in = map;
-	stream->avail_in = mapsize;
 	git_inflate_init(stream);
-
-	/* And generate the fake traditional header */
-	stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
-					 typename(type), size);
-	return 0;
+	return git_inflate(stream, 0);
 }
 
-static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size, const unsigned char *sha1)
+static void *unpack_sha1_rest(git_zstream *stream, void *buffer, unsigned long size, const unsigned char *sha1)
 {
 	int bytes = strlen(buffer) + 1;
 	unsigned char *buf = xmallocz(size);
@@ -1391,7 +1395,7 @@
 static void *unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size, const unsigned char *sha1)
 {
 	int ret;
-	z_stream stream;
+	git_zstream stream;
 	char hdr[8192];
 
 	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
@@ -1407,7 +1411,7 @@
 {
 	const unsigned char *data;
 	unsigned char delta_head[20], *in;
-	z_stream stream;
+	git_zstream stream;
 	int st;
 
 	memset(&stream, 0, sizeof(stream));
@@ -1529,7 +1533,7 @@
 				unsigned long *sizep)
 {
 	unsigned char *base;
-	unsigned int left;
+	unsigned long left;
 	unsigned long used;
 	enum object_type type;
 
@@ -1642,7 +1646,7 @@
 				    unsigned long size)
 {
 	int st;
-	z_stream stream;
+	git_zstream stream;
 	unsigned char *buffer, *in;
 
 	buffer = xmallocz(size);
@@ -2075,7 +2079,7 @@
 	int status;
 	unsigned long mapsize, size;
 	void *map;
-	z_stream stream;
+	git_zstream stream;
 	char hdr[32];
 
 	map = map_sha1_file(sha1, &mapsize);
@@ -2424,7 +2428,7 @@
 {
 	int fd, ret;
 	unsigned char compressed[4096];
-	z_stream stream;
+	git_zstream stream;
 	git_SHA_CTX c;
 	unsigned char parano_sha1[20];
 	char *filename;
@@ -2441,7 +2445,7 @@
 
 	/* Set it up */
 	memset(&stream, 0, sizeof(stream));
-	deflateInit(&stream, zlib_compression_level);
+	git_deflate_init(&stream, zlib_compression_level);
 	stream.next_out = compressed;
 	stream.avail_out = sizeof(compressed);
 	git_SHA1_Init(&c);
@@ -2449,8 +2453,8 @@
 	/* First header.. */
 	stream.next_in = (unsigned char *)hdr;
 	stream.avail_in = hdrlen;
-	while (deflate(&stream, 0) == Z_OK)
-		/* nothing */;
+	while (git_deflate(&stream, 0) == Z_OK)
+		; /* nothing */
 	git_SHA1_Update(&c, hdr, hdrlen);
 
 	/* Then the data itself.. */
@@ -2458,7 +2462,7 @@
 	stream.avail_in = len;
 	do {
 		unsigned char *in0 = stream.next_in;
-		ret = deflate(&stream, Z_FINISH);
+		ret = git_deflate(&stream, Z_FINISH);
 		git_SHA1_Update(&c, in0, stream.next_in - in0);
 		if (write_buffer(fd, compressed, stream.next_out - compressed) < 0)
 			die("unable to write sha1 file");
@@ -2468,7 +2472,7 @@
 
 	if (ret != Z_STREAM_END)
 		die("unable to deflate new object %s (%d)", sha1_to_hex(sha1), ret);
-	ret = deflateEnd(&stream);
+	ret = git_deflate_end_gently(&stream);
 	if (ret != Z_OK)
 		die("deflateEnd on object %s failed (%d)", sha1_to_hex(sha1), ret);
 	git_SHA1_Final(parano_sha1, &c);
diff --git a/strbuf.c b/strbuf.c
index 09c43ae..1a7df12 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -103,24 +103,27 @@
 	sb->buf[sb->len] = '\0';
 }
 
-struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
+struct strbuf **strbuf_split_buf(const char *str, size_t slen, int delim, int max)
 {
 	int alloc = 2, pos = 0;
-	char *n, *p;
+	const char *n, *p;
 	struct strbuf **ret;
 	struct strbuf *t;
 
 	ret = xcalloc(alloc, sizeof(struct strbuf *));
-	p = n = sb->buf;
-	while (n < sb->buf + sb->len) {
+	p = n = str;
+	while (n < str + slen) {
 		int len;
-		n = memchr(n, delim, sb->len - (n - sb->buf));
+		if (max <= 0 || pos + 1 < max)
+			n = memchr(n, delim, slen - (n - str));
+		else
+			n = NULL;
 		if (pos + 1 >= alloc) {
 			alloc = alloc * 2;
 			ret = xrealloc(ret, sizeof(struct strbuf *) * alloc);
 		}
 		if (!n)
-			n = sb->buf + sb->len - 1;
+			n = str + slen - 1;
 		len = n - p + 1;
 		t = xmalloc(sizeof(struct strbuf));
 		strbuf_init(t, len);
diff --git a/strbuf.h b/strbuf.h
index 9e6d9fa..46a33f8 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -44,7 +44,22 @@
 extern void strbuf_ltrim(struct strbuf *);
 extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
 
-extern struct strbuf **strbuf_split(const struct strbuf *, int delim);
+extern struct strbuf **strbuf_split_buf(const char *, size_t,
+					int delim, int max);
+static inline struct strbuf **strbuf_split_str(const char *str,
+					       int delim, int max)
+{
+	return strbuf_split_buf(str, strlen(str), delim, max);
+}
+static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,
+						int delim, int max)
+{
+	return strbuf_split_buf(sb->buf, sb->len, delim, max);
+}
+static inline struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
+{
+	return strbuf_split_max(sb, delim, 0);
+}
 extern void strbuf_list_free(struct strbuf **);
 
 /*----- add data in your buffer -----*/
diff --git a/submodule.c b/submodule.c
index b6dec70..11de09a 100644
--- a/submodule.c
+++ b/submodule.c
@@ -32,7 +32,7 @@
 	const char *git_dir;
 
 	strbuf_addf(&objects_directory, "%s/.git", path);
-	git_dir = read_gitfile_gently(objects_directory.buf);
+	git_dir = read_gitfile(objects_directory.buf);
 	if (git_dir) {
 		strbuf_reset(&objects_directory);
 		strbuf_addstr(&objects_directory, git_dir);
@@ -373,6 +373,10 @@
 	const char *argv[] = {NULL, NULL, "--not", "--all", NULL};
 	int argc = ARRAY_SIZE(argv) - 1;
 
+	/* No need to check if there are no submodules configured */
+	if (!config_name_for_path.nr)
+		return;
+
 	init_revisions(&rev, NULL);
 	argv[1] = xstrdup(sha1_to_hex(new_sha1));
 	setup_revisions(argc, argv, &rev, NULL);
@@ -388,6 +392,7 @@
 		while (parent) {
 			struct diff_options diff_opts;
 			diff_setup(&diff_opts);
+			DIFF_OPT_SET(&diff_opts, RECURSIVE);
 			diff_opts.output_format |= DIFF_FORMAT_CALLBACK;
 			diff_opts.format_callback = submodule_collect_changed_cb;
 			if (diff_setup_done(&diff_opts) < 0)
@@ -478,7 +483,7 @@
 		strbuf_addf(&submodule_path, "%s/%s", work_tree, ce->name);
 		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
 		strbuf_addf(&submodule_prefix, "%s%s/", prefix, ce->name);
-		git_dir = read_gitfile_gently(submodule_git_dir.buf);
+		git_dir = read_gitfile(submodule_git_dir.buf);
 		if (!git_dir)
 			git_dir = submodule_git_dir.buf;
 		if (is_directory(git_dir)) {
@@ -516,7 +521,7 @@
 	const char *git_dir;
 
 	strbuf_addf(&buf, "%s/.git", path);
-	git_dir = read_gitfile_gently(buf.buf);
+	git_dir = read_gitfile(buf.buf);
 	if (!git_dir)
 		git_dir = buf.buf;
 	if (!is_directory(git_dir)) {
diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh
index 143eb1f..292753f 100644
--- a/t/gitweb-lib.sh
+++ b/t/gitweb-lib.sh
@@ -107,4 +107,9 @@
 	test_done
 }
 
+perl -MCGI -MCGI::Util -MCGI::Carp -e 0 >/dev/null 2>&1 || {
+	skip_all='skipping gitweb tests, CGI module unusable'
+	test_done
+}
+
 gitweb_init
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 3db5626..3e140c1 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -904,4 +904,22 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'git -c does not split values on equals' '
+	echo "value with = in it" >expect &&
+	git -c core.foo="value with = in it" config core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'git -c dies on bogus config' '
+	test_must_fail git -c core.bare=foo rev-parse
+'
+
+test_expect_success 'git -c complains about empty key' '
+	test_must_fail git -c "=foo" rev-parse
+'
+
+test_expect_success 'git -c complains about empty key and value' '
+	test_must_fail git -c "" rev-parse
+'
+
 test_done
diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
index 1b0f82f..ed4275a 100755
--- a/t/t1402-check-ref-format.sh
+++ b/t/t1402-check-ref-format.sh
@@ -18,6 +18,9 @@
 valid_ref 'foo/bar/baz'
 valid_ref 'refs///heads/foo'
 invalid_ref 'heads/foo/'
+valid_ref '/heads/foo'
+valid_ref '///heads/foo'
+invalid_ref '/foo'
 invalid_ref './foo'
 invalid_ref '.refs/foo'
 invalid_ref 'heads/foo..bar'
@@ -27,6 +30,9 @@
 valid_ref 'heads/foo@bar'
 invalid_ref 'heads/v@{ation'
 invalid_ref 'heads/foo\bar'
+invalid_ref "$(printf 'heads/foo\t')"
+invalid_ref "$(printf 'heads/foo\177')"
+valid_ref "$(printf 'heads/fu\303\237')"
 
 test_expect_success "check-ref-format --branch @{-1}" '
 	T=$(git write-tree) &&
@@ -70,7 +76,10 @@
 
 valid_ref_normalized 'heads/foo' 'heads/foo'
 valid_ref_normalized 'refs///heads/foo' 'refs/heads/foo'
+valid_ref_normalized '/heads/foo' 'heads/foo'
+valid_ref_normalized '///heads/foo' 'heads/foo'
 invalid_ref_normalized 'foo'
+invalid_ref_normalized '/foo'
 invalid_ref_normalized 'heads/foo/../bar'
 invalid_ref_normalized 'heads/./foo'
 invalid_ref_normalized 'heads\foo'
diff --git a/t/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh
index 7f519e5..647d888 100755
--- a/t/t1412-reflog-loop.sh
+++ b/t/t1412-reflog-loop.sh
@@ -21,10 +21,10 @@
 
 test_expect_success 'reflog shows all entries' '
 	cat >expect <<-\EOF
-		topic@{0} two: updating HEAD
-		topic@{1} one: updating HEAD
-		topic@{2} two: updating HEAD
-		topic@{3} one: updating HEAD
+		topic@{0} reset: moving to two
+		topic@{1} reset: moving to one
+		topic@{2} reset: moving to two
+		topic@{3} reset: moving to one
 		topic@{4} branch: Created from HEAD
 	EOF
 	git log -g --format="%gd %gs" topic >actual &&
diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index fa69016..a42e039 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -169,4 +169,15 @@
 	test_must_fail test_dirty_mergeable
 '
 
+test_expect_success 'checkout -b <describe>' '
+	git tag -f -m "First commit" initial initial &&
+	git checkout -f change1 &&
+	name=$(git describe) &&
+	git checkout -b $name &&
+	git diff --exit-code change1 &&
+	echo "refs/heads/$name" >expect &&
+	git symbolic-ref HEAD >actual &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t3103-ls-tree-misc.sh b/t/t3103-ls-tree-misc.sh
new file mode 100755
index 0000000..09dcf04
--- /dev/null
+++ b/t/t3103-ls-tree-misc.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+test_description='
+Miscellaneous tests for git ls-tree.
+
+	      1. git ls-tree fails in presence of tree damage.
+
+'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	mkdir a &&
+	touch a/one &&
+	git add a/one &&
+	git commit -m test
+'
+
+test_expect_success 'ls-tree fails with non-zero exit code on broken tree' '
+	rm -f .git/objects/5f/cffbd6e4c5c5b8d81f5e9314b20e338e3ffff5 &&
+	test_must_fail git ls-tree -r HEAD
+'
+
+test_done
diff --git a/t/t3307-notes-man.sh b/t/t3307-notes-man.sh
index 2ea3be6..1aa366a 100755
--- a/t/t3307-notes-man.sh
+++ b/t/t3307-notes-man.sh
@@ -26,13 +26,13 @@
 '
 
 test_expect_success 'example 2: binary notes' '
-	cp "$TEST_DIRECTORY"/test4012.png . &&
+	cp "$TEST_DIRECTORY"/test-binary-1.png . &&
 	git checkout B &&
-	blob=$(git hash-object -w test4012.png) &&
+	blob=$(git hash-object -w test-binary-1.png) &&
 	git notes --ref=logo add -C "$blob" &&
 	git notes --ref=logo copy B C &&
 	git notes --ref=logo show C >actual &&
-	test_cmp test4012.png actual
+	test_cmp test-binary-1.png actual
 '
 
 test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 47c8371..8538813 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -295,7 +295,7 @@
 '
 
 test_expect_success 'edit ancestor with -p' '
-	FAKE_LINES="1 edit 2 3 4" git rebase -i -p HEAD~3 &&
+	FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3 &&
 	echo 2 > unrelated-file &&
 	test_tick &&
 	git commit -m L2-modified --amend unrelated-file &&
diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh
index 08201e2..6de4e22 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -37,7 +37,15 @@
 #      \
 #       B2     <-- origin/topic
 #
-# In all cases, 'topic' is rebased onto 'origin/topic'.
+# Clone 4 (merge using second parent as base):
+#
+# A1--A2--B3   <-- origin/master
+#  \
+#   B1--A3--M  <-- topic
+#    \     /
+#     \--A4    <-- topic2
+#      \
+#       B2     <-- origin/topic
 
 test_expect_success 'setup for merge-preserving rebase' \
 	'echo First > A &&
@@ -57,6 +65,13 @@
 	git merge origin/master
 	) &&
 
+	git clone ./. clone4 &&
+	(
+		cd clone4 &&
+		git checkout -b topic origin/topic &&
+		git merge origin/master
+	) &&
+
 	echo Fifth > B &&
 	git add B &&
 	git commit -m "Add different B" &&
@@ -123,4 +138,15 @@
 	)
 '
 
+test_expect_success 'rebase -p works when base inside second parent' '
+	(
+	cd clone4 &&
+	git fetch &&
+	git rebase -p HEAD^2 &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep "Modify B" | wc -l) &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep "Merge remote-tracking branch " | wc -l)
+	)
+'
+
 test_done
diff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh
index 14a23cd..ace8e54 100755
--- a/t/t3411-rebase-preserve-around-merges.sh
+++ b/t/t3411-rebase-preserve-around-merges.sh
@@ -37,7 +37,7 @@
 #        -- C1 --
 #
 test_expect_success 'squash F1 into D1' '
-	FAKE_LINES="1 squash 3 2" git rebase -i -p B1 &&
+	FAKE_LINES="1 squash 4 2 3" git rebase -i -p B1 &&
 	test "$(git rev-parse HEAD^2)" = "$(git rev-parse C1)" &&
 	test "$(git rev-parse HEAD~2)" = "$(git rev-parse B1)" &&
 	git tag E2
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 05ec062..2d9f9a0 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -12,7 +12,7 @@
 	'echo AIT >a && echo BIT >b && echo CIT >c && echo DIT >d &&
 	 git update-index --add a b c d &&
 	 echo git >a &&
-	 cat "$TEST_DIRECTORY"/test4012.png >b &&
+	 cat "$TEST_DIRECTORY"/test-binary-1.png >b &&
 	 echo git >c &&
 	 cat b b >d'
 
diff --git a/t/t4048-diff-combined-binary.sh b/t/t4048-diff-combined-binary.sh
new file mode 100755
index 0000000..87a8949
--- /dev/null
+++ b/t/t4048-diff-combined-binary.sh
@@ -0,0 +1,212 @@
+#!/bin/sh
+
+test_description='combined and merge diff handle binary files and textconv'
+. ./test-lib.sh
+
+test_expect_success 'setup binary merge conflict' '
+	echo oneQ1 | q_to_nul >binary &&
+	git add binary &&
+	git commit -m one &&
+	echo twoQ2 | q_to_nul >binary &&
+	git commit -a -m two &&
+	git checkout -b branch-binary HEAD^ &&
+	echo threeQ3 | q_to_nul >binary &&
+	git commit -a -m three &&
+	test_must_fail git merge master &&
+	echo resolvedQhooray | q_to_nul >binary &&
+	git commit -a -m resolved
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --git a/binary b/binary
+index 7ea6ded..9563691 100644
+Binary files a/binary and b/binary differ
+resolved
+
+diff --git a/binary b/binary
+index 6197570..9563691 100644
+Binary files a/binary and b/binary differ
+EOF
+test_expect_success 'diff -m indicates binary-ness' '
+	git show --format=%s -m >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --combined binary
+index 7ea6ded,6197570..9563691
+Binary files differ
+EOF
+test_expect_success 'diff -c indicates binary-ness' '
+	git show --format=%s -c >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --cc binary
+index 7ea6ded,6197570..9563691
+Binary files differ
+EOF
+test_expect_success 'diff --cc indicates binary-ness' '
+	git show --format=%s --cc >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'setup non-binary with binary attribute' '
+	git checkout master &&
+	test_commit one text &&
+	test_commit two text &&
+	git checkout -b branch-text HEAD^ &&
+	test_commit three text &&
+	test_must_fail git merge master &&
+	test_commit resolved text &&
+	echo text -diff >.gitattributes
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --git a/text b/text
+index 2bdf67a..2ab19ae 100644
+Binary files a/text and b/text differ
+resolved
+
+diff --git a/text b/text
+index f719efd..2ab19ae 100644
+Binary files a/text and b/text differ
+EOF
+test_expect_success 'diff -m respects binary attribute' '
+	git show --format=%s -m >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --combined text
+index 2bdf67a,f719efd..2ab19ae
+Binary files differ
+EOF
+test_expect_success 'diff -c respects binary attribute' '
+	git show --format=%s -c >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --cc text
+index 2bdf67a,f719efd..2ab19ae
+Binary files differ
+EOF
+test_expect_success 'diff --cc respects binary attribute' '
+	git show --format=%s --cc >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'setup textconv attribute' '
+	echo "text diff=upcase" >.gitattributes &&
+	git config diff.upcase.textconv "tr a-z A-Z <"
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --git a/text b/text
+index 2bdf67a..2ab19ae 100644
+--- a/text
++++ b/text
+@@ -1 +1 @@
+-THREE
++RESOLVED
+resolved
+
+diff --git a/text b/text
+index f719efd..2ab19ae 100644
+--- a/text
++++ b/text
+@@ -1 +1 @@
+-TWO
++RESOLVED
+EOF
+test_expect_success 'diff -m respects textconv attribute' '
+	git show --format=%s -m >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --combined text
+index 2bdf67a,f719efd..2ab19ae
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,1 @@@
+- THREE
+ -TWO
+++RESOLVED
+EOF
+test_expect_success 'diff -c respects textconv attribute' '
+	git show --format=%s -c >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --cc text
+index 2bdf67a,f719efd..2ab19ae
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,1 @@@
+- THREE
+ -TWO
+++RESOLVED
+EOF
+test_expect_success 'diff --cc respects textconv attribute' '
+	git show --format=%s --cc >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+diff --combined text
+index 2bdf67a,f719efd..2ab19ae
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,1 @@@
+- three
+ -two
+++resolved
+EOF
+test_expect_success 'diff-tree plumbing does not respect textconv' '
+	git diff-tree HEAD -c -p >full &&
+	tail -n +2 full >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+diff --cc text
+index 2bdf67a,f719efd..0000000
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,5 @@@
+++<<<<<<< HEAD
+ +THREE
+++=======
++ TWO
+++>>>>>>> MASTER
+EOF
+test_expect_success 'diff --cc respects textconv on worktree file' '
+	git reset --hard HEAD^ &&
+	test_must_fail git merge master &&
+	git diff >actual &&
+	test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index a1fddd4..ca5b027 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -47,7 +47,7 @@
 		git init &&
 		echo subcontent > subfile &&
 		git add subfile &&
-		git submodule add "$pwd/deepsubmodule" deepsubmodule &&
+		git submodule add "$pwd/deepsubmodule" subdir/deepsubmodule &&
 		git commit -a -m new
 	) &&
 	git submodule add "$pwd/submodule" submodule &&
@@ -58,7 +58,7 @@
 		git submodule update --init --recursive
 	) &&
 	echo "Fetching submodule submodule" > expect.out &&
-	echo "Fetching submodule submodule/deepsubmodule" >> expect.out
+	echo "Fetching submodule submodule/subdir/deepsubmodule" >> expect.out
 '
 
 test_expect_success "fetch --recurse-submodules recurses into submodules" '
@@ -277,12 +277,12 @@
 	(
 		cd submodule &&
 		(
-			cd deepsubmodule &&
+			cd subdir/deepsubmodule &&
 			git fetch &&
 			git checkout -q FETCH_HEAD
 		) &&
 		head1=$(git rev-parse --short HEAD^) &&
-		git add deepsubmodule &&
+		git add subdir/deepsubmodule &&
 		git commit -m "new deepsubmodule"
 		head2=$(git rev-parse --short HEAD) &&
 		echo "From $pwd/submodule" > ../expect.err.sub &&
@@ -309,12 +309,12 @@
 	(
 		cd submodule &&
 		(
-			cd deepsubmodule &&
+			cd subdir/deepsubmodule &&
 			git fetch &&
 			git checkout -q FETCH_HEAD
 		) &&
 		head1=$(git rev-parse --short HEAD^) &&
-		git add deepsubmodule &&
+		git add subdir/deepsubmodule &&
 		git commit -m "new deepsubmodule"
 		head2=$(git rev-parse --short HEAD) &&
 		echo "From $pwd/submodule" > ../expect.err.sub &&
@@ -345,13 +345,13 @@
 		git config fetch.recurseSubmodules false &&
 		(
 			cd submodule &&
-			git config -f .gitmodules submodule.deepsubmodule.fetchRecursive false
+			git config -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive false
 		) &&
 		git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&
 		git config --unset fetch.recurseSubmodules
 		(
 			cd submodule &&
-			git config --unset -f .gitmodules submodule.deepsubmodule.fetchRecursive
+			git config --unset -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive
 		)
 	) &&
 	test_i18ncmp expect.out actual.out &&
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 151ea53..e810314 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -202,9 +202,36 @@
 	test_cmp expected dst/.git
 '
 
+test_expect_success 'clone from .git file' '
+	git clone dst/.git dst2
+'
+
 test_expect_success 'clone separate gitdir where target already exists' '
 	rm -rf dst &&
 	test_must_fail git clone --separate-git-dir realgitdir src dst
 '
 
+test_expect_success 'clone --reference from original' '
+	git clone --shared --bare src src-1 &&
+	git clone --bare src src-2 &&
+	git clone --reference=src-2 --bare src-1 target-8 &&
+	grep /src-2/ target-8/objects/info/alternates
+'
+
+test_expect_success 'clone with more than one --reference' '
+	git clone --bare src src-3 &&
+	git clone --bare src src-4 &&
+	git clone --reference=src-3 --reference=src-4 src target-9 &&
+	grep /src-3/ target-9/.git/objects/info/alternates &&
+	grep /src-4/ target-9/.git/objects/info/alternates
+'
+
+test_expect_success 'clone from original with relative alternate' '
+	mkdir nest &&
+	git clone --bare src nest/src-5 &&
+	echo ../../../src/.git/objects >nest/src-5/objects/info/alternates &&
+	git clone --bare nest/src-5 target-10 &&
+	grep /src/\\.git/objects target-10/objects/info/alternates
+'
+
 test_done
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index d9f3439..432f086 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -154,7 +154,7 @@
 
 test_expect_success 'binary files cannot be merged' '
 	test_must_fail git merge-file -p \
-		orig.txt "$TEST_DIRECTORY"/test4012.png new1.txt 2> merge.err &&
+		orig.txt "$TEST_DIRECTORY"/test-binary-1.png new1.txt 2> merge.err &&
 	grep "Cannot merge binary files" merge.err
 '
 
diff --git a/t/t6027-merge-binary.sh b/t/t6027-merge-binary.sh
index b519626..0773541 100755
--- a/t/t6027-merge-binary.sh
+++ b/t/t6027-merge-binary.sh
@@ -6,7 +6,7 @@
 
 test_expect_success setup '
 
-	cat "$TEST_DIRECTORY"/test4012.png >m &&
+	cat "$TEST_DIRECTORY"/test-binary-1.png >m &&
 	git add m &&
 	git ls-files -s | sed -e "s/ 0	/ 1	/" >E1 &&
 	test_tick &&
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index a9b0ac1..19de5b1 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -110,4 +110,18 @@
 	grep -q "^refs/heads/master$" actual &&
 	cmp expect2 actual2
 '
+
+test_expect_success '--set-upstream @{-1}' '
+	git checkout from-master &&
+	git checkout from-master2 &&
+	git config branch.from-master2.merge > expect2 &&
+	git branch --set-upstream @{-1} follower &&
+	git config branch.from-master.merge > actual &&
+	git config branch.from-master2.merge > actual2 &&
+	git branch --set-upstream from-master follower &&
+	git config branch.from-master.merge > expect &&
+	test_cmp expect2 actual2 &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 2ac1c66..097ce2b 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -257,6 +257,11 @@
 	test_cmp expect actual
 '
 
+test_expect_success 'tag -l can accept multiple patterns' '
+	git tag -l "v1*" "v0*" >actual &&
+	test_cmp expect actual
+'
+
 # creating and verifying lightweight tags:
 
 test_expect_success \
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index f1cfc9a..b096dc8 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -429,6 +429,21 @@
 	test_i18ncmp expect output
 '
 
+test_expect_success 'resetting specific path that is unmerged' '
+	git rm --cached file2 &&
+	F1=$(git rev-parse HEAD:file1) &&
+	F2=$(git rev-parse HEAD:file2) &&
+	F3=$(git rev-parse HEAD:secondfile) &&
+	{
+		echo "100644 $F1 1	file2" &&
+		echo "100644 $F2 2	file2" &&
+		echo "100644 $F3 3	file2"
+	} | git update-index --index-info &&
+	git ls-files -u &&
+	test_must_fail git reset HEAD file2 &&
+	git diff-index --exit-code --cached HEAD
+'
+
 test_expect_success 'disambiguation (1)' '
 
 	git reset --hard &&
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 3f115d9..c22916d 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -77,7 +77,8 @@
 
 	(
 		cd addtest &&
-		git submodule add "$submodurl" submod &&
+		git submodule add -q "$submodurl" submod >actual &&
+		test ! -s actual &&
 		git submodule init
 	) &&
 
@@ -275,7 +276,8 @@
 	echo "$rev1" >expect &&
 
 	mkdir init &&
-	git submodule update &&
+	git submodule update -q >update.out &&
+	test ! -s update.out &&
 
 	inspect init &&
 	test_cmp expect head-sha1
@@ -448,6 +450,16 @@
 	)
 '
 
+test_expect_success 'use superproject as upstream when path is relative and no url is set there' '
+	(
+		cd addtest &&
+		git submodule add ../repo relative &&
+		test "$(git config -f .gitmodules submodule.relative.url)" = ../repo &&
+		git submodule sync relative &&
+		test "$(git config submodule.relative.url)" = "$submodurl/repo"
+	)
+'
+
 test_expect_success 'set up for relative path tests' '
 	mkdir reltest &&
 	(
diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh
index d600583..95ffe34 100755
--- a/t/t7403-submodule-sync.sh
+++ b/t/t7403-submodule-sync.sh
@@ -25,7 +25,8 @@
 	git clone super super-clone &&
 	(cd super-clone && git submodule update --init) &&
 	git clone super empty-clone &&
-	(cd empty-clone && git submodule init)
+	(cd empty-clone && git submodule init) &&
+	git clone super top-only-clone
 '
 
 test_expect_success 'change submodule' '
@@ -66,7 +67,7 @@
 	)
 '
 
-test_expect_success '"git submodule sync" should update submodule URLs if not yet cloned' '
+test_expect_success '"git submodule sync" should update known submodule URLs' '
 	(cd empty-clone &&
 	 git pull &&
 	 git submodule sync &&
@@ -74,4 +75,14 @@
 	)
 '
 
+test_expect_success '"git submodule sync" should not vivify uninteresting submodule' '
+	(cd top-only-clone &&
+	 git pull &&
+	 git submodule sync &&
+	 test -z "$(git config submodule.submodule.url)" &&
+	 git submodule sync submodule &&
+	 test -z "$(git config submodule.submodule.url)"
+	)
+'
+
 test_done
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index e5be13c..835a506 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -292,4 +292,22 @@
 	)
 '
 
+test_expect_success 'command passed to foreach retains notion of stdin' '
+	(
+		cd super &&
+		git submodule foreach echo success >../expected &&
+		yes | git submodule foreach "read y && test \"x\$y\" = xy && echo success" >../actual
+	) &&
+	test_cmp expected actual
+'
+
+test_expect_success 'command passed to foreach --recursive retains notion of stdin' '
+	(
+		cd clone2 &&
+		git submodule foreach --recursive echo success >../expected &&
+		yes | git submodule foreach --recursive "read y && test \"x\$y\" = xy && echo success" >../actual
+	) &&
+	test_cmp expected actual
+'
+
 test_done
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index 1fdfbd3..905255a 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -131,6 +131,127 @@
 
 '
 
+test_expect_success 'status with gitignore' '
+	{
+		echo ".gitignore" &&
+		echo "expect" &&
+		echo "output" &&
+		echo "untracked"
+	} >.gitignore &&
+
+	cat >expect <<-\EOF &&
+	 M dir1/modified
+	A  dir2/added
+	?? dir2/modified
+	EOF
+	git status -s >output &&
+	test_cmp expect output &&
+
+	cat >expect <<-\EOF &&
+	 M dir1/modified
+	A  dir2/added
+	?? dir2/modified
+	!! .gitignore
+	!! dir1/untracked
+	!! dir2/untracked
+	!! expect
+	!! output
+	!! untracked
+	EOF
+	git status -s --ignored >output &&
+	test_cmp expect output &&
+
+	cat >expect <<-\EOF &&
+	# On branch master
+	# Changes to be committed:
+	#   (use "git reset HEAD <file>..." to unstage)
+	#
+	#	new file:   dir2/added
+	#
+	# Changes not staged for commit:
+	#   (use "git add <file>..." to update what will be committed)
+	#   (use "git checkout -- <file>..." to discard changes in working directory)
+	#
+	#	modified:   dir1/modified
+	#
+	# Untracked files:
+	#   (use "git add <file>..." to include in what will be committed)
+	#
+	#	dir2/modified
+	# Ignored files:
+	#   (use "git add -f <file>..." to include in what will be committed)
+	#
+	#	.gitignore
+	#	dir1/untracked
+	#	dir2/untracked
+	#	expect
+	#	output
+	#	untracked
+	EOF
+	git status --ignored >output &&
+	test_cmp expect output
+'
+
+test_expect_success 'status with gitignore (nothing untracked)' '
+	{
+		echo ".gitignore" &&
+		echo "expect" &&
+		echo "dir2/modified" &&
+		echo "output" &&
+		echo "untracked"
+	} >.gitignore &&
+
+	cat >expect <<-\EOF &&
+	 M dir1/modified
+	A  dir2/added
+	EOF
+	git status -s >output &&
+	test_cmp expect output &&
+
+	cat >expect <<-\EOF &&
+	 M dir1/modified
+	A  dir2/added
+	!! .gitignore
+	!! dir1/untracked
+	!! dir2/modified
+	!! dir2/untracked
+	!! expect
+	!! output
+	!! untracked
+	EOF
+	git status -s --ignored >output &&
+	test_cmp expect output &&
+
+	cat >expect <<-\EOF &&
+	# On branch master
+	# Changes to be committed:
+	#   (use "git reset HEAD <file>..." to unstage)
+	#
+	#	new file:   dir2/added
+	#
+	# Changes not staged for commit:
+	#   (use "git add <file>..." to update what will be committed)
+	#   (use "git checkout -- <file>..." to discard changes in working directory)
+	#
+	#	modified:   dir1/modified
+	#
+	# Ignored files:
+	#   (use "git add -f <file>..." to include in what will be committed)
+	#
+	#	.gitignore
+	#	dir1/untracked
+	#	dir2/modified
+	#	dir2/untracked
+	#	expect
+	#	output
+	#	untracked
+	EOF
+	git status --ignored >output &&
+	test_cmp expect output
+'
+
+rm -f .gitignore
+
 cat >expect <<\EOF
 ## master
  M dir1/modified
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index e5da65b..41db05c 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -50,8 +50,8 @@
     'mkdir A B C D E F &&
      echo hello1 >A/newfile1.txt &&
      echo hello2 >B/newfile2.txt &&
-     cp "$TEST_DIRECTORY"/test9200a.png C/newfile3.png &&
-     cp "$TEST_DIRECTORY"/test9200a.png D/newfile4.png &&
+     cp "$TEST_DIRECTORY"/test-binary-1.png C/newfile3.png &&
+     cp "$TEST_DIRECTORY"/test-binary-1.png D/newfile4.png &&
      git add A/newfile1.txt &&
      git add B/newfile2.txt &&
      git add C/newfile3.png &&
@@ -76,8 +76,8 @@
      rm -f B/newfile2.txt &&
      rm -f C/newfile3.png &&
      echo Hello5  >E/newfile5.txt &&
-     cp "$TEST_DIRECTORY"/test9200b.png D/newfile4.png &&
-     cp "$TEST_DIRECTORY"/test9200a.png F/newfile6.png &&
+     cp "$TEST_DIRECTORY"/test-binary-2.png D/newfile4.png &&
+     cp "$TEST_DIRECTORY"/test-binary-1.png F/newfile6.png &&
      git add E/newfile5.txt &&
      git add F/newfile6.png &&
      git commit -a -m "Test: Remove, add and update" &&
@@ -165,7 +165,7 @@
      'mkdir "G g" &&
       echo ok then >"G g/with spaces.txt" &&
       git add "G g/with spaces.txt" && \
-      cp "$TEST_DIRECTORY"/test9200a.png "G g/with spaces.png" && \
+      cp "$TEST_DIRECTORY"/test-binary-1.png "G g/with spaces.png" && \
       git add "G g/with spaces.png" &&
       git commit -a -m "With spaces" &&
       id=$(git rev-list --max-count=1 HEAD) &&
@@ -177,7 +177,7 @@
 test_expect_success \
      'Update file with spaces in file name' \
      'echo Ok then >>"G g/with spaces.txt" &&
-      cat "$TEST_DIRECTORY"/test9200a.png >>"G g/with spaces.png" && \
+      cat "$TEST_DIRECTORY"/test-binary-1.png >>"G g/with spaces.png" && \
       git add "G g/with spaces.png" &&
       git commit -a -m "Update with spaces" &&
       id=$(git rev-list --max-count=1 HEAD) &&
@@ -202,7 +202,7 @@
      'mkdir -p Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö &&
       echo Foo >Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.txt &&
       git add Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.txt &&
-      cp "$TEST_DIRECTORY"/test9200a.png Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.png &&
+      cp "$TEST_DIRECTORY"/test-binary-1.png Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.png &&
       git add Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.png &&
       git commit -a -m "Går det så går det" && \
       id=$(git rev-list --max-count=1 HEAD) &&
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index f823c05..950d0ff 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -228,7 +228,7 @@
 	mkdir new &&
 	git --git-dir=new/.git init &&
 	git fast-export -C -C --signed-tags=strip --all > output &&
-	grep "^C \"file6\" \"file7\"\$" output &&
+	grep "^C file6 file7\$" output &&
 	cat output |
 	(cd new &&
 	 git fast-import &&
@@ -414,4 +414,30 @@
 	(cd result && git show master:foo)
 '
 
+test_expect_success 'fast-export quotes pathnames' '
+	git init crazy-paths &&
+	(cd crazy-paths &&
+	 blob=`echo foo | git hash-object -w --stdin` &&
+	 git update-index --add \
+		--cacheinfo 100644 $blob "$(printf "path with\\nnewline")" \
+		--cacheinfo 100644 $blob "path with \"quote\"" \
+		--cacheinfo 100644 $blob "path with \\backslash" \
+		--cacheinfo 100644 $blob "path with space" &&
+	 git commit -m addition &&
+	 git ls-files -z -s | perl -0pe "s{\\t}{$&subdir/}" >index &&
+	 git read-tree --empty &&
+	 git update-index -z --index-info <index &&
+	 git commit -m rename &&
+	 git read-tree --empty &&
+	 git commit -m deletion &&
+	 git fast-export HEAD >export.out &&
+	 git rev-list HEAD >expect &&
+	 git init result &&
+	 cd result &&
+	 git fast-import <../export.out &&
+	 git rev-list HEAD >actual &&
+	 test_cmp ../expect actual
+	)
+'
+
 test_done
diff --git a/t/test4012.png b/t/test-binary-1.png
similarity index 100%
rename from t/test4012.png
rename to t/test-binary-1.png
Binary files differ
diff --git a/t/test9200b.png b/t/test-binary-2.png
similarity index 100%
rename from t/test9200b.png
rename to t/test-binary-2.png
Binary files differ
diff --git a/t/test9200a.png b/t/test9200a.png
deleted file mode 100644
index 7b181d1..0000000
--- a/t/test9200a.png
+++ /dev/null
Binary files differ
diff --git a/unpack-trees.c b/unpack-trees.c
index e22b9ec..cc616c3 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -593,7 +593,7 @@
 static int unpack_failed(struct unpack_trees_options *o, const char *message)
 {
 	discard_index(&o->result);
-	if (!o->gently) {
+	if (!o->gently && !o->exiting_early) {
 		if (message)
 			return error("%s", message);
 		return -1;
@@ -1133,6 +1133,8 @@
 		display_error_msgs(o);
 	mark_all_ce_unused(o->src_index);
 	ret = unpack_failed(o, NULL);
+	if (o->exiting_early)
+		ret = 0;
 	goto done;
 }
 
diff --git a/unpack-trees.h b/unpack-trees.h
index 64f02cb..7998948 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -46,6 +46,7 @@
 		     debug_unpack,
 		     skip_sparse_checkout,
 		     gently,
+		     exiting_early,
 		     show_all_errors,
 		     dry_run;
 	const char *prefix;
diff --git a/upload-pack.c b/upload-pack.c
index ce5cbbe..03adf28 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -10,6 +10,7 @@
 #include "revision.h"
 #include "list-objects.h"
 #include "run-command.h"
+#include "sigchain.h"
 
 static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
 
@@ -498,11 +499,97 @@
 	}
 }
 
+static void check_non_tip(void)
+{
+	static const char *argv[] = {
+		"rev-list", "--stdin", NULL,
+	};
+	static struct child_process cmd;
+	struct object *o;
+	char namebuf[42]; /* ^ + SHA-1 + LF */
+	int i;
+
+	/* In the normal in-process case non-tip request can never happen */
+	if (!stateless_rpc)
+		goto error;
+
+	cmd.argv = argv;
+	cmd.git_cmd = 1;
+	cmd.no_stderr = 1;
+	cmd.in = -1;
+	cmd.out = -1;
+
+	if (start_command(&cmd))
+		goto error;
+
+	/*
+	 * If rev-list --stdin encounters an unknown commit, it
+	 * terminates, which will cause SIGPIPE in the write loop
+	 * below.
+	 */
+	sigchain_push(SIGPIPE, SIG_IGN);
+
+	namebuf[0] = '^';
+	namebuf[41] = '\n';
+	for (i = get_max_object_index(); 0 < i; ) {
+		o = get_indexed_object(--i);
+		if (!o)
+			continue;
+		if (!(o->flags & OUR_REF))
+			continue;
+		memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40);
+		if (write_in_full(cmd.in, namebuf, 42) < 0)
+			goto error;
+	}
+	namebuf[40] = '\n';
+	for (i = 0; i < want_obj.nr; i++) {
+		o = want_obj.objects[i].item;
+		if (o->flags & OUR_REF)
+			continue;
+		memcpy(namebuf, sha1_to_hex(o->sha1), 40);
+		if (write_in_full(cmd.in, namebuf, 41) < 0)
+			goto error;
+	}
+	close(cmd.in);
+
+	sigchain_pop(SIGPIPE);
+
+	/*
+	 * The commits out of the rev-list are not ancestors of
+	 * our ref.
+	 */
+	i = read_in_full(cmd.out, namebuf, 1);
+	if (i)
+		goto error;
+	close(cmd.out);
+
+	/*
+	 * rev-list may have died by encountering a bad commit
+	 * in the history, in which case we do want to bail out
+	 * even when it showed no commit.
+	 */
+	if (finish_command(&cmd))
+		goto error;
+
+	/* All the non-tip ones are ancestors of what we advertised */
+	return;
+
+error:
+	/* Pick one of them (we know there at least is one) */
+	for (i = 0; i < want_obj.nr; i++) {
+		o = want_obj.objects[i].item;
+		if (!(o->flags & OUR_REF))
+			die("git upload-pack: not our ref %s",
+			    sha1_to_hex(o->sha1));
+	}
+}
+
 static void receive_needs(void)
 {
 	struct object_array shallows = OBJECT_ARRAY_INIT;
 	static char line[1000];
 	int len, depth = 0;
+	int has_non_tip = 0;
 
 	shallow_nr = 0;
 	if (debug_fd)
@@ -559,26 +646,30 @@
 		if (strstr(line+45, "include-tag"))
 			use_include_tag = 1;
 
-		/* We have sent all our refs already, and the other end
-		 * should have chosen out of them; otherwise they are
-		 * asking for nonsense.
-		 *
-		 * Hmph.  We may later want to allow "want" line that
-		 * asks for something like "master~10" (symbolic)...
-		 * would it make sense?  I don't know.
-		 */
 		o = lookup_object(sha1_buf);
-		if (!o || !(o->flags & OUR_REF))
+		if (!o)
 			die("git upload-pack: not our ref %s",
 			    sha1_to_hex(sha1_buf));
 		if (!(o->flags & WANTED)) {
 			o->flags |= WANTED;
+			if (!(o->flags & OUR_REF))
+				has_non_tip = 1;
 			add_object_array(o, NULL, &want_obj);
 		}
 	}
 	if (debug_fd)
 		write_str_in_full(debug_fd, "#E\n");
 
+	/*
+	 * We have sent all our refs already, and the other end
+	 * should have chosen out of them. When we are operating
+	 * in the stateless RPC mode, however, their choice may
+	 * have been based on the set of older refs advertised
+	 * by another process that handled the initial request.
+	 */
+	if (has_non_tip)
+		check_non_tip();
+
 	if (!use_sideband && daemon_mode)
 		no_progress = 1;
 
diff --git a/usage.c b/usage.c
index b5e67e3..a2a6678 100644
--- a/usage.c
+++ b/usage.c
@@ -4,6 +4,7 @@
  * Copyright (C) Linus Torvalds, 2005
  */
 #include "git-compat-util.h"
+#include "cache.h"
 
 void vreportf(const char *prefix, const char *err, va_list params)
 {
@@ -12,6 +13,18 @@
 	fprintf(stderr, "%s%s\n", prefix, msg);
 }
 
+void vwritef(int fd, const char *prefix, const char *err, va_list params)
+{
+	char msg[4096];
+	int len = vsnprintf(msg, sizeof(msg), err, params);
+	if (len > sizeof(msg))
+		len = sizeof(msg);
+
+	write_in_full(fd, prefix, strlen(prefix));
+	write_in_full(fd, msg, len);
+	write_in_full(fd, "\n", 1);
+}
+
 static NORETURN void usage_builtin(const char *err, va_list params)
 {
 	vreportf("usage: ", err, params);
@@ -46,6 +59,11 @@
 	die_routine = routine;
 }
 
+void set_error_routine(void (*routine)(const char *err, va_list params))
+{
+	error_routine = routine;
+}
+
 void NORETURN usagef(const char *err, ...)
 {
 	va_list params;
diff --git a/userdiff.c b/userdiff.c
index e55310c..01d3a8b 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -281,3 +281,20 @@
 		return NULL;
 	return userdiff_find_by_name(check.value);
 }
+
+struct userdiff_driver *userdiff_get_textconv(struct userdiff_driver *driver)
+{
+	if (!driver->textconv)
+		return NULL;
+
+	if (driver->textconv_want_cache && !driver->textconv_cache) {
+		struct notes_cache *c = xmalloc(sizeof(*c));
+		struct strbuf name = STRBUF_INIT;
+
+		strbuf_addf(&name, "textconv/%s", driver->name);
+		notes_cache_init(c, name.buf, driver->textconv);
+		driver->textconv_cache = c;
+	}
+
+	return driver;
+}
diff --git a/userdiff.h b/userdiff.h
index 942d594..4a7e78f 100644
--- a/userdiff.h
+++ b/userdiff.h
@@ -23,4 +23,6 @@
 struct userdiff_driver *userdiff_find_by_name(const char *name);
 struct userdiff_driver *userdiff_find_by_path(const char *path);
 
+struct userdiff_driver *userdiff_get_textconv(struct userdiff_driver *driver);
+
 #endif /* USERDIFF */
diff --git a/wt-status.c b/wt-status.c
index 9f4e0ba..0237772 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -642,7 +642,7 @@
 	int i;
 	struct strbuf buf = STRBUF_INIT;
 
-	if (!s->untracked.nr)
+	if (!l->nr)
 		return;
 
 	wt_status_print_other_header(s, what, how);
diff --git a/zlib.c b/zlib.c
index c4d58da..3c63d48 100644
--- a/zlib.c
+++ b/zlib.c
@@ -4,58 +4,248 @@
  */
 #include "cache.h"
 
-void git_inflate_init(z_streamp strm)
+static const char *zerr_to_string(int status)
 {
-	const char *err;
-
-	switch (inflateInit(strm)) {
-	case Z_OK:
-		return;
-
+	switch (status) {
 	case Z_MEM_ERROR:
-		err = "out of memory";
-		break;
+		return "out of memory";
 	case Z_VERSION_ERROR:
-		err = "wrong version";
-		break;
-	default:
-		err = "error";
-	}
-	die("inflateInit: %s (%s)", err, strm->msg ? strm->msg : "no message");
-}
-
-void git_inflate_end(z_streamp strm)
-{
-	if (inflateEnd(strm) != Z_OK)
-		error("inflateEnd: %s", strm->msg ? strm->msg : "failed");
-}
-
-int git_inflate(z_streamp strm, int flush)
-{
-	int ret = inflate(strm, flush);
-	const char *err;
-
-	switch (ret) {
-	/* Out of memory is fatal. */
-	case Z_MEM_ERROR:
-		die("inflate: out of memory");
-
-	/* Data corruption errors: we may want to recover from them (fsck) */
+		return "wrong version";
 	case Z_NEED_DICT:
-		err = "needs dictionary"; break;
+		return "needs dictionary";
 	case Z_DATA_ERROR:
-		err = "data stream error"; break;
+		return "data stream error";
 	case Z_STREAM_ERROR:
-		err = "stream consistency error"; break;
+		return "stream consistency error";
 	default:
-		err = "unknown error"; break;
+		return "unknown error";
+	}
+}
 
+/*
+ * avail_in and avail_out in zlib are counted in uInt, which typically
+ * limits the size of the buffer we can use to 4GB when interacting
+ * with zlib in a single call to inflate/deflate.
+ */
+/* #define ZLIB_BUF_MAX ((uInt)-1) */
+#define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */
+static inline uInt zlib_buf_cap(unsigned long len)
+{
+	return (ZLIB_BUF_MAX < len) ? ZLIB_BUF_MAX : len;
+}
+
+static void zlib_pre_call(git_zstream *s)
+{
+	s->z.next_in = s->next_in;
+	s->z.next_out = s->next_out;
+	s->z.total_in = s->total_in;
+	s->z.total_out = s->total_out;
+	s->z.avail_in = zlib_buf_cap(s->avail_in);
+	s->z.avail_out = zlib_buf_cap(s->avail_out);
+}
+
+static void zlib_post_call(git_zstream *s)
+{
+	unsigned long bytes_consumed;
+	unsigned long bytes_produced;
+
+	bytes_consumed = s->z.next_in - s->next_in;
+	bytes_produced = s->z.next_out - s->next_out;
+	if (s->z.total_out != s->total_out + bytes_produced)
+		die("BUG: total_out mismatch");
+	if (s->z.total_in != s->total_in + bytes_consumed)
+		die("BUG: total_in mismatch");
+
+	s->total_out = s->z.total_out;
+	s->total_in = s->z.total_in;
+	s->next_in = s->z.next_in;
+	s->next_out = s->z.next_out;
+	s->avail_in -= bytes_consumed;
+	s->avail_out -= bytes_produced;
+}
+
+void git_inflate_init(git_zstream *strm)
+{
+	int status;
+
+	zlib_pre_call(strm);
+	status = inflateInit(&strm->z);
+	zlib_post_call(strm);
+	if (status == Z_OK)
+		return;
+	die("inflateInit: %s (%s)", zerr_to_string(status),
+	    strm->z.msg ? strm->z.msg : "no message");
+}
+
+void git_inflate_init_gzip_only(git_zstream *strm)
+{
+	/*
+	 * Use default 15 bits, +16 is to accept only gzip and to
+	 * yield Z_DATA_ERROR when fed zlib format.
+	 */
+	const int windowBits = 15 + 16;
+	int status;
+
+	zlib_pre_call(strm);
+	status = inflateInit2(&strm->z, windowBits);
+	zlib_post_call(strm);
+	if (status == Z_OK)
+		return;
+	die("inflateInit2: %s (%s)", zerr_to_string(status),
+	    strm->z.msg ? strm->z.msg : "no message");
+}
+
+void git_inflate_end(git_zstream *strm)
+{
+	int status;
+
+	zlib_pre_call(strm);
+	status = inflateEnd(&strm->z);
+	zlib_post_call(strm);
+	if (status == Z_OK)
+		return;
+	error("inflateEnd: %s (%s)", zerr_to_string(status),
+	      strm->z.msg ? strm->z.msg : "no message");
+}
+
+int git_inflate(git_zstream *strm, int flush)
+{
+	int status;
+
+	for (;;) {
+		zlib_pre_call(strm);
+		/* Never say Z_FINISH unless we are feeding everything */
+		status = inflate(&strm->z,
+				 (strm->z.avail_in != strm->avail_in)
+				 ? 0 : flush);
+		if (status == Z_MEM_ERROR)
+			die("inflate: out of memory");
+		zlib_post_call(strm);
+
+		/*
+		 * Let zlib work another round, while we can still
+		 * make progress.
+		 */
+		if ((strm->avail_out && !strm->z.avail_out) &&
+		    (status == Z_OK || status == Z_BUF_ERROR))
+			continue;
+		break;
+	}
+
+	switch (status) {
 	/* Z_BUF_ERROR: normal, needs more space in the output buffer */
 	case Z_BUF_ERROR:
 	case Z_OK:
 	case Z_STREAM_END:
-		return ret;
+		return status;
+	default:
+		break;
 	}
-	error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message");
-	return ret;
+	error("inflate: %s (%s)", zerr_to_string(status),
+	      strm->z.msg ? strm->z.msg : "no message");
+	return status;
+}
+
+#if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
+#define deflateBound(c,s)  ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
+#endif
+
+unsigned long git_deflate_bound(git_zstream *strm, unsigned long size)
+{
+	return deflateBound(&strm->z, size);
+}
+
+void git_deflate_init(git_zstream *strm, int level)
+{
+	int status;
+
+	zlib_pre_call(strm);
+	status = deflateInit(&strm->z, level);
+	zlib_post_call(strm);
+	if (status == Z_OK)
+		return;
+	die("deflateInit: %s (%s)", zerr_to_string(status),
+	    strm->z.msg ? strm->z.msg : "no message");
+}
+
+void git_deflate_init_gzip(git_zstream *strm, int level)
+{
+	/*
+	 * Use default 15 bits, +16 is to generate gzip header/trailer
+	 * instead of the zlib wrapper.
+	 */
+	const int windowBits = 15 + 16;
+	int status;
+
+	zlib_pre_call(strm);
+	status = deflateInit2(&strm->z, level,
+				  Z_DEFLATED, windowBits,
+				  8, Z_DEFAULT_STRATEGY);
+	zlib_post_call(strm);
+	if (status == Z_OK)
+		return;
+	die("deflateInit2: %s (%s)", zerr_to_string(status),
+	    strm->z.msg ? strm->z.msg : "no message");
+}
+
+void git_deflate_end(git_zstream *strm)
+{
+	int status;
+
+	zlib_pre_call(strm);
+	status = deflateEnd(&strm->z);
+	zlib_post_call(strm);
+	if (status == Z_OK)
+		return;
+	error("deflateEnd: %s (%s)", zerr_to_string(status),
+	      strm->z.msg ? strm->z.msg : "no message");
+}
+
+int git_deflate_end_gently(git_zstream *strm)
+{
+	int status;
+
+	zlib_pre_call(strm);
+	status = deflateEnd(&strm->z);
+	zlib_post_call(strm);
+	return status;
+}
+
+int git_deflate(git_zstream *strm, int flush)
+{
+	int status;
+
+	for (;;) {
+		zlib_pre_call(strm);
+
+		/* Never say Z_FINISH unless we are feeding everything */
+		status = deflate(&strm->z,
+				 (strm->z.avail_in != strm->avail_in)
+				 ? 0 : flush);
+		if (status == Z_MEM_ERROR)
+			die("deflate: out of memory");
+		zlib_post_call(strm);
+
+		/*
+		 * Let zlib work another round, while we can still
+		 * make progress.
+		 */
+		if ((strm->avail_out && !strm->z.avail_out) &&
+		    (status == Z_OK || status == Z_BUF_ERROR))
+			continue;
+		break;
+	}
+
+	switch (status) {
+	/* Z_BUF_ERROR: normal, needs more space in the output buffer */
+	case Z_BUF_ERROR:
+	case Z_OK:
+	case Z_STREAM_END:
+		return status;
+	default:
+		break;
+	}
+	error("deflate: %s (%s)", zerr_to_string(status),
+	      strm->z.msg ? strm->z.msg : "no message");
+	return status;
 }