Read .gitignore from index if it is skip-worktree
This adds index as a prerequisite for directory listing (with exclude). At the moment directory listing is used by "git clean", "git add", "git ls-files" and "git status"/"git commit" and unpack_trees()-related commands. These commands have been checked/modified to populate index before doing directory listing. add_excludes_from_file() does not enable this feature, because it is used to read .git/info/exclude and some explicit files specified by "git ls-files". Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
b5041c5f3b
commit
c28b3d6e7b
65
dir.c
65
dir.c
@ -200,11 +200,35 @@ void add_exclude(const char *string, const char *base,
|
||||
which->excludes[which->nr++] = x;
|
||||
}
|
||||
|
||||
static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
|
||||
{
|
||||
int pos, len;
|
||||
unsigned long sz;
|
||||
enum object_type type;
|
||||
void *data;
|
||||
struct index_state *istate = &the_index;
|
||||
|
||||
len = strlen(path);
|
||||
pos = index_name_pos(istate, path, len);
|
||||
if (pos < 0)
|
||||
return NULL;
|
||||
if (!ce_skip_worktree(istate->cache[pos]))
|
||||
return NULL;
|
||||
data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
|
||||
if (!data || type != OBJ_BLOB) {
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
*size = xsize_t(sz);
|
||||
return data;
|
||||
}
|
||||
|
||||
static int add_excludes_from_file_1(const char *fname,
|
||||
const char *base,
|
||||
int baselen,
|
||||
char **buf_p,
|
||||
struct exclude_list *which)
|
||||
struct exclude_list *which,
|
||||
int check_index)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, i;
|
||||
@ -212,20 +236,26 @@ static int add_excludes_from_file_1(const char *fname,
|
||||
char *buf, *entry;
|
||||
|
||||
fd = open(fname, O_RDONLY);
|
||||
if (fd < 0 || fstat(fd, &st) < 0)
|
||||
goto err;
|
||||
size = xsize_t(st.st_size);
|
||||
if (size == 0) {
|
||||
if (fd < 0 || fstat(fd, &st) < 0) {
|
||||
if (0 <= fd)
|
||||
close(fd);
|
||||
if (!check_index ||
|
||||
(buf = read_skip_worktree_file_from_index(fname, &size)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
size = xsize_t(st.st_size);
|
||||
if (size == 0) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
buf = xmalloc(size);
|
||||
if (read_in_full(fd, buf, size) != size) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
buf = xmalloc(size+1);
|
||||
if (read_in_full(fd, buf, size) != size)
|
||||
{
|
||||
free(buf);
|
||||
goto err;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (buf_p)
|
||||
*buf_p = buf;
|
||||
@ -240,17 +270,12 @@ static int add_excludes_from_file_1(const char *fname,
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (0 <= fd)
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void add_excludes_from_file(struct dir_struct *dir, const char *fname)
|
||||
{
|
||||
if (add_excludes_from_file_1(fname, "", 0, NULL,
|
||||
&dir->exclude_list[EXC_FILE]) < 0)
|
||||
&dir->exclude_list[EXC_FILE], 0) < 0)
|
||||
die("cannot use %s as an exclude file", fname);
|
||||
}
|
||||
|
||||
@ -301,7 +326,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
|
||||
strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
|
||||
add_excludes_from_file_1(dir->basebuf,
|
||||
dir->basebuf, stk->baselen,
|
||||
&stk->filebuf, el);
|
||||
&stk->filebuf, el, 1);
|
||||
dir->exclude_stack = stk;
|
||||
current = stk->baselen;
|
||||
}
|
||||
|
Reference in New Issue
Block a user