[GSoC][PATCH v7 26/26] stash: replace all "git apply" child processes with API calls

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



`apply_all_patches()` does not provide a method to apply patches
from strbuf. Because of this, this commit introduces a new
function `apply_patch_from_buf()` which applies a patch from buf.
It works by saving the strbuf as a file. This way we can call
`apply_all_patches()`. Before returning, the created file is
removed.
---
 builtin/stash.c | 61 +++++++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/builtin/stash.c b/builtin/stash.c
index 46e76a34e..74eda822c 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -13,6 +13,7 @@
 #include "revision.h"
 #include "log-tree.h"
 #include "diffcore.h"
+#include "apply.h"
 
 static const char * const git_stash_usage[] = {
 	N_("git stash list [<options>]"),
@@ -277,10 +278,6 @@ static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
 	struct child_process cp = CHILD_PROCESS_INIT;
 	const char *w_commit_hex = oid_to_hex(w_commit);
 
-	/*
-	 * Diff-tree would not be very hard to replace with a native function,
-	 * however it should be done together with apply_cached.
-	 */
 	cp.git_cmd = 1;
 	argv_array_pushl(&cp.args, "diff-tree", "--binary", NULL);
 	argv_array_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex);
@@ -288,18 +285,36 @@ static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
 	return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
 }
 
-static int apply_cached(struct strbuf *out)
+static int apply_patch_from_buf(struct strbuf *patch, int cached, int reverse,
+				int check_index)
 {
-	struct child_process cp = CHILD_PROCESS_INIT;
+	int ret = 0;
+	struct apply_state state;
+	struct argv_array args = ARGV_ARRAY_INIT;
+	const char *patch_path = ".git/stash_patch.patch";
+	FILE *patch_file;
 
-	/*
-	 * Apply currently only reads either from stdin or a file, thus
-	 * apply_all_patches would have to be updated to optionally take a
-	 * buffer.
-	 */
-	cp.git_cmd = 1;
-	argv_array_pushl(&cp.args, "apply", "--cached", NULL);
-	return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
+	if (init_apply_state(&state, NULL))
+		return -1;
+
+	state.cached = cached;
+	state.apply_in_reverse = reverse;
+	state.check_index = check_index;
+	if (state.cached)
+		state.check_index = 1;
+	if (state.check_index)
+		state.unsafe_paths = 0;
+
+	patch_file = fopen(patch_path, "w");
+	strbuf_write(patch, patch_file);
+	fclose(patch_file);
+
+	argv_array_push(&args, patch_path);
+	ret = apply_all_patches(&state, args.argc, args.argv, 0);
+
+	remove_path(patch_path);
+	clear_apply_state(&state);
+	return ret;
 }
 
 static int reset_head(const char *prefix)
@@ -418,7 +433,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
 				return -1;
 			}
 
-			ret = apply_cached(&out);
+			ret = apply_patch_from_buf(&out, 1, 0, 0);
 			strbuf_release(&out);
 			if (ret)
 				return -1;
@@ -1341,7 +1356,6 @@ static int do_push_stash(int argc, const char **argv, const char *prefix,
 			int i;
 			struct child_process cp1 = CHILD_PROCESS_INIT;
 			struct child_process cp2 = CHILD_PROCESS_INIT;
-			struct child_process cp3 = CHILD_PROCESS_INIT;
 			struct strbuf out = STRBUF_INIT;
 
 			cp1.git_cmd = 1;
@@ -1365,11 +1379,9 @@ static int do_push_stash(int argc, const char **argv, const char *prefix,
 			if (pipe_command(&cp2, NULL, 0, &out, 0, NULL, 0))
 				return -1;
 
-			cp3.git_cmd = 1;
-			argv_array_pushl(&cp3.args, "apply", "--index", "-R",
-					 NULL);
-			if (pipe_command(&cp3, out.buf, out.len, NULL, 0, NULL,
-					 0))
+			discard_cache();
+			read_cache();
+			if (apply_patch_from_buf(&out, 0, 1, 1))
 				return -1;
 		} else {
 			struct child_process cp = CHILD_PROCESS_INIT;
@@ -1405,12 +1417,7 @@ static int do_push_stash(int argc, const char **argv, const char *prefix,
 				return -1;
 		}
 	} else {
-		struct child_process cp = CHILD_PROCESS_INIT;
-
-		cp.git_cmd = 1;
-		argv_array_pushl(&cp.args, "apply", "-R", NULL);
-
-		if (pipe_command(&cp, patch.buf, patch.len, NULL, 0, NULL, 0)) {
+		if (apply_patch_from_buf(&patch, 0, 1, 0)) {
 			if (!quiet)
 				fprintf_ln(stderr, "Cannot remove worktree changes");
 			return -1;
-- 
2.18.0.573.g56500d98f




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux