Git fork

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()

+74 -32
+74 -32
refs.c
··· 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 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 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 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 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 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 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 ··· 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 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