Merge branch 'mg/use-default-abbrev-length-in-rev-list' into maint

* mg/use-default-abbrev-length-in-rev-list:
  rev-list: use default abbrev length when abbrev-commit is in effect
diff --git a/.mailmap b/.mailmap
index 88bd01e..a8091eb 100644
--- a/.mailmap
+++ b/.mailmap
@@ -5,6 +5,7 @@
 # same person appearing not to be so.
 #
 
+Alex Bennée <kernel-hacker@bennee.com>
 Alexander Gavrilov <angavrilov@gmail.com>
 Aneesh Kumar K.V <aneesh.kumar@gmail.com>
 Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
@@ -15,6 +16,7 @@
 David D. Kilzer <ddkilzer@kilzer.net>
 David Kågedal <davidk@lysator.liu.se>
 David S. Miller <davem@davemloft.net>
+Deskin Miller <deskinm@umich.edu>
 Dirk Süsserott <newsletter@dirk.my1.cc>
 Fredrik Kuivinen <freku045@student.liu.se>
 H. Peter Anvin <hpa@bonde.sc.orionmulti.com>
@@ -60,6 +62,7 @@
 Uwe Kleine-König <uzeisberger@io.fsforth.de>
 Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
 Ville Skyttä <scop@xemacs.org>
+Vitaly "_Vi" Shukela <public_vi@tut.by>
 William Pursell <bill.pursell@gmail.com>
 YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
 anonymous <linux@horizon.com>
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 8a8a395..04f69cf 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -264,7 +264,9 @@
 	mv $@+ $@
 
 user-manual.xml: user-manual.txt user-manual.conf
-	$(QUIET_ASCIIDOC)$(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d book $<
+	$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
+	$(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d book -o $@+ $< && \
+	mv $@+ $@
 
 technical/api-index.txt: technical/api-index-skel.txt \
 	technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS))
@@ -278,7 +280,9 @@
 XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css
 
 user-manual.html: user-manual.xml
-	$(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $<
+	$(QUIET_XSLTPROC)$(RM) $@+ $@ && \
+	xsltproc $(XSLTOPTS) -o $@+ $(XSLT) $< && \
+	mv $@+ $@
 
 git.info: user-manual.texi
 	$(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi
diff --git a/Documentation/RelNotes-1.7.0.4.txt b/Documentation/RelNotes-1.7.0.4.txt
new file mode 100644
index 0000000..cf7f60e
--- /dev/null
+++ b/Documentation/RelNotes-1.7.0.4.txt
@@ -0,0 +1,27 @@
+Git v1.7.0.4 Release Notes
+==========================
+
+Fixes since v1.7.0.3
+--------------------
+
+ * Optimized ntohl/htonl on big-endian machines were broken.
+
+ * Color values given to "color.<cmd>.<slot>" configuration can now have
+   more than one attributes (e.g. "bold ul").
+
+ * "git add -u nonexistent-path" did not complain.
+
+ * "git apply --whitespace=fix" didn't work well when an early patch in
+   a patch series adds trailing blank lines and a later one depended on
+   such a block of blank lines at the end.
+
+ * "git fast-export" didn't check error status and stop when marks file
+   cannot be opened.
+
+ * "git format-patch --ignore-if-in-upstream" gave unwarranted errors
+   when the range was empty, instead of silently finishing.
+
+ * "git remote prune" did not detect remote tracking refs that became
+   dangling correctly.
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/RelNotes-1.7.0.5.txt b/Documentation/RelNotes-1.7.0.5.txt
new file mode 100644
index 0000000..3149c91
--- /dev/null
+++ b/Documentation/RelNotes-1.7.0.5.txt
@@ -0,0 +1,26 @@
+Git v1.7.0.5 Release Notes
+==========================
+
+Fixes since v1.7.0.4
+--------------------
+
+ * "git daemon" failed to compile on platforms without sockaddr_storage type.
+
+ * Output from "git rev-list --pretty=oneline" was unparsable when a
+   commit did not have any message, which is abnormal but possible in a
+   repository converted from foreign scm.
+
+ * "git stash show <commit-that-is-not-a-stash>" gave an error message
+   that was not so useful.  Reworded the message to "<it> is not a
+   stash".
+
+ * Python scripts in contrib/ area now start with "#!/usr/bin/env python"
+   to honor user's PATH.
+
+ * "git imap-send" used to mistake any line that begins with "From " as a
+   message separator in format-patch output.
+
+ * Smart http server backend failed to report an internal server error and
+   infinitely looped instead after output pipe was closed.
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt
index 4833cac..d820569 100644
--- a/Documentation/blame-options.txt
+++ b/Documentation/blame-options.txt
@@ -79,14 +79,15 @@
 	of the --date option at linkgit:git-log[1].
 
 -M|<num>|::
-	Detect moving lines in the file as well.  When a commit
-	moves a block of lines in a file (e.g. the original file
-	has A and then B, and the commit changes it to B and
-	then A), the traditional 'blame' algorithm typically blames
-	the lines that were moved up (i.e. B) to the parent and
-	assigns blame to the lines that were moved down (i.e. A)
-	to the child commit.  With this option, both groups of lines
-	are blamed on the parent.
+	Detect moved or copied lines within a file. When a commit
+	moves or copies a block of lines (e.g. the original file
+	has A and then B, and the commit changes it to B and then
+	A), the traditional 'blame' algorithm notices only half of
+	the movement and typically blames the lines that were moved
+	up (i.e. B) to the parent and assigns blame to the lines that
+	were moved down (i.e. A) to the child commit.  With this
+	option, both groups of lines are blamed on the parent by
+	running extra passes of inspection.
 +
 <num> is optional but it is the lower bound on the number of
 alphanumeric characters that git must detect as moving
@@ -94,7 +95,7 @@
 commit.
 
 -C|<num>|::
-	In addition to `-M`, detect lines copied from other
+	In addition to `-M`, detect lines moved or copied from other
 	files that were modified in the same commit.  This is
 	useful when you reorganize your program and move code
 	around across files.  When this option is given twice,
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 437b4ac..f6ddd35 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -198,11 +198,11 @@
 
 core.autocrlf::
 	If true, makes git convert `CRLF` at the end of lines in text files to
-	`LF` when reading from the filesystem, and convert in reverse when
-	writing to the filesystem.  The variable can be set to
+	`LF` when reading from the work tree, and convert in reverse when
+	writing to the work tree.  The variable can be set to
 	'input', in which case the conversion happens only while
-	reading from the filesystem but files are written out with
-	`LF` at the end of lines.  A file is considered
+	reading from the work tree but files are written out to the work
+	tree with `LF` at the end of lines.  A file is considered
 	"text" (i.e. be subjected to the autocrlf mechanism) based on
 	the file's `crlf` attribute, or if `crlf` is unspecified,
 	based on the file's contents.  See linkgit:gitattributes[5].
@@ -885,7 +885,7 @@
 gc.aggressiveWindow::
 	The window size parameter used in the delta compression
 	algorithm used by 'git gc --aggressive'.  This defaults
-	to 10.
+	to 250.
 
 gc.auto::
 	When there are approximately more than this many loose
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 8707d0e..a1191d6 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -94,8 +94,8 @@
 pathnames and use NULs as output field terminators.
 endif::git-log[]
 ifndef::git-log[]
-	When `--raw` or `--numstat` has been given, do not munge
-	pathnames and use NULs as output field terminators.
+	When `--raw`, `--numstat`, `--name-only` or `--name-status` has been
+	given, do not munge pathnames and use NULs as output field terminators.
 endif::git-log[]
 +
 Without this option, each pathname output will have TAB, LF, double quotes,
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 6b6c3da..60fa684 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -63,7 +63,9 @@
 OPTIONS
 -------
 -d::
-	Delete a branch. The branch must be fully merged in HEAD.
+	Delete a branch. The branch must be fully merged in its
+	upstream branch, or in `HEAD` if no upstream was set with
+	`--track` or `--set-upstream`.
 
 -D::
 	Delete a branch irrespective of its merged status.
@@ -72,6 +74,8 @@
 	Create the branch's reflog.  This activates recording of
 	all changes made to the branch ref, enabling use of date
 	based sha1 expressions such as "<branchname>@\{yesterday}".
+	Note that in non-bare repositories, reflogs are usually
+	enabled by default by the `core.logallrefupdates` config option.
 
 -f::
 --force::
diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 6fc5323..7ef9d51 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -105,6 +105,9 @@
 of commits which would be displayed by "git log v1.0.4..parent".
 The hash suffix is "-g" + 7-char abbreviation for the tip commit
 of parent (which was `2414721b194453f058079d897d13c4e377f92dc6`).
+The "g" prefix stands for "git" and is used to allow describing the version of
+a software depending on the SCM the software is managed with. This is useful
+in an environment where people may use different SCMs.
 
 Doing a 'git describe' on a tag-name will just show the tag name:
 
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index 948ea26..400fe7f 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -8,13 +8,13 @@
 
 SYNOPSIS
 --------
-'git fetch' <options> <repository> <refspec>...
+'git fetch' [<options>] [<repository> [<refspec>...]]
 
-'git fetch' <options> <group>
+'git fetch' [<options>] <group>
 
-'git fetch' --multiple <options> [<repository> | <group>]...
+'git fetch' --multiple [<options>] [<repository> | <group>]...
 
-'git fetch' --all <options>
+'git fetch' --all [<options>]
 
 
 DESCRIPTION
diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.txt
index 5238820..277d9e1 100644
--- a/Documentation/git-http-backend.txt
+++ b/Documentation/git-http-backend.txt
@@ -35,7 +35,7 @@
 configuration file:
 
 http.getanyfile::
-	This serves older Git clients which are unable to use the
+	This serves Git clients older than version 1.6.6 that are unable to use the
 	upload pack service.  When enabled, clients are able to read
 	any file within the repository, including objects that are
 	no longer reachable from a branch but are still present.
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 57db955..ad446b0 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -16,7 +16,9 @@
 This command uploads a mailbox generated with 'git format-patch'
 into an IMAP drafts folder.  This allows patches to be sent as
 other email is when using mail clients that cannot read mailbox
-files directly.
+files directly. The command also works with any general mailbox
+in which emails have the fields "From", "Date", and "Subject" in
+that order.
 
 Typical usage is something like:
 
@@ -118,12 +120,6 @@
 users may wish to visit this web page for more information:
   http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email
 
-
-BUGS
-----
-Doesn't handle lines starting with "From " in the message body.
-
-
 Author
 ------
 Derived from isync 1.0.1 by Mike McCormack.
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 9c9618c..c2325ef 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -9,7 +9,8 @@
 SYNOPSIS
 --------
 [verse]
-'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
+'git merge' [-n] [--stat] [--no-commit] [--squash]
+	[-s <strategy>] [-X <strategy-option>]
 	[--[no-]rerere-autoupdate] [-m <msg>] <commit>...
 'git merge' <msg> HEAD <commit>...
 
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 49b6bd9..7a4e507 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -11,7 +11,7 @@
 [verse]
 'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
 	   [--repo=<repository>] [-f | --force] [-v | --verbose] [-u | --set-upstream]
-	   [<repository> <refspec>...]
+	   [<repository> [<refspec>...]]
 
 DESCRIPTION
 -----------
diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt
index df17d49..3f9d9c6 100644
--- a/Documentation/git-show-ref.txt
+++ b/Documentation/git-show-ref.txt
@@ -10,7 +10,7 @@
 [verse]
 'git show-ref' [-q|--quiet] [--verify] [--head] [-d|--dereference]
 	     [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
-	     [--heads] [--] <pattern>...
+	     [--heads] [--] [<pattern>...]
 'git show-ref' --exclude-existing[=<pattern>] < ref-list
 
 DESCRIPTION
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 4e00b31..fbae995 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -43,9 +43,11 @@
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.7.0.3/git.html[documentation for release 1.7.0.3]
+* link:v1.7.0.5/git.html[documentation for release 1.7.0.5]
 
 * release notes for
+  link:RelNotes-1.7.0.5.txt[1.7.0.5],
+  link:RelNotes-1.7.0.4.txt[1.7.0.4],
   link:RelNotes-1.7.0.3.txt[1.7.0.3],
   link:RelNotes-1.7.0.2.txt[1.7.0.2],
   link:RelNotes-1.7.0.1.txt[1.7.0.1],
diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index 3b83dba..81ac823 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -62,6 +62,11 @@
 	is used instead ('git merge-recursive' when merging a single
 	head, 'git merge-octopus' otherwise).
 
+-X <option>::
+--strategy-option=<option>::
+	Pass merge strategy specific option through to the merge
+	strategy.
+
 --summary::
 --no-summary::
 	Synonyms to --stat and --no-stat; these are deprecated and will be
@@ -74,8 +79,3 @@
 -v::
 --verbose::
 	Be verbose.
-
--X <option>::
---strategy-option=<option>::
-	Pass merge strategy specific option through to the merge
-	strategy.
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 9a5cdaf..369f91d 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -36,7 +36,7 @@
 
 The Git transport starts off by sending the command and repository
 on the wire using the pkt-line format, followed by a NUL byte and a
-hostname paramater, terminated by a NUL byte.
+hostname parameter, terminated by a NUL byte.
 
    0032git-upload-pack /project.git\0host=myserver.com\0
 
@@ -331,7 +331,7 @@
 
    C: 0009done\n
 
-   S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
+   S: 0031ACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
    S: [PACKFILE]
 ----
 
@@ -488,7 +488,7 @@
    C: 0000
    C: [PACKDATA]
 
-   S: 000aunpack ok\n
-   S: 0014ok refs/heads/debug\n
-   S: 0026ng refs/heads/master non-fast-forward\n
+   S: 000eunpack ok\n
+   S: 0018ok refs/heads/debug\n
+   S: 002ang refs/heads/master non-fast-forward\n
 ----
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 076c18e..6705b10 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.0.3
+DEF_VER=v1.7.0.5
 
 LF='
 '
diff --git a/Makefile b/Makefile
index 98372eb..5b86806 100644
--- a/Makefile
+++ b/Makefile
@@ -831,6 +831,7 @@
 		NO_UINTMAX_T = YesPlease
 		NO_STRTOUMAX = YesPlease
 	endif
+	PYTHON_PATH = /usr/local/bin/python
 endif
 ifeq ($(uname_S),OpenBSD)
 	NO_STRCASESTR = YesPlease
@@ -886,6 +887,7 @@
 	SNPRINTF_RETURNS_BOGUS = YesPlease
 	SHELL_PATH = /usr/gnu/bin/bash
 	NEEDS_LIBGEN = YesPlease
+	NEEDS_LIBICONV = YesPlease
 endif
 ifeq ($(uname_S),IRIX64)
 	NO_SETENV=YesPlease
@@ -904,6 +906,7 @@
 	SNPRINTF_RETURNS_BOGUS = YesPlease
 	SHELL_PATH=/usr/gnu/bin/bash
 	NEEDS_LIBGEN = YesPlease
+	NEEDS_LIBICONV = YesPlease
 endif
 ifeq ($(uname_S),HP-UX)
 	NO_IPV6=YesPlease
@@ -1557,9 +1560,8 @@
 	    -e '}' \
 	    -e 's|^import sys.*|&; \\\
 	           import os; \\\
-	           sys.path[0] = os.environ.has_key("GITPYTHONLIB") and \\\
-	                         os.environ["GITPYTHONLIB"] or \\\
-	                         "@@INSTLIBDIR@@"|' \
+	           sys.path.insert(0, os.getenv("GITPYTHONLIB",\
+	                                        "@@INSTLIBDIR@@"));|' \
 	    -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
 	    $@.py >$@+ && \
 	chmod +x $@+ && \
diff --git a/RelNotes b/RelNotes
index 02e7496..156a87e 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.7.0.3.txt
\ No newline at end of file
+Documentation/RelNotes-1.7.0.5.txt
\ No newline at end of file
diff --git a/branch.c b/branch.c
index 9e1f63e..2ab42aa 100644
--- a/branch.c
+++ b/branch.c
@@ -198,7 +198,7 @@
 		log_all_ref_updates = 1;
 
 	if (forcing)
-		snprintf(msg, sizeof msg, "branch: Reset from %s",
+		snprintf(msg, sizeof msg, "branch: Reset to %s",
 			 start_name);
 	else if (!dont_change_ref)
 		snprintf(msg, sizeof msg, "branch: Created from %s",
diff --git a/builtin-add.c b/builtin-add.c
index 2705f8d..87d2980 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -117,7 +117,19 @@
 	}
 }
 
-static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
+static char *find_used_pathspec(const char **pathspec)
+{
+	char *seen;
+	int i;
+
+	for (i = 0; pathspec[i];  i++)
+		; /* just counting */
+	seen = xcalloc(i, 1);
+	fill_pathspec_matches(pathspec, seen, i);
+	return seen;
+}
+
+static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
 {
 	char *seen;
 	int i, specs;
@@ -137,13 +149,7 @@
 	}
 	dir->nr = dst - dir->entries;
 	fill_pathspec_matches(pathspec, seen, specs);
-
-	for (i = 0; i < specs; i++) {
-		if (!seen[i] && pathspec[i][0] && !file_exists(pathspec[i]))
-			die("pathspec '%s' did not match any files",
-					pathspec[i]);
-	}
-        free(seen);
+	return seen;
 }
 
 static void treat_gitlinks(const char **pathspec)
@@ -359,6 +365,7 @@
 	int flags;
 	int add_new_files;
 	int require_pathspec;
+	char *seen = NULL;
 
 	git_config(add_config, NULL);
 
@@ -418,7 +425,7 @@
 		/* This picks up the paths that are not tracked */
 		baselen = fill_directory(&dir, pathspec);
 		if (pathspec)
-			prune_directory(&dir, pathspec, baselen);
+			seen = prune_directory(&dir, pathspec, baselen);
 	}
 
 	if (refresh_only) {
@@ -426,6 +433,19 @@
 		goto finish;
 	}
 
+	if (pathspec) {
+		int i;
+		if (!seen)
+			seen = find_used_pathspec(pathspec);
+		for (i = 0; pathspec[i]; i++) {
+			if (!seen[i] && pathspec[i][0]
+			    && !file_exists(pathspec[i]))
+				die("pathspec '%s' did not match any files",
+				    pathspec[i]);
+		}
+		free(seen);
+	}
+
 	exit_status |= add_files_to_cache(prefix, pathspec, flags);
 
 	if (add_new_files)
diff --git a/builtin-apply.c b/builtin-apply.c
index 3af4ae0..771c972 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1854,33 +1854,76 @@
 {
 	int i;
 	char *fixed_buf, *buf, *orig, *target;
+	int preimage_limit;
 
-	if (preimage->nr + try_lno > img->nr)
+	if (preimage->nr + try_lno <= img->nr) {
+		/*
+		 * The hunk falls within the boundaries of img.
+		 */
+		preimage_limit = preimage->nr;
+		if (match_end && (preimage->nr + try_lno != img->nr))
+			return 0;
+	} else if (ws_error_action == correct_ws_error &&
+		   (ws_rule & WS_BLANK_AT_EOF) && match_end) {
+		/*
+		 * This hunk that matches at the end extends beyond
+		 * the end of img, and we are removing blank lines
+		 * at the end of the file.  This many lines from the
+		 * beginning of the preimage must match with img, and
+		 * the remainder of the preimage must be blank.
+		 */
+		preimage_limit = img->nr - try_lno;
+	} else {
+		/*
+		 * The hunk extends beyond the end of the img and
+		 * we are not removing blanks at the end, so we
+		 * should reject the hunk at this position.
+		 */
 		return 0;
+	}
 
 	if (match_beginning && try_lno)
 		return 0;
 
-	if (match_end && preimage->nr + try_lno != img->nr)
-		return 0;
-
 	/* Quick hash check */
-	for (i = 0; i < preimage->nr; i++)
+	for (i = 0; i < preimage_limit; i++)
 		if (preimage->line[i].hash != img->line[try_lno + i].hash)
 			return 0;
 
-	/*
-	 * Do we have an exact match?  If we were told to match
-	 * at the end, size must be exactly at try+fragsize,
-	 * otherwise try+fragsize must be still within the preimage,
-	 * and either case, the old piece should match the preimage
-	 * exactly.
-	 */
-	if ((match_end
-	     ? (try + preimage->len == img->len)
-	     : (try + preimage->len <= img->len)) &&
-	    !memcmp(img->buf + try, preimage->buf, preimage->len))
-		return 1;
+	if (preimage_limit == preimage->nr) {
+		/*
+		 * Do we have an exact match?  If we were told to match
+		 * at the end, size must be exactly at try+fragsize,
+		 * otherwise try+fragsize must be still within the preimage,
+		 * and either case, the old piece should match the preimage
+		 * exactly.
+		 */
+		if ((match_end
+		     ? (try + preimage->len == img->len)
+		     : (try + preimage->len <= img->len)) &&
+		    !memcmp(img->buf + try, preimage->buf, preimage->len))
+			return 1;
+	} else {
+		/*
+		 * The preimage extends beyond the end of img, so
+		 * there cannot be an exact match.
+		 *
+		 * There must be one non-blank context line that match
+		 * a line before the end of img.
+		 */
+		char *buf_end;
+
+		buf = preimage->buf;
+		buf_end = buf;
+		for (i = 0; i < preimage_limit; i++)
+			buf_end += preimage->line[i].len;
+
+		for ( ; buf < buf_end; buf++)
+			if (!isspace(*buf))
+				break;
+		if (buf == buf_end)
+			return 0;
+	}
 
 	/*
 	 * No exact match. If we are ignoring whitespace, run a line-by-line
@@ -1891,7 +1934,10 @@
 		size_t imgoff = 0;
 		size_t preoff = 0;
 		size_t postlen = postimage->len;
-		for (i = 0; i < preimage->nr; i++) {
+		size_t extra_chars;
+		char *preimage_eof;
+		char *preimage_end;
+		for (i = 0; i < preimage_limit; i++) {
 			size_t prelen = preimage->line[i].len;
 			size_t imglen = img->line[try_lno+i].len;
 
@@ -1905,20 +1951,36 @@
 		}
 
 		/*
-		 * Ok, the preimage matches with whitespace fuzz. Update it and
-		 * the common postimage lines to use the same whitespace as the
-		 * target. imgoff now holds the true length of the target that
-		 * matches the preimage, and we need to update the line lengths
-		 * of the preimage to match the target ones.
+		 * Ok, the preimage matches with whitespace fuzz.
+		 *
+		 * imgoff now holds the true length of the target that
+		 * matches the preimage before the end of the file.
+		 *
+		 * Count the number of characters in the preimage that fall
+		 * beyond the end of the file and make sure that all of them
+		 * are whitespace characters. (This can only happen if
+		 * we are removing blank lines at the end of the file.)
 		 */
-		fixed_buf = xmalloc(imgoff);
-		memcpy(fixed_buf, img->buf + try, imgoff);
-		for (i = 0; i < preimage->nr; i++)
-			preimage->line[i].len = img->line[try_lno+i].len;
+		buf = preimage_eof = preimage->buf + preoff;
+		for ( ; i < preimage->nr; i++)
+			preoff += preimage->line[i].len;
+		preimage_end = preimage->buf + preoff;
+		for ( ; buf < preimage_end; buf++)
+			if (!isspace(*buf))
+				return 0;
 
 		/*
-		 * Update the preimage buffer and the postimage context lines.
+		 * Update the preimage and the common postimage context
+		 * lines to use the same whitespace as the target.
+		 * If whitespace is missing in the target (i.e.
+		 * if the preimage extends beyond the end of the file),
+		 * use the whitespace from the preimage.
 		 */
+		extra_chars = preimage_end - preimage_eof;
+		fixed_buf = xmalloc(imgoff + extra_chars);
+		memcpy(fixed_buf, img->buf + try, imgoff);
+		memcpy(fixed_buf + imgoff, preimage_eof, extra_chars);
+		imgoff += extra_chars;
 		update_pre_post_images(preimage, postimage,
 				fixed_buf, imgoff, postlen);
 		return 1;
@@ -1932,12 +1994,16 @@
 	 * it might with whitespace fuzz. We haven't been asked to
 	 * ignore whitespace, we were asked to correct whitespace
 	 * errors, so let's try matching after whitespace correction.
+	 *
+	 * The preimage may extend beyond the end of the file,
+	 * but in this loop we will only handle the part of the
+	 * preimage that falls within the file.
 	 */
 	fixed_buf = xmalloc(preimage->len + 1);
 	buf = fixed_buf;
 	orig = preimage->buf;
 	target = img->buf + try;
-	for (i = 0; i < preimage->nr; i++) {
+	for (i = 0; i < preimage_limit; i++) {
 		size_t fixlen; /* length after fixing the preimage */
 		size_t oldlen = preimage->line[i].len;
 		size_t tgtlen = img->line[try_lno + i].len;
@@ -1977,6 +2043,29 @@
 		target += tgtlen;
 	}
 
+
+	/*
+	 * Now handle the lines in the preimage that falls beyond the
+	 * end of the file (if any). They will only match if they are
+	 * empty or only contain whitespace (if WS_BLANK_AT_EOL is
+	 * false).
+	 */
+	for ( ; i < preimage->nr; i++) {
+		size_t fixlen; /* length after fixing the preimage */
+		size_t oldlen = preimage->line[i].len;
+		int j;
+
+		/* Try fixing the line in the preimage */
+		fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
+
+		for (j = 0; j < fixlen; j++)
+			if (!isspace(buf[j]))
+				goto unmatch_exit;
+
+		orig += oldlen;
+		buf += fixlen;
+	}
+
 	/*
 	 * Yes, the preimage is based on an older version that still
 	 * has whitespace breakages unfixed, and fixing them makes the
@@ -2002,9 +2091,6 @@
 	unsigned long backwards, forwards, try;
 	int backwards_lno, forwards_lno, try_lno;
 
-	if (preimage->nr > img->nr)
-		return -1;
-
 	/*
 	 * If match_beginning or match_end is specified, there is no
 	 * point starting from a wrong line that will never match and
@@ -2015,7 +2101,12 @@
 	else if (match_end)
 		line = img->nr - preimage->nr;
 
-	if (line > img->nr)
+	/*
+	 * Because the comparison is unsigned, the following test
+	 * will also take care of a negative line number that can
+	 * result when match_end and preimage is larger than the target.
+	 */
+	if ((size_t) line > img->nr)
 		line = img->nr;
 
 	try = 0;
@@ -2091,12 +2182,26 @@
 	int i, nr;
 	size_t remove_count, insert_count, applied_at = 0;
 	char *result;
+	int preimage_limit;
+
+	/*
+	 * If we are removing blank lines at the end of img,
+	 * the preimage may extend beyond the end.
+	 * If that is the case, we must be careful only to
+	 * remove the part of the preimage that falls within
+	 * the boundaries of img. Initialize preimage_limit
+	 * to the number of lines in the preimage that falls
+	 * within the boundaries.
+	 */
+	preimage_limit = preimage->nr;
+	if (preimage_limit > img->nr - applied_pos)
+		preimage_limit = img->nr - applied_pos;
 
 	for (i = 0; i < applied_pos; i++)
 		applied_at += img->line[i].len;
 
 	remove_count = 0;
-	for (i = 0; i < preimage->nr; i++)
+	for (i = 0; i < preimage_limit; i++)
 		remove_count += img->line[applied_pos + i].len;
 	insert_count = postimage->len;
 
@@ -2113,8 +2218,8 @@
 	result[img->len] = '\0';
 
 	/* Adjust the line table */
-	nr = img->nr + postimage->nr - preimage->nr;
-	if (preimage->nr < postimage->nr) {
+	nr = img->nr + postimage->nr - preimage_limit;
+	if (preimage_limit < postimage->nr) {
 		/*
 		 * NOTE: this knows that we never call remove_first_line()
 		 * on anything other than pre/post image.
@@ -2122,10 +2227,10 @@
 		img->line = xrealloc(img->line, nr * sizeof(*img->line));
 		img->line_allocated = img->line;
 	}
-	if (preimage->nr != postimage->nr)
+	if (preimage_limit != postimage->nr)
 		memmove(img->line + applied_pos + postimage->nr,
-			img->line + applied_pos + preimage->nr,
-			(img->nr - (applied_pos + preimage->nr)) *
+			img->line + applied_pos + preimage_limit,
+			(img->nr - (applied_pos + preimage_limit)) *
 			sizeof(*img->line));
 	memcpy(img->line + applied_pos,
 	       postimage->line,
@@ -2321,7 +2426,7 @@
 
 	if (applied_pos >= 0) {
 		if (new_blank_lines_at_end &&
-		    preimage.nr + applied_pos == img->nr &&
+		    preimage.nr + applied_pos >= img->nr &&
 		    (ws_rule & WS_BLANK_AT_EOF) &&
 		    ws_error_action != nowarn_ws_error) {
 			record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
@@ -2719,11 +2824,8 @@
 		if (stat_ret < 0) {
 			struct checkout costate;
 			/* checkout */
+			memset(&costate, 0, sizeof(costate));
 			costate.base_dir = "";
-			costate.base_dir_len = 0;
-			costate.force = 0;
-			costate.quiet = 0;
-			costate.not_new = 0;
 			costate.refresh_cache = 1;
 			if (checkout_entry(*ce, &costate, NULL) ||
 			    lstat(old_name, st))
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index b0a4029..c6dd71a 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -503,7 +503,7 @@
 
 	f = fopen(file, "w");
 	if (!f)
-		error("Unable to open marks file %s for writing.", file);
+		die_errno("Unable to open marks file %s for writing.", file);
 
 	for (i = 0; i < idnums.size; i++) {
 		if (deco->base && deco->base->type == 1) {
diff --git a/builtin-fetch.c b/builtin-fetch.c
index bbc425b..007dabf 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -13,10 +13,10 @@
 #include "sigchain.h"
 
 static const char * const builtin_fetch_usage[] = {
-	"git fetch [options] [<repository> <refspec>...]",
-	"git fetch [options] <group>",
-	"git fetch --multiple [options] [<repository> | <group>]...",
-	"git fetch --all [options]",
+	"git fetch [<options>] [<repository> [<refspec>...]]",
+	"git fetch [<options>] <group>",
+	"git fetch --multiple [<options>] [<repository> | <group>]...",
+	"git fetch --all [<options>]",
 	NULL
 };
 
diff --git a/builtin-log.c b/builtin-log.c
index e0d5caa..76962e1 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1106,8 +1106,15 @@
 			return 0;
 	}
 
-	if (ignore_if_in_upstream)
+	if (ignore_if_in_upstream) {
+		/* Don't say anything if head and upstream are the same. */
+		if (rev.pending.nr == 2) {
+			struct object_array_entry *o = rev.pending.objects;
+			if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
+				return 0;
+		}
 		get_patch_ids(&rev, &ids, prefix);
+	}
 
 	if (!use_stdout)
 		realstdout = xfdopen(xdup(1), "w");
diff --git a/builtin-push.c b/builtin-push.c
index f7bc2b2..9fc6931 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -10,7 +10,7 @@
 #include "parse-options.h"
 
 static const char * const push_usage[] = {
-	"git push [<options>] [<repository> <refspec>...]",
+	"git push [<options>] [<repository> [<refspec>...]]",
 	NULL,
 };
 
diff --git a/builtin-reflog.c b/builtin-reflog.c
index 64e45bd..bd7880d 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -13,7 +13,7 @@
  */
 
 static const char reflog_expire_usage[] =
-"git reflog (show|expire) [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
+"git reflog expire [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
 static const char reflog_delete_usage[] =
 "git reflog delete [--verbose] [--dry-run] [--rewrite] [--updateref] <refs>...";
 
diff --git a/builtin-reset.c b/builtin-reset.c
index 0f5022e..a174a31 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -23,7 +23,8 @@
 
 static const char * const git_reset_usage[] = {
 	"git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
-	"git reset [--mixed] <commit> [--] <paths>...",
+	"git reset [-q] <commit> [--] <paths>...",
+	"git reset --patch [<commit>] [--] [<paths>...]",
 	NULL
 };
 
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index eb8e2c2..51ceb19 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -133,9 +133,12 @@
 				 */
 				if (graph_show_remainder(revs->graph))
 					putchar('\n');
+				if (revs->commit_format == CMIT_FMT_ONELINE)
+					putchar('\n');
 			}
 		} else {
-			if (buf.len)
+			if (revs->commit_format != CMIT_FMT_USERFORMAT ||
+			    buf.len)
 				printf("%s%c", buf.buf, info->hdr_termination);
 		}
 		strbuf_release(&buf);
diff --git a/color.c b/color.c
index 62977f4..e8bcac0 100644
--- a/color.c
+++ b/color.c
@@ -47,7 +47,7 @@
 {
 	const char *ptr = value;
 	int len = value_len;
-	int attr = -1;
+	unsigned int attr = 0;
 	int fg = -2;
 	int bg = -2;
 
@@ -56,7 +56,7 @@
 		return;
 	}
 
-	/* [fg [bg]] [attr] */
+	/* [fg [bg]] [attr]... */
 	while (len > 0) {
 		const char *word = ptr;
 		int val, wordlen = 0;
@@ -85,19 +85,27 @@
 			goto bad;
 		}
 		val = parse_attr(word, wordlen);
-		if (val < 0 || attr != -1)
+		if (0 <= val)
+			attr |= (1 << val);
+		else
 			goto bad;
-		attr = val;
 	}
 
-	if (attr >= 0 || fg >= 0 || bg >= 0) {
+	if (attr || fg >= 0 || bg >= 0) {
 		int sep = 0;
+		int i;
 
 		*dst++ = '\033';
 		*dst++ = '[';
-		if (attr >= 0) {
-			*dst++ = '0' + attr;
-			sep++;
+
+		for (i = 0; attr; i++) {
+			unsigned bit = (1 << i);
+			if (!(attr & bit))
+				continue;
+			attr &= ~bit;
+			if (sep++)
+				*dst++ = ';';
+			*dst++ = '0' + i;
 		}
 		if (fg >= 0) {
 			if (sep++)
diff --git a/color.h b/color.h
index 3cb4b7f..bcb28cf 100644
--- a/color.h
+++ b/color.h
@@ -1,8 +1,20 @@
 #ifndef COLOR_H
 #define COLOR_H
 
-/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
-#define COLOR_MAXLEN 24
+/*  2 + (2 * num_attrs) + 8 + 1 + 8 + 'm' + NUL */
+/* "\033[1;2;4;5;7;38;5;2xx;48;5;2xxm\0" */
+/*
+ * The maximum length of ANSI color sequence we would generate:
+ * - leading ESC '['            2
+ * - attr + ';'                 2 * 8 (e.g. "1;")
+ * - fg color + ';'             9 (e.g. "38;5;2xx;")
+ * - fg color + ';'             9 (e.g. "48;5;2xx;")
+ * - terminating 'm' NUL        2
+ *
+ * The above overcounts attr (we only use 5 not 8) and one semicolon
+ * but it is close enough.
+ */
+#define COLOR_MAXLEN 40
 
 /*
  * IMPORTANT: Due to the way these color codes are emulated on Windows,
diff --git a/combine-diff.c b/combine-diff.c
index 6162691..3480dae 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -204,7 +204,7 @@
 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 num_parent, int result_deleted)
 {
 	unsigned int p_lno, lno;
 	unsigned long nmask = (1UL << n);
@@ -215,7 +215,7 @@
 	struct combine_diff_state state;
 	unsigned long sz;
 
-	if (!cnt)
+	if (result_deleted)
 		return; /* result deleted */
 
 	parent_file.ptr = grab_blob(parent, mode, &sz);
@@ -517,7 +517,7 @@
 }
 
 static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
-		       int use_color)
+		       int use_color, int result_deleted)
 {
 	unsigned long mark = (1UL<<num_parent);
 	unsigned long no_pre_delete = (2UL<<num_parent);
@@ -530,7 +530,7 @@
 	const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
 	const char *c_reset = diff_get_color(use_color, DIFF_RESET);
 
-	if (!cnt)
+	if (result_deleted)
 		return; /* result deleted */
 
 	while (1) {
@@ -687,6 +687,7 @@
 {
 	struct diff_options *opt = &rev->diffopt;
 	unsigned long result_size, cnt, lno;
+	int result_deleted = 0;
 	char *result, *cp;
 	struct sline *sline; /* survived lines */
 	int mode_differs = 0;
@@ -767,6 +768,7 @@
 		}
 		else {
 		deleted_file:
+			result_deleted = 1;
 			result_size = 0;
 			elem->mode = 0;
 			result = xcalloc(1, 1);
@@ -823,7 +825,7 @@
 			combine_diff(elem->parent[i].sha1,
 				     elem->parent[i].mode,
 				     &result_file, sline,
-				     cnt, i, num_parent);
+				     cnt, i, num_parent, result_deleted);
 		if (elem->parent[i].mode != elem->mode)
 			mode_differs = 1;
 	}
@@ -889,7 +891,7 @@
 			dump_quoted_path("+++ ", b_prefix, elem->path,
 					 c_meta, c_reset);
 		dump_sline(sline, cnt, num_parent,
-			   DIFF_OPT_TST(opt, COLOR_DIFF));
+			   DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
 	}
 	free(result);
 
diff --git a/compat/bswap.h b/compat/bswap.h
index f3b8c44..54756db 100644
--- a/compat/bswap.h
+++ b/compat/bswap.h
@@ -17,6 +17,8 @@
 		((val & 0x000000ff) << 24));
 }
 
+#undef bswap32
+
 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 
 #define bswap32(x) ({ \
diff --git a/compat/mingw.c b/compat/mingw.c
index ab65f77..59b18dc 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -259,8 +259,17 @@
 	int fh, rc;
 
 	/* must have write permission */
-	if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0)
-		return -1;
+	DWORD attrs = GetFileAttributes(file_name);
+	if (attrs != INVALID_FILE_ATTRIBUTES &&
+	    (attrs & FILE_ATTRIBUTE_READONLY)) {
+		/* ignore errors here; open() will report them */
+		SetFileAttributes(file_name, attrs & ~FILE_ATTRIBUTE_READONLY);
+	}
+
+	if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0) {
+		rc = -1;
+		goto revert_attrs;
+	}
 
 	time_t_to_filetime(times->modtime, &mft);
 	time_t_to_filetime(times->actime, &aft);
@@ -270,6 +279,13 @@
 	} else
 		rc = 0;
 	close(fh);
+
+revert_attrs:
+	if (attrs != INVALID_FILE_ATTRIBUTES &&
+	    (attrs & FILE_ATTRIBUTE_READONLY)) {
+		/* ignore errors again */
+		SetFileAttributes(file_name, attrs);
+	}
 	return rc;
 }
 
diff --git a/compat/vcbuild/include/termios.h b/compat/vcbuild/include/termios.h
new file mode 100644
index 0000000..0d8552a
--- /dev/null
+++ b/compat/vcbuild/include/termios.h
@@ -0,0 +1 @@
+/* Intentionally empty file to support building git with MSVC */
diff --git a/contrib/fast-import/import-zips.py b/contrib/fast-import/import-zips.py
index 7051a83..82f5ed3 100755
--- a/contrib/fast-import/import-zips.py
+++ b/contrib/fast-import/import-zips.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 ## zip archive frontend for git-fast-import
 ##
diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py
index 854cd94..046cb2b 100755
--- a/contrib/hg-to-git/hg-to-git.py
+++ b/contrib/hg-to-git/hg-to-git.py
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#!/usr/bin/env python
 
 """ hg-to-git.py - A Mercurial to GIT converter
 
diff --git a/contrib/p4import/git-p4import.py b/contrib/p4import/git-p4import.py
index 0f3d97b..b6e534b 100644
--- a/contrib/p4import/git-p4import.py
+++ b/contrib/p4import/git-p4import.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 #
 # This tool is copyright (c) 2006, Sean Estabrooks.
 # It is released under the Gnu Public License, version 2.
diff --git a/daemon.c b/daemon.c
index 7d9e1c0..a90ab10 100644
--- a/daemon.c
+++ b/daemon.c
@@ -590,14 +590,17 @@
 static int addrcmp(const struct sockaddr_storage *s1,
     const struct sockaddr_storage *s2)
 {
-	if (s1->ss_family != s2->ss_family)
-		return s1->ss_family - s2->ss_family;
-	if (s1->ss_family == AF_INET)
+	const struct sockaddr *sa1 = (const struct sockaddr*) s1;
+	const struct sockaddr *sa2 = (const struct sockaddr*) s2;
+
+	if (sa1->sa_family != sa2->sa_family)
+		return sa1->sa_family - sa2->sa_family;
+	if (sa1->sa_family == AF_INET)
 		return memcmp(&((struct sockaddr_in *)s1)->sin_addr,
 		    &((struct sockaddr_in *)s2)->sin_addr,
 		    sizeof(struct in_addr));
 #ifndef NO_IPV6
-	if (s1->ss_family == AF_INET6)
+	if (sa1->sa_family == AF_INET6)
 		return memcmp(&((struct sockaddr_in6 *)s1)->sin6_addr,
 		    &((struct sockaddr_in6 *)s2)->sin6_addr,
 		    sizeof(struct in6_addr));
diff --git a/diff.c b/diff.c
index 0d465fa..edec0f6 100644
--- a/diff.c
+++ b/diff.c
@@ -14,6 +14,7 @@
 #include "userdiff.h"
 #include "sigchain.h"
 #include "submodule.h"
+#include "ll-merge.h"
 
 #ifdef NO_FAST_WORKING_DIRECTORY
 #define FAST_WORKING_DIRECTORY 0
@@ -948,7 +949,7 @@
 		unsigned is_unmerged:1;
 		unsigned is_binary:1;
 		unsigned is_renamed:1;
-		unsigned int added, deleted;
+		uintmax_t added, deleted;
 	} **files;
 };
 
@@ -1040,7 +1041,7 @@
 static void show_stats(struct diffstat_t *data, struct diff_options *options)
 {
 	int i, len, add, del, adds = 0, dels = 0;
-	int max_change = 0, max_len = 0;
+	uintmax_t max_change = 0, max_len = 0;
 	int total_files = data->nr;
 	int width, name_width;
 	const char *reset, *set, *add_c, *del_c;
@@ -1069,7 +1070,7 @@
 
 	for (i = 0; i < data->nr; i++) {
 		struct diffstat_file *file = data->files[i];
-		int change = file->added + file->deleted;
+		uintmax_t change = file->added + file->deleted;
 		fill_print_name(file);
 		len = strlen(file->print_name);
 		if (max_len < len)
@@ -1097,8 +1098,8 @@
 	for (i = 0; i < data->nr; i++) {
 		const char *prefix = "";
 		char *name = data->files[i]->print_name;
-		int added = data->files[i]->added;
-		int deleted = data->files[i]->deleted;
+		uintmax_t added = data->files[i]->added;
+		uintmax_t deleted = data->files[i]->deleted;
 		int name_len;
 
 		/*
@@ -1119,9 +1120,11 @@
 		if (data->files[i]->is_binary) {
 			show_name(options->file, prefix, name, len);
 			fprintf(options->file, "  Bin ");
-			fprintf(options->file, "%s%d%s", del_c, deleted, reset);
+			fprintf(options->file, "%s%"PRIuMAX"%s",
+				del_c, deleted, reset);
 			fprintf(options->file, " -> ");
-			fprintf(options->file, "%s%d%s", add_c, added, reset);
+			fprintf(options->file, "%s%"PRIuMAX"%s",
+				add_c, added, reset);
 			fprintf(options->file, " bytes");
 			fprintf(options->file, "\n");
 			continue;
@@ -1150,7 +1153,7 @@
 			del = scale_linear(del, width, max_change);
 		}
 		show_name(options->file, prefix, name, len);
-		fprintf(options->file, "%5d%s", added + deleted,
+		fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
 				added + deleted ? " " : "");
 		show_graph(options->file, '+', add, add_c, reset);
 		show_graph(options->file, '-', del, del_c, reset);
@@ -1200,7 +1203,8 @@
 			fprintf(options->file, "-\t-\t");
 		else
 			fprintf(options->file,
-				"%d\t%d\t", file->added, file->deleted);
+				"%"PRIuMAX"\t%"PRIuMAX"\t",
+				file->added, file->deleted);
 		if (options->line_termination) {
 			fill_print_name(file);
 			if (!file->is_renamed)
@@ -1370,37 +1374,32 @@
 struct checkdiff_t {
 	const char *filename;
 	int lineno;
+	int conflict_marker_size;
 	struct diff_options *o;
 	unsigned ws_rule;
 	unsigned status;
 };
 
-static int is_conflict_marker(const char *line, unsigned long len)
+static int is_conflict_marker(const char *line, int marker_size, unsigned long len)
 {
 	char firstchar;
 	int cnt;
 
-	if (len < 8)
+	if (len < marker_size + 1)
 		return 0;
 	firstchar = line[0];
 	switch (firstchar) {
-	case '=': case '>': case '<':
+	case '=': case '>': case '<': case '|':
 		break;
 	default:
 		return 0;
 	}
-	for (cnt = 1; cnt < 7; cnt++)
+	for (cnt = 1; cnt < marker_size; cnt++)
 		if (line[cnt] != firstchar)
 			return 0;
-	/* line[0] thru line[6] are same as firstchar */
-	if (firstchar == '=') {
-		/* divider between ours and theirs? */
-		if (len != 8 || line[7] != '\n')
-			return 0;
-	} else if (len < 8 || !isspace(line[7])) {
-		/* not divider before ours nor after theirs */
+	/* line[1] thru line[marker_size-1] are same as firstchar */
+	if (len < marker_size + 1 || !isspace(line[marker_size]))
 		return 0;
-	}
 	return 1;
 }
 
@@ -1408,6 +1407,7 @@
 {
 	struct checkdiff_t *data = priv;
 	int color_diff = DIFF_OPT_TST(data->o, COLOR_DIFF);
+	int marker_size = data->conflict_marker_size;
 	const char *ws = diff_get_color(color_diff, DIFF_WHITESPACE);
 	const char *reset = diff_get_color(color_diff, DIFF_RESET);
 	const char *set = diff_get_color(color_diff, DIFF_FILE_NEW);
@@ -1416,7 +1416,7 @@
 	if (line[0] == '+') {
 		unsigned bad;
 		data->lineno++;
-		if (is_conflict_marker(line + 1, len - 1)) {
+		if (is_conflict_marker(line + 1, marker_size, len - 1)) {
 			data->status |= 1;
 			fprintf(data->o->file,
 				"%s:%d: leftover conflict marker\n",
@@ -1860,6 +1860,7 @@
 	data.lineno = 0;
 	data.o = o;
 	data.ws_rule = whitespace_rule(attr_path);
+	data.conflict_marker_size = ll_merge_marker_size(attr_path);
 
 	if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
 		die("unable to read files to diff");
@@ -3865,6 +3866,7 @@
 	const char **arg = argv;
 	struct child_process child;
 	struct strbuf buf = STRBUF_INIT;
+	int err = 0;
 
 	temp = prepare_temp_file(spec->path, spec);
 	*arg++ = pgm;
@@ -3875,16 +3877,20 @@
 	child.use_shell = 1;
 	child.argv = argv;
 	child.out = -1;
-	if (start_command(&child) != 0 ||
-	    strbuf_read(&buf, child.out, 0) < 0 ||
-	    finish_command(&child) != 0) {
-		close(child.out);
-		strbuf_release(&buf);
+	if (start_command(&child)) {
 		remove_tempfile();
-		error("error running textconv command '%s'", pgm);
 		return NULL;
 	}
+
+	if (strbuf_read(&buf, child.out, 0) < 0)
+		err = error("error reading from textconv command '%s'", pgm);
 	close(child.out);
+
+	if (finish_command(&child) || err) {
+		strbuf_release(&buf);
+		remove_tempfile();
+		return NULL;
+	}
 	remove_tempfile();
 
 	return strbuf_detach(&buf, outsize);
diff --git a/dir.c b/dir.c
index 133c333..cb83332 100644
--- a/dir.c
+++ b/dir.c
@@ -594,13 +594,29 @@
 	return 0;
 }
 
-static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
+/*
+ * This function tells us whether an excluded path matches a
+ * list of "interesting" pathspecs. That is, whether a path matched
+ * by any of the pathspecs could possibly be ignored by excluding
+ * the specified path. This can happen if:
+ *
+ *   1. the path is mentioned explicitly in the pathspec
+ *
+ *   2. the path is a directory prefix of some element in the
+ *      pathspec
+ */
+static int exclude_matches_pathspec(const char *path, int len,
+		const struct path_simplify *simplify)
 {
 	if (simplify) {
 		for (; simplify->path; simplify++) {
 			if (len == simplify->len
 			    && !memcmp(path, simplify->path, len))
 				return 1;
+			if (len < simplify->len
+			    && simplify->path[len] == '/'
+			    && !memcmp(path, simplify->path, len))
+				return 1;
 		}
 	}
 	return 0;
@@ -678,7 +694,7 @@
 {
 	int exclude = excluded(dir, path, &dtype);
 	if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
-	    && in_pathspec(path, *len, simplify))
+	    && exclude_matches_pathspec(path, *len, simplify))
 		dir_add_ignored(dir, path, *len);
 
 	/*
diff --git a/git-difftool.perl b/git-difftool.perl
index d975d07..adc42de 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -78,11 +78,13 @@
 			next;
 		}
 		if ($arg eq '-g' || $arg eq '--gui') {
-			my $tool = Git::command_oneline('config',
-			                                'diff.guitool');
-			if (length($tool)) {
-				$ENV{GIT_DIFF_TOOL} = $tool;
-			}
+			eval {
+				my $tool = Git::command_oneline('config',
+				                                'diff.guitool');
+				if (length($tool)) {
+					$ENV{GIT_DIFF_TOOL} = $tool;
+				}
+			};
 			next;
 		}
 		if ($arg eq '-y' || $arg eq '--no-prompt') {
diff --git a/git-send-email.perl b/git-send-email.perl
index e05455f..1b99f40 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -162,9 +162,12 @@
 
 # Handle interactive edition of files.
 my $multiedit;
-my $editor = Git::command_oneline('var', 'GIT_EDITOR');
+my $editor;
 
 sub do_edit {
+	if (!defined($editor)) {
+		$editor = Git::command_oneline('var', 'GIT_EDITOR');
+	}
 	if (defined($multiedit) && !$multiedit) {
 		map {
 			system('sh', '-c', $editor.' "$@"', $editor, $_);
diff --git a/git-stash.sh b/git-stash.sh
index aa47e54..59db3dc 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -210,14 +210,18 @@
 }
 
 show_stash () {
+	have_stash || die 'No stash found'
+
 	flags=$(git rev-parse --no-revs --flags "$@")
 	if test -z "$flags"
 	then
 		flags=--stat
 	fi
 
-	w_commit=$(git rev-parse --verify --default $ref_stash "$@") &&
-	b_commit=$(git rev-parse --verify "$w_commit^") &&
+	w_commit=$(git rev-parse --quiet --verify --default $ref_stash "$@") &&
+	b_commit=$(git rev-parse --quiet --verify "$w_commit^") ||
+		die "'$*' is not a stash"
+
 	git diff $flags $b_commit $w_commit
 }
 
diff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile
index c62dfd0..74b05dc 100644
--- a/git_remote_helpers/Makefile
+++ b/git_remote_helpers/Makefile
@@ -7,7 +7,11 @@
 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
 
 ifndef PYTHON_PATH
-	PYTHON_PATH = /usr/bin/python
+	ifeq ($(uname_S),FreeBSD)
+		PYTHON_PATH = /usr/local/bin/python
+	else
+		PYTHON_PATH = /usr/bin/python
+	endif
 endif
 ifndef prefix
 	prefix = $(HOME)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 3d80deb..9d4c582 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2209,8 +2209,7 @@
 sub git_get_project_config {
 	my ($key, $type) = @_;
 
-	# do we have project
-	return unless (defined $project && defined $git_dir);
+	return unless defined $git_dir;
 
 	# key sanity check
 	return unless ($key);
diff --git a/http-backend.c b/http-backend.c
index 345c12b..d1e83d0 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -538,15 +538,19 @@
 
 static NORETURN void die_webcgi(const char *err, va_list params)
 {
-	char buffer[1000];
+	static int dead;
 
-	http_status(500, "Internal Server Error");
-	hdr_nocache();
-	end_headers();
+	if (!dead) {
+		char buffer[1000];
+		dead = 1;
 
-	vsnprintf(buffer, sizeof(buffer), err, params);
-	fprintf(stderr, "fatal: %s\n", buffer);
-	exit(0);
+		vsnprintf(buffer, sizeof(buffer), err, params);
+		fprintf(stderr, "fatal: %s\n", buffer);
+		http_status(500, "Internal Server Error");
+		hdr_nocache();
+		end_headers();
+	}
+	exit(0); /* we successfully reported a failure ;-) */
 }
 
 static char* getdir(void)
diff --git a/imap-send.c b/imap-send.c
index 5631930..379dec4 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1306,8 +1306,14 @@
 
 	while (1) {
 		if (!prefixcmp(p, "From ")) {
+			p = strstr(p+5, "\nFrom: ");
+			if (!p) break;
+			p = strstr(p+7, "\nDate: ");
+			if (!p) break;
+			p = strstr(p+7, "\nSubject: ");
+			if (!p) break;
+			p += 10;
 			count++;
-			p += 5;
 		}
 		p = strstr(p+5, "\nFrom ");
 		if (!p)
diff --git a/refs.c b/refs.c
index 63e30d7..a7518b6 100644
--- a/refs.c
+++ b/refs.c
@@ -6,6 +6,7 @@
 
 /* ISSYMREF=01 and ISPACKED=02 are public interfaces */
 #define REF_KNOWS_PEELED 04
+#define REF_BROKEN 010
 
 struct ref_list {
 	struct ref_list *next;
@@ -275,8 +276,10 @@
 				list = get_ref_dir(ref, list);
 				continue;
 			}
-			if (!resolve_ref(ref, sha1, 1, &flag))
+			if (!resolve_ref(ref, sha1, 1, &flag)) {
 				hashclr(sha1);
+				flag |= REF_BROKEN;
+			}
 			list = add_ref(ref, sha1, flag, list, NULL);
 		}
 		free(ref);
@@ -539,10 +542,10 @@
 {
 	if (strncmp(base, entry->name, trim))
 		return 0;
-	/* Is this a "negative ref" that represents a deleted ref? */
-	if (is_null_sha1(entry->sha1))
-		return 0;
+
 	if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
+		if (entry->flag & REF_BROKEN)
+			return 0; /* ignore dangling symref */
 		if (!has_sha1_file(entry->sha1)) {
 			error("%s does not point to a valid object!", entry->name);
 			return 0;
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 89282cc..41df6bc 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -108,13 +108,17 @@
 
 '
 
-$test_case 'add (with different case)' '
+
+
+test_expect_failure 'add (with different case)' '
 
 	git reset --hard initial &&
 	rm camelcase &&
 	echo 1 >CamelCase &&
 	git add CamelCase &&
-	test $(git ls-files | grep -i camelcase | wc -l) = 1
+	camel=$(git ls-files | grep -i camelcase) &&
+	test $(echo "$camel" | wc -l) = 1 &&
+	test "z$(git cat-file blob :$camel)" = z1
 
 '
 
diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh
index 9956e3a..b946f87 100755
--- a/t/t1010-mktree.sh
+++ b/t/t1010-mktree.sh
@@ -58,14 +58,12 @@
 	test_cmp tree.missing actual
 '
 
-test_expect_failure 'mktree reads ls-tree -r output (1)' '
-	git mktree <all >actual &&
-	test_cmp tree actual
+test_expect_success 'mktree refuses to read ls-tree -r output (1)' '
+	test_must_fail git mktree <all >actual
 '
 
-test_expect_failure 'mktree reads ls-tree -r output (2)' '
-	git mktree <all.withsub >actual &&
-	test_cmp tree.withsub actual
+test_expect_success 'mktree refuses to read ls-tree -r output (2)' '
+	test_must_fail git mktree <all.withsub >actual
 '
 
 test_done
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 9120750..2ad2819 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -176,4 +176,9 @@
 
 '
 
+test_expect_success '"add -u non-existent" should fail' '
+	test_must_fail git add -u non-existent &&
+	! (git ls-files | grep "non-existent")
+'
+
 test_done
diff --git a/t/t2204-add-ignored.sh b/t/t2204-add-ignored.sh
new file mode 100755
index 0000000..24afdab
--- /dev/null
+++ b/t/t2204-add-ignored.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+test_description='giving ignored paths to git add'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	mkdir sub dir dir/sub &&
+	echo sub >.gitignore &&
+	echo ign >>.gitignore &&
+	for p in . sub dir dir/sub
+	do
+		>"$p/ign" &&
+		>"$p/file" || exit 1
+	done
+'
+
+for i in file dir/file dir 'd*'
+do
+	test_expect_success "no complaints for unignored $i" '
+		rm -f .git/index &&
+		git add "$i" &&
+		git ls-files "$i" >out &&
+		test -s out
+	'
+done
+
+for i in ign dir/ign dir/sub dir/sub/*ign sub/file sub sub/*
+do
+	test_expect_success "complaints for ignored $i" '
+		rm -f .git/index &&
+		test_must_fail git add "$i" 2>err &&
+		git ls-files "$i" >out &&
+		! test -s out &&
+		grep -e "Use -f if" err &&
+		cat err
+	'
+
+	test_expect_success "complaints for ignored $i with unignored file" '
+		rm -f .git/index &&
+		test_must_fail git add "$i" file 2>err &&
+		git ls-files "$i" >out &&
+		! test -s out &&
+		grep -e "Use -f if" err &&
+		cat err
+	'
+done
+
+for i in sub sub/*
+do
+	test_expect_success "complaints for ignored $i in dir" '
+		rm -f .git/index &&
+		(
+			cd dir &&
+			test_must_fail git add "$i" 2>err &&
+			git ls-files "$i" >out &&
+			! test -s out &&
+			grep -e "Use -f if" err &&
+			cat err
+		)
+	'
+done
+
+for i in ign file
+do
+	test_expect_success "complaints for ignored $i in sub" '
+		rm -f .git/index &&
+		(
+			cd sub &&
+			test_must_fail git add "$i" 2>err &&
+			git ls-files "$i" >out &&
+			! test -s out &&
+			grep -e "Use -f if" err &&
+			cat err
+		)
+	'
+done
+
+test_done
diff --git a/t/t3417-rebase-whitespace-fix.sh b/t/t3417-rebase-whitespace-fix.sh
new file mode 100755
index 0000000..220a740
--- /dev/null
+++ b/t/t3417-rebase-whitespace-fix.sh
@@ -0,0 +1,126 @@
+#!/bin/sh
+
+test_description='git rebase --whitespace=fix
+
+This test runs git rebase --whitespace=fix and make sure that it works.
+'
+
+. ./test-lib.sh
+
+# prepare initial revision of "file" with a blank line at the end
+cat >file <<EOF
+a
+b
+c
+
+EOF
+
+# expected contents in "file" after rebase
+cat >expect-first <<EOF
+a
+b
+c
+EOF
+
+# prepare second revision of "file"
+cat >second <<EOF
+a
+b
+c
+
+d
+e
+f
+
+
+
+
+EOF
+
+# expected contents in second revision after rebase
+cat >expect-second <<EOF
+a
+b
+c
+
+d
+e
+f
+EOF
+
+test_expect_success 'blank line at end of file; extend at end of file' '
+	git commit --allow-empty -m "Initial empty commit" &&
+	git add file && git commit -m first &&
+	mv second file &&
+	git add file &&	git commit -m second &&
+	git rebase --whitespace=fix HEAD^^ &&
+	git diff --exit-code HEAD^:file expect-first &&
+	test_cmp file expect-second
+'
+
+# prepare third revision of "file"
+sed -e's/Z//' >third <<EOF
+a
+b
+c
+
+d
+e
+f
+    Z
+ Z
+h
+i
+j
+k
+l
+EOF
+
+sed -e's/ //g' <third >expect-third
+
+test_expect_success 'two blanks line at end of file; extend at end of file' '
+	cp third file && git add file && git commit -m third &&
+	git rebase --whitespace=fix HEAD^^ &&
+	git diff --exit-code HEAD^:file expect-second &&
+	test_cmp file expect-third
+'
+
+test_expect_success 'same, but do not remove trailing spaces' '
+	git config core.whitespace "-blank-at-eol" &&
+	git reset --hard HEAD^ &&
+	cp third file && git add file && git commit -m third &&
+	git rebase --whitespace=fix HEAD^^
+	git diff --exit-code HEAD^:file expect-second &&
+	test_cmp file third
+'
+
+sed -e's/Z//' >beginning <<EOF
+a
+		    Z
+       Z
+EOF
+
+cat >expect-beginning <<EOF
+a
+
+
+1
+2
+3
+4
+5
+EOF
+
+test_expect_success 'at beginning of file' '
+	git config core.whitespace "blank-at-eol" &&
+	cp beginning file &&
+	git commit -m beginning file &&
+	for i in 1 2 3 4 5; do
+		echo $i
+	done >> file &&
+	git commit -m more file	&&
+	git rebase --whitespace=fix HEAD^^ &&
+	test_cmp file expect-beginning
+'
+
+test_done
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 85eb0fb..525c9a8 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -255,4 +255,9 @@
 	git add track-this
 '
 
+test_expect_success '"add non-existent" should fail' '
+	test_must_fail git add non-existent &&
+	! (git ls-files | grep "non-existent")
+'
+
 test_done
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index f2a2aaa..843ef7f 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -557,4 +557,8 @@
 	! grep "Use .--" error
 '
 
+test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
+	git format-patch --ignore-if-in-upstream HEAD
+'
+
 test_done
diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh
index 0391a58..6158985 100755
--- a/t/t4017-diff-retval.sh
+++ b/t/t4017-diff-retval.sh
@@ -120,7 +120,6 @@
 
 '
 
-
 test_expect_success 'check should test not just the last line' '
 	echo "" >>a &&
 	git --no-pager diff --check
@@ -142,4 +141,26 @@
 	git reset --hard
 '
 
+test_expect_success 'check honors conflict marker length' '
+	git reset --hard &&
+	echo ">>>>>>> boo" >>b &&
+	echo "======" >>a &&
+	git diff --check a &&
+	(
+		git diff --check b
+		test $? = 2
+	) &&
+	git reset --hard &&
+	echo ">>>>>>>> boo" >>b &&
+	echo "========" >>a &&
+	git diff --check &&
+	echo "b conflict-marker-size=8" >.gitattributes &&
+	(
+		git diff --check b
+		test $? = 2
+	) &&
+	git diff --check a &&
+	git reset --hard
+'
+
 test_done
diff --git a/t/t4026-color.sh b/t/t4026-color.sh
index 5ade44c..d5ccdd0 100755
--- a/t/t4026-color.sh
+++ b/t/t4026-color.sh
@@ -8,14 +8,13 @@
 
 color()
 {
-	git config diff.color.new "$1" &&
-	test "`git config --get-color diff.color.new`" = "$2"
+	actual=$(git config --get-color no.such.slot "$1") &&
+	test "$actual" = "$2"
 }
 
 invalid_color()
 {
-	git config diff.color.new "$1" &&
-	test -z "`git config --get-color diff.color.new 2>/dev/null`"
+	test_must_fail git config --get-color no.such.slot "$1"
 }
 
 test_expect_success 'reset' '
@@ -42,6 +41,14 @@
 	color "blue red ul" "[4;34;41m"
 '
 
+test_expect_success 'fg bg attr...' '
+	color "blue bold dim ul blink reverse" "[1;2;4;5;7;34m"
+'
+
+test_expect_success 'long color specification' '
+	color "254 255 bold dim ul blink reverse" "[1;2;4;5;7;38;5;254;48;5;255m"
+'
+
 test_expect_success '256 colors' '
 	color "254 bold 255" "[1;38;5;254;48;5;255m"
 '
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index 7584efa..40277c7 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -81,4 +81,12 @@
 	verify_helper sidesansone
 '
 
+test_expect_success 'diagnose truncated file' '
+	>file &&
+	git add file &&
+	git commit --amend -C HEAD &&
+	git show >out &&
+	grep "diff --cc file" out
+'
+
 test_done
diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh
index 0e3ce36..c617c2a 100755
--- a/t/t4104-apply-boundary.sh
+++ b/t/t4104-apply-boundary.sh
@@ -134,4 +134,13 @@
 
 '
 
+test_expect_success 'apply patch with 3 context lines matching at end' '
+	{ echo a; echo b; echo c; echo d; } >file &&
+	git add file &&
+	echo e >>file &&
+	git diff >patch &&
+	>file &&
+	test_must_fail git apply patch
+'
+
 test_done
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index ca26397..fb9ad24 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -261,4 +261,174 @@
 	grep "new blank line at EOF" error
 '
 
+test_expect_success 'applying beyond EOF requires one non-blank context line' '
+	{ echo; echo; echo; echo; } >one &&
+	git add one &&
+	{ echo b; } >>one &&
+	git diff -- one >patch &&
+
+	git checkout one &&
+	{ echo a; echo; } >one &&
+	cp one expect &&
+	test_must_fail git apply --whitespace=fix patch &&
+	test_cmp one expect &&
+	test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
+	test_cmp one expect
+'
+
+test_expect_success 'tons of blanks at EOF should not apply' '
+	for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+		echo; echo; echo; echo;
+	done >one &&
+	git add one &&
+	echo a >>one &&
+	git diff -- one >patch &&
+
+	>one &&
+	test_must_fail git apply --whitespace=fix patch &&
+	test_must_fail git apply --ignore-space-change --whitespace=fix patch
+'
+
+test_expect_success 'missing blank line at end with --whitespace=fix' '
+	echo a >one &&
+	echo >>one &&
+	git add one &&
+	echo b >>one &&
+	cp one expect &&
+	git diff -- one >patch &&
+	echo a >one &&
+	cp one saved-one &&
+	test_must_fail git apply patch &&
+	git apply --whitespace=fix patch &&
+	test_cmp one expect &&
+	mv saved-one one &&
+	git apply --ignore-space-change --whitespace=fix patch &&
+	test_cmp one expect
+'
+
+test_expect_success 'two missing blank lines at end with --whitespace=fix' '
+	{ echo a; echo; echo b; echo c; } >one &&
+	cp one no-blank-lines &&
+	{ echo; echo; } >>one &&
+	git add one &&
+	echo d >>one &&
+	cp one expect &&
+	echo >>one &&
+	git diff -- one >patch &&
+	cp no-blank-lines one &&
+	test_must_fail git apply patch &&
+	git apply --whitespace=fix patch &&
+	test_cmp one expect &&
+	mv no-blank-lines one &&
+	test_must_fail git apply patch &&
+	git apply --ignore-space-change --whitespace=fix patch &&
+	test_cmp one expect
+'
+
+test_expect_success 'shrink file with tons of missing blanks at end of file' '
+	{ echo a; echo b; echo c; } >one &&
+	cp one no-blank-lines &&
+	for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+		echo; echo; echo; echo;
+	done >>one &&
+	git add one &&
+	echo a >one &&
+	cp one expect &&
+	git diff -- one >patch &&
+	cp no-blank-lines one &&
+	test_must_fail git apply patch &&
+	git apply --whitespace=fix patch &&
+	test_cmp one expect &&
+	mv no-blank-lines one &&
+	git apply --ignore-space-change --whitespace=fix patch &&
+	test_cmp one expect
+'
+
+test_expect_success 'missing blanks at EOF must only match blank lines' '
+	{ echo a; echo b; } >one &&
+	git add one &&
+	{ echo c; echo d; } >>one &&
+	git diff -- one >patch &&
+
+	echo a >one &&
+	test_must_fail git apply patch
+	test_must_fail git apply --whitespace=fix patch &&
+	test_must_fail git apply --ignore-space-change --whitespace=fix patch
+'
+
+sed -e's/Z//' >one <<EOF
+a
+b
+c
+		      Z
+EOF
+
+test_expect_success 'missing blank line should match context line with spaces' '
+	git add one &&
+	echo d >>one &&
+	git diff -- one >patch &&
+	{ echo a; echo b; echo c; } >one &&
+	cp one expect &&
+	{ echo; echo d; } >>expect &&
+	git add one &&
+
+	git apply --whitespace=fix patch &&
+	test_cmp one expect
+'
+
+sed -e's/Z//' >one <<EOF
+a
+b
+c
+		      Z
+EOF
+
+test_expect_success 'same, but with the --ignore-space-option' '
+	git add one &&
+	echo d >>one &&
+	cp one expect &&
+	git diff -- one >patch &&
+	{ echo a; echo b; echo c; } >one &&
+	git add one &&
+
+	git checkout-index -f one &&
+	git apply --ignore-space-change --whitespace=fix patch &&
+	test_cmp one expect
+'
+
+test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
+	git config core.whitespace cr-at-eol &&
+	printf "a\r\n" >one &&
+	printf "b\r\n" >>one &&
+	printf "c\r\n" >>one &&
+	cp one save-one &&
+	printf "                 \r\n" >>one
+	git add one &&
+	printf "d\r\n" >>one &&
+	cp one expect &&
+	git diff -- one >patch &&
+	mv save-one one &&
+
+	git apply --ignore-space-change --whitespace=fix patch &&
+	test_cmp one expect
+'
+
+test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' '
+	git config --unset core.whitespace &&
+	printf "a\r\n" >one &&
+	printf "b\r\n" >>one &&
+	printf "c\r\n" >>one &&
+	cp one save-one &&
+	printf "                 \r\n" >>one
+	git add one &&
+	cp one expect &&
+	printf "d\r\n" >>one &&
+	git diff -- one >patch &&
+	mv save-one one &&
+	echo d >>expect &&
+
+	git apply --ignore-space-change --whitespace=fix patch &&
+	test_cmp one expect
+'
+
 test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index a82c5ff..2692050 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -507,15 +507,15 @@
 	(
 		cd seven &&
 		git remote prune origin
-	) 2>err &&
+	) >err 2>&1 &&
 	grep "has become dangling" err &&
 
-	: And the dangling symref will not cause other annoying errors
+	: And the dangling symref will not cause other annoying errors &&
 	(
 		cd seven &&
 		git branch -a
 	) 2>err &&
-	! grep "points nowhere" err
+	! grep "points nowhere" err &&
 	(
 		cd seven &&
 		test_must_fail git branch nomore origin
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index b0047d3..d24ca5c 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -209,4 +209,13 @@
 	test_cmp expect.gd-short actual.gd-short
 '
 
+test_expect_success 'oneline with empty message' '
+	git commit -m "dummy" --allow-empty &&
+	git commit -m "dummy" --allow-empty &&
+	git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. &&
+	git rev-list --oneline HEAD > /tmp/test.txt &&
+	test $(git rev-list --oneline HEAD | wc -l) -eq 5 &&
+	test $(git rev-list --oneline --graph HEAD | wc -l) -eq 5
+'
+
 test_done
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index 8d8b1c0..582d0b5 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -136,11 +136,11 @@
 	test_cmp expected result
 '
 
-test_expect_failure 'git-apply adds file' false
-test_expect_failure 'git-apply updates file' false
-test_expect_failure 'git-apply removes file' false
-test_expect_failure 'git-mv to skip-worktree' false
-test_expect_failure 'git-mv from skip-worktree' false
-test_expect_failure 'git-checkout' false
+#TODO test_expect_failure 'git-apply adds file' false
+#TODO test_expect_failure 'git-apply updates file' false
+#TODO test_expect_failure 'git-apply removes file' false
+#TODO test_expect_failure 'git-mv to skip-worktree' false
+#TODO test_expect_failure 'git-mv from skip-worktree' false
+#TODO test_expect_failure 'git-checkout' false
 
 test_done
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 19c72f5..1de83ef 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -92,6 +92,15 @@
 	restore_test_defaults
 '
 
+test_expect_success 'difftool --gui works without configured diff.guitool' '
+	git config diff.tool test-tool &&
+
+	diff=$(git difftool --no-prompt --gui branch) &&
+	test "$diff" = "branch" &&
+
+	restore_test_defaults
+'
+
 # Specify the diff tool using $GIT_DIFF_TOOL
 test_expect_success 'GIT_DIFF_TOOL variable' '
 	git config --unset diff.tool
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 356964e..d43f37c 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -150,20 +150,22 @@
 
 	git checkout -f master &&
 	mkdir sub &&
-	cd sub &&
-	git init  &&
-	echo test file > file &&
-	git add file &&
-	git commit -m sub_initial &&
-	cd .. &&
+	(
+		cd sub &&
+		git init  &&
+		echo test file > file &&
+		git add file &&
+		git commit -m sub_initial
+	) &&
 	git submodule add "`pwd`/sub" sub &&
 	git commit -m initial &&
 	test_tick &&
-	cd sub &&
-	echo more data >> file &&
-	git add file &&
-	git commit -m sub_second &&
-	cd .. &&
+	(
+		cd sub &&
+		echo more data >> file &&
+		git add file &&
+		git commit -m sub_second
+	) &&
 	git add sub &&
 	git commit -m second
 
@@ -264,19 +266,20 @@
 
 test_expect_success 'setup for limiting exports by PATH' '
 	mkdir limit-by-paths &&
-	cd limit-by-paths &&
-	git init &&
-	echo hi > there &&
-	git add there &&
-	git commit -m "First file" &&
-	echo foo > bar &&
-	git add bar &&
-	git commit -m "Second file" &&
-	git tag -a -m msg mytag &&
-	echo morefoo >> bar &&
-	git add bar &&
-	git commit -m "Change to second file" &&
-	cd ..
+	(
+		cd limit-by-paths &&
+		git init &&
+		echo hi > there &&
+		git add there &&
+		git commit -m "First file" &&
+		echo foo > bar &&
+		git add bar &&
+		git commit -m "Second file" &&
+		git tag -a -m msg mytag &&
+		echo morefoo >> bar &&
+		git add bar &&
+		git commit -m "Change to second file"
+	)
 '
 
 cat > limit-by-paths/expected << EOF
@@ -297,10 +300,11 @@
 EOF
 
 test_expect_success 'dropping tag of filtered out object' '
+(
 	cd limit-by-paths &&
 	git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
-	test_cmp output expected &&
-	cd ..
+	test_cmp output expected
+)
 '
 
 cat >> limit-by-paths/expected << EOF
@@ -313,10 +317,11 @@
 EOF
 
 test_expect_success 'rewriting tag of filtered out object' '
+(
 	cd limit-by-paths &&
 	git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
-	test_cmp output expected &&
-	cd ..
+	test_cmp output expected
+)
 '
 
 cat > limit-by-paths/expected << EOF
@@ -343,13 +348,13 @@
 EOF
 
 test_expect_failure 'no exact-ref revisions included' '
-	cd limit-by-paths &&
-	git fast-export master~2..master~1 > output &&
-	test_cmp output expected &&
-	cd ..
+	(
+		cd limit-by-paths &&
+		git fast-export master~2..master~1 > output &&
+		test_cmp output expected
+	)
 '
 
-
 test_expect_success 'set-up a few more tags for tag export tests' '
 	git checkout -f master &&
 	HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` &&