Fix a bug in seafile client.

wt_status_collect_untracked() function should not pass the full path
of a file to should_ignore() function.
This commit is contained in:
Jiaqiang Xu 2012-09-01 14:30:45 +08:00
parent 830656b772
commit 09bdee94a6
3 changed files with 149 additions and 163 deletions

View File

@ -14,6 +14,150 @@
#include "utils.h"
#include "cdc/cdc.h"
struct dir_entry {
unsigned int len;
char name[0]; /* more */
};
struct dir_struct {
int nr, alloc;
int ignored_nr, ignored_alloc;
enum {
DIR_SHOW_IGNORED = 1<<0,
DIR_SHOW_OTHER_DIRECTORIES = 1<<1,
DIR_HIDE_EMPTY_DIRECTORIES = 1<<2,
DIR_NO_GITLINKS = 1<<3,
DIR_COLLECT_IGNORED = 1<<4
} flags;
struct dir_entry **entries;
struct dir_entry **ignored;
};
static struct dir_entry *
dir_entry_new(const char *pathname, int len)
{
struct dir_entry *ent;
ent = malloc(sizeof(*ent) + len + 1);
ent->len = len;
memcpy(ent->name, pathname, len);
ent->name[len] = 0;
return ent;
}
static struct dir_entry *
dir_add_name(struct dir_struct *dir, const char *pathname,
int len, struct index_state *index)
{
if (index_name_exists(index, pathname, len, 0))
return NULL;
ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
}
static inline int
is_dot_or_dotdot(const char *name)
{
return (name[0] == '.' &&
(name[1] == '\0' ||
(name[1] == '.' && name[2] == '\0')));
}
static int
get_dtype(const char *dname, const char *path)
{
struct stat st;
int dtype = DT_UNKNOWN;
char *realpath = g_build_path (PATH_SEPERATOR, path, dname, NULL);
if (!g_lstat(realpath, &st)) {
if (S_ISREG(st.st_mode))
dtype = DT_REG;
if (S_ISDIR(st.st_mode))
dtype = DT_DIR;
}
g_free(realpath);
return dtype;
}
static int
read_directory_recursive(struct dir_struct *dir,
const char *base, int baselen,
int check_only,
struct index_state *index,
const char *worktree,
IgnoreFunc ignore_func)
{
char *realpath = g_build_path (PATH_SEPERATOR, worktree, base, NULL);
GDir *fdir = g_dir_open (realpath, 0, NULL);
const char *dname;
int contents = 0;
int dtype;
if (fdir) {
char path[PATH_MAX + 1];
memcpy(path, base, baselen);
while ((dname = g_dir_read_name(fdir)) != NULL) {
int len = 0;
if (is_dot_or_dotdot(dname))
continue;
if (ignore_func (dname, NULL))
continue;
dtype = get_dtype(dname, realpath);
switch (dtype) {
case DT_REG:
len = strlen(dname);
memcpy(path + baselen, dname, len + 1);
len = strlen(path);
break;
case DT_DIR:
len = strlen(dname);
memcpy(path + baselen, dname, len + 1);
memcpy(path + baselen + len, "/", 2);
len = strlen(path);
read_directory_recursive(dir, path, len, 0,
index, worktree, ignore_func);
continue;
default: /* DT_UNKNOWN */
len = 0;
break;
}
if(len > 0)
dir_add_name(dir, path, len, index);
}
g_dir_close(fdir);
}
g_free(realpath);
return contents;
}
static int
cmp_name(const void *p1, const void *p2)
{
const struct dir_entry *e1 = *(const struct dir_entry **)p1;
const struct dir_entry *e2 = *(const struct dir_entry **)p2;
return cache_name_compare(e1->name, e1->len,
e2->name, e2->len);
}
static int
read_directory(struct dir_struct *dir,
const char *worktree,
struct index_state *index,
IgnoreFunc ignore_func)
{
read_directory_recursive(dir, "", 0, 0, index, worktree, ignore_func);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;
}
void wt_status_collect_untracked(struct index_state *index,
GList **results,
const char *worktree,
@ -25,15 +169,14 @@ void wt_status_collect_untracked(struct index_state *index,
memset(&dir, 0, sizeof(dir));
read_directory(&dir, worktree, index);
read_directory(&dir, worktree, index, ignore_func);
for (i = 0; i < dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
unsigned char sha1[20] = { 0 };
de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_ADDED, sha1, ent->name);
*results = g_list_prepend (*results, de);
if (!ignore_func(ent->name, NULL)) {
unsigned char sha1[20] = { 0 };
de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_ADDED, sha1, ent->name);
*results = g_list_prepend (*results, de);
}
free(ent);
}

View File

@ -625,141 +625,6 @@ get_last_changer_of_file (const char *head, const char *path)
return ret;
}
static struct dir_entry *
dir_entry_new(const char *pathname, int len)
{
struct dir_entry *ent;
ent = malloc(sizeof(*ent) + len + 1);
ent->len = len;
memcpy(ent->name, pathname, len);
ent->name[len] = 0;
return ent;
}
static struct dir_entry *
dir_add_name(struct dir_struct *dir, const char *pathname,
int len, struct index_state *index)
{
if (index_name_exists(index, pathname, len, 0))
return NULL;
ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
}
static inline int
is_dot_or_dotdot(const char *name)
{
return (name[0] == '.' &&
(name[1] == '\0' ||
(name[1] == '.' && name[2] == '\0')));
}
#ifdef WIN32
static int
get_dtype(const char *dname, const char *path)
{
struct stat st;
int dtype = DT_UNKNOWN;
char *realpath = g_build_path (PATH_SEPERATOR, path, dname, NULL);
if (!g_lstat(realpath, &st)) {
if (S_ISREG(st.st_mode))
dtype = DT_REG;
if (S_ISDIR(st.st_mode))
dtype = DT_DIR;
}
g_free(realpath);
return dtype;
}
#endif
static int
read_directory_recursive(struct dir_struct *dir,
const char *base, int baselen,
int check_only,
struct index_state *index,
const char *worktree)
{
char *realpath = g_build_path (PATH_SEPERATOR, worktree, base, NULL);
#ifndef WIN32
DIR *fdir = opendir (realpath);
struct dirent *de;
#else
GDir *fdir = g_dir_open (realpath, 0, NULL);
#endif
const char *dname;
int contents = 0;
int dtype;
if (fdir) {
char path[PATH_MAX + 1];
memcpy(path, base, baselen);
#ifndef WIN32
while ((de = readdir(fdir)) != NULL) {
dtype = DTYPE(de);
dname = de->d_name;
#else
while ((dname = g_dir_read_name(fdir)) != NULL) {
dtype = get_dtype(dname, realpath);
#endif
int len = 0;
if (is_dot_or_dotdot(dname))
continue;
switch (dtype) {
case DT_REG:
len = strlen(dname);
memcpy(path + baselen, dname, len + 1);
len = strlen(path);
break;
case DT_DIR:
len = strlen(dname);
memcpy(path + baselen, dname, len + 1);
memcpy(path + baselen + len, "/", 2);
len = strlen(path);
read_directory_recursive(dir, path, len, 0, index, worktree);
continue;
default: /* DT_UNKNOWN */
len = 0;
break;
}
if(len > 0)
dir_add_name(dir, path, len, index);
}
#ifdef WIN32
g_dir_close(fdir);
#else
closedir(fdir);
#endif
}
g_free(realpath);
return contents;
}
static int
cmp_name(const void *p1, const void *p2)
{
const struct dir_entry *e1 = *(const struct dir_entry **)p1;
const struct dir_entry *e2 = *(const struct dir_entry **)p2;
return cache_name_compare(e1->name, e1->len,
e2->name, e2->len);
}
int
read_directory(struct dir_struct *dir, const char *worktree, struct index_state *index)
{
read_directory_recursive(dir, "", 0, 0, index, worktree);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;
}
void
fill_seafile_blocks (const unsigned char *sha1, BlockList *bl)
{

View File

@ -47,28 +47,6 @@ compare_file_content (const char *path, struct stat *st,
const unsigned char *ce_sha1,
struct SeafileCrypt *crypt);
struct dir_entry {
unsigned int len;
char name[0]; /* more */
};
struct dir_struct {
int nr, alloc;
int ignored_nr, ignored_alloc;
enum {
DIR_SHOW_IGNORED = 1<<0,
DIR_SHOW_OTHER_DIRECTORIES = 1<<1,
DIR_HIDE_EMPTY_DIRECTORIES = 1<<2,
DIR_NO_GITLINKS = 1<<3,
DIR_COLLECT_IGNORED = 1<<4
} flags;
struct dir_entry **entries;
struct dir_entry **ignored;
};
int
read_directory(struct dir_struct *dir, const char *worktree, struct index_state *index);
void
fill_seafile_blocks (const unsigned char *sha1, BlockList *bl);