Commit f7e59c4dcf46e0815ab0e7d435fd16755fdf616c

Vicent Marti 2011-06-01T18:34:21

index: Change the memory management for repo indexes The `git_repository_index` call now returns a brand new index that must be manually free'd.

diff --git a/include/git2/index.h b/include/git2/index.h
index 57401a9..45900d0 100644
--- a/include/git2/index.h
+++ b/include/git2/index.h
@@ -109,29 +109,24 @@ typedef struct git_index_entry_unmerged {
 } git_index_entry_unmerged;
 
 /**
- * Create a new Git index object as a memory representation
+ * Create a new bare Git index object as a memory representation
  * of the Git index file in 'index_path', without a repository
  * to back it.
  *
- * Since there is no ODB behind this index, any Index methods
- * which rely on the ODB (e.g. index_add) will fail with the
- * GIT_EBAREINDEX error code.
+ * Since there is no ODB or working directory behind this index,
+ * any Index methods which rely on these (e.g. index_add) will
+ * fail with the GIT_EBAREINDEX error code.
  *
- * @param index the pointer for the new index
- * @param index_path the path to the index file in disk
- * @return 0 on success; error code otherwise
- */
-GIT_EXTERN(int) git_index_open_bare(git_index **index, const char *index_path);
-
-/**
- * Open the Index inside the git repository pointed
- * by 'repo'.
+ * If you need to access the index of an actual repository,
+ * use the `git_repository_index` wrapper.
+ *
+ * The index must be freed once it's no longer in use.
  *
  * @param index the pointer for the new index
- * @param repo the git repo which owns the index
+ * @param index_path the path to the index file in disk
  * @return 0 on success; error code otherwise
  */
-GIT_EXTERN(int) git_index_open_inrepo(git_index **index, git_repository *repo);
+GIT_EXTERN(int) git_index_open(git_index **index, const char *index_path);
 
 /**
  * Clear the contents (all the entries) of an index object.
diff --git a/include/git2/repository.h b/include/git2/repository.h
index c47fcfc..0d67ff8 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -141,10 +141,18 @@ GIT_EXTERN(int) git_repository_open3(git_repository **repository,
 GIT_EXTERN(git_odb *) git_repository_database(git_repository *repo);
 
 /**
- * Get the Index file of a Git repository
+ * Open the Index file of a Git repository
  *
- * This is a cheap operation; the index is only opened on the first call,
- * and subsequent calls only retrieve the previous pointer.
+ * This returns a new and unique `git_index` object representing the
+ * active index for the repository.
+ *
+ * This method may be called more than once (e.g. on different threads).
+ *
+ * Each returned `git_index` object is independent and suffers no race
+ * conditions: synchronization is done at the FS level.
+ *
+ * Each returned `git_index` object must be manually freed by the user,
+ * using `git_index_free`.
  *
  * @param index Pointer where to store the index
  * @param repo a repository object
diff --git a/src/index.c b/src/index.c
index 3897802..c1edd15 100644
--- a/src/index.c
+++ b/src/index.c
@@ -168,13 +168,19 @@ static int index_initialize(git_index **index_out, git_repository *owner, const 
 	return git_index_read(index);
 }
 
-int git_index_open_bare(git_index **index_out, const char *index_path)
+int git_index_open(git_index **index_out, const char *index_path)
 {
+	assert(index_out && index_path);
 	return index_initialize(index_out, NULL, index_path);
 }
 
-int git_index_open_inrepo(git_index **index_out, git_repository *repo)
+/*
+ * Moved from `repository.c`
+ */
+int git_repository_index(git_index **index_out, git_repository *repo)
 {
+	assert(index_out && repo);
+
 	if (repo->is_bare)
 		return git__throw(GIT_EBAREINDEX, "Failed to open index. Repository is bare");
 
@@ -183,7 +189,7 @@ int git_index_open_inrepo(git_index **index_out, git_repository *repo)
 
 void git_index_free(git_index *index)
 {
-	if (index == NULL || index->repository != NULL)
+	if (index == NULL)
 		return;
 
 	git_index_clear(index);
diff --git a/src/repository.c b/src/repository.c
index 468c888..0dd3668 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -315,32 +315,9 @@ void git_repository_free(git_repository *repo)
 	if (repo->db != NULL)
 		git_odb_close(repo->db);
 
-	if (repo->index != NULL) {
-		repo->index->repository = NULL;
-		git_index_free(repo->index);
-	}
-
 	free(repo);
 }
 
-int git_repository_index(git_index **index_out, git_repository *repo)
-{
-	int error;
-
-	assert(index_out && repo);
-
-	if (repo->index == NULL) {
-		error = git_index_open_inrepo(&repo->index, repo);	/* TODO: move index.c to new error handling */
-		if (error < GIT_SUCCESS)
-			return git__rethrow(error, "Failed to open repository index");
-
-		assert(repo->index != NULL);
-	}
-
-	*index_out = repo->index;
-	return GIT_SUCCESS;
-}
-
 git_odb *git_repository_database(git_repository *repo)
 {
 	assert(repo);
diff --git a/src/repository.h b/src/repository.h
index 813cac9..bcf9b2b 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -25,7 +25,6 @@ struct git_object {
 
 struct git_repository {
 	git_odb *db;
-	git_index *index;
 
 	git_cache objects;
 	git_refcache references;
diff --git a/tests/t06-index.c b/tests/t06-index.c
index 93ca2c0..25adbf7 100644
--- a/tests/t06-index.c
+++ b/tests/t06-index.c
@@ -48,7 +48,7 @@ struct test_entry TEST_ENTRIES[] = {
 BEGIN_TEST(read0, "load an empty index")
 	git_index *index;
 
-	must_pass(git_index_open_bare(&index, "in-memory-index"));
+	must_pass(git_index_open(&index, "in-memory-index"));
 	must_be_true(index->on_disk == 0);
 
 	must_pass(git_index_read(index));
@@ -65,7 +65,7 @@ BEGIN_TEST(read1, "load a standard index (default test index)")
 	unsigned int i;
 	git_index_entry **entries;
 
-	must_pass(git_index_open_bare(&index, TEST_INDEX_PATH));
+	must_pass(git_index_open(&index, TEST_INDEX_PATH));
 	must_be_true(index->on_disk);
 
 	must_pass(git_index_read(index));
@@ -90,7 +90,7 @@ END_TEST
 BEGIN_TEST(read2, "load a standard index (git.git index)")
 	git_index *index;
 
-	must_pass(git_index_open_bare(&index, TEST_INDEX2_PATH));
+	must_pass(git_index_open(&index, TEST_INDEX2_PATH));
 	must_be_true(index->on_disk);
 
 	must_pass(git_index_read(index));
@@ -107,7 +107,7 @@ BEGIN_TEST(find0, "find an entry on an index")
 	git_index *index;
 	unsigned int i;
 
-	must_pass(git_index_open_bare(&index, TEST_INDEX_PATH));
+	must_pass(git_index_open(&index, TEST_INDEX_PATH));
 	must_pass(git_index_read(index));
 
 	for (i = 0; i < ARRAY_SIZE(TEST_ENTRIES); ++i) {
@@ -122,7 +122,7 @@ BEGIN_TEST(find1, "find an entry in an empty index")
 	git_index *index;
 	unsigned int i;
 
-	must_pass(git_index_open_bare(&index, "fake-index"));
+	must_pass(git_index_open(&index, "fake-index"));
 
 	for (i = 0; i < ARRAY_SIZE(TEST_ENTRIES); ++i) {
 		int idx = git_index_find(index, TEST_ENTRIES[i].path);
@@ -137,7 +137,7 @@ BEGIN_TEST(write0, "write an index back to disk")
 
 	must_pass(copy_file(TEST_INDEXBIG_PATH, "index_rewrite"));
 
-	must_pass(git_index_open_bare(&index, "index_rewrite"));
+	must_pass(git_index_open(&index, "index_rewrite"));
 	must_pass(git_index_read(index));
 	must_be_true(index->on_disk);
 
@@ -165,7 +165,7 @@ END_TEST
 BEGIN_TEST(sort1, "sort the entires in an empty index")
 	git_index *index;
 
-	must_pass(git_index_open_bare(&index, "fake-index"));
+	must_pass(git_index_open(&index, "fake-index"));
 
 	/* FIXME: this test is slightly dumb */
 	must_be_true(index->entries.sorted);