Commit 6de8aa7f3144efe10d706bca513c8add24e8f407

Edward Thomson 2020-06-02T12:21:22

Merge pull request #5532 from joshtriplett/pack-default-path git_packbuilder_write: Allow setting path to NULL to use the default path

diff --git a/include/git2/pack.h b/include/git2/pack.h
index 922a3cd..3b9beb6 100644
--- a/include/git2/pack.h
+++ b/include/git2/pack.h
@@ -155,7 +155,7 @@ GIT_EXTERN(int) git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb);
  * Write the new pack and corresponding index file to path.
  *
  * @param pb The packbuilder
- * @param path to the directory where the packfile and index should be stored
+ * @param path Path to the directory where the packfile and index should be stored, or NULL for default location
  * @param mode permissions to use creating a packfile or 0 for defaults
  * @param progress_cb function to call with progress information from the indexer (optional)
  * @param progress_cb_payload payload for the progress callback (optional)
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 2e5b640..1ac618a 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -1381,20 +1381,29 @@ int git_packbuilder_write(
 	git_indexer_progress_cb progress_cb,
 	void *progress_cb_payload)
 {
+	int error = -1;
+	git_buf object_path = GIT_BUF_INIT;
 	git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT;
-	git_indexer *indexer;
+	git_indexer *indexer = NULL;
 	git_indexer_progress stats;
 	struct pack_write_context ctx;
 	int t;
 
 	PREPARE_PACK;
 
+	if (path == NULL) {
+		if ((error = git_repository_item_path(&object_path, pb->repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0)
+			goto cleanup;
+		if ((error = git_buf_joinpath(&object_path, git_buf_cstr(&object_path), "pack")) < 0)
+			goto cleanup;
+		path = git_buf_cstr(&object_path);
+	}
+
 	opts.progress_cb = progress_cb;
 	opts.progress_cb_payload = progress_cb_payload;
 
-	if (git_indexer_new(
-		&indexer, path, mode, pb->odb, &opts) < 0)
-		return -1;
+	if ((error = git_indexer_new(&indexer, path, mode, pb->odb, &opts)) < 0)
+		goto cleanup;
 
 	if (!git_repository__configmap_lookup(&t, pb->repo, GIT_CONFIGMAP_FSYNCOBJECTFILES) && t)
 		git_indexer__set_fsync(indexer, 1);
@@ -1402,16 +1411,18 @@ int git_packbuilder_write(
 	ctx.indexer = indexer;
 	ctx.stats = &stats;
 
-	if (git_packbuilder_foreach(pb, write_cb, &ctx) < 0 ||
-		git_indexer_commit(indexer, &stats) < 0) {
-		git_indexer_free(indexer);
-		return -1;
-	}
+	if ((error = git_packbuilder_foreach(pb, write_cb, &ctx)) < 0)
+		goto cleanup;
+
+	if ((error = git_indexer_commit(indexer, &stats)) < 0)
+		goto cleanup;
 
 	git_oid_cpy(&pb->pack_oid, git_indexer_hash(indexer));
 
+cleanup:
 	git_indexer_free(indexer);
-	return 0;
+	git_buf_dispose(&object_path);
+	return error;
 }
 
 #undef PREPARE_PACK
diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c
index 32f0612..5f5441a 100644
--- a/tests/pack/packbuilder.c
+++ b/tests/pack/packbuilder.c
@@ -151,6 +151,15 @@ void test_pack_packbuilder__get_hash(void)
 	cl_assert_equal_s(hex, "7f5fa362c664d68ba7221259be1cbd187434b2f0");
 }
 
+void test_pack_packbuilder__write_default_path(void)
+{
+	seed_packbuilder();
+
+	cl_git_pass(git_packbuilder_write(_packbuilder, NULL, 0, NULL, NULL));
+	cl_assert(git_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx"));
+	cl_assert(git_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack"));
+}
+
 static void test_write_pack_permission(mode_t given, mode_t expected)
 {
 	struct stat statbuf;