@@ -220,6 +220,57 @@ int within_depth(const char *name, int namelen,
220
220
return 1 ;
221
221
}
222
222
223
+ /*
224
+ * Read the contents of the blob with the given OID into a buffer.
225
+ * Append a trailing LF to the end if the last line doesn't have one.
226
+ *
227
+ * Returns:
228
+ * -1 when the OID is invalid or unknown or does not refer to a blob.
229
+ * 0 when the blob is empty.
230
+ * 1 along with { data, size } of the (possibly augmented) buffer
231
+ * when successful.
232
+ *
233
+ * Optionally updates the given sha1_stat with the given OID (when valid).
234
+ */
235
+ static int do_read_blob (const struct object_id * oid ,
236
+ struct sha1_stat * sha1_stat ,
237
+ size_t * size_out ,
238
+ char * * data_out )
239
+ {
240
+ enum object_type type ;
241
+ unsigned long sz ;
242
+ char * data ;
243
+
244
+ * size_out = 0 ;
245
+ * data_out = NULL ;
246
+
247
+ data = read_sha1_file (oid -> hash , & type , & sz );
248
+ if (!data || type != OBJ_BLOB ) {
249
+ free (data );
250
+ return -1 ;
251
+ }
252
+
253
+ if (sha1_stat ) {
254
+ memset (& sha1_stat -> stat , 0 , sizeof (sha1_stat -> stat ));
255
+ hashcpy (sha1_stat -> sha1 , oid -> hash );
256
+ }
257
+
258
+ if (sz == 0 ) {
259
+ free (data );
260
+ return 0 ;
261
+ }
262
+
263
+ if (data [sz - 1 ] != '\n' ) {
264
+ data = xrealloc (data , st_add (sz , 1 ));
265
+ data [sz ++ ] = '\n' ;
266
+ }
267
+
268
+ * size_out = xsize_t (sz );
269
+ * data_out = data ;
270
+
271
+ return 1 ;
272
+ }
273
+
223
274
#define DO_MATCH_EXCLUDE (1<<0)
224
275
#define DO_MATCH_DIRECTORY (1<<1)
225
276
#define DO_MATCH_SUBMODULE (1<<2)
@@ -600,32 +651,22 @@ void add_exclude(const char *string, const char *base,
600
651
x -> el = el ;
601
652
}
602
653
603
- static void * read_skip_worktree_file_from_index (const struct index_state * istate ,
604
- const char * path , size_t * size ,
605
- struct sha1_stat * sha1_stat )
654
+ static int read_skip_worktree_file_from_index (const struct index_state * istate ,
655
+ const char * path ,
656
+ size_t * size_out ,
657
+ char * * data_out ,
658
+ struct sha1_stat * sha1_stat )
606
659
{
607
660
int pos , len ;
608
- unsigned long sz ;
609
- enum object_type type ;
610
- void * data ;
611
661
612
662
len = strlen (path );
613
663
pos = index_name_pos (istate , path , len );
614
664
if (pos < 0 )
615
- return NULL ;
665
+ return -1 ;
616
666
if (!ce_skip_worktree (istate -> cache [pos ]))
617
- return NULL ;
618
- data = read_sha1_file (istate -> cache [pos ]-> oid .hash , & type , & sz );
619
- if (!data || type != OBJ_BLOB ) {
620
- free (data );
621
- return NULL ;
622
- }
623
- * size = xsize_t (sz );
624
- if (sha1_stat ) {
625
- memset (& sha1_stat -> stat , 0 , sizeof (sha1_stat -> stat ));
626
- hashcpy (sha1_stat -> sha1 , istate -> cache [pos ]-> oid .hash );
627
- }
628
- return data ;
667
+ return -1 ;
668
+
669
+ return do_read_blob (& istate -> cache [pos ]-> oid , sha1_stat , size_out , data_out );
629
670
}
630
671
631
672
/*
@@ -739,6 +780,10 @@ static void invalidate_directory(struct untracked_cache *uc,
739
780
dir -> dirs [i ]-> recurse = 0 ;
740
781
}
741
782
783
+ static int add_excludes_from_buffer (char * buf , size_t size ,
784
+ const char * base , int baselen ,
785
+ struct exclude_list * el );
786
+
742
787
/*
743
788
* Given a file with name "fname", read it (either from disk, or from
744
789
* an index if 'istate' is non-null), parse it and store the
@@ -754,27 +799,24 @@ static int add_excludes(const char *fname, const char *base, int baselen,
754
799
struct sha1_stat * sha1_stat )
755
800
{
756
801
struct stat st ;
757
- int fd , i , lineno = 1 ;
802
+ int r ;
803
+ int fd ;
758
804
size_t size = 0 ;
759
- char * buf , * entry ;
805
+ char * buf ;
760
806
761
807
fd = open (fname , O_RDONLY );
762
808
if (fd < 0 || fstat (fd , & st ) < 0 ) {
763
809
if (fd < 0 )
764
810
warn_on_fopen_errors (fname );
765
811
else
766
812
close (fd );
767
- if (!istate ||
768
- (buf = read_skip_worktree_file_from_index (istate , fname , & size , sha1_stat )) == NULL )
813
+ if (!istate )
769
814
return -1 ;
770
- if (size == 0 ) {
771
- free (buf );
772
- return 0 ;
773
- }
774
- if (buf [size - 1 ] != '\n' ) {
775
- buf = xrealloc (buf , st_add (size , 1 ));
776
- buf [size ++ ] = '\n' ;
777
- }
815
+ r = read_skip_worktree_file_from_index (istate , fname ,
816
+ & size , & buf ,
817
+ sha1_stat );
818
+ if (r != 1 )
819
+ return r ;
778
820
} else {
779
821
size = xsize_t (st .st_size );
780
822
if (size == 0 ) {
@@ -813,6 +855,17 @@ static int add_excludes(const char *fname, const char *base, int baselen,
813
855
}
814
856
}
815
857
858
+ add_excludes_from_buffer (buf , size , base , baselen , el );
859
+ return 0 ;
860
+ }
861
+
862
+ static int add_excludes_from_buffer (char * buf , size_t size ,
863
+ const char * base , int baselen ,
864
+ struct exclude_list * el )
865
+ {
866
+ int i , lineno = 1 ;
867
+ char * entry ;
868
+
816
869
el -> filebuf = buf ;
817
870
818
871
if (skip_utf8_bom (& buf , size ))
@@ -841,6 +894,23 @@ int add_excludes_from_file_to_list(const char *fname, const char *base,
841
894
return add_excludes (fname , base , baselen , el , istate , NULL );
842
895
}
843
896
897
+ int add_excludes_from_blob_to_list (
898
+ struct object_id * oid ,
899
+ const char * base , int baselen ,
900
+ struct exclude_list * el )
901
+ {
902
+ char * buf ;
903
+ size_t size ;
904
+ int r ;
905
+
906
+ r = do_read_blob (oid , NULL , & size , & buf );
907
+ if (r != 1 )
908
+ return r ;
909
+
910
+ add_excludes_from_buffer (buf , size , base , baselen , el );
911
+ return 0 ;
912
+ }
913
+
844
914
struct exclude_list * add_exclude_list (struct dir_struct * dir ,
845
915
int group_type , const char * src )
846
916
{
0 commit comments