mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 13:36:17 +00:00
Merge pull request #2269 from libgit2/rb/fix-leading-slash-ignores
Fix core.excludesfile named .gitignore
This commit is contained in:
commit
37ab5ecc10
@ -61,8 +61,7 @@ int git_attr_file__parse_buffer(
|
||||
git_repository *repo, void *parsedata, const char *buffer, git_attr_file *attrs)
|
||||
{
|
||||
int error = 0;
|
||||
const char *scan = NULL;
|
||||
char *context = NULL;
|
||||
const char *scan = NULL, *context = NULL;
|
||||
git_attr_rule *rule = NULL;
|
||||
|
||||
GIT_UNUSED(parsedata);
|
||||
@ -72,10 +71,10 @@ int git_attr_file__parse_buffer(
|
||||
scan = buffer;
|
||||
|
||||
/* if subdir file path, convert context for file paths */
|
||||
if (attrs->key && git__suffixcmp(attrs->key, "/" GIT_ATTR_FILE) == 0) {
|
||||
if (attrs->key &&
|
||||
git_path_root(attrs->key + 2) < 0 &&
|
||||
git__suffixcmp(attrs->key, "/" GIT_ATTR_FILE) == 0)
|
||||
context = attrs->key + 2;
|
||||
context[strlen(context) - strlen(GIT_ATTR_FILE)] = '\0';
|
||||
}
|
||||
|
||||
while (!error && *scan) {
|
||||
/* allocate rule if needed */
|
||||
@ -115,10 +114,6 @@ int git_attr_file__parse_buffer(
|
||||
|
||||
git_attr_rule__free(rule);
|
||||
|
||||
/* restore file path used for context */
|
||||
if (context)
|
||||
context[strlen(context)] = '.'; /* first char of GIT_ATTR_FILE */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -414,7 +409,10 @@ int git_attr_fnmatch__parse(
|
||||
if ((spec->flags & GIT_ATTR_FNMATCH_FULLPATH) != 0 &&
|
||||
source != NULL && git_path_root(pattern) < 0)
|
||||
{
|
||||
size_t sourcelen = strlen(source);
|
||||
/* use context path minus the trailing filename */
|
||||
char *slash = strrchr(source, '/');
|
||||
size_t sourcelen = slash ? slash - source + 1 : 0;
|
||||
|
||||
/* given an unrooted fullpath match from a file inside a repo,
|
||||
* prefix the pattern with the relative directory of the source file
|
||||
*/
|
||||
|
12
src/ignore.c
12
src/ignore.c
@ -14,8 +14,7 @@ static int parse_ignore_file(
|
||||
{
|
||||
int error = 0;
|
||||
git_attr_fnmatch *match = NULL;
|
||||
const char *scan = NULL;
|
||||
char *context = NULL;
|
||||
const char *scan = NULL, *context = NULL;
|
||||
int ignore_case = false;
|
||||
|
||||
/* Prefer to have the caller pass in a git_ignores as the parsedata
|
||||
@ -25,10 +24,10 @@ static int parse_ignore_file(
|
||||
else if (git_repository__cvar(&ignore_case, repo, GIT_CVAR_IGNORECASE) < 0)
|
||||
return error;
|
||||
|
||||
if (ignores->key && git__suffixcmp(ignores->key, "/" GIT_IGNORE_FILE) == 0) {
|
||||
if (ignores->key &&
|
||||
git_path_root(ignores->key + 2) < 0 &&
|
||||
git__suffixcmp(ignores->key, "/" GIT_IGNORE_FILE) == 0)
|
||||
context = ignores->key + 2;
|
||||
context[strlen(context) - strlen(GIT_IGNORE_FILE)] = '\0';
|
||||
}
|
||||
|
||||
scan = buffer;
|
||||
|
||||
@ -64,9 +63,6 @@ static int parse_ignore_file(
|
||||
}
|
||||
|
||||
git__free(match);
|
||||
/* restore file path used for context */
|
||||
if (context)
|
||||
context[strlen(context)] = '.'; /* first char of GIT_IGNORE_FILE */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -130,22 +130,18 @@ void test_attr_ignore__skip_gitignore_directory(void)
|
||||
|
||||
void test_attr_ignore__expand_tilde_to_homedir(void)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
git_buf cleanup = GIT_BUF_INIT;
|
||||
git_config *cfg;
|
||||
|
||||
assert_is_ignored(false, "example.global_with_tilde");
|
||||
|
||||
cl_fake_home(&cleanup);
|
||||
|
||||
/* construct fake home with fake global excludes */
|
||||
|
||||
cl_must_pass(p_mkdir("home", 0777));
|
||||
cl_git_pass(git_path_prettify(&path, "home", NULL));
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
|
||||
|
||||
cl_git_mkfile("home/globalexcludes", "# found me\n*.global_with_tilde\n");
|
||||
cl_git_mkfile("home/globalexclude", "# found me\n*.global_with_tilde\n");
|
||||
|
||||
cl_git_pass(git_repository_config(&cfg, g_repo));
|
||||
cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexcludes"));
|
||||
cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexclude"));
|
||||
git_config_free(cfg);
|
||||
|
||||
git_attr_cache_flush(g_repo); /* must reset to pick up change */
|
||||
@ -154,8 +150,9 @@ void test_attr_ignore__expand_tilde_to_homedir(void)
|
||||
|
||||
cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES));
|
||||
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
|
||||
cl_fake_home_cleanup(&cleanup);
|
||||
|
||||
git_buf_free(&path);
|
||||
git_attr_cache_flush(g_repo); /* must reset to pick up change */
|
||||
|
||||
assert_is_ignored(false, "example.global_with_tilde");
|
||||
}
|
||||
|
@ -490,3 +490,24 @@ void clar__assert_equal_file(
|
||||
clar__assert_equal(file, line, "mismatched file length", 1, "%"PRIuZ,
|
||||
(size_t)expected_bytes, (size_t)total_bytes);
|
||||
}
|
||||
|
||||
void cl_fake_home(git_buf *restore)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore));
|
||||
|
||||
cl_must_pass(p_mkdir("home", 0777));
|
||||
cl_git_pass(git_path_prettify(&path, "home", NULL));
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
|
||||
git_buf_free(&path);
|
||||
}
|
||||
|
||||
void cl_fake_home_cleanup(git_buf *restore)
|
||||
{
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore->ptr));
|
||||
git_buf_free(restore);
|
||||
}
|
||||
|
@ -120,4 +120,7 @@ int cl_repo_get_bool(git_repository *repo, const char *cfg);
|
||||
|
||||
void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value);
|
||||
|
||||
void cl_fake_home(git_buf *restore);
|
||||
void cl_fake_home_cleanup(git_buf *restore);
|
||||
|
||||
#endif
|
||||
|
@ -364,6 +364,62 @@ void test_status_ignore__subdirectories_not_at_root(void)
|
||||
cl_assert_equal_i(0, counts.wrong_sorted_path);
|
||||
}
|
||||
|
||||
void test_status_ignore__leading_slash_ignores(void)
|
||||
{
|
||||
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
|
||||
status_entry_counts counts;
|
||||
git_buf home = GIT_BUF_INIT;
|
||||
static const char *paths_2[] = {
|
||||
"dir/.gitignore",
|
||||
"dir/a/ignore_me",
|
||||
"dir/b/ignore_me",
|
||||
"dir/ignore_me",
|
||||
"ignore_also/file",
|
||||
"ignore_me",
|
||||
"test/.gitignore",
|
||||
"test/ignore_me/and_me/file",
|
||||
"test/ignore_me/file",
|
||||
"test/ignore_me/file2",
|
||||
};
|
||||
static const unsigned int statuses_2[] = {
|
||||
GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
|
||||
GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
|
||||
GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
|
||||
};
|
||||
|
||||
make_test_data();
|
||||
|
||||
cl_fake_home(&home);
|
||||
cl_git_mkfile("home/.gitignore", "/ignore_me\n");
|
||||
{
|
||||
git_config *cfg;
|
||||
cl_git_pass(git_repository_config(&cfg, g_repo));
|
||||
cl_git_pass(git_config_set_string(
|
||||
cfg, "core.excludesfile", "~/.gitignore"));
|
||||
git_config_free(cfg);
|
||||
}
|
||||
|
||||
cl_git_rewritefile("empty_standard_repo/.git/info/exclude", "/ignore_also\n");
|
||||
cl_git_rewritefile("empty_standard_repo/dir/.gitignore", "/ignore_me\n");
|
||||
cl_git_rewritefile("empty_standard_repo/test/.gitignore", "/and_me\n");
|
||||
|
||||
memset(&counts, 0x0, sizeof(status_entry_counts));
|
||||
counts.expected_entry_count = 10;
|
||||
counts.expected_paths = paths_2;
|
||||
counts.expected_statuses = statuses_2;
|
||||
|
||||
opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
|
||||
|
||||
cl_git_pass(git_status_foreach_ext(
|
||||
g_repo, &opts, cb_status__normal, &counts));
|
||||
|
||||
cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
|
||||
cl_assert_equal_i(0, counts.wrong_status_flags_count);
|
||||
cl_assert_equal_i(0, counts.wrong_sorted_path);
|
||||
|
||||
cl_fake_home_cleanup(&home);
|
||||
}
|
||||
|
||||
void test_status_ignore__adding_internal_ignores(void)
|
||||
{
|
||||
int ignored;
|
||||
|
Loading…
Reference in New Issue
Block a user