Skip to content

Commit d4a0b12

Browse files
author
Vicent Marti
committed
refs: Partial rewrite for read-only refs
This new version of the references code is significantly faster and hopefully easier to read. External API stays the same. A new method `git_reference_reload()` has been added to force updating a memory reference from disk. In-memory references are no longer updated automagically -- this was killing us. If a reference is deleted externally and the user doesn't reload the memory object, nothing critical happens: any functions using that reference should fail gracefully (e.g. deletion, renaming, and so on). All generated references from the API are read only and must be free'd by the user. There is no reference counting and no traces of generated references are kept in the library. There is no longer an internal representation for references. There is only one reference struct `git_reference`, and symbolic/oid targets are stored inside an union. Packfile references are stored using an optimized struct with flex array for reference names. This should significantly reduce the memory cost of loading the packfile from disk.
1 parent 549bbd1 commit d4a0b12

File tree

5 files changed

+671
-857
lines changed

5 files changed

+671
-857
lines changed

include/git2/refs.h

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,13 @@ GIT_EXTERN(const char *) git_reference_name(git_reference *ref);
116116
* Thie method iteratively peels a symbolic reference
117117
* until it resolves to a direct reference to an OID.
118118
*
119+
* The peeled reference is returned in the `resolved_ref`
120+
* argument, and must be freed manually once it's no longer
121+
* needed.
122+
*
119123
* If a direct reference is passed as an argument,
120-
* that reference is returned immediately
124+
* a copy of that reference is returned. This copy must
125+
* be manually freed too.
121126
*
122127
* @param resolved_ref Pointer to the peeled reference
123128
* @param ref The reference
@@ -170,11 +175,19 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
170175
* The new name will be checked for validity and may be
171176
* modified into a normalized form.
172177
*
173-
* The given git_reference will be updated.
178+
* The given git_reference will be updated in place.
174179
*
175180
* The reference will be immediately renamed in-memory
176181
* and on disk.
177182
*
183+
* If the `force` flag is not enabled, and there's already
184+
* a reference with the given name, the renaming will fail.
185+
*
186+
* @param ref The reference to rename
187+
* @param new_name The new name for the reference
188+
* @param force Overwrite an existing reference
189+
* @return GIT_SUCCESS or an error code
190+
*
178191
*/
179192
GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force);
180193

@@ -186,6 +199,8 @@ GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, i
186199
* The reference will be immediately removed on disk and from
187200
* memory. The given reference pointer will no longer be valid.
188201
*
202+
* @param ref The reference to remove
203+
* @return GIT_SUCCESS or an error code
189204
*/
190205
GIT_EXTERN(int) git_reference_delete(git_reference *ref);
191206

@@ -250,13 +265,33 @@ GIT_EXTERN(int) git_reference_listall(git_strarray *array, git_repository *repo,
250265
GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload);
251266

252267
/**
253-
* Check if a reference is packed
268+
* Check if a reference has been loaded from a packfile
254269
*
255-
* @param ref git_reference
270+
* @param ref A git reference
256271
* @return 0 in case it's not packed; 1 otherwise
257272
*/
258273
GIT_EXTERN(int) git_reference_is_packed(git_reference *ref);
259274

275+
/**
276+
* Reload a reference from disk
277+
*
278+
* Reference pointers may become outdated if the Git
279+
* repository is accessed simultaneously by other clients
280+
* whilt the library is open.
281+
*
282+
* This method forces a reload of the reference from disk,
283+
* to ensure that the provided information is still
284+
* reliable.
285+
*
286+
* If the reload fails (e.g. the reference no longer exists
287+
* on disk, or has become corrupted), an error code will be
288+
* returned and the reference pointer will be invalidated.
289+
*
290+
* @param ref The reference to reload
291+
* @return GIT_SUCCESS on success, or an error code
292+
*/
293+
GIT_EXTERN(int) git_reference_reload(git_reference *ref);
294+
260295
/**
261296
* Free the given reference
262297
*

0 commit comments

Comments
 (0)