Skip to content

Commit 578d81d

Browse files
jeffhostetlergitster
authored andcommitted
dir: allow exclusions from blob in addition to file
Refactor add_excludes() to separate the reading of the exclude file into a buffer and the parsing of the buffer into exclude_list items. Add add_excludes_from_blob_to_list() to allow an exclude file be specified with an OID without assuming a local worktree or index exists. Refactor read_skip_worktree_file_from_index() and add do_read_blob() to eliminate duplication of preliminary processing of blob contents. Signed-off-by: Jeff Hostetler <[email protected]> Reviewed-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cb5918a commit 578d81d

File tree

2 files changed

+104
-31
lines changed

2 files changed

+104
-31
lines changed

dir.c

Lines changed: 101 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,57 @@ int within_depth(const char *name, int namelen,
220220
return 1;
221221
}
222222

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+
223274
#define DO_MATCH_EXCLUDE (1<<0)
224275
#define DO_MATCH_DIRECTORY (1<<1)
225276
#define DO_MATCH_SUBMODULE (1<<2)
@@ -600,32 +651,22 @@ void add_exclude(const char *string, const char *base,
600651
x->el = el;
601652
}
602653

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)
606659
{
607660
int pos, len;
608-
unsigned long sz;
609-
enum object_type type;
610-
void *data;
611661

612662
len = strlen(path);
613663
pos = index_name_pos(istate, path, len);
614664
if (pos < 0)
615-
return NULL;
665+
return -1;
616666
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);
629670
}
630671

631672
/*
@@ -739,6 +780,10 @@ static void invalidate_directory(struct untracked_cache *uc,
739780
dir->dirs[i]->recurse = 0;
740781
}
741782

783+
static int add_excludes_from_buffer(char *buf, size_t size,
784+
const char *base, int baselen,
785+
struct exclude_list *el);
786+
742787
/*
743788
* Given a file with name "fname", read it (either from disk, or from
744789
* 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,
754799
struct sha1_stat *sha1_stat)
755800
{
756801
struct stat st;
757-
int fd, i, lineno = 1;
802+
int r;
803+
int fd;
758804
size_t size = 0;
759-
char *buf, *entry;
805+
char *buf;
760806

761807
fd = open(fname, O_RDONLY);
762808
if (fd < 0 || fstat(fd, &st) < 0) {
763809
if (fd < 0)
764810
warn_on_fopen_errors(fname);
765811
else
766812
close(fd);
767-
if (!istate ||
768-
(buf = read_skip_worktree_file_from_index(istate, fname, &size, sha1_stat)) == NULL)
813+
if (!istate)
769814
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;
778820
} else {
779821
size = xsize_t(st.st_size);
780822
if (size == 0) {
@@ -813,6 +855,17 @@ static int add_excludes(const char *fname, const char *base, int baselen,
813855
}
814856
}
815857

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+
816869
el->filebuf = buf;
817870

818871
if (skip_utf8_bom(&buf, size))
@@ -841,6 +894,23 @@ int add_excludes_from_file_to_list(const char *fname, const char *base,
841894
return add_excludes(fname, base, baselen, el, istate, NULL);
842895
}
843896

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+
844914
struct exclude_list *add_exclude_list(struct dir_struct *dir,
845915
int group_type, const char *src)
846916
{

dir.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ extern struct exclude_list *add_exclude_list(struct dir_struct *dir,
256256
extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
257257
struct exclude_list *el, struct index_state *istate);
258258
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
259+
extern int add_excludes_from_blob_to_list(struct object_id *oid,
260+
const char *base, int baselen,
261+
struct exclude_list *el);
259262
extern void parse_exclude_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen);
260263
extern void add_exclude(const char *string, const char *base,
261264
int baselen, struct exclude_list *el, int srcpos);

0 commit comments

Comments
 (0)