mirror of
https://github.com/haiwen/seafile.git
synced 2025-01-09 04:17:30 +08:00
[client] Improve ignore file.
Ignore local changes to ignored files. Consider the following sequence: 1. a file is committed; 2. this file is added to seafile-ignore.txt so it's ignored from now on; 3. this file is changed; If we don't ignore changes to this file, the worktree will be left in an unclean state and pauses sync. The same rule also applies for files under an ignored folder. To make it easier to check whether a file is under an ignored folder, we have to apply a restriction: If you want to ignore folder 'foo', you write 'foo/' in seafile-ignore.txt. Writing 'foo' will only ignore regular files or symlinks.
This commit is contained in:
parent
66e1657e83
commit
ec1b878264
@ -326,7 +326,7 @@ static gboolean
|
||||
should_ignore(const char *basepath, const char *filename, void *data)
|
||||
{
|
||||
GPatternSpec **spec = ignore_patterns;
|
||||
GList *p, *ignore_list = (GList *)data;
|
||||
GList *ignore_list = (GList *)data;
|
||||
|
||||
/* Ignore file/dir if its name is too long. */
|
||||
if (strlen(filename) >= SEAF_DIR_NAME_LEN)
|
||||
@ -358,9 +358,6 @@ should_ignore(const char *basepath, const char *filename, void *data)
|
||||
|
||||
int i;
|
||||
char c;
|
||||
char *str;
|
||||
GPatternSpec *ignore_spec;
|
||||
SeafStat st;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(illegals); i++) {
|
||||
if (strchr (filename, illegals[i])) {
|
||||
@ -373,33 +370,14 @@ should_ignore(const char *basepath, const char *filename, void *data)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore files in ignore.txt */
|
||||
str = g_build_filename(basepath, filename, NULL);
|
||||
|
||||
/* first check the path is a reg file or a dir */
|
||||
if (seaf_stat(str, &st) < 0) {
|
||||
g_free(str);
|
||||
char *fullpath = g_build_path ("/", basepath, filename, NULL);
|
||||
if (seaf_repo_check_ignore_file (ignore_list, fullpath)) {
|
||||
g_free (fullpath);
|
||||
return TRUE;
|
||||
}
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
g_free(str);
|
||||
str = g_build_filename(basepath, filename, "/", NULL);
|
||||
}
|
||||
g_free (fullpath);
|
||||
|
||||
for (p = ignore_list; p != NULL; p = p->next) {
|
||||
char *pattern = (char *)p->data;
|
||||
|
||||
ignore_spec = g_pattern_spec_new(pattern);
|
||||
if (g_pattern_match_string(ignore_spec, str)) {
|
||||
g_free(str);
|
||||
g_pattern_spec_free(ignore_spec);
|
||||
return TRUE;
|
||||
}
|
||||
g_pattern_spec_free(ignore_spec);
|
||||
}
|
||||
|
||||
g_free(str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -689,8 +667,7 @@ seaf_repo_is_worktree_changed (SeafRepo *repo)
|
||||
}
|
||||
repo->index_corrupted = FALSE;
|
||||
|
||||
wt_status_collect_changes_worktree (&istate, &res,
|
||||
repo->worktree, should_ignore);
|
||||
wt_status_collect_changes_worktree (&istate, &res, repo->worktree);
|
||||
if (res != NULL)
|
||||
goto changed;
|
||||
|
||||
@ -2779,7 +2756,13 @@ GList *seaf_repo_load_ignore_files (const char *worktree)
|
||||
|
||||
/* trim the last '\n' character */
|
||||
path[strlen(path)-1] = '\0';
|
||||
pattern = g_strdup_printf("%s/%s", worktree, path);
|
||||
|
||||
/* Change 'foo/' to 'foo/ *'. */
|
||||
if (path[strlen(path)-1] == '/')
|
||||
pattern = g_strdup_printf("%s/%s*", worktree, path);
|
||||
else
|
||||
pattern = g_strdup_printf("%s/%s", worktree, path);
|
||||
|
||||
list = g_list_prepend(list, g_strdup(pattern));
|
||||
}
|
||||
|
||||
@ -2792,6 +2775,42 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
seaf_repo_check_ignore_file (GList *ignore_list, const char *fullpath)
|
||||
{
|
||||
char *str;
|
||||
SeafStat st;
|
||||
GPatternSpec *ignore_spec;
|
||||
GList *p;
|
||||
|
||||
str = g_strdup(fullpath);
|
||||
|
||||
/* first check the path is a reg file or a dir */
|
||||
if (seaf_stat(str, &st) < 0) {
|
||||
g_free(str);
|
||||
return TRUE;
|
||||
}
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
g_free(str);
|
||||
str = g_strconcat (fullpath, "/", NULL);
|
||||
}
|
||||
|
||||
for (p = ignore_list; p != NULL; p = p->next) {
|
||||
char *pattern = (char *)p->data;
|
||||
|
||||
ignore_spec = g_pattern_spec_new(pattern);
|
||||
if (g_pattern_match_string(ignore_spec, str)) {
|
||||
g_free (str);
|
||||
g_pattern_spec_free(ignore_spec);
|
||||
return TRUE;
|
||||
}
|
||||
g_pattern_spec_free(ignore_spec);
|
||||
}
|
||||
|
||||
g_free (str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free ignored file list
|
||||
*/
|
||||
|
@ -348,6 +348,13 @@ seaf_repo_manager_update_repo_relay_info (SeafRepoManager *mgr,
|
||||
const char *new_addr,
|
||||
const char *new_port);
|
||||
|
||||
GList *seaf_repo_load_ignore_files (const char *worktree);
|
||||
void seaf_repo_free_ignore_files (GList *ignore_list);
|
||||
GList *
|
||||
seaf_repo_load_ignore_files (const char *worktree);
|
||||
|
||||
gboolean
|
||||
seaf_repo_check_ignore_file (GList *ignore_list, const char *fullpath);
|
||||
|
||||
void
|
||||
seaf_repo_free_ignore_files (GList *ignore_list);
|
||||
|
||||
#endif
|
||||
|
@ -230,12 +230,13 @@ is_empty_dir (const char *path, IgnoreFunc should_ignore)
|
||||
|
||||
void wt_status_collect_changes_worktree(struct index_state *index,
|
||||
GList **results,
|
||||
const char *worktree,
|
||||
IgnoreFunc ignore_func)
|
||||
const char *worktree)
|
||||
{
|
||||
DiffEntry *de;
|
||||
int entries, i;
|
||||
|
||||
GList *ignore_list = seaf_repo_load_ignore_files (worktree);
|
||||
|
||||
entries = index->cache_nr;
|
||||
for (i = 0; i < entries; i++) {
|
||||
char *realpath;
|
||||
@ -301,15 +302,20 @@ void wt_status_collect_changes_worktree(struct index_state *index,
|
||||
}
|
||||
|
||||
if (S_ISDIR (ce->ce_mode)) {
|
||||
/* if (!S_ISDIR (st.st_mode) || */
|
||||
/* !is_empty_dir (realpath, ignore_func)) { */
|
||||
/* de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_DIR_DELETED, */
|
||||
/* ce->sha1, ce->name); */
|
||||
/* *results = g_list_prepend (*results, de); */
|
||||
/* } */
|
||||
g_free (realpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Don't check changes to ignored files.
|
||||
* This can happen when a file is committed and then added to
|
||||
* ignore.txt. After that changes to this file will not committed,
|
||||
* and it should be ignored here.
|
||||
*/
|
||||
if (seaf_repo_check_ignore_file (ignore_list, realpath)) {
|
||||
g_free (realpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_free (realpath);
|
||||
|
||||
changed = ie_match_stat (index, ce, &st, 0);
|
||||
@ -322,6 +328,8 @@ void wt_status_collect_changes_worktree(struct index_state *index,
|
||||
ce->sha1, ce->name);
|
||||
*results = g_list_prepend (*results, de);
|
||||
}
|
||||
|
||||
seaf_repo_free_ignore_files (ignore_list);
|
||||
}
|
||||
|
||||
static struct cache_entry *
|
||||
|
@ -12,8 +12,7 @@ typedef gboolean (*IgnoreFunc) (const char *basepath, const char *filename, void
|
||||
void
|
||||
wt_status_collect_changes_worktree(struct index_state *index,
|
||||
GList **results,
|
||||
const char *worktree,
|
||||
IgnoreFunc ignore_func);
|
||||
const char *worktree);
|
||||
|
||||
void
|
||||
wt_status_collect_untracked(struct index_state *index,
|
||||
|
Loading…
Reference in New Issue
Block a user