Teach "git apply" to prepend a prefix with "--root=<root>"

With "git apply --root=<root>", all file names in the patch are prepended
with <root>.  If a "-p" value was given, the paths are stripped _before_
prepending <root>.

Wished for by HPA.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff --git a/builtin-apply.c b/builtin-apply.c
index c497889..bf52896 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -57,6 +57,8 @@
 static int squelch_whitespace_errors = 5;
 static int applied_after_fixing_ws;
 static const char *patch_input_file;
+static const char *root;
+static int root_len;
 
 static void parse_whitespace_option(const char *option)
 {
@@ -331,6 +333,8 @@
 				 */
 				strbuf_remove(&name, 0, cp - name.buf);
 				free(def);
+				if (root)
+					strbuf_insert(&name, 0, root, root_len);
 				return strbuf_detach(&name, NULL);
 			}
 		}
@@ -369,6 +373,14 @@
 		free(def);
 	}
 
+	if (root) {
+		char *ret = xmalloc(root_len + len + 1);
+		strcpy(ret, root);
+		memcpy(ret + root_len, start, len);
+		ret[root_len + len] = '\0';
+		return ret;
+	}
+
 	return xmemdupz(start, len);
 }
 
@@ -3118,6 +3130,18 @@
 			inaccurate_eof = 1;
 			continue;
 		}
+		if (!strncmp(arg, "--root=", strlen("--root="))) {
+			arg += strlen("--root=");
+			root_len = strlen(arg);
+			if (root_len && arg[root_len + 1] != '/') {
+				char *new_root;
+				root = new_root = xmalloc(root_len + 2);
+				strcpy(new_root, arg);
+				strcpy(new_root + root_len++, "/");
+			} else
+				root = arg;
+			continue;
+		}
 		if (0 < prefix_length)
 			arg = prefix_filename(prefix, prefix_length, arg);