Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
bc0f3227
Unverified
Commit
bc0f3227
authored
Jun 09, 2018
by
Edward Thomson
Committed by
GitHub
Jun 09, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4670 from pks-t/pks/ignore-leadingdir
Fix negative gitignore rules with leading directories
parents
0ef3242e
d22fd81c
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
60 additions
and
33 deletions
+60
-33
src/attr_file.c
+3
-2
src/ignore.c
+10
-15
tests/status/ignore.c
+47
-16
No files found.
src/attr_file.c
View file @
bc0f3227
...
@@ -594,8 +594,9 @@ int git_attr_fnmatch__parse(
...
@@ -594,8 +594,9 @@ int git_attr_fnmatch__parse(
}
}
if
(
*
pattern
==
'!'
&&
(
spec
->
flags
&
GIT_ATTR_FNMATCH_ALLOWNEG
)
!=
0
)
{
if
(
*
pattern
==
'!'
&&
(
spec
->
flags
&
GIT_ATTR_FNMATCH_ALLOWNEG
)
!=
0
)
{
spec
->
flags
=
spec
->
flags
|
spec
->
flags
=
spec
->
flags
|
GIT_ATTR_FNMATCH_NEGATIVE
;
GIT_ATTR_FNMATCH_NEGATIVE
|
GIT_ATTR_FNMATCH_LEADINGDIR
;
if
((
spec
->
flags
&
GIT_ATTR_FNMATCH_NOLEADINGDIR
)
==
0
)
spec
->
flags
|=
GIT_ATTR_FNMATCH_LEADINGDIR
;
pattern
++
;
pattern
++
;
}
}
...
...
src/ignore.c
View file @
bc0f3227
...
@@ -133,23 +133,12 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
...
@@ -133,23 +133,12 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
continue
;
continue
;
}
}
/*
* When dealing with a directory, we add '/<star>' so
* p_fnmatch() honours FNM_PATHNAME. Checking for LEADINGDIR
* alone isn't enough as that's also set for nagations, so we
* need to check that NEGATIVE is off.
*/
git_buf_clear
(
&
buf
);
git_buf_clear
(
&
buf
);
if
(
rule
->
containing_dir
)
{
if
(
rule
->
containing_dir
)
git_buf_puts
(
&
buf
,
rule
->
containing_dir
);
git_buf_puts
(
&
buf
,
rule
->
containing_dir
);
}
git_buf_puts
(
&
buf
,
rule
->
pattern
);
error
=
git_buf_puts
(
&
buf
,
rule
->
pattern
);
if
((
rule
->
flags
&
(
GIT_ATTR_FNMATCH_LEADINGDIR
|
GIT_ATTR_FNMATCH_NEGATIVE
))
==
GIT_ATTR_FNMATCH_LEADINGDIR
)
if
(
git_buf_oom
(
&
buf
))
error
=
git_buf_PUTS
(
&
buf
,
"/*"
);
if
(
error
<
0
)
goto
out
;
goto
out
;
if
((
error
=
p_fnmatch
(
git_buf_cstr
(
&
buf
),
path
,
fnflags
))
<
0
)
{
if
((
error
=
p_fnmatch
(
git_buf_cstr
(
&
buf
),
path
,
fnflags
))
<
0
)
{
...
@@ -203,7 +192,10 @@ static int parse_ignore_file(
...
@@ -203,7 +192,10 @@ static int parse_ignore_file(
break
;
break
;
}
}
match
->
flags
=
GIT_ATTR_FNMATCH_ALLOWSPACE
|
GIT_ATTR_FNMATCH_ALLOWNEG
;
match
->
flags
=
GIT_ATTR_FNMATCH_ALLOWSPACE
|
GIT_ATTR_FNMATCH_ALLOWNEG
|
GIT_ATTR_FNMATCH_NOLEADINGDIR
;
if
(
!
(
error
=
git_attr_fnmatch__parse
(
if
(
!
(
error
=
git_attr_fnmatch__parse
(
match
,
&
attrs
->
pool
,
context
,
&
scan
)))
match
,
&
attrs
->
pool
,
context
,
&
scan
)))
...
@@ -445,6 +437,9 @@ static bool ignore_lookup_in_rules(
...
@@ -445,6 +437,9 @@ static bool ignore_lookup_in_rules(
git_attr_fnmatch
*
match
;
git_attr_fnmatch
*
match
;
git_vector_rforeach
(
&
file
->
rules
,
j
,
match
)
{
git_vector_rforeach
(
&
file
->
rules
,
j
,
match
)
{
if
(
match
->
flags
&
GIT_ATTR_FNMATCH_DIRECTORY
&&
path
->
is_dir
==
GIT_DIR_FLAG_FALSE
)
continue
;
if
(
git_attr_fnmatch__match
(
match
,
path
))
{
if
(
git_attr_fnmatch__match
(
match
,
path
))
{
*
ignored
=
((
match
->
flags
&
GIT_ATTR_FNMATCH_NEGATIVE
)
==
0
)
?
*
ignored
=
((
match
->
flags
&
GIT_ATTR_FNMATCH_NEGATIVE
)
==
0
)
?
GIT_IGNORE_TRUE
:
GIT_IGNORE_FALSE
;
GIT_IGNORE_TRUE
:
GIT_IGNORE_FALSE
;
...
...
tests/status/ignore.c
View file @
bc0f3227
...
@@ -1158,27 +1158,58 @@ void test_status_ignore__subdir_ignore_everything_except_certain_files(void)
...
@@ -1158,27 +1158,58 @@ void test_status_ignore__subdir_ignore_everything_except_certain_files(void)
void
test_status_ignore__deeper
(
void
)
void
test_status_ignore__deeper
(
void
)
{
{
int
ignored
;
const
char
*
test_files
[]
=
{
"empty_standard_repo/foo.data"
,
g_repo
=
cl_git_sandbox_init
(
"empty_standard_repo"
);
"empty_standard_repo/bar.data"
,
"empty_standard_repo/dont_ignore/foo.data"
,
"empty_standard_repo/dont_ignore/bar.data"
,
NULL
};
make_test_data
(
"empty_standard_repo"
,
test_files
);
cl_git_mkfile
(
"empty_standard_repo/.gitignore"
,
cl_git_mkfile
(
"empty_standard_repo/.gitignore"
,
"*.data
\n
"
"*.data
\n
"
"!dont_ignore/*.data
\n
"
);
"!dont_ignore/*.data
\n
"
);
cl_git_pass
(
p_mkdir
(
"empty_standard_repo/dont_ignore"
,
0777
));
assert_is_ignored
(
"foo.data"
);
cl_git_mkfile
(
"empty_standard_repo/foo.data"
,
""
);
assert_is_ignored
(
"bar.data"
);
cl_git_mkfile
(
"empty_standard_repo/bar.data"
,
""
);
cl_git_mkfile
(
"empty_standard_repo/dont_ignore/foo.data"
,
""
);
cl_git_mkfile
(
"empty_standard_repo/dont_ignore/bar.data"
,
""
);
cl_git_pass
(
git_ignore_path_is_ignored
(
&
ignored
,
g_repo
,
"foo.data"
));
refute_is_ignored
(
"dont_ignore/foo.data"
);
cl_assert_equal_i
(
1
,
ignored
);
refute_is_ignored
(
"dont_ignore/bar.data"
);
cl_git_pass
(
git_ignore_path_is_ignored
(
&
ignored
,
g_repo
,
"bar.data"
));
}
cl_assert_equal_i
(
1
,
ignored
);
cl_git_pass
(
git_ignore_path_is_ignored
(
&
ignored
,
g_repo
,
"dont_ignore/foo.data"
));
void
test_status_ignore__unignored_dir_with_ignored_contents
(
void
)
cl_assert_equal_i
(
0
,
ignored
);
{
cl_git_pass
(
git_ignore_path_is_ignored
(
&
ignored
,
g_repo
,
"dont_ignore/bar.data"
));
static
const
char
*
test_files
[]
=
{
cl_assert_equal_i
(
0
,
ignored
);
"empty_standard_repo/dir/a.test"
,
"empty_standard_repo/dir/subdir/a.test"
,
NULL
};
make_test_data
(
"empty_standard_repo"
,
test_files
);
cl_git_mkfile
(
"empty_standard_repo/.gitignore"
,
"*.test
\n
"
"!dir/*
\n
"
);
refute_is_ignored
(
"dir/a.test"
);
assert_is_ignored
(
"dir/subdir/a.test"
);
}
void
test_status_ignore__unignored_subdirs
(
void
)
{
static
const
char
*
test_files
[]
=
{
"empty_standard_repo/dir/a.test"
,
"empty_standard_repo/dir/subdir/a.test"
,
NULL
};
make_test_data
(
"empty_standard_repo"
,
test_files
);
cl_git_mkfile
(
"empty_standard_repo/.gitignore"
,
"dir/*
\n
"
"!dir/*/
\n
"
);
assert_is_ignored
(
"dir/a.test"
);
refute_is_ignored
(
"dir/subdir/a.test"
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment