Commit e87bcb3d770316fcb59f35d0aa6919c14a2a0eaa

Edward Thomson 2021-07-30T10:32:02

Merge branch 'pr/5491'

diff --git a/include/git2/common.h b/include/git2/common.h
index dee260e..4402dfd 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -207,7 +207,9 @@ typedef enum {
 	GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS,
 	GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE,
 	GIT_OPT_GET_MWINDOW_FILE_LIMIT,
-	GIT_OPT_SET_MWINDOW_FILE_LIMIT
+	GIT_OPT_SET_MWINDOW_FILE_LIMIT,
+	GIT_OPT_SET_ODB_PACKED_PRIORITY,
+	GIT_OPT_SET_ODB_LOOSE_PRIORITY
 } git_libgit2_opt_t;
 
 /**
@@ -421,6 +423,14 @@ typedef enum {
  *		> authentication, use expect/continue when POSTing data.
  *		> This option is not available on Windows.
  *
+ *   opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, int priority)
+ *      > Override the default priority of the packed ODB backend which
+ *      > is added when default backends are assigned to a repository
+ *
+ *   opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, int priority)
+ *      > Override the default priority of the loose ODB backend which
+ *      > is added when default backends are assigned to a repository
+ *
  * @param option Option key
  * @param ... value to set the option
  * @return 0 on success, <0 on failure
diff --git a/src/libgit2.c b/src/libgit2.c
index f27c999..089c835 100644
--- a/src/libgit2.c
+++ b/src/libgit2.c
@@ -50,6 +50,8 @@ extern size_t git_mwindow__mapped_limit;
 extern size_t git_mwindow__file_limit;
 extern size_t git_indexer__max_objects;
 extern bool git_disable_pack_keep_file_checks;
+extern int git_odb__packed_priority;
+extern int git_odb__loose_priority;
 
 char *git__user_agent;
 char *git__ssl_ciphers;
@@ -368,6 +370,14 @@ int git_libgit2_opts(int key, ...)
 		git_http__expect_continue = (va_arg(ap, int) != 0);
 		break;
 
+	case GIT_OPT_SET_ODB_PACKED_PRIORITY:
+		git_odb__packed_priority = va_arg(ap, int);
+		break;
+
+	case GIT_OPT_SET_ODB_LOOSE_PRIORITY:
+		git_odb__loose_priority = va_arg(ap, int);
+		break;
+
 	default:
 		git_error_set(GIT_ERROR_INVALID, "invalid option key");
 		error = -1;
diff --git a/src/odb.c b/src/odb.c
index 05bdaf6..35e2259 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -23,14 +23,14 @@
 
 #define GIT_ALTERNATES_FILE "info/alternates"
 
+#define GIT_ALTERNATES_MAX_DEPTH 5
+
 /*
  * We work under the assumption that most objects for long-running
  * operations will be packed
  */
-#define GIT_LOOSE_PRIORITY 1
-#define GIT_PACKED_PRIORITY 2
-
-#define GIT_ALTERNATES_MAX_DEPTH 5
+int git_odb__loose_priority = 1;
+int git_odb__packed_priority = 2;
 
 bool git_odb__strict_hash_verification = true;
 
@@ -613,12 +613,12 @@ int git_odb__add_default_backends(
 
 	/* add the loose object backend */
 	if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 ||
-		add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0)
+		add_backend_internal(db, loose, git_odb__loose_priority, as_alternates, inode) < 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, inode) < 0)
+		add_backend_internal(db, packed, git_odb__packed_priority, as_alternates, inode) < 0)
 		return -1;
 
 	if (git_mutex_lock(&db->lock) < 0) {
diff --git a/tests/odb/sorting.c b/tests/odb/sorting.c
index 6af8b0d..dc87a85 100644
--- a/tests/odb/sorting.c
+++ b/tests/odb/sorting.c
@@ -68,3 +68,26 @@ void test_odb_sorting__alternate_backends_sorting(void)
 
 	check_backend_sorting(_odb);
 }
+
+void test_odb_sorting__override_default_backend_priority(void)
+{
+	git_odb *new_odb;
+	git_odb_backend *loose, *packed, *backend;
+	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, 5));
+	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, 3));
+	git_odb_backend_pack(&packed, "./testrepo.git/objects");
+	git_odb_backend_loose(&loose, "./testrepo.git/objects", -1, 0, 0, 0);
+
+	cl_git_pass(git_odb_open(&new_odb, cl_fixture("testrepo.git/objects")));
+	cl_assert_equal_sz(2, git_odb_num_backends(new_odb));
+
+	cl_git_pass(git_odb_get_backend(&backend, new_odb, 0));
+	cl_assert_equal_p(loose->read, backend->read);
+
+	cl_git_pass(git_odb_get_backend(&backend, new_odb, 1));
+	cl_assert_equal_p(packed->read, backend->read);
+
+	git_odb_free(new_odb);
+	loose->free(loose);
+	packed->free(packed);
+}