Skip to content

Commit 2691faa

Browse files
pks-tgitster
authored andcommitted
odb: make creation of on-disk structures pluggable
When creating a new "files" object database source we have to create a couple of directories. These directories are of course specific to this particular backend, and a different backend may require a setup that is completely different. Make the creation of on-disk structures pluggable to accommodate for this. Note that there is one exception though: the "objects" directory must exist in a repository regardless of which backend is in use. If it doesn't exist then the repository is not treated as a Git repository at all. Consequently, we create this directory regardless of the backend. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent bdf92ad commit 2691faa

3 files changed

Lines changed: 62 additions & 15 deletions

File tree

odb/source-files.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "odb/source-files.h"
1010
#include "odb/source-loose.h"
1111
#include "packfile.h"
12+
#include "path.h"
1213
#include "strbuf.h"
1314
#include "write-or-die.h"
1415

@@ -41,6 +42,23 @@ static void odb_source_files_close(struct odb_source *source)
4142
odb_source_close(&files->packed->base);
4243
}
4344

45+
static int odb_source_files_create_on_disk(struct odb_source *source)
46+
{
47+
struct strbuf path = STRBUF_INIT;
48+
49+
safe_create_dir(source->odb->repo, source->path, 1);
50+
51+
strbuf_addf(&path, "%s/pack", source->path);
52+
safe_create_dir(source->odb->repo, path.buf, 1);
53+
54+
strbuf_reset(&path);
55+
strbuf_addf(&path, "%s/info", source->path);
56+
safe_create_dir(source->odb->repo, path.buf, 1);
57+
58+
strbuf_release(&path);
59+
return 0;
60+
}
61+
4462
static void odb_source_files_prepare(struct odb_source *source,
4563
enum odb_prepare_flags flags)
4664
{
@@ -271,6 +289,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
271289

272290
files->base.free = odb_source_files_free;
273291
files->base.close = odb_source_files_close;
292+
files->base.create_on_disk = odb_source_files_create_on_disk;
274293
files->base.prepare = odb_source_files_prepare;
275294
files->base.read_object_info = odb_source_files_read_object_info;
276295
files->base.read_object_stream = odb_source_files_read_object_stream;

odb/source.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ struct odb_source {
8989
*/
9090
void (*close)(struct odb_source *source);
9191

92+
/*
93+
* This callback is expected to create on-disk data structures that are
94+
* required for this source to operate.
95+
*
96+
* The callback is expected to return 0 on success, a negative error
97+
* code otherwise.
98+
*
99+
* This callback may be NULL in case the source does not need any
100+
* on-disk setup.
101+
*/
102+
int (*create_on_disk)(struct odb_source *source);
103+
92104
/*
93105
* This callback is expected to prepare the source so that it becomes
94106
* ready for use. It optionally clears underlying caches of the object
@@ -316,6 +328,17 @@ static inline void odb_source_close(struct odb_source *source)
316328
source->close(source);
317329
}
318330

331+
/*
332+
* Create on-disk data structures that are required for this source to operate
333+
* correctly. Returns 0 on success, a negative error code otherwise.
334+
*/
335+
static inline int odb_source_create_on_disk(struct odb_source *source)
336+
{
337+
if (!source->create_on_disk)
338+
return 0;
339+
return source->create_on_disk(source);
340+
}
341+
319342
/*
320343
* Prepare the object database source and clear any caches. Depending on the
321344
* backend used this may have the effect that concurrently-written objects

setup.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,29 +2666,34 @@ static int create_default_files(struct repository *repo,
26662666
static void create_object_database(struct repository *repo)
26672667
{
26682668
char *object_directory, *alternate_object_directories;
2669-
struct strbuf path = STRBUF_INIT;
2670-
size_t baselen;
26712669

26722670
get_object_directories(&object_directory, &alternate_object_directories);
2673-
repo->objects = odb_new(repo, object_directory,
2674-
alternate_object_directories);
26752671

2676-
strbuf_addstr(&path, repo_get_object_directory(repo));
2677-
baselen = path.len;
2678-
2679-
safe_create_dir(repo, path.buf, 1);
2672+
/*
2673+
* Create the "objects" directory in the common directory. This is done
2674+
* so that the repository can be discovered regardless of the backend
2675+
* used.
2676+
*
2677+
* Note that we only do this in case the object directory wasn't
2678+
* overwritten via an environment variable. If it _is_ being overridden
2679+
* then we skip this step, as the repository won't be discoverable
2680+
* anyway without the environment variable.
2681+
*/
2682+
if (!object_directory) {
2683+
struct strbuf objects_dir = STRBUF_INIT;
2684+
repo_common_path_append(repo, &objects_dir, "objects");
2685+
safe_create_dir(repo, objects_dir.buf, 1);
2686+
strbuf_release(&objects_dir);
2687+
}
26802688

2681-
strbuf_setlen(&path, baselen);
2682-
strbuf_addstr(&path, "/pack");
2683-
safe_create_dir(repo, path.buf, 1);
2689+
repo->objects = odb_new(repo, object_directory,
2690+
alternate_object_directories);
26842691

2685-
strbuf_setlen(&path, baselen);
2686-
strbuf_addstr(&path, "/info");
2687-
safe_create_dir(repo, path.buf, 1);
2692+
if (odb_source_create_on_disk(repo->objects->sources) < 0)
2693+
die("failed creating object database");
26882694

26892695
free(alternate_object_directories);
26902696
free(object_directory);
2691-
strbuf_release(&path);
26922697
}
26932698

26942699
static void separate_git_dir(const char *git_dir, const char *git_link)

0 commit comments

Comments
 (0)