mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-05 20:33:41 +00:00
status: fix handling of filenames with special prefixes
Fix libgit2/libgit2sharp#379
This commit is contained in:
parent
2d2260da41
commit
2e40a60e84
@ -85,7 +85,7 @@ int git_attr_file__parse_buffer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* parse the next "pattern attr attr attr" line */
|
/* parse the next "pattern attr attr attr" line */
|
||||||
if (!(error = git_attr_fnmatch__parse(
|
if (!(error = git_attr_fnmatch__parse_gitattr_format(
|
||||||
&rule->match, attrs->pool, context, &scan)) &&
|
&rule->match, attrs->pool, context, &scan)) &&
|
||||||
!(error = git_attr_assignment__parse(
|
!(error = git_attr_assignment__parse(
|
||||||
repo, attrs->pool, &rule->assigns, &scan)))
|
repo, attrs->pool, &rule->assigns, &scan)))
|
||||||
@ -337,23 +337,16 @@ void git_attr_path__free(git_attr_path *info)
|
|||||||
* GIT_ENOTFOUND if the fnmatch does not require matching, or
|
* GIT_ENOTFOUND if the fnmatch does not require matching, or
|
||||||
* another error code there was an actual problem.
|
* another error code there was an actual problem.
|
||||||
*/
|
*/
|
||||||
int git_attr_fnmatch__parse(
|
int git_attr_fnmatch__parse_gitattr_format(
|
||||||
git_attr_fnmatch *spec,
|
git_attr_fnmatch *spec,
|
||||||
git_pool *pool,
|
git_pool *pool,
|
||||||
const char *source,
|
const char *source,
|
||||||
const char **base)
|
const char **base)
|
||||||
{
|
{
|
||||||
const char *pattern, *scan;
|
const char *pattern;
|
||||||
int slash_count, allow_space;
|
|
||||||
|
|
||||||
assert(spec && base && *base);
|
assert(spec && base && *base);
|
||||||
|
|
||||||
if (parse_optimized_patterns(spec, pool, *base))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
spec->flags = (spec->flags & GIT_ATTR_FNMATCH_ALLOWSPACE);
|
|
||||||
allow_space = (spec->flags != 0);
|
|
||||||
|
|
||||||
pattern = *base;
|
pattern = *base;
|
||||||
|
|
||||||
while (git__isspace(*pattern)) pattern++;
|
while (git__isspace(*pattern)) pattern++;
|
||||||
@ -375,6 +368,39 @@ int git_attr_fnmatch__parse(
|
|||||||
pattern++;
|
pattern++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (git_attr_fnmatch__parse_shellglob_format(spec, pool,
|
||||||
|
source, &pattern) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*base = pattern;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fills a spec for the purpose of pure pathspec matching, not
|
||||||
|
* related to a gitattribute file parsing.
|
||||||
|
*
|
||||||
|
* This will return 0 if the spec was filled out, or
|
||||||
|
* another error code there was an actual problem.
|
||||||
|
*/
|
||||||
|
int git_attr_fnmatch__parse_shellglob_format(
|
||||||
|
git_attr_fnmatch *spec,
|
||||||
|
git_pool *pool,
|
||||||
|
const char *source,
|
||||||
|
const char **base)
|
||||||
|
{
|
||||||
|
const char *pattern, *scan;
|
||||||
|
int slash_count, allow_space;
|
||||||
|
|
||||||
|
assert(spec && base && *base);
|
||||||
|
|
||||||
|
if (parse_optimized_patterns(spec, pool, *base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
allow_space = (spec->flags & GIT_ATTR_FNMATCH_ALLOWSPACE) != 0;
|
||||||
|
pattern = *base;
|
||||||
|
|
||||||
slash_count = 0;
|
slash_count = 0;
|
||||||
for (scan = pattern; *scan != '\0'; ++scan) {
|
for (scan = pattern; *scan != '\0'; ++scan) {
|
||||||
/* scan until (non-escaped) white space */
|
/* scan until (non-escaped) white space */
|
||||||
@ -609,6 +635,7 @@ static void git_attr_rule__clear(git_attr_rule *rule)
|
|||||||
/* match.pattern is stored in a git_pool, so no need to free */
|
/* match.pattern is stored in a git_pool, so no need to free */
|
||||||
rule->match.pattern = NULL;
|
rule->match.pattern = NULL;
|
||||||
rule->match.length = 0;
|
rule->match.length = 0;
|
||||||
|
rule->match.flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_attr_rule__free(git_attr_rule *rule)
|
void git_attr_rule__free(git_attr_rule *rule)
|
||||||
|
@ -115,7 +115,13 @@ extern uint32_t git_attr_file__name_hash(const char *name);
|
|||||||
* other utilities
|
* other utilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern int git_attr_fnmatch__parse(
|
extern int git_attr_fnmatch__parse_gitattr_format(
|
||||||
|
git_attr_fnmatch *spec,
|
||||||
|
git_pool *pool,
|
||||||
|
const char *source,
|
||||||
|
const char **base);
|
||||||
|
|
||||||
|
extern int git_attr_fnmatch__parse_shellglob_format(
|
||||||
git_attr_fnmatch *spec,
|
git_attr_fnmatch *spec,
|
||||||
git_pool *pool,
|
git_pool *pool,
|
||||||
const char *source,
|
const char *source,
|
||||||
|
@ -49,7 +49,7 @@ static int parse_ignore_file(
|
|||||||
|
|
||||||
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
||||||
|
|
||||||
if (!(error = git_attr_fnmatch__parse(
|
if (!(error = git_attr_fnmatch__parse_gitattr_format(
|
||||||
match, ignores->pool, context, &scan)))
|
match, ignores->pool, context, &scan)))
|
||||||
{
|
{
|
||||||
match->flags |= GIT_ATTR_FNMATCH_IGNORE;
|
match->flags |= GIT_ATTR_FNMATCH_IGNORE;
|
||||||
|
@ -78,7 +78,7 @@ int git_pathspec_init(
|
|||||||
|
|
||||||
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
||||||
|
|
||||||
ret = git_attr_fnmatch__parse(match, strpool, NULL, &pattern);
|
ret = git_attr_fnmatch__parse_shellglob_format(match, strpool, NULL, &pattern);
|
||||||
if (ret == GIT_ENOTFOUND) {
|
if (ret == GIT_ENOTFOUND) {
|
||||||
git__free(match);
|
git__free(match);
|
||||||
continue;
|
continue;
|
||||||
|
@ -459,3 +459,37 @@ void test_status_ignore__automatically_ignore_bad_files(void)
|
|||||||
cl_git_pass(git_status_should_ignore(&ignored, g_repo, "path/whatever.c"));
|
cl_git_pass(git_status_should_ignore(&ignored, g_repo, "path/whatever.c"));
|
||||||
cl_assert(!ignored);
|
cl_assert(!ignored);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_status_ignore__filenames_with_special_prefixes_do_not_interfere_with_status_retrieval(void)
|
||||||
|
{
|
||||||
|
status_entry_single st;
|
||||||
|
char *test_cases[] = {
|
||||||
|
"!file",
|
||||||
|
"#blah",
|
||||||
|
"[blah]",
|
||||||
|
"[attr]",
|
||||||
|
"[attr]blah",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; *(test_cases + i) != NULL; i++) {
|
||||||
|
git_buf file = GIT_BUF_INIT;
|
||||||
|
char *file_name = *(test_cases + i);
|
||||||
|
git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
|
||||||
|
|
||||||
|
cl_git_pass(git_buf_joinpath(&file, "empty_standard_repo", file_name));
|
||||||
|
cl_git_mkfile(git_buf_cstr(&file), "Please don't ignore me!");
|
||||||
|
|
||||||
|
memset(&st, 0, sizeof(st));
|
||||||
|
cl_git_pass(git_status_foreach(repo, cb_status__single, &st));
|
||||||
|
cl_assert(st.count == 1);
|
||||||
|
cl_assert(st.status == GIT_STATUS_WT_NEW);
|
||||||
|
|
||||||
|
cl_git_pass(git_status_file(&st.status, repo, file_name));
|
||||||
|
cl_assert(st.status == GIT_STATUS_WT_NEW);
|
||||||
|
|
||||||
|
cl_git_sandbox_cleanup();
|
||||||
|
git_buf_free(&file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user