From a29c6b5f47676d864af1e78c7927bc3cb2b329d7 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Fri, 19 Apr 2013 23:51:18 +0200 Subject: [PATCH 1/2] odb: Do not allow duplicate on-disk backends --- src/odb.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/odb.c b/src/odb.c index c98df247c..1c7969fcb 100644 --- a/src/odb.c +++ b/src/odb.c @@ -29,7 +29,8 @@ typedef struct { git_odb_backend *backend; int priority; - int is_alternate; + bool is_alternate; + ino_t disk_inode; } backend_internal; size_t git_odb__cache_size = GIT_DEFAULT_CACHE_SIZE; @@ -365,7 +366,9 @@ int git_odb_new(git_odb **out) return 0; } -static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int priority, int is_alternate) +static int add_backend_internal( + git_odb *odb, git_odb_backend *backend, + int priority, bool is_alternate, ino_t disk_inode) { backend_internal *internal; @@ -382,6 +385,7 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio internal->backend = backend; internal->priority = priority; internal->is_alternate = is_alternate; + internal->disk_inode = disk_inode; if (git_vector_insert(&odb->backends, internal) < 0) { git__free(internal); @@ -395,26 +399,41 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio int git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority) { - return add_backend_internal(odb, backend, priority, 0); + return add_backend_internal(odb, backend, priority, false, 0); } int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority) { - return add_backend_internal(odb, backend, priority, 1); + return add_backend_internal(odb, backend, priority, true, 0); } -static int add_default_backends(git_odb *db, const char *objects_dir, int as_alternates, int alternate_depth) +static int add_default_backends( + git_odb *db, const char *objects_dir, + bool as_alternates, int alternate_depth) { + size_t i; + struct stat st; git_odb_backend *loose, *packed; + if (p_stat(objects_dir, &st) < 0) { + giterr_set(GITERR_ODB, "Failed to load object database in '%s'", objects_dir); + return -1; + } + + for (i = 0; i < db->backends.length; ++i) { + backend_internal *backend = git_vector_get(&db->backends, i); + if (backend->disk_inode == st.st_ino) + return 0; + } + /* add the loose object backend */ if (git_odb_backend_loose(&loose, objects_dir, -1, 0) < 0 || - add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates) < 0) + add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, st.st_ino) < 0) return -1; /* add the packed file backend */ if (git_odb_backend_pack(&packed, objects_dir) < 0 || - add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates) < 0) + add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates, st.st_ino) < 0) return -1; return load_alternates(db, objects_dir, alternate_depth); @@ -464,7 +483,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ alternate = git_buf_cstr(&alternates_path); } - if ((result = add_default_backends(odb, alternate, 1, alternate_depth + 1)) < 0) + if ((result = add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0) break; } @@ -476,7 +495,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ int git_odb_add_disk_alternate(git_odb *odb, const char *path) { - return add_default_backends(odb, path, 1, 0); + return add_default_backends(odb, path, true, 0); } int git_odb_open(git_odb **out, const char *objects_dir) From 4ef2c79cb6dc81e17b68ccf7c270bcc7e4f85bfb Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Mon, 22 Apr 2013 16:37:40 +0200 Subject: [PATCH 2/2] odb: Disable inode checks for Win32 --- src/odb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/odb.c b/src/odb.c index 1c7969fcb..8249c5adc 100644 --- a/src/odb.c +++ b/src/odb.c @@ -415,6 +415,9 @@ static int add_default_backends( struct stat st; git_odb_backend *loose, *packed; + /* TODO: inodes are not really relevant on Win32, so we need to find + * a cross-platform workaround for this */ +#ifndef GIT_WIN32 if (p_stat(objects_dir, &st) < 0) { giterr_set(GITERR_ODB, "Failed to load object database in '%s'", objects_dir); return -1; @@ -425,6 +428,7 @@ static int add_default_backends( if (backend->disk_inode == st.st_ino) return 0; } +#endif /* add the loose object backend */ if (git_odb_backend_loose(&loose, objects_dir, -1, 0) < 0 ||