Skip to content

Commit 11fa509

Browse files
committed
Merge branch 'mh/iterate-refs'
* mh/iterate-refs: refs.c: make create_cached_refs() static Retain caches of submodule refs Store the submodule name in struct cached_refs Allocate cached_refs objects dynamically Change the signature of read_packed_refs() Access reference caches only through new function get_cached_refs() Extract a function clear_cached_refs()
2 parents 5fbdb9c + 3ab24ef commit 11fa509

File tree

1 file changed

+74
-32
lines changed

1 file changed

+74
-32
lines changed

refs.c

Lines changed: 74 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,15 @@ static struct ref_list *sort_ref_list(struct ref_list *list)
153153
* when doing a full libification.
154154
*/
155155
static struct cached_refs {
156+
struct cached_refs *next;
156157
char did_loose;
157158
char did_packed;
158159
struct ref_list *loose;
159160
struct ref_list *packed;
160-
} cached_refs, submodule_refs;
161+
/* The submodule name, or "" for the main repo. */
162+
char name[FLEX_ARRAY];
163+
} *cached_refs;
164+
161165
static struct ref_list *current_ref;
162166

163167
static struct ref_list *extra_refs;
@@ -171,10 +175,8 @@ static void free_ref_list(struct ref_list *list)
171175
}
172176
}
173177

174-
static void invalidate_cached_refs(void)
178+
static void clear_cached_refs(struct cached_refs *ca)
175179
{
176-
struct cached_refs *ca = &cached_refs;
177-
178180
if (ca->did_loose && ca->loose)
179181
free_ref_list(ca->loose);
180182
if (ca->did_packed && ca->packed)
@@ -183,7 +185,54 @@ static void invalidate_cached_refs(void)
183185
ca->did_loose = ca->did_packed = 0;
184186
}
185187

186-
static void read_packed_refs(FILE *f, struct cached_refs *cached_refs)
188+
static struct cached_refs *create_cached_refs(const char *submodule)
189+
{
190+
int len;
191+
struct cached_refs *refs;
192+
if (!submodule)
193+
submodule = "";
194+
len = strlen(submodule) + 1;
195+
refs = xmalloc(sizeof(struct cached_refs) + len);
196+
refs->next = NULL;
197+
refs->did_loose = refs->did_packed = 0;
198+
refs->loose = refs->packed = NULL;
199+
memcpy(refs->name, submodule, len);
200+
return refs;
201+
}
202+
203+
/*
204+
* Return a pointer to a cached_refs for the specified submodule. For
205+
* the main repository, use submodule==NULL. The returned structure
206+
* will be allocated and initialized but not necessarily populated; it
207+
* should not be freed.
208+
*/
209+
static struct cached_refs *get_cached_refs(const char *submodule)
210+
{
211+
struct cached_refs *refs = cached_refs;
212+
if (!submodule)
213+
submodule = "";
214+
while (refs) {
215+
if (!strcmp(submodule, refs->name))
216+
return refs;
217+
refs = refs->next;
218+
}
219+
220+
refs = create_cached_refs(submodule);
221+
refs->next = cached_refs;
222+
cached_refs = refs;
223+
return refs;
224+
}
225+
226+
static void invalidate_cached_refs(void)
227+
{
228+
struct cached_refs *refs = cached_refs;
229+
while (refs) {
230+
clear_cached_refs(refs);
231+
refs = refs->next;
232+
}
233+
}
234+
235+
static struct ref_list *read_packed_refs(FILE *f)
187236
{
188237
struct ref_list *list = NULL;
189238
struct ref_list *last = NULL;
@@ -215,7 +264,7 @@ static void read_packed_refs(FILE *f, struct cached_refs *cached_refs)
215264
!get_sha1_hex(refline + 1, sha1))
216265
hashcpy(last->peeled, sha1);
217266
}
218-
cached_refs->packed = sort_ref_list(list);
267+
return sort_ref_list(list);
219268
}
220269

221270
void add_extra_ref(const char *name, const unsigned char *sha1, int flag)
@@ -231,23 +280,20 @@ void clear_extra_refs(void)
231280

232281
static struct ref_list *get_packed_refs(const char *submodule)
233282
{
234-
const char *packed_refs_file;
235-
struct cached_refs *refs;
283+
struct cached_refs *refs = get_cached_refs(submodule);
236284

237-
if (submodule) {
238-
packed_refs_file = git_path_submodule(submodule, "packed-refs");
239-
refs = &submodule_refs;
240-
free_ref_list(refs->packed);
241-
} else {
242-
packed_refs_file = git_path("packed-refs");
243-
refs = &cached_refs;
244-
}
285+
if (!refs->did_packed) {
286+
const char *packed_refs_file;
287+
FILE *f;
245288

246-
if (!refs->did_packed || submodule) {
247-
FILE *f = fopen(packed_refs_file, "r");
289+
if (submodule)
290+
packed_refs_file = git_path_submodule(submodule, "packed-refs");
291+
else
292+
packed_refs_file = git_path("packed-refs");
293+
f = fopen(packed_refs_file, "r");
248294
refs->packed = NULL;
249295
if (f) {
250-
read_packed_refs(f, refs);
296+
refs->packed = read_packed_refs(f);
251297
fclose(f);
252298
}
253299
refs->did_packed = 1;
@@ -358,17 +404,13 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
358404

359405
static struct ref_list *get_loose_refs(const char *submodule)
360406
{
361-
if (submodule) {
362-
free_ref_list(submodule_refs.loose);
363-
submodule_refs.loose = get_ref_dir(submodule, "refs", NULL);
364-
return submodule_refs.loose;
365-
}
407+
struct cached_refs *refs = get_cached_refs(submodule);
366408

367-
if (!cached_refs.did_loose) {
368-
cached_refs.loose = get_ref_dir(NULL, "refs", NULL);
369-
cached_refs.did_loose = 1;
409+
if (!refs->did_loose) {
410+
refs->loose = get_ref_dir(submodule, "refs", NULL);
411+
refs->did_loose = 1;
370412
}
371-
return cached_refs.loose;
413+
return refs->loose;
372414
}
373415

374416
/* We allow "recursive" symbolic refs. Only within reason, though */
@@ -378,17 +420,17 @@ static struct ref_list *get_loose_refs(const char *submodule)
378420
static int resolve_gitlink_packed_ref(char *name, int pathlen, const char *refname, unsigned char *result)
379421
{
380422
FILE *f;
381-
struct cached_refs refs;
423+
struct ref_list *packed_refs;
382424
struct ref_list *ref;
383425
int retval;
384426

385427
strcpy(name + pathlen, "packed-refs");
386428
f = fopen(name, "r");
387429
if (!f)
388430
return -1;
389-
read_packed_refs(f, &refs);
431+
packed_refs = read_packed_refs(f);
390432
fclose(f);
391-
ref = refs.packed;
433+
ref = packed_refs;
392434
retval = -1;
393435
while (ref) {
394436
if (!strcmp(ref->name, refname)) {
@@ -398,7 +440,7 @@ static int resolve_gitlink_packed_ref(char *name, int pathlen, const char *refna
398440
}
399441
ref = ref->next;
400442
}
401-
free_ref_list(refs.packed);
443+
free_ref_list(packed_refs);
402444
return retval;
403445
}
404446

0 commit comments

Comments
 (0)