@@ -811,9 +811,13 @@ static struct ref_cache {
811811 struct ref_cache * next ;
812812 struct ref_entry * loose ;
813813 struct ref_entry * packed ;
814- /* The submodule name, or "" for the main repo. */
815- char name [FLEX_ARRAY ];
816- } * ref_cache ;
814+ /*
815+ * The submodule name, or "" for the main repo. We allocate
816+ * length 1 rather than FLEX_ARRAY so that the main ref_cache
817+ * is initialized correctly.
818+ */
819+ char name [1 ];
820+ } ref_cache , * submodule_ref_caches ;
817821
818822static void clear_packed_ref_cache (struct ref_cache * refs )
819823{
@@ -851,18 +855,18 @@ static struct ref_cache *create_ref_cache(const char *submodule)
851855 */
852856static struct ref_cache * get_ref_cache (const char * submodule )
853857{
854- struct ref_cache * refs = ref_cache ;
855- if (!submodule )
856- submodule = "" ;
857- while (refs ) {
858+ struct ref_cache * refs ;
859+
860+ if (!submodule || !* submodule )
861+ return & ref_cache ;
862+
863+ for (refs = submodule_ref_caches ; refs ; refs = refs -> next )
858864 if (!strcmp (submodule , refs -> name ))
859865 return refs ;
860- refs = refs -> next ;
861- }
862866
863867 refs = create_ref_cache (submodule );
864- refs -> next = ref_cache ;
865- ref_cache = refs ;
868+ refs -> next = submodule_ref_caches ;
869+ submodule_ref_caches = refs ;
866870 return refs ;
867871}
868872
@@ -1011,8 +1015,8 @@ static struct ref_dir *get_packed_refs(struct ref_cache *refs)
10111015
10121016void add_packed_ref (const char * refname , const unsigned char * sha1 )
10131017{
1014- add_ref (get_packed_refs (get_ref_cache ( NULL ) ),
1015- create_ref_entry (refname , sha1 , REF_ISPACKED , 1 ));
1018+ add_ref (get_packed_refs (& ref_cache ),
1019+ create_ref_entry (refname , sha1 , REF_ISPACKED , 1 ));
10161020}
10171021
10181022/*
@@ -1187,7 +1191,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
11871191 */
11881192static struct ref_entry * get_packed_ref (const char * refname )
11891193{
1190- return find_ref (get_packed_refs (get_ref_cache ( NULL ) ), refname );
1194+ return find_ref (get_packed_refs (& ref_cache ), refname );
11911195}
11921196
11931197const char * resolve_ref_unsafe (const char * refname , unsigned char * sha1 , int reading , int * flag )
@@ -1592,7 +1596,7 @@ int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
15921596
15931597int for_each_ref (each_ref_fn fn , void * cb_data )
15941598{
1595- return do_for_each_ref (get_ref_cache ( NULL ) , "" , fn , 0 , 0 , cb_data );
1599+ return do_for_each_ref (& ref_cache , "" , fn , 0 , 0 , cb_data );
15961600}
15971601
15981602int for_each_ref_submodule (const char * submodule , each_ref_fn fn , void * cb_data )
@@ -1602,7 +1606,7 @@ int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
16021606
16031607int for_each_ref_in (const char * prefix , each_ref_fn fn , void * cb_data )
16041608{
1605- return do_for_each_ref (get_ref_cache ( NULL ) , prefix , fn , strlen (prefix ), 0 , cb_data );
1609+ return do_for_each_ref (& ref_cache , prefix , fn , strlen (prefix ), 0 , cb_data );
16061610}
16071611
16081612int for_each_ref_in_submodule (const char * submodule , const char * prefix ,
@@ -1643,7 +1647,7 @@ int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *c
16431647
16441648int for_each_replace_ref (each_ref_fn fn , void * cb_data )
16451649{
1646- return do_for_each_ref (get_ref_cache ( NULL ) , "refs/replace/" , fn , 13 , 0 , cb_data );
1650+ return do_for_each_ref (& ref_cache , "refs/replace/" , fn , 13 , 0 , cb_data );
16471651}
16481652
16491653int head_ref_namespaced (each_ref_fn fn , void * cb_data )
@@ -1666,7 +1670,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
16661670 struct strbuf buf = STRBUF_INIT ;
16671671 int ret ;
16681672 strbuf_addf (& buf , "%srefs/" , get_git_namespace ());
1669- ret = do_for_each_ref (get_ref_cache ( NULL ) , buf .buf , fn , 0 , 0 , cb_data );
1673+ ret = do_for_each_ref (& ref_cache , buf .buf , fn , 0 , 0 , cb_data );
16701674 strbuf_release (& buf );
16711675 return ret ;
16721676}
@@ -1708,7 +1712,7 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
17081712
17091713int for_each_rawref (each_ref_fn fn , void * cb_data )
17101714{
1711- return do_for_each_ref (get_ref_cache ( NULL ) , "" , fn , 0 ,
1715+ return do_for_each_ref (& ref_cache , "" , fn , 0 ,
17121716 DO_FOR_EACH_INCLUDE_BROKEN , cb_data );
17131717}
17141718
@@ -1914,7 +1918,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
19141918 * name is a proper prefix of our refname.
19151919 */
19161920 if (missing &&
1917- !is_refname_available (refname , NULL , get_packed_refs (get_ref_cache ( NULL ) ))) {
1921+ !is_refname_available (refname , NULL , get_packed_refs (& ref_cache ))) {
19181922 last_errno = ENOTDIR ;
19191923 goto error_return ;
19201924 }
@@ -2103,7 +2107,7 @@ int pack_refs(unsigned int flags)
21032107
21042108 write_or_die (cbdata .fd , PACKED_REFS_HEADER , strlen (PACKED_REFS_HEADER ));
21052109
2106- do_for_each_entry (get_ref_cache ( NULL ) , "" , pack_one_ref , & cbdata );
2110+ do_for_each_entry (& ref_cache , "" , pack_one_ref , & cbdata );
21072111 if (commit_lock_file (& packlock ) < 0 )
21082112 die_errno ("unable to overwrite old ref-pack file" );
21092113 prune_refs (cbdata .ref_to_prune );
@@ -2161,7 +2165,6 @@ static int repack_ref_fn(struct ref_entry *entry, void *cb_data)
21612165static int repack_without_ref (const char * refname )
21622166{
21632167 int fd ;
2164- struct ref_cache * refs = get_ref_cache (NULL );
21652168 struct ref_dir * packed ;
21662169
21672170 if (!get_packed_ref (refname ))
@@ -2172,8 +2175,8 @@ static int repack_without_ref(const char *refname)
21722175 unable_to_lock_error (git_path ("packed-refs" ), errno );
21732176 return error ("cannot delete '%s' from packed refs" , refname );
21742177 }
2175- clear_packed_ref_cache (refs );
2176- packed = get_packed_refs (refs );
2178+ clear_packed_ref_cache (& ref_cache );
2179+ packed = get_packed_refs (& ref_cache );
21772180 /* Remove refname from the cache. */
21782181 if (remove_entry (packed , refname ) == -1 ) {
21792182 /*
@@ -2213,7 +2216,7 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
22132216 ret |= repack_without_ref (lock -> ref_name );
22142217
22152218 unlink_or_warn (git_path ("logs/%s" , lock -> ref_name ));
2216- clear_loose_ref_cache (get_ref_cache ( NULL ) );
2219+ clear_loose_ref_cache (& ref_cache );
22172220 unlock_ref (lock );
22182221 return ret ;
22192222}
@@ -2235,7 +2238,6 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
22352238 struct stat loginfo ;
22362239 int log = !lstat (git_path ("logs/%s" , oldrefname ), & loginfo );
22372240 const char * symref = NULL ;
2238- struct ref_cache * refs = get_ref_cache (NULL );
22392241
22402242 if (log && S_ISLNK (loginfo .st_mode ))
22412243 return error ("reflog for %s is a symlink" , oldrefname );
@@ -2247,10 +2249,10 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
22472249 if (!symref )
22482250 return error ("refname %s not found" , oldrefname );
22492251
2250- if (!is_refname_available (newrefname , oldrefname , get_packed_refs (refs )))
2252+ if (!is_refname_available (newrefname , oldrefname , get_packed_refs (& ref_cache )))
22512253 return 1 ;
22522254
2253- if (!is_refname_available (newrefname , oldrefname , get_loose_refs (refs )))
2255+ if (!is_refname_available (newrefname , oldrefname , get_loose_refs (& ref_cache )))
22542256 return 1 ;
22552257
22562258 if (log && rename (git_path ("logs/%s" , oldrefname ), git_path (TMP_RENAMED_LOG )))
@@ -2506,7 +2508,7 @@ int write_ref_sha1(struct ref_lock *lock,
25062508 unlock_ref (lock );
25072509 return -1 ;
25082510 }
2509- clear_loose_ref_cache (get_ref_cache ( NULL ) );
2511+ clear_loose_ref_cache (& ref_cache );
25102512 if (log_ref_write (lock -> ref_name , lock -> old_sha1 , sha1 , logmsg ) < 0 ||
25112513 (strcmp (lock -> ref_name , lock -> orig_ref_name ) &&
25122514 log_ref_write (lock -> orig_ref_name , lock -> old_sha1 , sha1 , logmsg ) < 0 )) {
0 commit comments