[PATCH 20/32] narrow-tree: add join_narrow_tree to do tree fixup for commits

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

 



As stated somewhere, the index in narrow repo is also narrowed. When a
users are done with his changes and about to commit, the new narrow
tree created from index will be grafted back to a base toplevel tree
(usually from parent commit). The result is a new toplevel tree with
user's changes and suitable for commits.

This function does exactly that.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx>
---
 narrow-tree.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 narrow-tree.h |    2 +
 2 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/narrow-tree.c b/narrow-tree.c
index 46e913d..73d4f22 100644
--- a/narrow-tree.c
+++ b/narrow-tree.c
@@ -1,4 +1,14 @@
 #include "cache.h"
+#include "commit.h"
+#include "tree.h"
+#include "diff.h"
+#include "revision.h"
+#include "refs.h"
+#include "tag.h"
+#include "progress.h"
+#include "pack.h"
+#include "sha1-lookup.h"
+#include "csum-file.h"
 #include "narrow-tree.h"
 
 static const char *narrow_prefix;
@@ -29,3 +39,59 @@ const char *get_narrow_prefix()
 {
 	return narrow_prefix;
 }
+
+/*
+ * The opposite of narrow_tree(). Put the subtree back to the original tree.
+ */
+int join_narrow_tree(const unsigned char *base,
+		     unsigned char *newsha1,
+		     const unsigned char *subtree_sha1,
+		     const char *prefix)
+{
+	struct tree_desc desc;
+	struct name_entry entry;
+	struct strbuf buffer;
+	enum object_type type;
+	const char *slash;
+	char *buf;
+	int subtree_len;
+	unsigned long size;
+
+	slash = strchr(prefix, '/');
+	subtree_len = slash ? slash - prefix : strlen(prefix);
+
+	buf = read_sha1_file(base, &type, &size);
+	if (!buf || type != OBJ_TREE)
+		die("Bad tree %s", sha1_to_hex(base));
+
+	init_tree_desc(&desc, buf, size);
+	strbuf_init(&buffer, 8192);
+	while (tree_entry(&desc, &entry)) {
+		strbuf_addf(&buffer, "%o %.*s%c", entry.mode, strlen(entry.path), entry.path, '\0');
+
+		if (S_ISDIR(entry.mode) &&
+		    subtree_len == strlen(entry.path) &&
+		    !strncmp(entry.path, prefix, subtree_len)) {
+			if (slash && slash[1]) /* trailing slash does not count */
+				join_narrow_tree(entry.sha1, newsha1,
+						 subtree_sha1, slash+1);
+			else
+				memcpy(newsha1, subtree_sha1, 20); /* replace the tree */
+
+			/* FIXME, what if placeholder tree does not exist? */
+
+			strbuf_add(&buffer, newsha1, 20);
+		}
+		else
+			strbuf_add(&buffer, entry.sha1, 20);
+	}
+
+	free(buf);
+	if (write_sha1_file(buffer.buf, buffer.len, tree_type, newsha1)) {
+		error("Could not write replaced tree for %s", sha1_to_hex(subtree_sha1));
+		strbuf_release(&buffer);
+		return 1;
+	}
+	strbuf_release(&buffer);
+	return 0;
+}
diff --git a/narrow-tree.h b/narrow-tree.h
index aa8c94f..ecb3ded 100644
--- a/narrow-tree.h
+++ b/narrow-tree.h
@@ -1 +1,3 @@
 extern int check_narrow_prefix();
+extern int join_narrow_tree(const unsigned char *base, unsigned char *newsha1,
+			    const unsigned char *subtree_sha1, const char *prefix);
-- 
1.7.1.rc1.69.g24c2f7

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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]