Skip to content

Commit 166794b

Browse files
committed
Merge branch 'hn/reftable' into pu
* hn/reftable: Reftable support for git-core Add reftable library refs: document how ref_iterator_advance_fn should handle symrefs create .git/refs in files-backend.c refs.h: clarify reflog iteration order
2 parents 996e90e + 6cd2a36 commit 166794b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+7248
-28
lines changed

Makefile

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

820821
GENERATED_H += config-list.h
821822
GENERATED_H += command-list.h
@@ -966,6 +967,7 @@ LIB_OBJS += ref-filter.o
966967
LIB_OBJS += reflog-walk.o
967968
LIB_OBJS += refs.o
968969
LIB_OBJS += refs/files-backend.o
970+
LIB_OBJS += refs/reftable-backend.o
969971
LIB_OBJS += refs/iterator.o
970972
LIB_OBJS += refs/packed-backend.o
971973
LIB_OBJS += refs/ref-cache.o
@@ -1170,7 +1172,7 @@ THIRD_PARTY_SOURCES += compat/regex/%
11701172
THIRD_PARTY_SOURCES += sha1collisiondetection/%
11711173
THIRD_PARTY_SOURCES += sha1dc/%
11721174

1173-
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB)
1175+
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB)
11741176
EXTLIBS =
11751177

11761178
GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -2368,11 +2370,28 @@ VCSSVN_OBJS += vcs-svn/sliding_window.o
23682370
VCSSVN_OBJS += vcs-svn/svndiff.o
23692371
VCSSVN_OBJS += vcs-svn/svndump.o
23702372

2373+
REFTABLE_OBJS += reftable/basics.o
2374+
REFTABLE_OBJS += reftable/block.o
2375+
REFTABLE_OBJS += reftable/bytes.o
2376+
REFTABLE_OBJS += reftable/file.o
2377+
REFTABLE_OBJS += reftable/iter.o
2378+
REFTABLE_OBJS += reftable/merged.o
2379+
REFTABLE_OBJS += reftable/pq.o
2380+
REFTABLE_OBJS += reftable/reader.o
2381+
REFTABLE_OBJS += reftable/record.o
2382+
REFTABLE_OBJS += reftable/slice.o
2383+
REFTABLE_OBJS += reftable/stack.o
2384+
REFTABLE_OBJS += reftable/tree.o
2385+
REFTABLE_OBJS += reftable/writer.o
2386+
REFTABLE_OBJS += reftable/zlib-compat.o
2387+
2388+
23712389
TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
23722390
OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
23732391
$(XDIFF_OBJS) \
23742392
$(VCSSVN_OBJS) \
23752393
$(FUZZ_OBJS) \
2394+
$(REFTABLE_OBJS) \
23762395
common-main.o \
23772396
git.o
23782397
ifndef NO_CURL
@@ -2513,6 +2532,9 @@ $(XDIFF_LIB): $(XDIFF_OBJS)
25132532
$(VCSSVN_LIB): $(VCSSVN_OBJS)
25142533
$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
25152534

2535+
$(REFTABLE_LIB): $(REFTABLE_OBJS)
2536+
$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
2537+
25162538
export DEFAULT_EDITOR DEFAULT_PAGER
25172539

25182540
Documentation/GIT-EXCLUDED-PROGRAMS: FORCE

builtin/init-db.c

Lines changed: 34 additions & 15 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,12 +224,19 @@ 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.
228239
*/
229-
safe_create_dir(git_path("refs"), 1);
230-
adjust_shared_perm(git_path("refs"));
231240

232241
if (refs_init_db(&err))
233242
die("failed to set up refs db: %s", err.buf);
@@ -236,17 +245,20 @@ static int create_default_files(const char *template_path,
236245
* Create the default symlink from ".git/HEAD" to the "master"
237246
* branch, if it does not exist yet.
238247
*/
239-
path = git_path_buf(&buf, "HEAD");
240-
reinit = (!access(path, R_OK)
241-
|| readlink(path, junk, sizeof(junk)-1) != -1);
242248
if (!reinit) {
243249
if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
244250
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+
*/
245256
}
246257

247258
/* This forces creation of new config file */
248-
xsnprintf(repo_version_string, sizeof(repo_version_string),
249-
"%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);
250262
git_config_set("core.repositoryformatversion", repo_version_string);
251263

252264
/* Check filemode trustability */
@@ -380,7 +392,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
380392
*/
381393
check_repository_format();
382394

383-
reinit = create_default_files(template_dir, original_git_dir);
395+
reinit = create_default_files(template_dir, original_git_dir, flags);
384396

385397
create_object_directory();
386398

@@ -405,6 +417,10 @@ int init_db(const char *git_dir, const char *real_git_dir,
405417
git_config_set("receive.denyNonFastforwards", "true");
406418
}
407419

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

@@ -483,15 +499,18 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
483499
const char *template_dir = NULL;
484500
unsigned int flags = 0;
485501
const struct option init_db_options[] = {
486-
OPT_STRING(0, "template", &template_dir, N_("template-directory"),
487-
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")),
488505
OPT_SET_INT(0, "bare", &is_bare_repository_cfg,
489-
N_("create a bare repository"), 1),
506+
N_("create a bare repository"), 1),
490507
{ OPTION_CALLBACK, 0, "shared", &init_shared_repository,
491-
N_("permissions"),
492-
N_("specify that the git repository is to be shared amongst several users"),
493-
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 },
494511
OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
512+
OPT_BIT(0, "reftable", &flags, N_("use reftable"),
513+
INIT_DB_REFTABLE),
495514
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
496515
N_("separate git dir from working tree")),
497516
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
{
@@ -1850,13 +1850,13 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map,
18501850
* Create, record, and return a ref_store instance for the specified
18511851
* gitdir.
18521852
*/
1853-
static struct ref_store *ref_store_init(const char *gitdir,
1853+
static struct ref_store *ref_store_init(const char *gitdir, const char *be_name,
18541854
unsigned int flags)
18551855
{
1856-
const char *be_name = "files";
1857-
struct ref_storage_be *be = find_ref_storage_backend(be_name);
1856+
struct ref_storage_be *be;
18581857
struct ref_store *refs;
18591858

1859+
be = find_ref_storage_backend(be_name);
18601860
if (!be)
18611861
BUG("reference backend %s is unknown", be_name);
18621862

@@ -1872,7 +1872,10 @@ struct ref_store *get_main_ref_store(struct repository *r)
18721872
if (!r->gitdir)
18731873
BUG("attempting to get main_ref_store outside of repository");
18741874

1875-
r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
1875+
r->refs = ref_store_init(r->gitdir,
1876+
r->ref_storage_format ? r->ref_storage_format :
1877+
"files",
1878+
REF_STORE_ALL_CAPS);
18761879
return r->refs;
18771880
}
18781881

@@ -1927,7 +1930,7 @@ struct ref_store *get_submodule_ref_store(const char *submodule)
19271930
goto done;
19281931

19291932
/* assume that add_submodule_odb() has been called */
1930-
refs = ref_store_init(submodule_sb.buf,
1933+
refs = ref_store_init(submodule_sb.buf, "files", /* XXX */
19311934
REF_STORE_READ | REF_STORE_ODB);
19321935
register_ref_store_map(&submodule_ref_stores, "submodule",
19331936
refs, submodule);
@@ -1941,6 +1944,7 @@ struct ref_store *get_submodule_ref_store(const char *submodule)
19411944

19421945
struct ref_store *get_worktree_ref_store(const struct worktree *wt)
19431946
{
1947+
const char *format = "files"; /* XXX */
19441948
struct ref_store *refs;
19451949
const char *id;
19461950

@@ -1954,9 +1958,9 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
19541958

19551959
if (wt->id)
19561960
refs = ref_store_init(git_common_path("worktrees/%s", wt->id),
1957-
REF_STORE_ALL_CAPS);
1961+
format, REF_STORE_ALL_CAPS);
19581962
else
1959-
refs = ref_store_init(get_git_common_dir(),
1963+
refs = ref_store_init(get_git_common_dir(), format,
19601964
REF_STORE_ALL_CAPS);
19611965

19621966
if (refs)

refs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,18 +446,21 @@ int delete_refs(const char *msg, struct string_list *refnames,
446446
int refs_delete_reflog(struct ref_store *refs, const char *refname);
447447
int delete_reflog(const char *refname);
448448

449-
/* iterate over reflog entries */
449+
/* Iterate over reflog entries. */
450450
typedef int each_reflog_ent_fn(
451451
struct object_id *old_oid, struct object_id *new_oid,
452452
const char *committer, timestamp_t timestamp,
453453
int tz, const char *msg, void *cb_data);
454454

455+
/* Iterate in over reflog entries, oldest entry first. */
455456
int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
456457
each_reflog_ent_fn fn, void *cb_data);
457458
int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
458459
const char *refname,
459460
each_reflog_ent_fn fn,
460461
void *cb_data);
462+
463+
/* Call a function for each reflog entry, oldest entry first. */
461464
int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data);
462465
int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data);
463466

refs/files-backend.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,9 +3157,15 @@ static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
31573157
files_downcast(ref_store, REF_STORE_WRITE, "init_db");
31583158
struct strbuf sb = STRBUF_INIT;
31593159

3160+
files_ref_path(refs, &sb, "refs");
3161+
safe_create_dir(sb.buf, 1);
3162+
/* adjust permissions even if directory already exists. */
3163+
adjust_shared_perm(sb.buf);
3164+
31603165
/*
31613166
* Create .git/refs/{heads,tags}
31623167
*/
3168+
strbuf_reset(&sb);
31633169
files_ref_path(refs, &sb, "refs/heads");
31643170
safe_create_dir(sb.buf, 1);
31653171

refs/refs-internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,11 @@ void base_ref_iterator_free(struct ref_iterator *iter);
438438

439439
/* Virtual function declarations for ref_iterators: */
440440

441+
/*
442+
* backend-specific implementation of ref_iterator_advance.
443+
* For symrefs, the function should set REF_ISSYMREF, and it should also dereference
444+
* the symref to provide the OID referent.
445+
*/
441446
typedef int ref_iterator_advance_fn(struct ref_iterator *ref_iterator);
442447

443448
typedef int ref_iterator_peel_fn(struct ref_iterator *ref_iterator,
@@ -656,6 +661,7 @@ struct ref_storage_be {
656661
};
657662

658663
extern struct ref_storage_be refs_be_files;
664+
extern struct ref_storage_be refs_be_reftable;
659665
extern struct ref_storage_be refs_be_packed;
660666

661667
/*

0 commit comments

Comments
 (0)