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
next prev 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).