@@ -153,11 +153,15 @@ static struct ref_list *sort_ref_list(struct ref_list *list)
153
153
* when doing a full libification.
154
154
*/
155
155
static struct cached_refs {
156
+ struct cached_refs * next ;
156
157
char did_loose ;
157
158
char did_packed ;
158
159
struct ref_list * loose ;
159
160
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
+
161
165
static struct ref_list * current_ref ;
162
166
163
167
static struct ref_list * extra_refs ;
@@ -171,10 +175,8 @@ static void free_ref_list(struct ref_list *list)
171
175
}
172
176
}
173
177
174
- static void invalidate_cached_refs ( void )
178
+ static void clear_cached_refs ( struct cached_refs * ca )
175
179
{
176
- struct cached_refs * ca = & cached_refs ;
177
-
178
180
if (ca -> did_loose && ca -> loose )
179
181
free_ref_list (ca -> loose );
180
182
if (ca -> did_packed && ca -> packed )
@@ -183,7 +185,54 @@ static void invalidate_cached_refs(void)
183
185
ca -> did_loose = ca -> did_packed = 0 ;
184
186
}
185
187
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 )
187
236
{
188
237
struct ref_list * list = NULL ;
189
238
struct ref_list * last = NULL ;
@@ -215,7 +264,7 @@ static void read_packed_refs(FILE *f, struct cached_refs *cached_refs)
215
264
!get_sha1_hex (refline + 1 , sha1 ))
216
265
hashcpy (last -> peeled , sha1 );
217
266
}
218
- cached_refs -> packed = sort_ref_list (list );
267
+ return sort_ref_list (list );
219
268
}
220
269
221
270
void add_extra_ref (const char * name , const unsigned char * sha1 , int flag )
@@ -231,23 +280,20 @@ void clear_extra_refs(void)
231
280
232
281
static struct ref_list * get_packed_refs (const char * submodule )
233
282
{
234
- const char * packed_refs_file ;
235
- struct cached_refs * refs ;
283
+ struct cached_refs * refs = get_cached_refs (submodule );
236
284
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 ;
245
288
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" );
248
294
refs -> packed = NULL ;
249
295
if (f ) {
250
- read_packed_refs (f , refs );
296
+ refs -> packed = read_packed_refs (f );
251
297
fclose (f );
252
298
}
253
299
refs -> did_packed = 1 ;
@@ -358,17 +404,13 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
358
404
359
405
static struct ref_list * get_loose_refs (const char * submodule )
360
406
{
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 );
366
408
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 ;
370
412
}
371
- return cached_refs . loose ;
413
+ return refs -> loose ;
372
414
}
373
415
374
416
/* We allow "recursive" symbolic refs. Only within reason, though */
@@ -378,17 +420,17 @@ static struct ref_list *get_loose_refs(const char *submodule)
378
420
static int resolve_gitlink_packed_ref (char * name , int pathlen , const char * refname , unsigned char * result )
379
421
{
380
422
FILE * f ;
381
- struct cached_refs refs ;
423
+ struct ref_list * packed_refs ;
382
424
struct ref_list * ref ;
383
425
int retval ;
384
426
385
427
strcpy (name + pathlen , "packed-refs" );
386
428
f = fopen (name , "r" );
387
429
if (!f )
388
430
return -1 ;
389
- read_packed_refs (f , & refs );
431
+ packed_refs = read_packed_refs (f );
390
432
fclose (f );
391
- ref = refs . packed ;
433
+ ref = packed_refs ;
392
434
retval = -1 ;
393
435
while (ref ) {
394
436
if (!strcmp (ref -> name , refname )) {
@@ -398,7 +440,7 @@ static int resolve_gitlink_packed_ref(char *name, int pathlen, const char *refna
398
440
}
399
441
ref = ref -> next ;
400
442
}
401
- free_ref_list (refs . packed );
443
+ free_ref_list (packed_refs );
402
444
return retval ;
403
445
}
404
446
0 commit comments