Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6c4dadb

Browse files
author
Vicent Martí
committed
Merge pull request libgit2#1669 from arrbee/fix-index-add-bypath
In loose objects backend, constrain mkdir calls to avoid extra mkdirs
2 parents 9f1b2c5 + 32c12ea commit 6c4dadb

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

src/fileops.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ int git_futils_mkdir(
348348
int tmp_errno = errno;
349349

350350
/* ignore error if directory already exists */
351-
if (p_stat(make_path.ptr, &st) < 0 || !S_ISDIR(st.st_mode)) {
351+
if (p_stat(make_path.ptr, &st) < 0 ||
352+
!(S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
352353
errno = tmp_errno;
353354
giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
354355
goto done;

src/odb_loose.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ typedef struct loose_backend {
3333

3434
int object_zlib_level; /** loose object zlib compression level. */
3535
int fsync_object_files; /** loose object file fsync flag. */
36-
char *objects_dir;
36+
37+
size_t objects_dirlen;
38+
char objects_dir[GIT_FLEX_ARRAY];
3739
} loose_backend;
3840

3941
/* State structure for exploring directories,
@@ -56,24 +58,30 @@ typedef struct {
5658
*
5759
***********************************************************/
5860

59-
static int object_file_name(git_buf *name, const char *dir, const git_oid *id)
61+
static int object_file_name(
62+
git_buf *name, const loose_backend *be, const git_oid *id)
6063
{
61-
git_buf_sets(name, dir);
62-
63-
/* expand length for 40 hex sha1 chars + 2 * '/' + '\0' */
64-
if (git_buf_grow(name, git_buf_len(name) + GIT_OID_HEXSZ + 3) < 0)
64+
/* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */
65+
if (git_buf_grow(name, be->objects_dirlen + GIT_OID_HEXSZ + 3) < 0)
6566
return -1;
6667

68+
git_buf_set(name, be->objects_dir, be->objects_dirlen);
6769
git_path_to_dir(name);
6870

6971
/* loose object filename: aa/aaa... (41 bytes) */
70-
git_oid_pathfmt(name->ptr + git_buf_len(name), id);
72+
git_oid_pathfmt(name->ptr + name->size, id);
7173
name->size += GIT_OID_HEXSZ + 1;
7274
name->ptr[name->size] = '\0';
7375

7476
return 0;
7577
}
7678

79+
static int object_mkdir(const git_buf *name, const loose_backend *be)
80+
{
81+
return git_futils_mkdir(
82+
name->ptr + be->objects_dirlen, be->objects_dir, GIT_OBJECT_DIR_MODE,
83+
GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR);
84+
}
7785

7886
static size_t get_binary_object_header(obj_hdr *hdr, git_buf *obj)
7987
{
@@ -457,7 +465,7 @@ static int locate_object(
457465
loose_backend *backend,
458466
const git_oid *oid)
459467
{
460-
int error = object_file_name(object_location, backend->objects_dir, oid);
468+
int error = object_file_name(object_location, backend, oid);
461469

462470
if (!error && !git_path_exists(object_location->ptr))
463471
return GIT_ENOTFOUND;
@@ -769,8 +777,8 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream)
769777
int error = 0;
770778

771779
if (git_filebuf_hash(oid, &stream->fbuf) < 0 ||
772-
object_file_name(&final_path, backend->objects_dir, oid) < 0 ||
773-
git_futils_mkpath2file(final_path.ptr, GIT_OBJECT_DIR_MODE) < 0)
780+
object_file_name(&final_path, backend, oid) < 0 ||
781+
object_mkdir(&final_path, backend) < 0)
774782
error = -1;
775783
/*
776784
* Don't try to add an existing object to the repository. This
@@ -880,8 +888,8 @@ static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const v
880888
git_filebuf_write(&fbuf, header, header_len);
881889
git_filebuf_write(&fbuf, data, len);
882890

883-
if (object_file_name(&final_path, backend->objects_dir, oid) < 0 ||
884-
git_futils_mkpath2file(final_path.ptr, GIT_OBJECT_DIR_MODE) < 0 ||
891+
if (object_file_name(&final_path, backend, oid) < 0 ||
892+
object_mkdir(&final_path, backend) < 0 ||
885893
git_filebuf_commit_at(&fbuf, final_path.ptr, GIT_OBJECT_FILE_MODE) < 0)
886894
error = -1;
887895

@@ -898,7 +906,6 @@ static void loose_backend__free(git_odb_backend *_backend)
898906
assert(_backend);
899907
backend = (loose_backend *)_backend;
900908

901-
git__free(backend->objects_dir);
902909
git__free(backend);
903910
}
904911

@@ -909,13 +916,20 @@ int git_odb_backend_loose(
909916
int do_fsync)
910917
{
911918
loose_backend *backend;
919+
size_t objects_dirlen;
920+
921+
assert(backend_out && objects_dir);
922+
923+
objects_dirlen = strlen(objects_dir);
912924

913-
backend = git__calloc(1, sizeof(loose_backend));
925+
backend = git__calloc(1, sizeof(loose_backend) + objects_dirlen + 2);
914926
GITERR_CHECK_ALLOC(backend);
915927

916928
backend->parent.version = GIT_ODB_BACKEND_VERSION;
917-
backend->objects_dir = git__strdup(objects_dir);
918-
GITERR_CHECK_ALLOC(backend->objects_dir);
929+
backend->objects_dirlen = objects_dirlen;
930+
memcpy(backend->objects_dir, objects_dir, objects_dirlen);
931+
if (backend->objects_dir[backend->objects_dirlen - 1] != '/')
932+
backend->objects_dir[backend->objects_dirlen++] = '/';
919933

920934
if (compression_level < 0)
921935
compression_level = Z_BEST_SPEED;

0 commit comments

Comments
 (0)