@@ -157,7 +157,7 @@ static struct cached_refs {
157157 char did_packed ;
158158 struct ref_list * loose ;
159159 struct ref_list * packed ;
160- } cached_refs ;
160+ } cached_refs , submodule_refs ;
161161static struct ref_list * current_ref ;
162162
163163static struct ref_list * extra_refs ;
@@ -229,23 +229,45 @@ void clear_extra_refs(void)
229229 extra_refs = NULL ;
230230}
231231
232- static struct ref_list * get_packed_refs (void )
232+ static struct ref_list * get_packed_refs (const char * submodule )
233233{
234- if (!cached_refs .did_packed ) {
235- FILE * f = fopen (git_path ("packed-refs" ), "r" );
236- cached_refs .packed = NULL ;
234+ const char * packed_refs_file ;
235+ struct cached_refs * refs ;
236+
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+ }
245+
246+ if (!refs -> did_packed || submodule ) {
247+ FILE * f = fopen (packed_refs_file , "r" );
248+ refs -> packed = NULL ;
237249 if (f ) {
238- read_packed_refs (f , & cached_refs );
250+ read_packed_refs (f , refs );
239251 fclose (f );
240252 }
241- cached_refs . did_packed = 1 ;
253+ refs -> did_packed = 1 ;
242254 }
243- return cached_refs . packed ;
255+ return refs -> packed ;
244256}
245257
246- static struct ref_list * get_ref_dir (const char * base , struct ref_list * list )
258+ static struct ref_list * get_ref_dir (const char * submodule , const char * base ,
259+ struct ref_list * list )
247260{
248- DIR * dir = opendir (git_path ("%s" , base ));
261+ DIR * dir ;
262+ const char * path ;
263+
264+ if (submodule )
265+ path = git_path_submodule (submodule , "%s" , base );
266+ else
267+ path = git_path ("%s" , base );
268+
269+
270+ dir = opendir (path );
249271
250272 if (dir ) {
251273 struct dirent * de ;
@@ -261,6 +283,7 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
261283 struct stat st ;
262284 int flag ;
263285 int namelen ;
286+ const char * refdir ;
264287
265288 if (de -> d_name [0 ] == '.' )
266289 continue ;
@@ -270,16 +293,27 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
270293 if (has_extension (de -> d_name , ".lock" ))
271294 continue ;
272295 memcpy (ref + baselen , de -> d_name , namelen + 1 );
273- if (stat (git_path ("%s" , ref ), & st ) < 0 )
296+ refdir = submodule
297+ ? git_path_submodule (submodule , "%s" , ref )
298+ : git_path ("%s" , ref );
299+ if (stat (refdir , & st ) < 0 )
274300 continue ;
275301 if (S_ISDIR (st .st_mode )) {
276- list = get_ref_dir (ref , list );
302+ list = get_ref_dir (submodule , ref , list );
277303 continue ;
278304 }
279- if (! resolve_ref ( ref , sha1 , 1 , & flag ) ) {
305+ if (submodule ) {
280306 hashclr (sha1 );
281- flag |= REF_BROKEN ;
282- }
307+ flag = 0 ;
308+ if (resolve_gitlink_ref (submodule , ref , sha1 ) < 0 ) {
309+ hashclr (sha1 );
310+ flag |= REF_BROKEN ;
311+ }
312+ } else
313+ if (!resolve_ref (ref , sha1 , 1 , & flag )) {
314+ hashclr (sha1 );
315+ flag |= REF_BROKEN ;
316+ }
283317 list = add_ref (ref , sha1 , flag , list , NULL );
284318 }
285319 free (ref );
@@ -322,10 +356,16 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
322356 for_each_rawref (warn_if_dangling_symref , & data );
323357}
324358
325- static struct ref_list * get_loose_refs (void )
359+ static struct ref_list * get_loose_refs (const char * submodule )
326360{
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+ }
366+
327367 if (!cached_refs .did_loose ) {
328- cached_refs .loose = get_ref_dir ("refs" , NULL );
368+ cached_refs .loose = get_ref_dir (NULL , "refs" , NULL );
329369 cached_refs .did_loose = 1 ;
330370 }
331371 return cached_refs .loose ;
@@ -459,7 +499,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
459499 git_snpath (path , sizeof (path ), "%s" , ref );
460500 /* Special case: non-existing file. */
461501 if (lstat (path , & st ) < 0 ) {
462- struct ref_list * list = get_packed_refs ();
502+ struct ref_list * list = get_packed_refs (NULL );
463503 while (list ) {
464504 if (!strcmp (ref , list -> name )) {
465505 hashcpy (sha1 , list -> sha1 );
@@ -588,7 +628,7 @@ int peel_ref(const char *ref, unsigned char *sha1)
588628 return -1 ;
589629
590630 if ((flag & REF_ISPACKED )) {
591- struct ref_list * list = get_packed_refs ();
631+ struct ref_list * list = get_packed_refs (NULL );
592632
593633 while (list ) {
594634 if (!strcmp (list -> name , ref )) {
@@ -615,12 +655,12 @@ int peel_ref(const char *ref, unsigned char *sha1)
615655 return -1 ;
616656}
617657
618- static int do_for_each_ref (const char * base , each_ref_fn fn , int trim ,
619- int flags , void * cb_data )
658+ static int do_for_each_ref (const char * submodule , const char * base , each_ref_fn fn ,
659+ int trim , int flags , void * cb_data )
620660{
621661 int retval = 0 ;
622- struct ref_list * packed = get_packed_refs ();
623- struct ref_list * loose = get_loose_refs ();
662+ struct ref_list * packed = get_packed_refs (submodule );
663+ struct ref_list * loose = get_loose_refs (submodule );
624664
625665 struct ref_list * extra ;
626666
@@ -657,24 +697,38 @@ static int do_for_each_ref(const char *base, each_ref_fn fn, int trim,
657697 return retval ;
658698}
659699
660- int head_ref (each_ref_fn fn , void * cb_data )
700+
701+ static int do_head_ref (const char * submodule , each_ref_fn fn , void * cb_data )
661702{
662703 unsigned char sha1 [20 ];
663704 int flag ;
664705
706+ if (submodule ) {
707+ if (resolve_gitlink_ref (submodule , "HEAD" , sha1 ) == 0 )
708+ return fn ("HEAD" , sha1 , 0 , cb_data );
709+
710+ return 0 ;
711+ }
712+
665713 if (resolve_ref ("HEAD" , sha1 , 1 , & flag ))
666714 return fn ("HEAD" , sha1 , flag , cb_data );
715+
667716 return 0 ;
668717}
669718
719+ int head_ref (each_ref_fn fn , void * cb_data )
720+ {
721+ return do_head_ref (NULL , fn , cb_data );
722+ }
723+
670724int for_each_ref (each_ref_fn fn , void * cb_data )
671725{
672- return do_for_each_ref ("refs/" , fn , 0 , 0 , cb_data );
726+ return do_for_each_ref (NULL , "refs/" , fn , 0 , 0 , cb_data );
673727}
674728
675729int for_each_ref_in (const char * prefix , each_ref_fn fn , void * cb_data )
676730{
677- return do_for_each_ref (prefix , fn , strlen (prefix ), 0 , cb_data );
731+ return do_for_each_ref (NULL , prefix , fn , strlen (prefix ), 0 , cb_data );
678732}
679733
680734int for_each_tag_ref (each_ref_fn fn , void * cb_data )
@@ -694,7 +748,7 @@ int for_each_remote_ref(each_ref_fn fn, void *cb_data)
694748
695749int for_each_replace_ref (each_ref_fn fn , void * cb_data )
696750{
697- return do_for_each_ref ("refs/replace/" , fn , 13 , 0 , cb_data );
751+ return do_for_each_ref (NULL , "refs/replace/" , fn , 13 , 0 , cb_data );
698752}
699753
700754int for_each_glob_ref_in (each_ref_fn fn , const char * pattern ,
@@ -734,7 +788,7 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
734788
735789int for_each_rawref (each_ref_fn fn , void * cb_data )
736790{
737- return do_for_each_ref ("refs/" , fn , 0 ,
791+ return do_for_each_ref (NULL , "refs/" , fn , 0 ,
738792 DO_FOR_EACH_INCLUDE_BROKEN , cb_data );
739793}
740794
@@ -958,7 +1012,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
9581012 * name is a proper prefix of our refname.
9591013 */
9601014 if (missing &&
961- !is_refname_available (ref , NULL , get_packed_refs (), 0 )) {
1015+ !is_refname_available (ref , NULL , get_packed_refs (NULL ), 0 )) {
9621016 last_errno = ENOTDIR ;
9631017 goto error_return ;
9641018 }
@@ -1021,7 +1075,7 @@ static int repack_without_ref(const char *refname)
10211075 int fd ;
10221076 int found = 0 ;
10231077
1024- packed_ref_list = get_packed_refs ();
1078+ packed_ref_list = get_packed_refs (NULL );
10251079 for (list = packed_ref_list ; list ; list = list -> next ) {
10261080 if (!strcmp (refname , list -> name )) {
10271081 found = 1 ;
@@ -1110,10 +1164,10 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
11101164 if (!symref )
11111165 return error ("refname %s not found" , oldref );
11121166
1113- if (!is_refname_available (newref , oldref , get_packed_refs (), 0 ))
1167+ if (!is_refname_available (newref , oldref , get_packed_refs (NULL ), 0 ))
11141168 return 1 ;
11151169
1116- if (!is_refname_available (newref , oldref , get_loose_refs (), 0 ))
1170+ if (!is_refname_available (newref , oldref , get_loose_refs (NULL ), 0 ))
11171171 return 1 ;
11181172
11191173 lock = lock_ref_sha1_basic (renamed_ref , NULL , 0 , NULL );
0 commit comments