Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1023,12 +1023,16 @@ struct checkout {
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);

struct cache_def {
char path[PATH_MAX + 1];
int len;
struct strbuf path;
int flags;
int track_flags;
int prefix_len_stat_func;
};
#define CACHE_DEF_INIT { STRBUF_INIT, 0, 0, 0 }
static inline void cache_def_clear(struct cache_def *cache)
{
strbuf_release(&cache->path);
}

extern int has_symlink_leading_path(const char *name, int len);
extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int);
Expand Down
4 changes: 2 additions & 2 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
{
int namelen;
char alt_name[PATH_MAX];
char alt_name[MAX_LONG_PATH];

if (!do_lstat(follow, file_name, buf))
return 0;
Expand All @@ -576,7 +576,7 @@ static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
return -1;
while (namelen && file_name[namelen-1] == '/')
--namelen;
if (!namelen || namelen >= PATH_MAX)
if (!namelen || namelen >= MAX_LONG_PATH)
return -1;

memcpy(alt_name, file_name, namelen);
Expand Down
59 changes: 34 additions & 25 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,7 @@ int add_excludes_from_file_to_list(const char *fname,
buf = xrealloc(buf, size+1);
buf[size++] = '\n';
}
}
else {
} else {
size = xsize_t(st.st_size);
if (size == 0) {
close(fd);
Expand Down Expand Up @@ -766,17 +765,19 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)

group = &dir->exclude_list_group[EXC_DIRS];

/* Pop the exclude lists from the EXCL_DIRS exclude_list_group
/*
* Pop the exclude lists from the EXCL_DIRS exclude_list_group
* which originate from directories not in the prefix of the
* path being checked. */
* path being checked.
*/
while ((stk = dir->exclude_stack) != NULL) {
if (stk->baselen <= baselen &&
!strncmp(dir->basebuf, base, stk->baselen))
!strncmp(dir->basebuf.buf, base, stk->baselen))
break;
el = &group->el[dir->exclude_stack->exclude_ix];
dir->exclude_stack = stk->prev;
dir->exclude = NULL;
free((char *)el->src); /* see strdup() below */
free((char *)el->src); /* see strbuf_detach() below */
clear_exclude_list(el);
free(stk);
group->nr--;
Expand All @@ -786,17 +787,25 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
if (dir->exclude)
return;

/*
* Lazy initialization. All call sites currently just
* memset(dir, 0, sizeof(*dir)) before use. Changing all of
* them seems lots of work for little benefit.
*/
if (!dir->basebuf.buf)
strbuf_init(&dir->basebuf, PATH_MAX);

/* Read from the parent directories and push them down. */
current = stk ? stk->baselen : -1;
strbuf_setlen(&dir->basebuf, current < 0 ? 0 : current);
while (current < baselen) {
struct exclude_stack *stk = xcalloc(1, sizeof(*stk));
const char *cp;

if (current < 0) {
cp = base;
current = 0;
}
else {
} else {
cp = strchr(base + current + 1, '/');
if (!cp)
die("oops in prep_exclude");
Expand All @@ -806,48 +815,47 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
stk->baselen = cp - base;
stk->exclude_ix = group->nr;
el = add_exclude_list(dir, EXC_DIRS, NULL);
memcpy(dir->basebuf + current, base + current,
stk->baselen - current);
strbuf_add(&dir->basebuf, base + current, stk->baselen - current);
assert(stk->baselen == dir->basebuf.len);

/* Abort if the directory is excluded */
if (stk->baselen) {
int dt = DT_DIR;
dir->basebuf[stk->baselen - 1] = 0;
dir->basebuf.buf[stk->baselen - 1] = 0;
dir->exclude = last_exclude_matching_from_lists(dir,
dir->basebuf, stk->baselen - 1,
dir->basebuf + current, &dt);
dir->basebuf[stk->baselen - 1] = '/';
dir->basebuf.buf, stk->baselen - 1,
dir->basebuf.buf + current, &dt);
dir->basebuf.buf[stk->baselen - 1] = '/';
if (dir->exclude &&
dir->exclude->flags & EXC_FLAG_NEGATIVE)
dir->exclude = NULL;
if (dir->exclude) {
dir->basebuf[stk->baselen] = 0;
dir->exclude_stack = stk;
return;
}
}

/* Try to read per-directory file unless path is too long */
if (dir->exclude_per_dir &&
stk->baselen + strlen(dir->exclude_per_dir) < PATH_MAX) {
strcpy(dir->basebuf + stk->baselen,
dir->exclude_per_dir);
/* Try to read per-directory file */
if (dir->exclude_per_dir) {
/*
* dir->basebuf gets reused by the traversal, but we
* need fname to remain unchanged to ensure the src
* member of each struct exclude correctly
* back-references its source file. Other invocations
* of add_exclude_list provide stable strings, so we
* strdup() and free() here in the caller.
* strbuf_detach() and free() here in the caller.
*/
el->src = strdup(dir->basebuf);
add_excludes_from_file_to_list(dir->basebuf,
dir->basebuf, stk->baselen, el, 1);
struct strbuf sb = STRBUF_INIT;
strbuf_addbuf(&sb, &dir->basebuf);
strbuf_addstr(&sb, dir->exclude_per_dir);
el->src = strbuf_detach(&sb, NULL);
add_excludes_from_file_to_list(el->src, el->src,
stk->baselen, el, 1);
}
dir->exclude_stack = stk;
current = stk->baselen;
}
dir->basebuf[baselen] = '\0';
strbuf_setlen(&dir->basebuf, baselen);
}

/*
Expand Down Expand Up @@ -1648,4 +1656,5 @@ void clear_directory(struct dir_struct *dir)
free(stk);
stk = prev;
}
strbuf_release(&dir->basebuf);
}
44 changes: 23 additions & 21 deletions dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ struct dir_entry {
#define EXC_FLAG_MUSTBEDIR 8
#define EXC_FLAG_NEGATIVE 16

struct exclude {
/*
* This allows callers of last_exclude_matching() etc.
* to determine the origin of the matching pattern.
*/
struct exclude_list *el;

const char *pattern;
int patternlen;
int nowildcardlen;
const char *base;
int baselen;
int flags;

/*
* Counting starts from 1 for line numbers in ignore files,
* and from -1 decrementing for patterns from CLI args.
*/
int srcpos;
};

/*
* Each excludes file will be parsed into a fresh exclude_list which
* is appended to the relevant exclude_list_group (either EXC_DIRS or
Expand All @@ -32,26 +53,7 @@ struct exclude_list {
/* origin of list, e.g. path to filename, or descriptive string */
const char *src;

struct exclude {
/*
* This allows callers of last_exclude_matching() etc.
* to determine the origin of the matching pattern.
*/
struct exclude_list *el;

const char *pattern;
int patternlen;
int nowildcardlen;
const char *base;
int baselen;
int flags;

/*
* Counting starts from 1 for line numbers in ignore files,
* and from -1 decrementing for patterns from CLI args.
*/
int srcpos;
} **excludes;
struct exclude **excludes;
};

/*
Expand Down Expand Up @@ -117,7 +119,7 @@ struct dir_struct {
*/
struct exclude_stack *exclude_stack;
struct exclude *exclude;
char basebuf[PATH_MAX];
struct strbuf basebuf;
};

/*
Expand Down
4 changes: 2 additions & 2 deletions preload-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ static void *preload_thread(void *_data)
struct thread_data *p = _data;
struct index_state *index = p->index;
struct cache_entry **cep = index->cache + p->offset;
struct cache_def cache;
struct cache_def cache = CACHE_DEF_INIT;

memset(&cache, 0, sizeof(cache));
nr = p->nr;
if (nr + p->offset > index->cache_nr)
nr = index->cache_nr - p->offset;
Expand All @@ -64,6 +63,7 @@ static void *preload_thread(void *_data)
continue;
ce_mark_uptodate(ce);
} while (--nr > 0);
cache_def_clear(&cache);
return NULL;
}

Expand Down
Loading