Skip to content

Commit 6cd2a36

Browse files
hanwenpeff
authored andcommitted
Reftable support for git-core
For background, see the previous commit introducing the library. TODO: * Make CI on gitgitgadget compile. * Redo interaction between repo config, repo storage version * Resolve the design problem with reflog expiry. * Resolve spots marked with XXX Example use: $ ~/vc/git/git init --reftable warning: templates not found in /usr/local/google/home/hanwen/share/git-core/templates Initialized empty Git repository in /tmp/qz/.git/ $ echo q > a $ ~/vc/git/git add a $ ~/vc/git/git commit -mx fatal: not a git repository (or any of the parent directories): .git [master (root-commit) 373d969] x 1 file changed, 1 insertion(+) create mode 100644 a $ ~/vc/git/git show-ref 373d96972fca9b63595740bba3898a762778ba20 HEAD 373d96972fca9b63595740bba3898a762778ba20 refs/heads/master $ ls -l .git/reftable/ total 12 -rw------- 1 hanwen primarygroup 126 Jan 23 20:08 000000000001-000000000001.ref -rw------- 1 hanwen primarygroup 4277 Jan 23 20:08 000000000002-000000000002.ref $ go run ~/vc/reftable/cmd/dump.go -table /tmp/qz/.git/reftable/000000000002-000000000002.ref ** DEBUG ** name /tmp/qz/.git/reftable/000000000002-000000000002.ref, sz 4209: 'r' reftable.readerOffsets{Present:true, Offset:0x0, IndexOffset:0x0}, 'o' reftable.readerOffsets{Present:false, Offset:0x0, IndexOffset:0x0} 'g' reftable.readerOffsets{Present:true, Offset:0x1000, IndexOffset:0x0} ** REFS ** reftable.RefRecord{RefName:"refs/heads/master", UpdateIndex:0x2, Value:[]uint8{0x37, 0x3d, 0x96, 0x97, 0x2f, 0xca, 0x9b, 0x63, 0x59, 0x57, 0x40, 0xbb, 0xa3, 0x89, 0x8a, 0x76, 0x27, 0x78, 0xba, 0x20}, TargetValue:[]uint8(nil), Target:""} ** LOGS ** reftable.LogRecord{RefName:"HEAD", UpdateIndex:0x2, New:[]uint8{0x37, 0x3d, 0x96, 0x97, 0x2f, 0xca, 0x9b, 0x63, 0x59, 0x57, 0x40, 0xbb, 0xa3, 0x89, 0x8a, 0x76, 0x27, 0x78, 0xba, 0x20}, Old:[]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, Name:"Han-Wen Nienhuys", Email:"[email protected]", Time:0x5e29ef27, TZOffset:100, Message:"commit (initial): x\n"} Signed-off-by: Han-Wen Nienhuys <[email protected]> Co-authored-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 592edca commit 6cd2a36

File tree

9 files changed

+966
-25
lines changed

9 files changed

+966
-25
lines changed

Makefile

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ TEST_SHELL_PATH = $(SHELL_PATH)
813813
LIB_FILE = libgit.a
814814
XDIFF_LIB = xdiff/lib.a
815815
VCSSVN_LIB = vcs-svn/lib.a
816+
REFTABLE_LIB = reftable/libreftable.a
816817

817818
GENERATED_H += command-list.h
818819

@@ -958,6 +959,7 @@ LIB_OBJS += rebase-interactive.o
958959
LIB_OBJS += reflog-walk.o
959960
LIB_OBJS += refs.o
960961
LIB_OBJS += refs/files-backend.o
962+
LIB_OBJS += refs/reftable-backend.o
961963
LIB_OBJS += refs/iterator.o
962964
LIB_OBJS += refs/packed-backend.o
963965
LIB_OBJS += refs/ref-cache.o
@@ -1162,7 +1164,7 @@ THIRD_PARTY_SOURCES += compat/regex/%
11621164
THIRD_PARTY_SOURCES += sha1collisiondetection/%
11631165
THIRD_PARTY_SOURCES += sha1dc/%
11641166

1165-
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB)
1167+
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB)
11661168
EXTLIBS =
11671169

11681170
GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -2343,11 +2345,28 @@ VCSSVN_OBJS += vcs-svn/fast_export.o
23432345
VCSSVN_OBJS += vcs-svn/svndiff.o
23442346
VCSSVN_OBJS += vcs-svn/svndump.o
23452347

2348+
REFTABLE_OBJS += reftable/basics.o
2349+
REFTABLE_OBJS += reftable/block.o
2350+
REFTABLE_OBJS += reftable/bytes.o
2351+
REFTABLE_OBJS += reftable/file.o
2352+
REFTABLE_OBJS += reftable/iter.o
2353+
REFTABLE_OBJS += reftable/merged.o
2354+
REFTABLE_OBJS += reftable/pq.o
2355+
REFTABLE_OBJS += reftable/reader.o
2356+
REFTABLE_OBJS += reftable/record.o
2357+
REFTABLE_OBJS += reftable/slice.o
2358+
REFTABLE_OBJS += reftable/stack.o
2359+
REFTABLE_OBJS += reftable/tree.o
2360+
REFTABLE_OBJS += reftable/writer.o
2361+
REFTABLE_OBJS += reftable/zlib-compat.o
2362+
2363+
23462364
TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
23472365
OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
23482366
$(XDIFF_OBJS) \
23492367
$(VCSSVN_OBJS) \
23502368
$(FUZZ_OBJS) \
2369+
$(REFTABLE_OBJS) \
23512370
common-main.o \
23522371
git.o
23532372
ifndef NO_CURL
@@ -2484,6 +2503,9 @@ $(XDIFF_LIB): $(XDIFF_OBJS)
24842503
$(VCSSVN_LIB): $(VCSSVN_OBJS)
24852504
$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
24862505

2506+
$(REFTABLE_LIB): $(REFTABLE_OBJS)
2507+
$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
2508+
24872509
export DEFAULT_EDITOR DEFAULT_PAGER
24882510

24892511
Documentation/GIT-EXCLUDED-PROGRAMS: FORCE

builtin/init-db.c

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)
177177
}
178178

179179
static int create_default_files(const char *template_path,
180-
const char *original_git_dir)
180+
const char *original_git_dir, int flags)
181181
{
182182
struct stat st1;
183183
struct strbuf buf = STRBUF_INIT;
@@ -213,6 +213,8 @@ static int create_default_files(const char *template_path,
213213
is_bare_repository_cfg = init_is_bare_repository;
214214
if (init_shared_repository != -1)
215215
set_shared_repository(init_shared_repository);
216+
if (flags & INIT_DB_REFTABLE)
217+
the_repository->ref_storage_format = xstrdup("reftable");
216218

217219
/*
218220
* We would have created the above under user's umask -- under
@@ -222,6 +224,15 @@ static int create_default_files(const char *template_path,
222224
adjust_shared_perm(get_git_dir());
223225
}
224226

227+
/*
228+
* Check to see if .git/HEAD exists; this must happen before
229+
* initializing the ref db, because we want to see if there is an
230+
* existing HEAD.
231+
*/
232+
path = git_path_buf(&buf, "HEAD");
233+
reinit = (!access(path, R_OK) ||
234+
readlink(path, junk, sizeof(junk) - 1) != -1);
235+
225236
/*
226237
* We need to create a "refs" dir in any case so that older
227238
* versions of git can tell that this is a repository.
@@ -234,17 +245,20 @@ static int create_default_files(const char *template_path,
234245
* Create the default symlink from ".git/HEAD" to the "master"
235246
* branch, if it does not exist yet.
236247
*/
237-
path = git_path_buf(&buf, "HEAD");
238-
reinit = (!access(path, R_OK)
239-
|| readlink(path, junk, sizeof(junk)-1) != -1);
240248
if (!reinit) {
241249
if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
242250
exit(1);
251+
} else {
252+
/*
253+
* XXX should check whether our ref backend matches the
254+
* original one; if not, either die() or convert
255+
*/
243256
}
244257

245258
/* This forces creation of new config file */
246-
xsnprintf(repo_version_string, sizeof(repo_version_string),
247-
"%d", GIT_REPO_VERSION);
259+
xsnprintf(repo_version_string, sizeof(repo_version_string), "%d",
260+
flags & INIT_DB_REFTABLE ? GIT_REPO_VERSION_READ :
261+
GIT_REPO_VERSION);
248262
git_config_set("core.repositoryformatversion", repo_version_string);
249263

250264
/* Check filemode trustability */
@@ -378,7 +392,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
378392
*/
379393
check_repository_format();
380394

381-
reinit = create_default_files(template_dir, original_git_dir);
395+
reinit = create_default_files(template_dir, original_git_dir, flags);
382396

383397
create_object_directory();
384398

@@ -403,6 +417,10 @@ int init_db(const char *git_dir, const char *real_git_dir,
403417
git_config_set("receive.denyNonFastforwards", "true");
404418
}
405419

420+
if (flags & INIT_DB_REFTABLE) {
421+
git_config_set("extensions.refStorage", "reftable");
422+
}
423+
406424
if (!(flags & INIT_DB_QUIET)) {
407425
int len = strlen(git_dir);
408426

@@ -481,15 +499,18 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
481499
const char *template_dir = NULL;
482500
unsigned int flags = 0;
483501
const struct option init_db_options[] = {
484-
OPT_STRING(0, "template", &template_dir, N_("template-directory"),
485-
N_("directory from which templates will be used")),
502+
OPT_STRING(0, "template", &template_dir,
503+
N_("template-directory"),
504+
N_("directory from which templates will be used")),
486505
OPT_SET_INT(0, "bare", &is_bare_repository_cfg,
487-
N_("create a bare repository"), 1),
506+
N_("create a bare repository"), 1),
488507
{ OPTION_CALLBACK, 0, "shared", &init_shared_repository,
489-
N_("permissions"),
490-
N_("specify that the git repository is to be shared amongst several users"),
491-
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
508+
N_("permissions"),
509+
N_("specify that the git repository is to be shared amongst several users"),
510+
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0 },
492511
OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
512+
OPT_BIT(0, "reftable", &flags, N_("use reftable"),
513+
INIT_DB_REFTABLE),
493514
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
494515
N_("separate git dir from working tree")),
495516
OPT_END()

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ int path_inside_repo(const char *prefix, const char *path);
625625

626626
#define INIT_DB_QUIET 0x0001
627627
#define INIT_DB_EXIST_OK 0x0002
628+
#define INIT_DB_REFTABLE 0x0004
628629

629630
int init_db(const char *git_dir, const char *real_git_dir,
630631
const char *template_dir, unsigned int flags);
@@ -1041,6 +1042,7 @@ struct repository_format {
10411042
int is_bare;
10421043
int hash_algo;
10431044
char *work_tree;
1045+
char *ref_storage;
10441046
struct string_list unknown_extensions;
10451047
};
10461048

refs.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/*
2121
* List of all available backends
2222
*/
23-
static struct ref_storage_be *refs_backends = &refs_be_files;
23+
static struct ref_storage_be *refs_backends = &refs_be_reftable;
2424

2525
static struct ref_storage_be *find_ref_storage_backend(const char *name)
2626
{
@@ -1836,13 +1836,13 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map,
18361836
* Create, record, and return a ref_store instance for the specified
18371837
* gitdir.
18381838
*/
1839-
static struct ref_store *ref_store_init(const char *gitdir,
1839+
static struct ref_store *ref_store_init(const char *gitdir, const char *be_name,
18401840
unsigned int flags)
18411841
{
1842-
const char *be_name = "files";
1843-
struct ref_storage_be *be = find_ref_storage_backend(be_name);
1842+
struct ref_storage_be *be;
18441843
struct ref_store *refs;
18451844

1845+
be = find_ref_storage_backend(be_name);
18461846
if (!be)
18471847
BUG("reference backend %s is unknown", be_name);
18481848

@@ -1858,7 +1858,10 @@ struct ref_store *get_main_ref_store(struct repository *r)
18581858
if (!r->gitdir)
18591859
BUG("attempting to get main_ref_store outside of repository");
18601860

1861-
r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
1861+
r->refs = ref_store_init(r->gitdir,
1862+
r->ref_storage_format ? r->ref_storage_format :
1863+
"files",
1864+
REF_STORE_ALL_CAPS);
18621865
return r->refs;
18631866
}
18641867

@@ -1913,7 +1916,7 @@ struct ref_store *get_submodule_ref_store(const char *submodule)
19131916
goto done;
19141917

19151918
/* assume that add_submodule_odb() has been called */
1916-
refs = ref_store_init(submodule_sb.buf,
1919+
refs = ref_store_init(submodule_sb.buf, "files", /* XXX */
19171920
REF_STORE_READ | REF_STORE_ODB);
19181921
register_ref_store_map(&submodule_ref_stores, "submodule",
19191922
refs, submodule);
@@ -1927,6 +1930,7 @@ struct ref_store *get_submodule_ref_store(const char *submodule)
19271930

19281931
struct ref_store *get_worktree_ref_store(const struct worktree *wt)
19291932
{
1933+
const char *format = "files"; /* XXX */
19301934
struct ref_store *refs;
19311935
const char *id;
19321936

@@ -1940,9 +1944,9 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
19401944

19411945
if (wt->id)
19421946
refs = ref_store_init(git_common_path("worktrees/%s", wt->id),
1943-
REF_STORE_ALL_CAPS);
1947+
format, REF_STORE_ALL_CAPS);
19441948
else
1945-
refs = ref_store_init(get_git_common_dir(),
1949+
refs = ref_store_init(get_git_common_dir(), format,
19461950
REF_STORE_ALL_CAPS);
19471951

19481952
if (refs)

refs/refs-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ struct ref_storage_be {
661661
};
662662

663663
extern struct ref_storage_be refs_be_files;
664+
extern struct ref_storage_be refs_be_reftable;
664665
extern struct ref_storage_be refs_be_packed;
665666

666667
/*

0 commit comments

Comments
 (0)