Skip to content

Commit 4d7ec76

Browse files
committed
odb: add git_odb_loose_backend_options
Move the arguments to `git_odb_loose` into an options structure.
1 parent dbccfc2 commit 4d7ec76

File tree

5 files changed

+91
-38
lines changed

5 files changed

+91
-38
lines changed

include/git2/odb_backend.h

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,55 @@ GIT_BEGIN_DECL
3434
*/
3535
GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir);
3636

37+
typedef enum {
38+
GIT_ODB_BACKEND_LOOSE_FSYNC = (1 << 0)
39+
} git_odb_backend_loose_flag_t;
40+
41+
/** Options for configuring a loose object backend. */
42+
typedef struct {
43+
unsigned int version; /**< version for the struct */
44+
45+
/** A combination of the `git_odb_backend_loose_flag_t` types. */
46+
uint32_t flags;
47+
48+
/**
49+
* zlib compression level to use (0-9), where 1 is the fastest
50+
* at the expense of larger files, and 9 produces the best
51+
* compression at the expense of speed. 0 indicates that no
52+
* compression should be performed. -1 is the default (currently
53+
* optimizing for speed).
54+
*/
55+
int compression_level;
56+
57+
/** Permissions to use creating a directory or 0 for defaults */
58+
unsigned int dir_mode;
59+
60+
/** Permissions to use creating a file or 0 for defaults */
61+
unsigned int file_mode;
62+
} git_odb_backend_loose_options;
63+
64+
/* The current version of the diff options structure */
65+
#define GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION 1
66+
67+
/* Stack initializer for diff options. Alternatively use
68+
* `git_diff_options_init` programmatic initialization.
69+
*/
70+
#define GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT \
71+
{ GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION, 0, -1 }
72+
3773
/**
3874
* Create a backend for loose objects
3975
*
4076
* @param out location to store the odb backend pointer
4177
* @param objects_dir the Git repository's objects directory
42-
* @param compression_level zlib compression level to use
43-
* @param do_fsync whether to do an fsync() after writing
44-
* @param dir_mode permissions to use creating a directory or 0 for defaults
45-
* @param file_mode permissions to use creating a file or 0 for defaults
78+
* @param opts options for the loose object backend or NULL
4679
*
4780
* @return 0 or an error code
4881
*/
4982
GIT_EXTERN(int) git_odb_backend_loose(
5083
git_odb_backend **out,
5184
const char *objects_dir,
52-
int compression_level,
53-
int do_fsync,
54-
unsigned int dir_mode,
55-
unsigned int file_mode);
85+
git_odb_backend_loose_options *opts);
5686

5787
/**
5888
* Create a backend out of a single packfile

src/libgit2/odb.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ int git_odb__add_default_backends(
625625
struct stat st;
626626
ino_t inode;
627627
git_odb_backend *loose, *packed;
628+
git_odb_backend_loose_options loose_opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT;
628629

629630
/* TODO: inodes are not really relevant on Win32, so we need to find
630631
* a cross-platform workaround for this */
@@ -659,8 +660,11 @@ int git_odb__add_default_backends(
659660
git_mutex_unlock(&db->lock);
660661
#endif
661662

663+
if (db->do_fsync)
664+
loose_opts.flags |= GIT_ODB_BACKEND_LOOSE_FSYNC;
665+
662666
/* add the loose object backend */
663-
if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 ||
667+
if (git_odb_backend_loose(&loose, objects_dir, &loose_opts) < 0 ||
664668
add_backend_internal(db, loose, git_odb__loose_priority, as_alternates, inode) < 0)
665669
return -1;
666670

src/libgit2/odb_loose.c

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ typedef struct {
4646
typedef struct loose_backend {
4747
git_odb_backend parent;
4848

49-
int object_zlib_level; /** loose object zlib compression level. */
50-
int fsync_object_files; /** loose object file fsync flag. */
51-
mode_t object_file_mode;
52-
mode_t object_dir_mode;
49+
git_odb_backend_loose_options options;
5350

5451
size_t objects_dirlen;
5552
char objects_dir[GIT_FLEX_ARRAY];
@@ -100,7 +97,9 @@ static int object_file_name(
10097
static int object_mkdir(const git_str *name, const loose_backend *be)
10198
{
10299
return git_futils_mkdir_relative(
103-
name->ptr + be->objects_dirlen, be->objects_dir, be->object_dir_mode,
100+
name->ptr + be->objects_dirlen,
101+
be->objects_dir,
102+
be->options.dir_mode,
104103
GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR, NULL);
105104
}
106105

@@ -827,9 +826,10 @@ static void loose_backend__writestream_free(git_odb_stream *_stream)
827826
static int filebuf_flags(loose_backend *backend)
828827
{
829828
int flags = GIT_FILEBUF_TEMPORARY |
830-
(backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT);
829+
(backend->options.compression_level << GIT_FILEBUF_DEFLATE_SHIFT);
831830

832-
if (backend->fsync_object_files || git_repository__fsync_gitdir)
831+
if ((backend->options.flags & GIT_ODB_BACKEND_LOOSE_FSYNC) ||
832+
git_repository__fsync_gitdir)
833833
flags |= GIT_FILEBUF_FSYNC;
834834

835835
return flags;
@@ -865,7 +865,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe
865865

866866
if (git_str_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 ||
867867
git_filebuf_open(&stream->fbuf, tmp_path.ptr, filebuf_flags(backend),
868-
backend->object_file_mode) < 0 ||
868+
backend->options.file_mode) < 0 ||
869869
stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0)
870870
{
871871
git_filebuf_cleanup(&stream->fbuf);
@@ -1083,7 +1083,7 @@ static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, c
10831083

10841084
if (git_str_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 ||
10851085
git_filebuf_open(&fbuf, final_path.ptr, filebuf_flags(backend),
1086-
backend->object_file_mode) < 0)
1086+
backend->options.file_mode) < 0)
10871087
{
10881088
error = -1;
10891089
goto cleanup;
@@ -1126,13 +1126,31 @@ static void loose_backend__free(git_odb_backend *_backend)
11261126
git__free(_backend);
11271127
}
11281128

1129+
static void normalize_options(
1130+
git_odb_backend_loose_options *opts,
1131+
const git_odb_backend_loose_options *given_opts)
1132+
{
1133+
git_odb_backend_loose_options init = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT;
1134+
1135+
if (given_opts)
1136+
memcpy(opts, given_opts, sizeof(git_odb_backend_loose_options));
1137+
else
1138+
memcpy(opts, &init, sizeof(git_odb_backend_loose_options));
1139+
1140+
if (opts->compression_level < 0)
1141+
opts->compression_level = Z_BEST_SPEED;
1142+
1143+
if (opts->dir_mode == 0)
1144+
opts->dir_mode = GIT_OBJECT_DIR_MODE;
1145+
1146+
if (opts->file_mode == 0)
1147+
opts->file_mode = GIT_OBJECT_FILE_MODE;
1148+
}
1149+
11291150
int git_odb_backend_loose(
11301151
git_odb_backend **backend_out,
11311152
const char *objects_dir,
1132-
int compression_level,
1133-
int do_fsync,
1134-
unsigned int dir_mode,
1135-
unsigned int file_mode)
1153+
git_odb_backend_loose_options *opts)
11361154
{
11371155
loose_backend *backend;
11381156
size_t objects_dirlen, alloclen;
@@ -1150,22 +1168,11 @@ int git_odb_backend_loose(
11501168
backend->parent.version = GIT_ODB_BACKEND_VERSION;
11511169
backend->objects_dirlen = objects_dirlen;
11521170
memcpy(backend->objects_dir, objects_dir, objects_dirlen);
1171+
11531172
if (backend->objects_dir[backend->objects_dirlen - 1] != '/')
11541173
backend->objects_dir[backend->objects_dirlen++] = '/';
11551174

1156-
if (compression_level < 0)
1157-
compression_level = Z_BEST_SPEED;
1158-
1159-
if (dir_mode == 0)
1160-
dir_mode = GIT_OBJECT_DIR_MODE;
1161-
1162-
if (file_mode == 0)
1163-
file_mode = GIT_OBJECT_FILE_MODE;
1164-
1165-
backend->object_zlib_level = compression_level;
1166-
backend->fsync_object_files = do_fsync;
1167-
backend->object_dir_mode = dir_mode;
1168-
backend->object_file_mode = file_mode;
1175+
normalize_options(&backend->options, opts);
11691176

11701177
backend->parent.read = &loose_backend__read;
11711178
backend->parent.write = &loose_backend__write;

tests/libgit2/odb/loose.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ static void test_write_object_permission(
196196
git_oid oid;
197197
struct stat statbuf;
198198
mode_t mask, os_mask;
199+
git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT;
199200

200201
/* Windows does not return group/user bits from stat,
201202
* files are never executable.
@@ -209,8 +210,11 @@ static void test_write_object_permission(
209210
mask = p_umask(0);
210211
p_umask(mask);
211212

213+
opts.dir_mode = dir_mode;
214+
opts.file_mode = file_mode;
215+
212216
cl_git_pass(git_odb_new(&odb, NULL));
213-
cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, 0, dir_mode, file_mode));
217+
cl_git_pass(git_odb_backend_loose(&backend, "test-objects", &opts));
214218
cl_git_pass(git_odb_add_backend(odb, backend, 1));
215219
cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJECT_BLOB));
216220

@@ -243,9 +247,16 @@ static void write_object_to_loose_odb(int fsync)
243247
git_odb *odb;
244248
git_odb_backend *backend;
245249
git_oid oid;
250+
git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT;
251+
252+
if (fsync)
253+
opts.flags |= GIT_ODB_BACKEND_LOOSE_FSYNC;
254+
255+
opts.dir_mode = 0777;
256+
opts.file_mode = 0666;
246257

247258
cl_git_pass(git_odb_new(&odb, NULL));
248-
cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, fsync, 0777, 0666));
259+
cl_git_pass(git_odb_backend_loose(&backend, "test-objects", &opts));
249260
cl_git_pass(git_odb_add_backend(odb, backend, 1));
250261
cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJECT_BLOB));
251262
git_odb_free(odb);

tests/libgit2/odb/sorting.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,11 @@ void test_odb_sorting__override_default_backend_priority(void)
7979
{
8080
git_odb *new_odb;
8181
git_odb_backend *loose, *packed, *backend;
82+
8283
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, 5));
8384
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, 3));
8485
git_odb_backend_pack(&packed, "./testrepo.git/objects");
85-
git_odb_backend_loose(&loose, "./testrepo.git/objects", -1, 0, 0, 0);
86+
git_odb_backend_loose(&loose, "./testrepo.git/objects", NULL);
8687

8788
cl_git_pass(git_odb_open(&new_odb, cl_fixture("testrepo.git/objects"), NULL));
8889
cl_assert_equal_sz(2, git_odb_num_backends(new_odb));

0 commit comments

Comments
 (0)