Subject: [PATCH 15/17] write-tree: requires --narrow-base in narrow repository

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Sun, 5 Sep 2010 16:47:42 +1000

Without a base, a full tree cannot be generated, because the index
does not contain all trees.

--narrow-base is ignored if the repository is not a narrow one.

git-am is modified to "test" write-tree, which makes git-rebase works
in simple cases.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 builtin/write-tree.c |   25 +++++++++++++++++++++++++
 git-am.sh            |    2 +-
 2 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/builtin/write-tree.c b/builtin/write-tree.c
index b223af4..5da3cb3 100644
--- a/builtin/write-tree.c
+++ b/builtin/write-tree.c
@@ -8,6 +8,7 @@
 #include "tree.h"
 #include "cache-tree.h"
 #include "parse-options.h"
+#include "narrow-tree.h"
 
 static const char * const write_tree_usage[] = {
 	"git write-tree [--missing-ok] [--prefix=<prefix>/]",
@@ -18,6 +19,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 {
 	int flags = 0, ret;
 	const char *prefix = NULL;
+	const char *narrow_str = NULL;
 	unsigned char sha1[20];
 	const char *me = "git-write-tree";
 	struct option write_tree_options[] = {
@@ -26,6 +28,9 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 		{ OPTION_STRING, 0, "prefix", &prefix, "<prefix>/",
 		  "write tree object for a subdirectory <prefix>" ,
 		  PARSE_OPT_LITERAL_ARGHELP },
+		{ OPTION_STRING, 0, "narrow-base", &narrow_str, "base tree",
+		  "base tree in narrow index" ,
+		  PARSE_OPT_LITERAL_ARGHELP },
 		{ OPTION_BIT, 0, "ignore-cache-tree", &flags, NULL,
 		  "only useful for debugging",
 		  PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, NULL,
@@ -40,6 +45,26 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 	ret = write_cache_as_tree(sha1, flags, prefix);
 	switch (ret) {
 	case 0:
+		if (get_narrow_prefix()) {
+			unsigned char sha1_param[20];
+			unsigned char narrow_base[20];
+			unsigned char old_sha1[20];
+			unsigned long size;
+			void *buf;
+
+			if (!narrow_str)
+				die("write-tree in narrow repo requires --narrow-base");
+
+			if (get_sha1(narrow_str, sha1_param))
+				die("Invalid SHA1 %s", narrow_str);
+			buf = read_object_with_reference(sha1_param, tree_type, &size, narrow_base);
+			if (!buf)
+				die("Bad treeish %s", sha1_to_hex(sha1));
+			free(buf);
+			hashcpy(old_sha1, sha1);
+			if (join_narrow_tree(sha1, narrow_base, old_sha1, get_narrow_prefix()))
+				die("Failed to join tree");
+		}
 		printf("%s\n", sha1_to_hex(sha1));
 		break;
 	case WRITE_TREE_UNREADABLE_INDEX:
diff --git a/git-am.sh b/git-am.sh
index e7f008c..6adda43 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -783,7 +783,7 @@ do
 		"$GIT_DIR"/hooks/pre-applypatch || stop_here $this
 	fi
 
-	tree=$(git write-tree) &&
+	tree=$(git write-tree --narrow-base=HEAD) &&
 	commit=$(
 		if test -n "$ignore_date"
 		then
-- 
1.7.1.rc1.69.g24c2f7