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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.