@@ -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,44 +697,89 @@ 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+
724+ int head_ref_submodule (const char * submodule , each_ref_fn fn , void * cb_data )
725+ {
726+ return do_head_ref (submodule , fn , cb_data );
727+ }
728+
670729int for_each_ref (each_ref_fn fn , void * cb_data )
671730{
672- return do_for_each_ref ("refs/" , fn , 0 , 0 , cb_data );
731+ return do_for_each_ref (NULL , "refs/" , fn , 0 , 0 , cb_data );
732+ }
733+
734+ int for_each_ref_submodule (const char * submodule , each_ref_fn fn , void * cb_data )
735+ {
736+ return do_for_each_ref (submodule , "refs/" , fn , 0 , 0 , cb_data );
673737}
674738
675739int for_each_ref_in (const char * prefix , each_ref_fn fn , void * cb_data )
676740{
677- return do_for_each_ref (prefix , fn , strlen (prefix ), 0 , cb_data );
741+ return do_for_each_ref (NULL , prefix , fn , strlen (prefix ), 0 , cb_data );
742+ }
743+
744+ int for_each_ref_in_submodule (const char * submodule , const char * prefix ,
745+ each_ref_fn fn , void * cb_data )
746+ {
747+ return do_for_each_ref (submodule , prefix , fn , strlen (prefix ), 0 , cb_data );
678748}
679749
680750int for_each_tag_ref (each_ref_fn fn , void * cb_data )
681751{
682752 return for_each_ref_in ("refs/tags/" , fn , cb_data );
683753}
684754
755+ int for_each_tag_ref_submodule (const char * submodule , each_ref_fn fn , void * cb_data )
756+ {
757+ return for_each_ref_in_submodule (submodule , "refs/tags/" , fn , cb_data );
758+ }
759+
685760int for_each_branch_ref (each_ref_fn fn , void * cb_data )
686761{
687762 return for_each_ref_in ("refs/heads/" , fn , cb_data );
688763}
689764
765+ int for_each_branch_ref_submodule (const char * submodule , each_ref_fn fn , void * cb_data )
766+ {
767+ return for_each_ref_in_submodule (submodule , "refs/heads/" , fn , cb_data );
768+ }
769+
690770int for_each_remote_ref (each_ref_fn fn , void * cb_data )
691771{
692772 return for_each_ref_in ("refs/remotes/" , fn , cb_data );
693773}
694774
775+ int for_each_remote_ref_submodule (const char * submodule , each_ref_fn fn , void * cb_data )
776+ {
777+ return for_each_ref_in_submodule (submodule , "refs/remotes/" , fn , cb_data );
778+ }
779+
695780int for_each_replace_ref (each_ref_fn fn , void * cb_data )
696781{
697- return do_for_each_ref ("refs/replace/" , fn , 13 , 0 , cb_data );
782+ return do_for_each_ref (NULL , "refs/replace/" , fn , 13 , 0 , cb_data );
698783}
699784
700785int for_each_glob_ref_in (each_ref_fn fn , const char * pattern ,
@@ -734,7 +819,7 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
734819
735820int for_each_rawref (each_ref_fn fn , void * cb_data )
736821{
737- return do_for_each_ref ("refs/" , fn , 0 ,
822+ return do_for_each_ref (NULL , "refs/" , fn , 0 ,
738823 DO_FOR_EACH_INCLUDE_BROKEN , cb_data );
739824}
740825
@@ -958,7 +1043,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
9581043 * name is a proper prefix of our refname.
9591044 */
9601045 if (missing &&
961- !is_refname_available (ref , NULL , get_packed_refs (), 0 )) {
1046+ !is_refname_available (ref , NULL , get_packed_refs (NULL ), 0 )) {
9621047 last_errno = ENOTDIR ;
9631048 goto error_return ;
9641049 }
@@ -1021,7 +1106,7 @@ static int repack_without_ref(const char *refname)
10211106 int fd ;
10221107 int found = 0 ;
10231108
1024- packed_ref_list = get_packed_refs ();
1109+ packed_ref_list = get_packed_refs (NULL );
10251110 for (list = packed_ref_list ; list ; list = list -> next ) {
10261111 if (!strcmp (refname , list -> name )) {
10271112 found = 1 ;
@@ -1119,10 +1204,10 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
11191204 if (!symref )
11201205 return error ("refname %s not found" , oldref );
11211206
1122- if (!is_refname_available (newref , oldref , get_packed_refs (), 0 ))
1207+ if (!is_refname_available (newref , oldref , get_packed_refs (NULL ), 0 ))
11231208 return 1 ;
11241209
1125- if (!is_refname_available (newref , oldref , get_loose_refs (), 0 ))
1210+ if (!is_refname_available (newref , oldref , get_loose_refs (NULL ), 0 ))
11261211 return 1 ;
11271212
11281213 lock = lock_ref_sha1_basic (renamed_ref , NULL , 0 , NULL );
0 commit comments