Merge branch 'lt/fix-apply' into maint

* lt/fix-apply:
  git-am: --whitespace=x option.
  git-apply: war on whitespace -- finishing touches.
  git-apply --whitespace=nowarn
  apply --whitespace: configuration option.
  apply: squelch excessive errors and --whitespace=error-all
  apply --whitespace fixes and enhancements.
  The war on trailing whitespace
diff --git a/combine-diff.c b/combine-diff.c
index d812600..a23894d 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -621,7 +621,8 @@
 }
 
 static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
-			   int dense, const char *header)
+			   int dense, const char *header,
+			   struct diff_options *opt)
 {
 	unsigned long size, cnt, lno;
 	char *result, *cp, *ep;
@@ -631,6 +632,7 @@
 	char ourtmp_buf[TMPPATHLEN];
 	char *ourtmp = ourtmp_buf;
 	int working_tree_file = !memcmp(elem->sha1, null_sha1, 20);
+	int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV;
 
 	/* Read the result of merge first */
 	if (!working_tree_file) {
@@ -724,7 +726,7 @@
 
 		if (header) {
 			shown_header++;
-			puts(header);
+			printf("%s%c", header, opt->line_termination);
 		}
 		printf("diff --%s ", dense ? "cc" : "combined");
 		if (quote_c_style(elem->path, NULL, NULL, 0))
@@ -735,10 +737,10 @@
 		printf("index ");
 		for (i = 0; i < num_parent; i++) {
 			abb = find_unique_abbrev(elem->parent[i].sha1,
-						 DEFAULT_ABBREV);
+						 abbrev);
 			printf("%s%s", i ? "," : "", abb);
 		}
-		abb = find_unique_abbrev(elem->sha1, DEFAULT_ABBREV);
+		abb = find_unique_abbrev(elem->sha1, abbrev);
 		printf("..%s\n", abb);
 
 		if (mode_differs) {
@@ -797,7 +799,7 @@
 		inter_name_termination = 0;
 
 	if (header)
-		puts(header);
+		printf("%s%c", header, line_termination);
 
 	for (i = 0; i < num_parent; i++) {
 		if (p->parent[i].mode)
@@ -862,7 +864,7 @@
 
 	default:
 	case DIFF_FORMAT_PATCH:
-		return show_patch_diff(p, num_parent, dense, header);
+		return show_patch_diff(p, num_parent, dense, header, opt);
 	}
 }
 
diff --git a/diffcore-break.c b/diffcore-break.c
index c57513a..95b5eb4 100644
--- a/diffcore-break.c
+++ b/diffcore-break.c
@@ -58,6 +58,10 @@
 	if (!S_ISREG(src->mode) || !S_ISREG(dst->mode))
 		return 0; /* leave symlink rename alone */
 
+	if (src->sha1_valid && dst->sha1_valid &&
+	    !memcmp(src->sha1, dst->sha1, 20))
+		return 0; /* they are the same */
+
 	if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
 		return 0; /* error but caught downstream */
 
diff --git a/git-mv.perl b/git-mv.perl
index 83dc7e4..f3e859a 100755
--- a/git-mv.perl
+++ b/git-mv.perl
@@ -19,25 +19,26 @@
 	exit(1);
 }
 
-my $GIT_DIR = `git rev-parse --git-dir`;
-exit 1 if $?; # rev-parse would have given "not a git dir" message.
-chomp($GIT_DIR);
-
 our ($opt_n, $opt_f, $opt_h, $opt_k, $opt_v);
 getopts("hnfkv") || usage;
 usage() if $opt_h;
 @ARGV >= 1 or usage;
 
+my $GIT_DIR = `git rev-parse --git-dir`;
+exit 1 if $?; # rev-parse would have given "not a git dir" message.
+chomp($GIT_DIR);
+
 my (@srcArgs, @dstArgs, @srcs, @dsts);
 my ($src, $dst, $base, $dstDir);
 
+# remove any trailing slash in arguments
+for (@ARGV) { s/\/*$//; }
+
 my $argCount = scalar @ARGV;
 if (-d $ARGV[$argCount-1]) {
 	$dstDir = $ARGV[$argCount-1];
-	# remove any trailing slash
-	$dstDir =~ s/\/$//;
 	@srcArgs = @ARGV[0..$argCount-2];
-	
+
 	foreach $src (@srcArgs) {
 		$base = $src;
 		$base =~ s/^.*\///;
@@ -46,10 +47,14 @@
 	}
 }
 else {
-    if ($argCount != 2) {
+    if ($argCount < 2) {
+	print "Error: need at least two arguments\n";
+	exit(1);
+    }
+    if ($argCount > 2) {
 	print "Error: moving to directory '"
 	    . $ARGV[$argCount-1]
-	    . "' not possible; not exisiting\n";
+	    . "' not possible; not existing\n";
 	exit(1);
     }
     @srcArgs = ($ARGV[0]);
@@ -57,6 +62,16 @@
     $dstDir = "";
 }
 
+# normalize paths, needed to compare against versioned files and update-index
+# also, this is nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c"
+for (@srcArgs, @dstArgs) {
+    s|^\./||;
+    s|/\./|/| while (m|/\./|);
+    s|//+|/|g;
+    # Also "a/b/../c" ==> "a/c"
+    1 while (s,(^|/)[^/]+/\.\./,$1,);
+}
+
 my (@allfiles,@srcfiles,@dstfiles);
 my $safesrc;
 my (%overwritten, %srcForDst);