Merge branch 'rr/git-uri-doc' into maint

* rr/git-uri-doc:
  Git url doc: mark ftp/ftps as read-only and deprecate them
diff --git a/Documentation/Makefile b/Documentation/Makefile
index cf5916f..267dfe1 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -44,9 +44,10 @@
 man7dir=$(mandir)/man7
 # DESTDIR=
 
-ASCIIDOC=asciidoc
+ASCIIDOC = asciidoc
 ASCIIDOC_EXTRA =
 MANPAGE_XSL = manpage-normal.xsl
+XMLTO = xmlto
 XMLTO_EXTRA =
 INSTALL?=install
 RM ?= rm -f
@@ -245,7 +246,7 @@
 
 %.1 %.5 %.7 : %.xml manpage-base-url.xsl
 	$(QUIET_XMLTO)$(RM) $@ && \
-	xmlto -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
+	$(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
 
 %.xml : %.txt
 	$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
diff --git a/Documentation/RelNotes/1.7.12.3.txt b/Documentation/RelNotes/1.7.12.3.txt
index 8d4f879..ecda427 100644
--- a/Documentation/RelNotes/1.7.12.3.txt
+++ b/Documentation/RelNotes/1.7.12.3.txt
@@ -4,6 +4,18 @@
 Fixes since v1.7.12.2
 ---------------------
 
+ * "git am" mishandled a patch attached as application/octet-stream
+   (e.g. not text/*); Content-Transfer-Encoding (e.g. base64) was not
+   honored correctly.
+
+ * It was unclear in the documentation for "git blame" that it is
+   unnecessary for users to use the "--follow" option.
+
+ * A repository created with "git clone --single" had its fetch
+   refspecs set up just like a clone without "--single", leading the
+   subsequent "git fetch" to slurp all the other branches, defeating
+   the whole point of specifying "only this branch".
+
  * "git fetch" over http had an old workaround for an unlikely server
    misconfiguration; it turns out that this hurts debuggability of the
    configuration in general, and has been reverted.
@@ -12,6 +24,10 @@
    is much less common, and did not advertise the more common "gzip" on
    its Accept-Encoding header.
 
+ * "git receive-pack" (the counterpart to "git push") did not give
+   progress output while processing objects it received to the puser
+   when run over the smart-http protocol.
+
  * "git status" honored the ignore=dirty settings in .gitmodules but
    "git commit" didn't.
 
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 39d326a..b4d6476 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -10,7 +10,8 @@
 --depth=<depth>::
 	Deepen the history of a 'shallow' repository created by
 	`git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
-	by the specified number of commits.
+	to the specified number of commits from the tip of each remote
+	branch history. Tags for the deepened commits are not fetched.
 
 ifndef::git-pull[]
 --dry-run::
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 9c1d395..fd9e36b 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -155,7 +155,7 @@
 The optional configuration variable `core.excludesfile` indicates a path to a
 file containing patterns of file names to exclude from git-add, similar to
 $GIT_DIR/info/exclude.  Patterns in the exclude file are used in addition to
-those in info/exclude.  See linkgit:gitrepository-layout[5].
+those in info/exclude.  See linkgit:gitignore[5].
 
 
 EXAMPLES
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index 7ee9236..e44173f 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -20,6 +20,12 @@
 
 The command can also limit the range of lines annotated.
 
+The origin of lines is automatically followed across whole-file
+renames (currently there is no option to turn the rename-following
+off). To follow lines moved from one file to another, or to follow
+lines that were copied and pasted from another file, etc., see the
+`-C` and `-M` options.
+
 The report does not tell you anything about lines which have been deleted or
 replaced; you need to use a tool such as 'git diff' or the "pickaxe"
 interface briefly mentioned in the following paragraph.
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 47235be..4f44131 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -129,11 +129,13 @@
 	use `git branch --list <pattern>` to list matching branches.
 
 -v::
+-vv::
 --verbose::
 	When in list mode,
 	show sha1 and commit subject line for each head, along with
 	relationship to upstream branch (if any). If given twice, print
-	the name of the upstream branch, as well.
+	the name of the upstream branch, as well (see also `git remote
+	show <remote>`).
 
 -q::
 --quiet::
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 79fb984..9f42c0d 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -63,6 +63,10 @@
 	Remove only files ignored by git.  This may be useful to rebuild
 	everything from scratch, but keep manually created files.
 
+SEE ALSO
+--------
+linkgit:gitignore[5]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index c1ddd4c..6d98ef3 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -29,7 +29,8 @@
 After the clone, a plain `git fetch` without arguments will update
 all the remote-tracking branches, and a `git pull` without
 arguments will in addition merge the remote master branch into the
-current master branch, if any.
+current master branch, if any (this is untrue when "--single-branch"
+is given; see below).
 
 This default configuration is achieved by creating references to
 the remote branch heads under `refs/remotes/origin` and
@@ -152,9 +153,10 @@
 -b <name>::
 	Instead of pointing the newly created HEAD to the branch pointed
 	to by the cloned repository's HEAD, point to `<name>` branch
-	instead. `--branch` can also take tags and treat them like
-	detached HEAD. In a non-bare repository, this is the branch
-	that will be checked out.
+	instead. In a non-bare repository, this is the branch that will
+	be checked out.
+	`--branch` can also take tags and detaches the HEAD at that commit
+	in the resulting repository.
 
 --upload-pack <upload-pack>::
 -u <upload-pack>::
@@ -193,6 +195,11 @@
 	clone with the `--depth` option, this is the default, unless
 	`--no-single-branch` is given to fetch the histories near the
 	tips of all branches.
+	Further fetches into the resulting repository will only update the
+	remote tracking branch for the branch this option was used for the
+	initial cloning.  If the HEAD at the remote did not point at any
+	branch when `--single-branch` clone was made, no remote tracking
+	branch is created.
 
 --recursive::
 --recurse-submodules::
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 48bd04e..d1d227a 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -43,9 +43,10 @@
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.7.12.2/git.html[documentation for release 1.7.12.2]
+* link:v1.7.12.3/git.html[documentation for release 1.7.12.3]
 
 * release notes for
+  link:RelNotes/1.7.12.3.txt[1.7.12.3],
   link:RelNotes/1.7.12.2.txt[1.7.12.2],
   link:RelNotes/1.7.12.1.txt[1.7.12.1],
   link:RelNotes/1.7.12.txt[1.7.12].
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index e16f3e1..52ab93d 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -66,6 +66,11 @@
 global and system-wide files are considered (they have the lowest
 precedence).
 
+When the `.gitattributes` file is missing from the work tree, the
+path in the index is used as a fall-back.  During checkout process,
+`.gitattributes` in the index is used and then the file in the
+working tree is used as a fall-back.
+
 If you wish to affect only a single repository (i.e., to assign
 attributes to files that are particular to
 one user's workflow for that repository), then
@@ -927,7 +932,7 @@
 macro attribute "binary" is equivalent to:
 
 ------------
-[attr]binary -diff -text
+[attr]binary -diff -merge -text
 ------------
 
 
diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt
index f6ba90c..3bc1500 100644
--- a/Documentation/gitcli.txt
+++ b/Documentation/gitcli.txt
@@ -93,7 +93,7 @@
 From the git 1.5.4 series and further, many git commands (not all of them at the
 time of the writing though) come with an enhanced option parser.
 
-Here is an exhaustive list of the facilities provided by this option parser.
+Here is a list of the facilities provided by this option parser.
 
 
 Magic Options
@@ -137,6 +137,16 @@
 `git clean -fdx`.
 
 
+Abbreviating long options
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Commands that support the enhanced option parser accepts unique
+prefix of a long option as if it is fully spelled out, but use this
+with a caution.  For example, `git commit --amen` behaves as if you
+typed `git commit --amend`, but that is true only until a later version
+of Git introduces another option that shares the same prefix,
+e.g `git commit --amenity" option.
+
+
 Separating argument from the option
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 You can write the mandatory option parameter to an option as a separate
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index c1f692a..1b82fe1 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -41,18 +41,24 @@
    variable 'core.excludesfile'.
 
 Which file to place a pattern in depends on how the pattern is meant to
-be used. Patterns which should be version-controlled and distributed to
-other repositories via clone (i.e., files that all developers will want
-to ignore) should go into a `.gitignore` file. Patterns which are
-specific to a particular repository but which do not need to be shared
-with other related repositories (e.g., auxiliary files that live inside
-the repository but are specific to one user's workflow) should go into
-the `$GIT_DIR/info/exclude` file.  Patterns which a user wants git to
-ignore in all situations (e.g., backup or temporary files generated by
-the user's editor of choice) generally go into a file specified by
-`core.excludesfile` in the user's `~/.gitconfig`. Its default value is
-$XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty,
-$HOME/.config/git/ignore is used instead.
+be used.
+
+ * Patterns which should be version-controlled and distributed to
+   other repositories via clone (i.e., files that all developers will want
+   to ignore) should go into a `.gitignore` file.
+
+ * Patterns which are
+   specific to a particular repository but which do not need to be shared
+   with other related repositories (e.g., auxiliary files that live inside
+   the repository but are specific to one user's workflow) should go into
+   the `$GIT_DIR/info/exclude` file.
+
+ * Patterns which a user wants git to
+   ignore in all situations (e.g., backup or temporary files generated by
+   the user's editor of choice) generally go into a file specified by
+   `core.excludesfile` in the user's `~/.gitconfig`. Its default value is
+   $XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or
+   empty, $HOME/.config/git/ignore is used instead.
 
 The underlying git plumbing tools, such as
 'git ls-files' and 'git read-tree', read
@@ -68,11 +74,15 @@
    for readability.
 
  - A line starting with # serves as a comment.
+   Put a backslash ("`\`") in front of the first hash for patterns
+   that begin with a hash.
 
- - An optional prefix '!' which negates the pattern; any
+ - An optional prefix "`!`" which negates the pattern; any
    matching file excluded by a previous pattern will become
    included again.  If a negated pattern matches, this will
    override lower precedence patterns sources.
+   Put a backslash ("`\`") in front of the first "`!`" for patterns
+   that begin with a literal "`!`", for example, "`\!important!.txt`".
 
  - If the pattern ends with a slash, it is removed for the
    purpose of the following description, but it would only find
diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt
index 595a3cf..66db802 100644
--- a/Documentation/merge-strategies.txt
+++ b/Documentation/merge-strategies.txt
@@ -32,13 +32,14 @@
 	This option forces conflicting hunks to be auto-resolved cleanly by
 	favoring 'our' version.  Changes from the other tree that do not
 	conflict with our side are reflected to the merge result.
+	For a binary file, the entire contents are taken from our side.
 +
 This should not be confused with the 'ours' merge strategy, which does not
 even look at what the other tree contains at all.  It discards everything
 the other tree did, declaring 'our' history contains all that happened in it.
 
 theirs;;
-	This is opposite of 'ours'.
+	This is the opposite of 'ours'.
 
 patience;;
 	With this option, 'merge-recursive' spends a little extra time
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index d98481a..ecdbf90 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.12.2
+DEF_VER=v1.7.12.3
 
 LF='
 '
diff --git a/attr.c b/attr.c
index 056d702..887a9ae 100644
--- a/attr.c
+++ b/attr.c
@@ -306,7 +306,7 @@
 }
 
 static const char *builtin_attr[] = {
-	"[attr]binary -diff -text",
+	"[attr]binary -diff -merge -text",
 	NULL,
 };
 
diff --git a/builtin/clone.c b/builtin/clone.c
index e314b0b..0d663e3 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -610,6 +610,54 @@
 	}
 }
 
+static void write_refspec_config(const char* src_ref_prefix,
+		const struct ref* our_head_points_at,
+		const struct ref* remote_head_points_at, struct strbuf* branch_top)
+{
+	struct strbuf key = STRBUF_INIT;
+	struct strbuf value = STRBUF_INIT;
+
+	if (option_mirror || !option_bare) {
+		if (option_single_branch && !option_mirror) {
+			if (option_branch) {
+				if (strstr(our_head_points_at->name, "refs/tags/"))
+					strbuf_addf(&value, "+%s:%s", our_head_points_at->name,
+						our_head_points_at->name);
+				else
+					strbuf_addf(&value, "+%s:%s%s", our_head_points_at->name,
+						branch_top->buf, option_branch);
+			} else if (remote_head_points_at) {
+				strbuf_addf(&value, "+%s:%s%s", remote_head_points_at->name,
+						branch_top->buf,
+						skip_prefix(remote_head_points_at->name, "refs/heads/"));
+			}
+			/*
+			 * otherwise, the next "git fetch" will
+			 * simply fetch from HEAD without updating
+			 * any remote tracking branch, which is what
+			 * we want.
+			 */
+		} else {
+			strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top->buf);
+		}
+		/* Configure the remote */
+		if (value.len) {
+			strbuf_addf(&key, "remote.%s.fetch", option_origin);
+			git_config_set_multivar(key.buf, value.buf, "^$", 0);
+			strbuf_reset(&key);
+
+			if (option_mirror) {
+				strbuf_addf(&key, "remote.%s.mirror", option_origin);
+				git_config_set(key.buf, "true");
+				strbuf_reset(&key);
+			}
+		}
+	}
+
+	strbuf_release(&key);
+	strbuf_release(&value);
+}
+
 int cmd_clone(int argc, const char **argv, const char *prefix)
 {
 	int is_bundle = 0, is_local;
@@ -755,20 +803,6 @@
 	}
 
 	strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
-
-	if (option_mirror || !option_bare) {
-		/* Configure the remote */
-		strbuf_addf(&key, "remote.%s.fetch", option_origin);
-		git_config_set_multivar(key.buf, value.buf, "^$", 0);
-		strbuf_reset(&key);
-
-		if (option_mirror) {
-			strbuf_addf(&key, "remote.%s.mirror", option_origin);
-			git_config_set(key.buf, "true");
-			strbuf_reset(&key);
-		}
-	}
-
 	strbuf_addf(&key, "remote.%s.url", option_origin);
 	git_config_set(key.buf, repo);
 	strbuf_reset(&key);
@@ -853,6 +887,9 @@
 					      "refs/heads/master");
 	}
 
+	write_refspec_config(src_ref_prefix, our_head_points_at,
+			remote_head_points_at, &branch_top);
+
 	if (is_local)
 		clone_local(path, git_dir);
 	else if (refs && complete_refs_before_fetch)
diff --git a/builtin/commit.c b/builtin/commit.c
index 62028e7..7a83cae 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1452,6 +1452,7 @@
 		usage_with_options(builtin_commit_usage, builtin_commit_options);
 
 	wt_status_prepare(&s);
+	gitmodules_config();
 	git_config(git_commit_config, &s);
 	determine_whence(&s);
 	s.colopts = 0;
diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c
index 9973bd9..fe12857 100644
--- a/builtin/mailinfo.c
+++ b/builtin/mailinfo.c
@@ -19,9 +19,6 @@
 static enum  {
 	TE_DONTCARE, TE_QP, TE_BASE64
 } transfer_encoding;
-static enum  {
-	TYPE_TEXT, TYPE_OTHER
-} message_type;
 
 static struct strbuf charset = STRBUF_INIT;
 static int patch_lines;
@@ -184,8 +181,6 @@
 	struct strbuf *boundary = xmalloc(sizeof(struct strbuf));
 	strbuf_init(boundary, line->len);
 
-	if (!strcasestr(line->buf, "text/"))
-		 message_type = TYPE_OTHER;
 	if (slurp_attr(line->buf, "boundary=", boundary)) {
 		strbuf_insert(boundary, 0, "--", 2);
 		if (++content_top > &content[MAX_BOUNDARIES]) {
@@ -681,7 +676,6 @@
 	/* set some defaults */
 	transfer_encoding = TE_DONTCARE;
 	strbuf_reset(&charset);
-	message_type = TYPE_TEXT;
 
 	/* slurp in this section's info */
 	while (read_one_header_line(&line, fin))
@@ -895,11 +889,6 @@
 			strbuf_insert(&line, 0, prev.buf, prev.len);
 			strbuf_reset(&prev);
 
-			/* binary data most likely doesn't have newlines */
-			if (message_type != TYPE_TEXT) {
-				handle_filter(&line);
-				break;
-			}
 			/*
 			 * This is a decoded line that may contain
 			 * multiple new lines.  Pass only one chunk
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 2cb854f..165a633 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -701,7 +701,7 @@
 
 	if (unpacker_error) {
 		for (cmd = commands; cmd; cmd = cmd->next)
-			cmd->error_string = "n/a (unpacker error)";
+			cmd->error_string = "unpacker error";
 		return;
 	}
 
@@ -801,7 +801,7 @@
 
 static const char *pack_lockfile;
 
-static const char *unpack(void)
+static const char *unpack(int err_fd)
 {
 	struct pack_header hdr;
 	const char *hdr_err;
@@ -821,6 +821,7 @@
 
 	if (ntohl(hdr.hdr_entries) < unpack_limit) {
 		int code, i = 0;
+		struct child_process child;
 		const char *unpacker[5];
 		unpacker[i++] = "unpack-objects";
 		if (quiet)
@@ -829,7 +830,12 @@
 			unpacker[i++] = "--strict";
 		unpacker[i++] = hdr_arg;
 		unpacker[i++] = NULL;
-		code = run_command_v_opt(unpacker, RUN_GIT_CMD);
+		memset(&child, 0, sizeof(child));
+		child.argv = unpacker;
+		child.no_stdout = 1;
+		child.err = err_fd;
+		child.git_cmd = 1;
+		code = run_command(&child);
 		if (!code)
 			return NULL;
 		return "unpack-objects abnormal exit";
@@ -854,6 +860,7 @@
 		memset(&ip, 0, sizeof(ip));
 		ip.argv = keeper;
 		ip.out = -1;
+		ip.err = err_fd;
 		ip.git_cmd = 1;
 		status = start_command(&ip);
 		if (status) {
@@ -870,6 +877,26 @@
 	}
 }
 
+static const char *unpack_with_sideband(void)
+{
+	struct async muxer;
+	const char *ret;
+
+	if (!use_sideband)
+		return unpack(0);
+
+	memset(&muxer, 0, sizeof(muxer));
+	muxer.proc = copy_to_sideband;
+	muxer.in = -1;
+	if (start_async(&muxer))
+		return NULL;
+
+	ret = unpack(muxer.in);
+
+	finish_async(&muxer);
+	return ret;
+}
+
 static void report(struct command *commands, const char *unpack_status)
 {
 	struct command *cmd;
@@ -967,7 +994,7 @@
 		const char *unpack_status = NULL;
 
 		if (!delete_only(commands))
-			unpack_status = unpack();
+			unpack_status = unpack_with_sideband();
 		execute_commands(commands, unpack_status);
 		if (pack_lockfile)
 			unlink_or_warn(pack_lockfile);
diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index 01af9df..b2171a0 100755
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -403,7 +403,7 @@
 			echo "            \\"
 			echo "             O -- O -- O ($oldrev)"
 			echo ""
-			echo "The removed revisions are not necessarilly gone - if another reference"
+			echo "The removed revisions are not necessarily gone - if another reference"
 			echo "still refers to them they will stay in the repository."
 			rewind_only=1
 		else
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 7f8c187..10ed9e5 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -8028,7 +8028,7 @@
 		%latest_commit = %{$commitlist[0]};
 		my $latest_epoch = $latest_commit{'committer_epoch'};
 		exit_if_unmodified_since($latest_epoch);
-		%latest_date = parse_date($latest_epoch, $latest_commit{'comitter_tz'});
+		%latest_date = parse_date($latest_epoch, $latest_commit{'committer_tz'});
 	}
 	print $cgi->header(
 		-type => $content_type,
diff --git a/ll-merge.c b/ll-merge.c
index f3f7692..acea33b 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -35,7 +35,7 @@
  */
 static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
 			   mmbuffer_t *result,
-			   const char *path_unused,
+			   const char *path,
 			   mmfile_t *orig, const char *orig_name,
 			   mmfile_t *src1, const char *name1,
 			   mmfile_t *src2, const char *name2,
@@ -46,16 +46,34 @@
 	assert(opts);
 
 	/*
-	 * The tentative merge result is "ours" for the final round,
-	 * or common ancestor for an internal merge.  Still return
-	 * "conflicted merge" status.
+	 * The tentative merge result is the or common ancestor for an internal merge.
 	 */
-	stolen = opts->virtual_ancestor ? orig : src1;
+	if (opts->virtual_ancestor) {
+		stolen = orig;
+	} else {
+		switch (opts->variant) {
+		default:
+			warning("Cannot merge binary files: %s (%s vs. %s)",
+				path, name1, name2);
+			/* fallthru */
+		case XDL_MERGE_FAVOR_OURS:
+			stolen = src1;
+			break;
+		case XDL_MERGE_FAVOR_THEIRS:
+			stolen = src2;
+			break;
+		}
+	}
 
 	result->ptr = stolen->ptr;
 	result->size = stolen->size;
 	stolen->ptr = NULL;
-	return 1;
+
+	/*
+	 * With -Xtheirs or -Xours, we have cleanly merged;
+	 * otherwise we got a conflict.
+	 */
+	return (opts->variant ? 0 : 1);
 }
 
 static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
@@ -73,8 +91,6 @@
 	if (buffer_is_binary(orig->ptr, orig->size) ||
 	    buffer_is_binary(src1->ptr, src1->size) ||
 	    buffer_is_binary(src2->ptr, src2->size)) {
-		warning("Cannot merge binary files: %s (%s vs. %s)",
-			path, name1, name2);
 		return ll_binary_merge(drv_unused, result,
 				       path,
 				       orig, orig_name,
diff --git a/po/de.po b/po/de.po
index a3cf695..9e9f2da 100644
--- a/po/de.po
+++ b/po/de.po
@@ -55,7 +55,7 @@
 
 #: bundle.c:140
 msgid "Repository lacks these prerequisite commits:"
-msgstr "Dem Projektarchiv fehlen folgende vorrausgesetzte Versionen:"
+msgstr "Dem Projektarchiv fehlen folgende vorausgesetzte Versionen:"
 
 #: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
 #: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
@@ -1758,7 +1758,7 @@
 #: builtin/apply.c:4291
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr ""
-"entfernt <Anzahl> vorrangestellte Schrägstriche von herkömmlichen "
+"entfernt <Anzahl> vorangestellte Schrägstriche von herkömmlichen "
 "Differenzpfaden"
 
 #: builtin/apply.c:4294
@@ -2065,7 +2065,7 @@
 #: builtin/branch.c:613
 msgid "cannot rename the current branch while not on any."
 msgstr ""
-"Kann aktuellen Zweig nicht umbennen, solange du dich auf keinem befindest."
+"Kann aktuellen Zweig nicht umbenennen, solange du dich auf keinem befindest."
 
 #: builtin/branch.c:623
 #, c-format
@@ -2353,7 +2353,7 @@
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
-"git checkout: --ours/--theirs, --force and --merge sind inkompatibel wenn\n"
+"git checkout: --ours/--theirs, --force und --merge sind inkompatibel wenn\n"
 "du aus der Bereitstellung auscheckst."
 
 #: builtin/checkout.c:1093
@@ -3666,7 +3666,7 @@
 #: builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
-msgstr "Konnte git-Verknüfung %s nicht erstellen"
+msgstr "Konnte git-Verknüpfung %s nicht erstellen"
 
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
@@ -3778,11 +3778,11 @@
 
 #: builtin/log.c:1205
 msgid "-n and -k are mutually exclusive."
-msgstr "-n und -k schliessen sich gegenseitig aus"
+msgstr "-n und -k schließen sich gegenseitig aus"
 
 #: builtin/log.c:1207
 msgid "--subject-prefix and -k are mutually exclusive."
-msgstr "--subject-prefix und -k schliessen sich gegenseitig aus"
+msgstr "--subject-prefix und -k schließen sich gegenseitig aus"
 
 #: builtin/log.c:1215
 msgid "--name-only does not make sense"
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index ccb5435..741b6b6 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -18,16 +18,6 @@
 modification *should* take notice and update the test vectors here.
 '
 
-################################################################
-# It appears that people try to run tests without building...
-
-../git >/dev/null
-if test $? != 1
-then
-	echo >&2 'You do not seem to have built git yet.'
-	exit 1
-fi
-
 . ./test-lib.sh
 
 ################################################################
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index bf7a2cd..08aa24c 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -177,9 +177,7 @@
 	test_when_finished "remove_object $tag" &&
 	echo $tag >.git/refs/tags/wrong &&
 	test_when_finished "git update-ref -d refs/tags/wrong" &&
-	test_must_fail git fsck --tags 2>out &&
-	cat out &&
-	grep "error in tag.*broken links" out
+	test_must_fail git fsck --tags
 '
 
 test_expect_success 'cleaned up' '
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 250c720..418f515 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -159,7 +159,7 @@
 	    git commit -a -m "Second commit" &&
 	    git repack
 	) &&
-	cp -a parent child &&
+	cp -R parent child &&
 	(
 	    # Set the child to auto-pack if more than one pack exists
 	    cd child &&
diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh
index 35ec294..69ee13c 100755
--- a/t/t5504-fetch-receive-strict.sh
+++ b/t/t5504-fetch-receive-strict.sh
@@ -89,7 +89,7 @@
 
 cat >exp <<EOF
 To dst
-!	refs/heads/master:refs/heads/test	[remote rejected] (n/a (unpacker error))
+!	refs/heads/master:refs/heads/test	[remote rejected] (unpacker error)
 EOF
 
 test_expect_success 'push with receive.fsckobjects' '
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
index 16ef041..80d20c8 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch.sh
@@ -22,7 +22,7 @@
 '
 
 test_expect_success 'create http-accessible bare repository with loose objects' '
-	cp -a .git "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+	cp -R .git "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
 	(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
 	 git config core.bare true &&
 	 mkdir -p hooks &&
diff --git a/t/t5709-clone-refspec.sh b/t/t5709-clone-refspec.sh
new file mode 100755
index 0000000..6f1ea98
--- /dev/null
+++ b/t/t5709-clone-refspec.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+test_description='test refspec written by clone-command'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	# Make two branches, "master" and "side"
+	echo one >file &&
+	git add file &&
+	git commit -m one &&
+	echo two >file &&
+	git commit -a -m two &&
+	git tag two &&
+	echo three >file &&
+	git commit -a -m three &&
+	git checkout -b side &&
+	echo four >file &&
+	git commit -a -m four &&
+	git checkout master &&
+
+	# default clone
+	git clone . dir_all &&
+
+	# default --single that follows HEAD=master
+	git clone --single-branch . dir_master &&
+
+	# default --single that follows HEAD=side
+	git checkout side &&
+	git clone --single-branch . dir_side &&
+
+	# explicit --single that follows side
+	git checkout master &&
+	git clone --single-branch --branch side . dir_side2 &&
+
+	# default --single with --mirror
+	git clone --single-branch --mirror . dir_mirror &&
+
+	# default --single with --branch and --mirror
+	git clone --single-branch --mirror --branch side . dir_mirror_side &&
+
+	# --single that does not know what branch to follow
+	git checkout two^ &&
+	git clone --single-branch . dir_detached &&
+
+	# explicit --single with tag
+	git clone --single-branch --branch two . dir_tag &&
+
+	# advance both "master" and "side" branches
+	git checkout side &&
+	echo five >file &&
+	git commit -a -m five &&
+	git checkout master &&
+	echo six >file &&
+	git commit -a -m six &&
+
+	# update tag
+	git tag -d two && git tag two
+'
+
+test_expect_success 'by default all branches will be kept updated' '
+	(
+		cd dir_all && git fetch &&
+		git for-each-ref refs/remotes/origin |
+		sed -e "/HEAD$/d" \
+		    -e "s|/remotes/origin/|/heads/|" >../actual
+	) &&
+	# follow both master and side
+	git for-each-ref refs/heads >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'by default no tags will be kept updated' '
+	(
+		cd dir_all && git fetch &&
+		git for-each-ref refs/tags >../actual
+	) &&
+	git for-each-ref refs/tags >expect &&
+	test_must_fail test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at master' '
+	(
+		cd dir_master && git fetch &&
+		git for-each-ref refs/remotes/origin |
+		sed -e "/HEAD$/d" \
+		    -e "s|/remotes/origin/|/heads/|" >../actual
+	) &&
+	# only follow master
+	git for-each-ref refs/heads/master >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at side' '
+	(
+		cd dir_side && git fetch &&
+		git for-each-ref refs/remotes/origin |
+		sed -e "/HEAD$/d" \
+		    -e "s|/remotes/origin/|/heads/|" >../actual
+	) &&
+	# only follow side
+	git for-each-ref refs/heads/side >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch side' '
+	(
+		cd dir_side2 && git fetch &&
+		git for-each-ref refs/remotes/origin |
+		sed -e "/HEAD$/d" \
+		    -e "s|/remotes/origin/|/heads/|" >../actual
+	) &&
+	# only follow side
+	git for-each-ref refs/heads/side >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch with tag fetches updated tag' '
+	(
+		cd dir_tag && git fetch &&
+		git for-each-ref refs/tags >../actual
+	) &&
+	git for-each-ref refs/tags >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--single-branch with --mirror' '
+	(
+		cd dir_mirror && git fetch &&
+		git for-each-ref refs > ../actual
+	) &&
+	git for-each-ref refs >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch and --mirror' '
+	(
+		cd dir_mirror_side && git fetch &&
+		git for-each-ref refs > ../actual
+	) &&
+	git for-each-ref refs >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--single-branch with detached' '
+	(
+		cd dir_detached && git fetch &&
+		git for-each-ref refs/remotes/origin |
+		sed -e "/HEAD$/d" \
+		    -e "s|/remotes/origin/|/heads/|" >../actual
+	)
+	# nothing
+	>expect &&
+	test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-helpers.sh
index 5702334..e7dc668 100755
--- a/t/t5800-remote-helpers.sh
+++ b/t/t5800-remote-helpers.sh
@@ -76,7 +76,7 @@
 # git-remote-testgit, but is too slow to leave in for general use.
 : test_expect_success 'racily pushing to local repo' '
 	test_when_finished "rm -rf server2 localclone2" &&
-	cp -a server server2 &&
+	cp -R server server2 &&
 	git clone "testgit::${PWD}/server2" localclone2 &&
 	(cd localclone2 &&
 	echo content >>file &&
diff --git a/t/t6037-merge-ours-theirs.sh b/t/t6037-merge-ours-theirs.sh
index 2cf42c7..3889eca 100755
--- a/t/t6037-merge-ours-theirs.sh
+++ b/t/t6037-merge-ours-theirs.sh
@@ -53,7 +53,19 @@
 	! grep 1 file
 '
 
-test_expect_success 'pull with -X' '
+test_expect_success 'binary file with -Xours/-Xtheirs' '
+	echo file binary >.gitattributes &&
+
+	git reset --hard master &&
+	git merge -s recursive -X theirs side &&
+	git diff --exit-code side HEAD -- file &&
+
+	git reset --hard master &&
+	git merge -s recursive -X ours side &&
+	git diff --exit-code master HEAD -- file
+'
+
+test_expect_success 'pull passes -X to underlying merge' '
 	git reset --hard master && git pull -s recursive -Xours . side &&
 	git reset --hard master && git pull -s recursive -X ours . side &&
 	git reset --hard master && git pull -s recursive -Xtheirs . side &&
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 78c4286..b8ee348 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -15,22 +15,6 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see http://www.gnu.org/licenses/ .
 
-# if --tee was passed, write the output not only to the terminal, but
-# additionally to the file test-results/$BASENAME.out, too.
-case "$GIT_TEST_TEE_STARTED, $* " in
-done,*)
-	# do not redirect again
-	;;
-*' --tee '*|*' --va'*)
-	mkdir -p test-results
-	BASE=test-results/$(basename "$0" .sh)
-	(GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
-	 echo $? > $BASE.exit) | tee $BASE.out
-	test "$(cat $BASE.exit)" = 0
-	exit
-	;;
-esac
-
 # Keep the original TERM for say_color
 ORIGINAL_TERM=$TERM
 
@@ -51,9 +35,34 @@
 fi
 GIT_BUILD_DIR="$TEST_DIRECTORY"/..
 
+################################################################
+# It appears that people try to run tests without building...
+"$GIT_BUILD_DIR/git" >/dev/null
+if test $? != 1
+then
+	echo >&2 'error: you do not seem to have built git yet.'
+	exit 1
+fi
+
 . "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
 export PERL_PATH SHELL_PATH
 
+# if --tee was passed, write the output not only to the terminal, but
+# additionally to the file test-results/$BASENAME.out, too.
+case "$GIT_TEST_TEE_STARTED, $* " in
+done,*)
+	# do not redirect again
+	;;
+*' --tee '*|*' --va'*)
+	mkdir -p test-results
+	BASE=test-results/$(basename "$0" .sh)
+	(GIT_TEST_TEE_STARTED=done ${SHELL_PATH} "$0" "$@" 2>&1;
+	 echo $? > $BASE.exit) | tee $BASE.out
+	test "$(cat $BASE.exit)" = 0
+	exit
+	;;
+esac
+
 # For repeatability, reset the environment to known value.
 LANG=C
 LC_ALL=C