Thread (2 messages) flat view 2 messages, 2 authors, 2016-06-15
DORMANTno replies

[PATCH 1/8] git-apply: work from subdirectory.

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:13
Subsystem: the rest · Maintainer: Linus Torvalds

Possibly related (same subject, not in this thread)

This adds three things:

 - prefix_filename() is like prefix_path() but can be used to
   name any file on the filesystem, not the files that might go
   into the index file.

 - git-apply uses setup_git_directory() to find out the GIT_DIR
   and reads configuration file.  Later this would allow us to
   affect the behaviour of the command from the configuration.

 - When git-apply is run from a subdirectory, it applies the
   given patch only to the files under the current directory and
   below.

Signed-off-by: Junio C Hamano <redacted>

---

 apply.c |   15 +++++++++++++++
 cache.h |    1 +
 setup.c |   15 +++++++++++++++
 3 files changed, 31 insertions(+), 0 deletions(-)

applies-to: 9ccf8849fa9b522a344645c2f28f12ab036e30d5
c20b8d006edfa964b3df5e4c5cc28cb93edcb240
diff --git a/apply.c b/apply.c
index 50be8f3..ae06d41 100644
--- a/apply.c
+++ b/apply.c
@@ -16,6 +16,9 @@
 //  --numstat does numeric diffstat, and doesn't actually apply
 //  --index-info shows the old and new index info for paths if available.
 //
+static const char *prefix;
+static int prefix_length;
+
 static int allow_binary_replacement = 0;
 static int check_index = 0;
 static int write_index = 0;
@@ -1706,6 +1709,12 @@ static int use_patch(struct patch *p)
 			return 0;
 		x = x->next;
 	}
+	if (prefix && *prefix) {
+		int pathlen = strlen(pathname);
+		if (pathlen <= prefix_length ||
+		    memcmp(prefix, pathname, prefix_length))
+			return 0;
+	}
 	return 1;
 }
 
@@ -1784,6 +1793,10 @@ int main(int argc, char **argv)
 	int i;
 	int read_stdin = 1;
 
+	prefix = setup_git_directory();
+	prefix_length = prefix ? strlen(prefix) : 0;
+	git_config(git_default_config);
+
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 		int fd;
@@ -1845,6 +1858,8 @@ int main(int argc, char **argv)
 			line_termination = 0;
 			continue;
 		}
+		arg = prefix_filename(prefix, prefix_length, arg);
+
 		fd = open(arg, O_RDONLY);
 		if (fd < 0)
 			usage(apply_usage);
diff --git a/cache.h b/cache.h
index 6ac94c5..62920ce 100644
--- a/cache.h
+++ b/cache.h
@@ -149,6 +149,7 @@ extern char *get_graft_file(void);
 extern const char **get_pathspec(const char *prefix, const char **pathspec);
 extern const char *setup_git_directory(void);
 extern const char *prefix_path(const char *prefix, int len, const char *path);
+extern const char *prefix_filename(const char *prefix, int len, const char *path);
 
 #define alloc_nr(x) (((x)+16)*3/2)
 
diff --git a/setup.c b/setup.c
index ab3c778..54f6a34 100644
--- a/setup.c
+++ b/setup.c
@@ -47,6 +47,21 @@ const char *prefix_path(const char *pref
 	return path;
 }
 
+/* 
+ * Unlike prefix_path, this should be used if the named file does
+ * not have to interact with index entry; i.e. name of a random file
+ * on the filesystem.
+ */
+const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
+{
+	static char path[PATH_MAX];
+	if (!pfx || !*pfx || arg[0] == '/')
+		return arg;
+	memcpy(path, pfx, pfx_len);
+	strcpy(path + pfx_len, arg);
+	return path;
+}
+
 const char **get_pathspec(const char *prefix, const char **pathspec)
 {
 	const char *entry = *pathspec;
---
0.99.9.GIT
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help