@@ -225,157 +225,6 @@ static NORETURN void die_invalid_line(const char *path,
225225
226226}
227227
228- /*
229- * This value is set in `base.flags` if the peeled value of the
230- * current reference is known. In that case, `peeled` contains the
231- * correct peeled value for the reference, which might be `null_sha1`
232- * if the reference is not a tag or if it is broken.
233- */
234- #define REF_KNOWS_PEELED 0x40
235-
236- /*
237- * An iterator over a packed-refs file that is currently mmapped.
238- */
239- struct mmapped_ref_iterator {
240- struct ref_iterator base ;
241-
242- struct packed_ref_cache * packed_refs ;
243-
244- /* The current position in the mmapped file: */
245- const char * pos ;
246-
247- /* The end of the mmapped file: */
248- const char * eof ;
249-
250- struct object_id oid , peeled ;
251-
252- struct strbuf refname_buf ;
253- };
254-
255- static int mmapped_ref_iterator_advance (struct ref_iterator * ref_iterator )
256- {
257- struct mmapped_ref_iterator * iter =
258- (struct mmapped_ref_iterator * )ref_iterator ;
259- const char * p = iter -> pos , * eol ;
260-
261- strbuf_reset (& iter -> refname_buf );
262-
263- if (iter -> pos == iter -> eof )
264- return ref_iterator_abort (ref_iterator );
265-
266- iter -> base .flags = REF_ISPACKED ;
267-
268- if (iter -> eof - p < GIT_SHA1_HEXSZ + 2 ||
269- parse_oid_hex (p , & iter -> oid , & p ) ||
270- !isspace (* p ++ ))
271- die_invalid_line (iter -> packed_refs -> refs -> path ,
272- iter -> pos , iter -> eof - iter -> pos );
273-
274- eol = memchr (p , '\n' , iter -> eof - p );
275- if (!eol )
276- die_unterminated_line (iter -> packed_refs -> refs -> path ,
277- iter -> pos , iter -> eof - iter -> pos );
278-
279- strbuf_add (& iter -> refname_buf , p , eol - p );
280- iter -> base .refname = iter -> refname_buf .buf ;
281-
282- if (check_refname_format (iter -> base .refname , REFNAME_ALLOW_ONELEVEL )) {
283- if (!refname_is_safe (iter -> base .refname ))
284- die ("packed refname is dangerous: %s" ,
285- iter -> base .refname );
286- oidclr (& iter -> oid );
287- iter -> base .flags |= REF_BAD_NAME | REF_ISBROKEN ;
288- }
289- if (iter -> packed_refs -> peeled == PEELED_FULLY ||
290- (iter -> packed_refs -> peeled == PEELED_TAGS &&
291- starts_with (iter -> base .refname , "refs/tags/" )))
292- iter -> base .flags |= REF_KNOWS_PEELED ;
293-
294- iter -> pos = eol + 1 ;
295-
296- if (iter -> pos < iter -> eof && * iter -> pos == '^' ) {
297- p = iter -> pos + 1 ;
298- if (iter -> eof - p < GIT_SHA1_HEXSZ + 1 ||
299- parse_oid_hex (p , & iter -> peeled , & p ) ||
300- * p ++ != '\n' )
301- die_invalid_line (iter -> packed_refs -> refs -> path ,
302- iter -> pos , iter -> eof - iter -> pos );
303- iter -> pos = p ;
304-
305- /*
306- * Regardless of what the file header said, we
307- * definitely know the value of *this* reference. But
308- * we suppress it if the reference is broken:
309- */
310- if ((iter -> base .flags & REF_ISBROKEN )) {
311- oidclr (& iter -> peeled );
312- iter -> base .flags &= ~REF_KNOWS_PEELED ;
313- } else {
314- iter -> base .flags |= REF_KNOWS_PEELED ;
315- }
316- } else {
317- oidclr (& iter -> peeled );
318- }
319-
320- return ITER_OK ;
321- }
322-
323- static int mmapped_ref_iterator_peel (struct ref_iterator * ref_iterator ,
324- struct object_id * peeled )
325- {
326- struct mmapped_ref_iterator * iter =
327- (struct mmapped_ref_iterator * )ref_iterator ;
328-
329- if ((iter -> base .flags & REF_KNOWS_PEELED )) {
330- oidcpy (peeled , & iter -> peeled );
331- return is_null_oid (& iter -> peeled ) ? -1 : 0 ;
332- } else if ((iter -> base .flags & (REF_ISBROKEN | REF_ISSYMREF ))) {
333- return -1 ;
334- } else {
335- return !!peel_object (iter -> oid .hash , peeled -> hash );
336- }
337- }
338-
339- static int mmapped_ref_iterator_abort (struct ref_iterator * ref_iterator )
340- {
341- struct mmapped_ref_iterator * iter =
342- (struct mmapped_ref_iterator * )ref_iterator ;
343-
344- release_packed_ref_cache (iter -> packed_refs );
345- strbuf_release (& iter -> refname_buf );
346- base_ref_iterator_free (ref_iterator );
347- return ITER_DONE ;
348- }
349-
350- static struct ref_iterator_vtable mmapped_ref_iterator_vtable = {
351- mmapped_ref_iterator_advance ,
352- mmapped_ref_iterator_peel ,
353- mmapped_ref_iterator_abort
354- };
355-
356- struct ref_iterator * mmapped_ref_iterator_begin (
357- struct packed_ref_cache * packed_refs ,
358- const char * pos , const char * eof )
359- {
360- struct mmapped_ref_iterator * iter = xcalloc (1 , sizeof (* iter ));
361- struct ref_iterator * ref_iterator = & iter -> base ;
362-
363- if (!packed_refs -> buf )
364- return empty_ref_iterator_begin ();
365-
366- base_ref_iterator_init (ref_iterator , & mmapped_ref_iterator_vtable , 1 );
367-
368- iter -> packed_refs = packed_refs ;
369- acquire_packed_ref_cache (iter -> packed_refs );
370- iter -> pos = pos ;
371- iter -> eof = eof ;
372- strbuf_init (& iter -> refname_buf , 0 );
373-
374- iter -> base .oid = & iter -> oid ;
375-
376- return ref_iterator ;
377- }
378-
379228struct packed_ref_entry {
380229 const char * start ;
381230 size_t len ;
@@ -858,38 +707,120 @@ static int packed_read_raw_ref(struct ref_store *ref_store,
858707 return 0 ;
859708}
860709
710+ /*
711+ * This value is set in `base.flags` if the peeled value of the
712+ * current reference is known. In that case, `peeled` contains the
713+ * correct peeled value for the reference, which might be `null_sha1`
714+ * if the reference is not a tag or if it is broken.
715+ */
716+ #define REF_KNOWS_PEELED 0x40
717+
718+ /*
719+ * An iterator over a packed-refs file that is currently mmapped.
720+ */
861721struct packed_ref_iterator {
862722 struct ref_iterator base ;
863723
864- struct packed_ref_cache * cache ;
865- struct ref_iterator * iter0 ;
724+ struct packed_ref_cache * packed_refs ;
725+
726+ /* The current position in the mmapped file: */
727+ const char * pos ;
728+
729+ /* The end of the mmapped file: */
730+ const char * eof ;
731+
732+ struct object_id oid , peeled ;
733+
734+ struct strbuf refname_buf ;
735+
866736 unsigned int flags ;
867737};
868738
739+ static int next_record (struct packed_ref_iterator * iter )
740+ {
741+ const char * p = iter -> pos , * eol ;
742+
743+ strbuf_reset (& iter -> refname_buf );
744+
745+ if (iter -> pos == iter -> eof )
746+ return ITER_DONE ;
747+
748+ iter -> base .flags = REF_ISPACKED ;
749+
750+ if (iter -> eof - p < GIT_SHA1_HEXSZ + 2 ||
751+ parse_oid_hex (p , & iter -> oid , & p ) ||
752+ !isspace (* p ++ ))
753+ die_invalid_line (iter -> packed_refs -> refs -> path ,
754+ iter -> pos , iter -> eof - iter -> pos );
755+
756+ eol = memchr (p , '\n' , iter -> eof - p );
757+ if (!eol )
758+ die_unterminated_line (iter -> packed_refs -> refs -> path ,
759+ iter -> pos , iter -> eof - iter -> pos );
760+
761+ strbuf_add (& iter -> refname_buf , p , eol - p );
762+ iter -> base .refname = iter -> refname_buf .buf ;
763+
764+ if (check_refname_format (iter -> base .refname , REFNAME_ALLOW_ONELEVEL )) {
765+ if (!refname_is_safe (iter -> base .refname ))
766+ die ("packed refname is dangerous: %s" ,
767+ iter -> base .refname );
768+ oidclr (& iter -> oid );
769+ iter -> base .flags |= REF_BAD_NAME | REF_ISBROKEN ;
770+ }
771+ if (iter -> packed_refs -> peeled == PEELED_FULLY ||
772+ (iter -> packed_refs -> peeled == PEELED_TAGS &&
773+ starts_with (iter -> base .refname , "refs/tags/" )))
774+ iter -> base .flags |= REF_KNOWS_PEELED ;
775+
776+ iter -> pos = eol + 1 ;
777+
778+ if (iter -> pos < iter -> eof && * iter -> pos == '^' ) {
779+ p = iter -> pos + 1 ;
780+ if (iter -> eof - p < GIT_SHA1_HEXSZ + 1 ||
781+ parse_oid_hex (p , & iter -> peeled , & p ) ||
782+ * p ++ != '\n' )
783+ die_invalid_line (iter -> packed_refs -> refs -> path ,
784+ iter -> pos , iter -> eof - iter -> pos );
785+ iter -> pos = p ;
786+
787+ /*
788+ * Regardless of what the file header said, we
789+ * definitely know the value of *this* reference. But
790+ * we suppress it if the reference is broken:
791+ */
792+ if ((iter -> base .flags & REF_ISBROKEN )) {
793+ oidclr (& iter -> peeled );
794+ iter -> base .flags &= ~REF_KNOWS_PEELED ;
795+ } else {
796+ iter -> base .flags |= REF_KNOWS_PEELED ;
797+ }
798+ } else {
799+ oidclr (& iter -> peeled );
800+ }
801+
802+ return ITER_OK ;
803+ }
804+
869805static int packed_ref_iterator_advance (struct ref_iterator * ref_iterator )
870806{
871807 struct packed_ref_iterator * iter =
872808 (struct packed_ref_iterator * )ref_iterator ;
873809 int ok ;
874810
875- while ((ok = ref_iterator_advance (iter -> iter0 )) == ITER_OK ) {
811+ while ((ok = next_record (iter )) == ITER_OK ) {
876812 if (iter -> flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
877- ref_type (iter -> iter0 -> refname ) != REF_TYPE_PER_WORKTREE )
813+ ref_type (iter -> base . refname ) != REF_TYPE_PER_WORKTREE )
878814 continue ;
879815
880816 if (!(iter -> flags & DO_FOR_EACH_INCLUDE_BROKEN ) &&
881- !ref_resolves_to_object (iter -> iter0 -> refname ,
882- iter -> iter0 -> oid ,
883- iter -> iter0 -> flags ))
817+ !ref_resolves_to_object (iter -> base .refname , & iter -> oid ,
818+ iter -> flags ))
884819 continue ;
885820
886- iter -> base .refname = iter -> iter0 -> refname ;
887- iter -> base .oid = iter -> iter0 -> oid ;
888- iter -> base .flags = iter -> iter0 -> flags ;
889821 return ITER_OK ;
890822 }
891823
892- iter -> iter0 = NULL ;
893824 if (ref_iterator_abort (ref_iterator ) != ITER_DONE )
894825 ok = ITER_ERROR ;
895826
@@ -902,7 +833,14 @@ static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
902833 struct packed_ref_iterator * iter =
903834 (struct packed_ref_iterator * )ref_iterator ;
904835
905- return ref_iterator_peel (iter -> iter0 , peeled );
836+ if ((iter -> base .flags & REF_KNOWS_PEELED )) {
837+ oidcpy (peeled , & iter -> peeled );
838+ return is_null_oid (& iter -> peeled ) ? -1 : 0 ;
839+ } else if ((iter -> base .flags & (REF_ISBROKEN | REF_ISSYMREF ))) {
840+ return -1 ;
841+ } else {
842+ return !!peel_object (iter -> oid .hash , peeled -> hash );
843+ }
906844}
907845
908846static int packed_ref_iterator_abort (struct ref_iterator * ref_iterator )
@@ -911,10 +849,8 @@ static int packed_ref_iterator_abort(struct ref_iterator *ref_iterator)
911849 (struct packed_ref_iterator * )ref_iterator ;
912850 int ok = ITER_DONE ;
913851
914- if (iter -> iter0 )
915- ok = ref_iterator_abort (iter -> iter0 );
916-
917- release_packed_ref_cache (iter -> cache );
852+ strbuf_release (& iter -> refname_buf );
853+ release_packed_ref_cache (iter -> packed_refs );
918854 base_ref_iterator_free (ref_iterator );
919855 return ok ;
920856}
@@ -940,6 +876,11 @@ static struct ref_iterator *packed_ref_iterator_begin(
940876 required_flags |= REF_STORE_ODB ;
941877 refs = packed_downcast (ref_store , required_flags , "ref_iterator_begin" );
942878
879+ packed_refs = get_packed_ref_cache (refs );
880+
881+ if (!packed_refs -> buf )
882+ return empty_ref_iterator_begin ();
883+
943884 iter = xcalloc (1 , sizeof (* iter ));
944885 ref_iterator = & iter -> base ;
945886 base_ref_iterator_init (ref_iterator , & packed_ref_iterator_vtable , 1 );
@@ -949,16 +890,19 @@ static struct ref_iterator *packed_ref_iterator_begin(
949890 * the packed-ref cache is up to date with what is on disk,
950891 * and re-reads it if not.
951892 */
952- iter -> cache = packed_refs = get_packed_ref_cache ( refs ) ;
893+ iter -> packed_refs = packed_refs ;
953894 acquire_packed_ref_cache (packed_refs );
954895
955896 if (prefix && * prefix )
956897 start = find_reference_location (packed_refs , prefix , 0 );
957898 else
958899 start = packed_refs -> buf + packed_refs -> header_len ;
959900
960- iter -> iter0 = mmapped_ref_iterator_begin (packed_refs ,
961- start , packed_refs -> eof );
901+ iter -> pos = start ;
902+ iter -> eof = packed_refs -> eof ;
903+ strbuf_init (& iter -> refname_buf , 0 );
904+
905+ iter -> base .oid = & iter -> oid ;
962906
963907 iter -> flags = flags ;
964908
0 commit comments