Skip to content

Commit a46ec45

Browse files
schuVicent Marti
authored andcommitted
refs: split internal and external references
Currently libgit2 shares pointers to its internal reference cache with the user. This leads to several problems like invalidation of reference pointers when reordering the cache or manipulation of the cache from user side. Give each user its own git_reference instead of leaking the internal representation (struct reference). Add the following new API functions: * git_reference_free * git_reference_is_packed Signed-off-by: schu <schu-github@schulog.org>
1 parent d3104fa commit a46ec45

File tree

5 files changed

+360
-174
lines changed

5 files changed

+360
-174
lines changed

include/git2/refs.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ GIT_BEGIN_DECL
2323
/**
2424
* Lookup a reference by its name in a repository.
2525
*
26-
* The generated reference is owned by the repository and
27-
* should not be freed by the user.
26+
* The generated reference must be freed by the user.
2827
*
2928
* @param reference_out pointer to the looked-up reference
3029
* @param repo the repository to look up the reference
@@ -39,8 +38,7 @@ GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_reposito
3938
* The reference will be created in the repository and written
4039
* to the disk.
4140
*
42-
* This reference is owned by the repository and shall not
43-
* be free'd by the user.
41+
* The generated reference must be freed by the user.
4442
*
4543
* If `force` is true and there already exists a reference
4644
* with the same name, it will be overwritten.
@@ -60,8 +58,7 @@ GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repos
6058
* The reference will be created in the repository and written
6159
* to the disk.
6260
*
63-
* This reference is owned by the repository and shall not
64-
* be free'd by the user.
61+
* The generated reference must be freed by the user.
6562
*
6663
* If `force` is true and there already exists a reference
6764
* with the same name, it will be overwritten.
@@ -173,7 +170,9 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
173170
* The new name will be checked for validity and may be
174171
* modified into a normalized form.
175172
*
176-
* The refernece will be immediately renamed in-memory
173+
* The given git_reference will be updated.
174+
*
175+
* The reference will be immediately renamed in-memory
177176
* and on disk.
178177
*
179178
*/
@@ -200,9 +199,6 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
200199
* Once the `packed-refs` file has been written properly,
201200
* the loose references will be removed from disk.
202201
*
203-
* WARNING: calling this method may invalidate any existing
204-
* references previously loaded on the cache.
205-
*
206202
* @param repo Repository where the loose refs will be packed
207203
* @return GIT_SUCCESS or an error code
208204
*/
@@ -253,6 +249,21 @@ GIT_EXTERN(int) git_reference_listall(git_strarray *array, git_repository *repo,
253249
*/
254250
GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload);
255251

252+
/**
253+
* Check if a reference is packed
254+
*
255+
* @param ref git_reference
256+
* @return 0 in case it's not packed; 1 otherwise
257+
*/
258+
GIT_EXTERN(int) git_reference_is_packed(git_reference *ref);
259+
260+
/**
261+
* Free the given reference
262+
*
263+
* @param ref git_reference
264+
*/
265+
GIT_EXTERN(void) git_reference_free(git_reference *ref);
266+
256267
/** @} */
257268
GIT_END_DECL
258269
#endif

src/commit.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,13 @@ int git_commit_create(
137137

138138
if (error == GIT_SUCCESS && update_ref != NULL) {
139139
git_reference *head;
140+
git_reference *target;
140141

141142
error = git_reference_lookup(&head, repo, update_ref);
142143
if (error < GIT_SUCCESS)
143144
return git__rethrow(error, "Failed to create commit");
144145

145-
error = git_reference_resolve(&head, head);
146+
error = git_reference_resolve(&target, head);
146147
if (error < GIT_SUCCESS) {
147148
if (error != GIT_ENOTFOUND)
148149
return git__rethrow(error, "Failed to create commit");
@@ -156,7 +157,7 @@ int git_commit_create(
156157
return git_reference_create_oid(&head, repo, git_reference_target(head), oid, 1);
157158
}
158159

159-
error = git_reference_set_oid(head, oid);
160+
error = git_reference_set_oid(target, oid);
160161
}
161162

162163
if (error < GIT_SUCCESS)

0 commit comments

Comments
 (0)