git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Elijah Newren <newren@gmail.com>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 13/17] commit: add narrow's commit_tree version
Date: Sun,  5 Sep 2010 16:47:40 +1000	[thread overview]
Message-ID: <1283669264-15759-14-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1283669264-15759-1-git-send-email-pclouds@gmail.com>

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.

The narrow version uses join_narrow_tree() to recreate a full tree
from a base toplevel tree (typically commit parent's tree) and a tree
created from index.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Equivalence to Elijah's 07/15 and 08/15. My way generates some throw away
 trees at write_cache_as_tree(), not good.

 commit.c      |   16 +++++++++
 commit.h      |    5 +++
 narrow-tree.c |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 narrow-tree.h |    4 ++
 4 files changed, 126 insertions(+), 0 deletions(-)

diff --git a/commit.c b/commit.c
index 0094ec1..c7fe7fc 100644
--- a/commit.c
+++ b/commit.c
@@ -6,6 +6,7 @@
 #include "diff.h"
 #include "revision.h"
 #include "notes.h"
+#include "narrow-tree.h"
 
 int save_commit_buffer = 1;
 
@@ -864,3 +865,18 @@ int commit_tree(const char *msg, unsigned char *tree,
 	strbuf_release(&buffer);
 	return result;
 }
+
+int commit_narrow_tree(const char *msg, unsigned char *tree,
+		       const unsigned char *narrow_base,
+		       struct commit_list *parents, unsigned char *ret,
+		       const char *author)
+{
+	unsigned char sha1[20];
+
+	if (get_narrow_prefix()) {
+		if (join_narrow_tree(sha1, narrow_base, tree, get_narrow_prefix()))
+			die("Failed to join tree");
+		tree = sha1;
+	}
+	return commit_tree(msg, tree, parents, ret, author);
+}
diff --git a/commit.h b/commit.h
index 9113bbe..c718439 100644
--- a/commit.h
+++ b/commit.h
@@ -170,5 +170,10 @@ struct commit_list *reduce_heads(struct commit_list *heads);
 extern int commit_tree(const char *msg, unsigned char *tree,
 		struct commit_list *parents, unsigned char *ret,
 		const char *author);
+extern int commit_narrow_tree(const char *msg, unsigned char *tree,
+			      const unsigned char *narrow_base,
+			      struct commit_list *parents,
+			      unsigned char *ret,
+			      const char *author);
 
 #endif /* COMMIT_H */
diff --git a/narrow-tree.c b/narrow-tree.c
index 85dbab4..110fac2 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;
@@ -104,3 +114,94 @@ char *get_narrow_string()
 	}
 	return strbuf_detach(&sb, NULL);
 }
+
+/*
+ * The opposite of narrow_tree(). Put the subtree back to the original tree.
+ */
+static int join_narrow_tree_rec(unsigned char *result,
+				const unsigned char *basetree,
+				const unsigned char *newtree,
+				const char **prefix,
+				char *base,
+				int baselen)
+{
+	struct tree_desc desc;
+	struct name_entry entry;
+	struct strbuf buffer;
+	enum object_type type;
+	unsigned long size;
+	const char **p;
+	int len, found;
+	char *buf;
+
+	buf = read_sha1_file(basetree, &type, &size);
+	if (!buf || type != OBJ_TREE)
+		die("Bad tree %s", sha1_to_hex(basetree));
+
+	if (baselen)
+		base[baselen++] = '/';
+
+	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)) {
+			strbuf_add(&buffer, entry.sha1, 20);
+			continue;
+		}
+
+		p = prefix;
+		len = strlen(entry.path);
+		found = 0;
+
+		while (*p) {
+			if (!strcmp(entry.path, *p)) {
+				found = 2;
+				break;
+			}
+			if (!prefixcmp(*p, entry.path)) {
+				found = 1;
+				break;
+			}
+			p++;
+		}
+		switch (found) {
+		case 1:
+			memcpy(base+baselen, entry.path, len+1);
+			join_narrow_tree_rec(result, entry.sha1, newtree,
+					     prefix, base, baselen+len+1);
+			break;
+		case 2:
+			if (!path_to_tree_sha1(result, newtree, *p))
+				die("Could not find tree %s in the new tree", *p);
+			break;
+		case 0:
+			hashcpy(result, entry.sha1);
+			break;
+		}
+
+		/* FIXME, what if placeholder tree does not exist? */
+
+		strbuf_add(&buffer, result, 20);
+	}
+
+	free(buf);
+	if (write_sha1_file(buffer.buf, buffer.len, tree_type, result)) {
+		base[baselen] = '\0';
+		error("Could not write tree %s", base);
+		strbuf_release(&buffer);
+		return 1;
+	}
+	strbuf_release(&buffer);
+	return 0;
+}
+
+int join_narrow_tree(unsigned char *result,
+		     const unsigned char *basetree,
+		     const unsigned char *newtree,
+		     const char **prefix)
+{
+	char path[PATH_MAX];
+	return join_narrow_tree_rec(result, basetree, newtree, prefix, path, 0);
+}
diff --git a/narrow-tree.h b/narrow-tree.h
index 2097436..e7d84c4 100644
--- a/narrow-tree.h
+++ b/narrow-tree.h
@@ -1,3 +1,7 @@
 extern int valid_narrow_prefix(const char *prefix, const char *prev_prefix, int quiet);
 extern int check_narrow_prefix();
 extern char *get_narrow_string();
+extern int join_narrow_tree(unsigned char *result,
+			    const unsigned char *base,
+			    const unsigned char *newtree,
+			    const char **prefix);
-- 
1.7.1.rc1.69.g24c2f7

  parent reply	other threads:[~2010-09-05  6:50 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-05  6:47 [PATCH 00/17] Narrow clone v3 (was subtree clone) Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 01/17] rev-list: do not do commit simplification if simplify_history = 0 Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 02/17] tree.c: add path_to_sha1() Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 03/17] Introduce $GIT_DIR/narrow Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 04/17] index: make narrow index incompatible with older git Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 05/17] pack-objects: support narrow packs with pathspecs Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 06/17] {fetch,upload}-pack: support narrow repository Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 07/17] unpack-trees: split traverse_trees() code into a separate function Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 08/17] unpack-trees: support unpack trees in narrow repository Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 09/17] cache-tree: only cache tree within narrow area Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 10/17] get_pathspec(): support narrow pathspec rewriting Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 11/17] pathspec retrieval fix Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 12/17] clone: support --narrow option Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` Nguyễn Thái Ngọc Duy [this message]
2010-09-05  6:47 ` [PATCH 14/17] commit: use commit_narrow_tree() to support narrow repo Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 15/17] write-tree: requires --narrow-base in narrow repository Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 16/17] merge: try to do local merge if possible in narrow repo Nguyễn Thái Ngọc Duy
2010-09-05  6:47 ` [PATCH 17/17] Add narrow clone demonstration test Nguyễn Thái Ngọc Duy
2010-09-05  6:55 ` [PATCH 00/17] Narrow clone v3 (was subtree clone) Sverre Rabbelier
2010-09-05  7:13   ` Nguyen Thai Ngoc Duy
2010-09-05 21:05     ` Elijah Newren
2010-09-06  5:17 ` Elijah Newren
2010-09-06  5:24   ` Nguyen Thai Ngoc Duy
2010-09-06 20:29   ` Sverre Rabbelier
2010-09-06 20:40     ` Elijah Newren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1283669264-15759-14-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=newren@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).