From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 05/16] Hook up replace-object to allow bulk commit replacement
Date: Sat, 31 Jul 2010 23:18:14 +0700 [thread overview]
Message-ID: <1280593105-22015-6-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1280593105-22015-1-git-send-email-pclouds@gmail.com>
$GIT_DIR/subtree contains commit mapping in subtree mode. It's quite
large that putting it in $GIT_DIR/refs/replace may slow git down
significantly. Even with this, there will be a split second delay for
every git command.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Makefile | 2 +
replace_object.c | 5 ++
subtree.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
subtree.h | 2 +
4 files changed, 126 insertions(+), 0 deletions(-)
create mode 100644 subtree.c
create mode 100644 subtree.h
diff --git a/Makefile b/Makefile
index f33648d..0d13538 100644
--- a/Makefile
+++ b/Makefile
@@ -525,6 +525,7 @@ LIB_H += sigchain.h
LIB_H += strbuf.h
LIB_H += string-list.h
LIB_H += submodule.h
+LIB_H += subtree.h
LIB_H += tag.h
LIB_H += transport.h
LIB_H += tree.h
@@ -629,6 +630,7 @@ LIB_OBJS += sigchain.o
LIB_OBJS += strbuf.o
LIB_OBJS += string-list.o
LIB_OBJS += submodule.o
+LIB_OBJS += subtree.o
LIB_OBJS += symlinks.o
LIB_OBJS += tag.o
LIB_OBJS += trace.o
diff --git a/replace_object.c b/replace_object.c
index eb59604..5fe4099 100644
--- a/replace_object.c
+++ b/replace_object.c
@@ -1,6 +1,7 @@
#include "cache.h"
#include "sha1-lookup.h"
#include "refs.h"
+#include "subtree.h"
static struct replace_object {
unsigned char sha1[2][20];
@@ -82,6 +83,7 @@ static void prepare_replace_object(void)
if (replace_object_prepared)
return;
+ prepare_subtree_commit();
for_each_replace_ref(register_replace_ref, NULL);
replace_object_prepared = 1;
}
@@ -99,6 +101,9 @@ const unsigned char *lookup_replace_object(const unsigned char *sha1)
prepare_replace_object();
+ if (core_subtree)
+ cur = subtree_lookup_object(cur);
+
/* Try to recursively replace the object */
do {
if (--depth < 0)
diff --git a/subtree.c b/subtree.c
new file mode 100644
index 0000000..601d827
--- /dev/null
+++ b/subtree.c
@@ -0,0 +1,117 @@
+#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"
+
+static struct replace_object {
+ unsigned char sha1[2][20];
+} **subtree_commit;
+
+static struct replace_object **subtree_commit, **subtree_commit_r;
+static int subtree_commit_nr, subtree_commit_r_nr, subtree_commit_alloc;
+
+static const unsigned char *replace_sha1_access(size_t index, void *table)
+{
+ struct replace_object **replace = table;
+ return replace[index]->sha1[0];
+}
+
+static int subtree_replace_object_pos(struct replace_object **store, int nr,
+ const unsigned char *sha1)
+{
+ return sha1_pos(sha1, store, nr, replace_sha1_access);
+}
+
+static int subtree_register_object(struct replace_object **store,
+ int *nr,
+ const unsigned char *sha1,
+ struct replace_object *replace,
+ int ignore_dups)
+{
+ int pos = subtree_replace_object_pos(store, *nr, sha1);
+
+ if (0 <= pos) {
+ if (ignore_dups)
+ free(replace);
+ else {
+ free(store[pos]);
+ store[pos] = replace;
+ }
+ return 1;
+ }
+ pos = -pos - 1;
+ (*nr)++;
+ if (pos < *nr)
+ memmove(store + pos + 1,
+ store + pos,
+ (*nr - pos - 1) *
+ sizeof(*store));
+ store[pos] = replace;
+ return 0;
+}
+
+void prepare_subtree_commit()
+{
+ int fd;
+ struct stat stat;
+ struct replace_object *ro;
+ int ro_size, ro_table_size;
+ char *subtree, *entry;
+
+ if (!core_subtree)
+ return;
+
+ fd = open(git_path("subtree"), O_RDONLY);
+ if (fd == -1)
+ return;
+
+ if (fstat(fd, &stat))
+ die("Could not stat .git/subtree");
+
+ if (stat.st_size % 82)
+ die("Invalid .git/subtree size");
+
+ subtree_commit_alloc = stat.st_size / 82;
+ ro_size = sizeof(struct replace_object) * subtree_commit_alloc;
+ ro_table_size = sizeof(struct replace_object*) * subtree_commit_alloc;
+ subtree_commit_nr = 0;
+ subtree_commit_r_nr = 0;
+
+ subtree_commit = xmalloc(ro_size + ro_table_size*2);
+ subtree_commit_r = (struct replace_object **)(((char*)subtree_commit) + ro_table_size);
+ ro = (struct replace_object *)(((char*)subtree_commit) + 2*ro_table_size);
+
+ entry = subtree = xmmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+
+ for (entry = subtree; subtree_commit_nr < subtree_commit_alloc; entry += 82, ro++) {
+ if (entry[40] != ' ' || entry[81] != '\n')
+ die("Broken .git/subtree");
+
+ get_sha1_hex(entry, ro->sha1[0]);
+ get_sha1_hex(entry+41, ro->sha1[1]);
+ if (subtree_register_object(subtree_commit, &subtree_commit_nr,
+ ro->sha1[0], ro, 1) ||
+ subtree_register_object(subtree_commit_r, &subtree_commit_r_nr,
+ ro->sha1[1], ro, 1))
+ die("duplicate replace ref: %s", sha1_to_hex(ro->sha1[0]));
+ }
+ munmap(subtree, stat.st_size);
+ close(fd);
+}
+
+const unsigned char *subtree_lookup_object(const unsigned char *sha1)
+{
+ int pos = subtree_replace_object_pos(subtree_commit,
+ subtree_commit_nr,
+ sha1);
+ if (0 <= pos)
+ return subtree_commit[pos]->sha1[1];
+ return sha1;
+}
diff --git a/subtree.h b/subtree.h
new file mode 100644
index 0000000..157153a
--- /dev/null
+++ b/subtree.h
@@ -0,0 +1,2 @@
+void prepare_subtree_commit();
+const unsigned char *subtree_lookup_object(const unsigned char *sha1);
--
1.7.1.rc1.69.g24c2f7
next prev parent reply other threads:[~2010-08-01 2:38 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-31 16:18 [PATCH 00/16] Subtree clone proof of concept Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 01/16] Add core.subtree Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 02/16] list-objects: limit traversing within the given subtree if core.subtree is set Nguyễn Thái Ngọc Duy
2010-08-01 11:30 ` Ævar Arnfjörð Bjarmason
2010-08-01 23:11 ` Nguyen Thai Ngoc Duy
2010-08-02 4:21 ` Elijah Newren
2010-08-02 6:51 ` Nguyen Thai Ngoc Duy
2010-07-31 16:18 ` [PATCH 03/16] parse_object: keep sha1 even when parsing replaced one Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 04/16] Allow to invalidate a commit in in-memory object store Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` Nguyễn Thái Ngọc Duy [this message]
2010-08-02 19:58 ` [PATCH 05/16] Hook up replace-object to allow bulk commit replacement Junio C Hamano
2010-08-02 22:42 ` Nguyen Thai Ngoc Duy
2010-07-31 16:18 ` [PATCH 06/16] upload-pack: use a separate variable to control whether internal rev-list is used Nguyễn Thái Ngọc Duy
2010-08-02 4:25 ` Elijah Newren
2010-07-31 16:18 ` [PATCH 07/16] upload-pack: support subtree pack Nguyễn Thái Ngọc Duy
2010-08-02 4:27 ` Elijah Newren
2010-07-31 16:18 ` [PATCH 08/16] fetch-pack: support --subtree Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 09/16] subtree: rewrite incoming commits Nguyễn Thái Ngọc Duy
2010-08-02 4:37 ` Elijah Newren
2010-07-31 16:18 ` [PATCH 10/16] clone: support subtree clone with parameter --subtree Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 11/16] pack-objects: add --subtree (for pushing) Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 12/16] subtree: rewriting outgoing commits Nguyễn Thái Ngọc Duy
2010-08-02 4:40 ` Elijah Newren
2010-07-31 16:18 ` [PATCH 13/16] Update commit_tree() interface to take base tree too Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 14/16] commit_tree(): rewriting/replacing new commits Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 15/16] commit: rewrite outgoing commits Nguyễn Thái Ngọc Duy
2010-07-31 16:18 ` [PATCH 16/16] do not use thin packs and subtree together (just a bad feeling about this) Nguyễn Thái Ngọc Duy
2010-08-01 4:14 ` [PATCH 00/16] Subtree clone proof of concept Sverre Rabbelier
2010-08-01 6:58 ` Nguyen Thai Ngoc Duy
2010-08-01 20:05 ` Sverre Rabbelier
2010-08-02 5:18 ` Elijah Newren
2010-08-02 7:10 ` Nguyen Thai Ngoc Duy
2010-08-02 22:55 ` Nguyen Thai Ngoc Duy
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=1280593105-22015-6-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/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).