@@ -225,157 +225,6 @@ static NORETURN void die_invalid_line(const char *path,
225
225
226
226
}
227
227
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
-
379
228
struct packed_ref_entry {
380
229
const char * start ;
381
230
size_t len ;
@@ -858,38 +707,120 @@ static int packed_read_raw_ref(struct ref_store *ref_store,
858
707
return 0 ;
859
708
}
860
709
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
+ */
861
721
struct packed_ref_iterator {
862
722
struct ref_iterator base ;
863
723
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
+
866
736
unsigned int flags ;
867
737
};
868
738
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
+
869
805
static int packed_ref_iterator_advance (struct ref_iterator * ref_iterator )
870
806
{
871
807
struct packed_ref_iterator * iter =
872
808
(struct packed_ref_iterator * )ref_iterator ;
873
809
int ok ;
874
810
875
- while ((ok = ref_iterator_advance (iter -> iter0 )) == ITER_OK ) {
811
+ while ((ok = next_record (iter )) == ITER_OK ) {
876
812
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 )
878
814
continue ;
879
815
880
816
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 ))
884
819
continue ;
885
820
886
- iter -> base .refname = iter -> iter0 -> refname ;
887
- iter -> base .oid = iter -> iter0 -> oid ;
888
- iter -> base .flags = iter -> iter0 -> flags ;
889
821
return ITER_OK ;
890
822
}
891
823
892
- iter -> iter0 = NULL ;
893
824
if (ref_iterator_abort (ref_iterator ) != ITER_DONE )
894
825
ok = ITER_ERROR ;
895
826
@@ -902,7 +833,14 @@ static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
902
833
struct packed_ref_iterator * iter =
903
834
(struct packed_ref_iterator * )ref_iterator ;
904
835
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
+ }
906
844
}
907
845
908
846
static 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)
911
849
(struct packed_ref_iterator * )ref_iterator ;
912
850
int ok = ITER_DONE ;
913
851
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 );
918
854
base_ref_iterator_free (ref_iterator );
919
855
return ok ;
920
856
}
@@ -940,6 +876,11 @@ static struct ref_iterator *packed_ref_iterator_begin(
940
876
required_flags |= REF_STORE_ODB ;
941
877
refs = packed_downcast (ref_store , required_flags , "ref_iterator_begin" );
942
878
879
+ packed_refs = get_packed_ref_cache (refs );
880
+
881
+ if (!packed_refs -> buf )
882
+ return empty_ref_iterator_begin ();
883
+
943
884
iter = xcalloc (1 , sizeof (* iter ));
944
885
ref_iterator = & iter -> base ;
945
886
base_ref_iterator_init (ref_iterator , & packed_ref_iterator_vtable , 1 );
@@ -949,16 +890,19 @@ static struct ref_iterator *packed_ref_iterator_begin(
949
890
* the packed-ref cache is up to date with what is on disk,
950
891
* and re-reads it if not.
951
892
*/
952
- iter -> cache = packed_refs = get_packed_ref_cache ( refs ) ;
893
+ iter -> packed_refs = packed_refs ;
953
894
acquire_packed_ref_cache (packed_refs );
954
895
955
896
if (prefix && * prefix )
956
897
start = find_reference_location (packed_refs , prefix , 0 );
957
898
else
958
899
start = packed_refs -> buf + packed_refs -> header_len ;
959
900
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 ;
962
906
963
907
iter -> flags = flags ;
964
908
0 commit comments