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
16d742eb
Commit
16d742eb
authored
May 13, 2015
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3119 from ethomson/ignore
Attributes: don't match files for folders
parents
cd430bc7
882cc37f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
82 additions
and
39 deletions
+82
-39
src/attr.c
+2
-1
src/attr_file.c
+18
-37
tests/attr/ignore.c
+62
-1
No files found.
src/attr.c
View file @
16d742eb
...
@@ -309,7 +309,8 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
...
@@ -309,7 +309,8 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
if
(
error
==
0
)
if
(
error
==
0
)
error
=
preload_attr_file
(
error
=
preload_attr_file
(
repo
,
attr_session
,
GIT_ATTR_FILE__FROM_FILE
,
NULL
,
sys
.
ptr
);
repo
,
attr_session
,
GIT_ATTR_FILE__FROM_FILE
,
NULL
,
sys
.
ptr
);
else
if
(
error
!=
GIT_ENOTFOUND
)
if
(
error
!=
GIT_ENOTFOUND
)
return
error
;
return
error
;
git_buf_free
(
&
sys
);
git_buf_free
(
&
sys
);
...
...
src/attr_file.c
View file @
16d742eb
...
@@ -359,6 +359,7 @@ bool git_attr_fnmatch__match(
...
@@ -359,6 +359,7 @@ bool git_attr_fnmatch__match(
git_attr_fnmatch
*
match
,
git_attr_fnmatch
*
match
,
git_attr_path
*
path
)
git_attr_path
*
path
)
{
{
const
char
*
relpath
=
path
->
path
;
const
char
*
filename
;
const
char
*
filename
;
int
flags
=
0
;
int
flags
=
0
;
...
@@ -375,6 +376,8 @@ bool git_attr_fnmatch__match(
...
@@ -375,6 +376,8 @@ bool git_attr_fnmatch__match(
if
(
git__prefixcmp
(
path
->
path
,
match
->
containing_dir
))
if
(
git__prefixcmp
(
path
->
path
,
match
->
containing_dir
))
return
0
;
return
0
;
}
}
relpath
+=
match
->
containing_dir_length
;
}
}
if
(
match
->
flags
&
GIT_ATTR_FNMATCH_ICASE
)
if
(
match
->
flags
&
GIT_ATTR_FNMATCH_ICASE
)
...
@@ -383,7 +386,7 @@ bool git_attr_fnmatch__match(
...
@@ -383,7 +386,7 @@ bool git_attr_fnmatch__match(
flags
|=
FNM_LEADING_DIR
;
flags
|=
FNM_LEADING_DIR
;
if
(
match
->
flags
&
GIT_ATTR_FNMATCH_FULLPATH
)
{
if
(
match
->
flags
&
GIT_ATTR_FNMATCH_FULLPATH
)
{
filename
=
path
->
path
;
filename
=
rel
path
;
flags
|=
FNM_PATHNAME
;
flags
|=
FNM_PATHNAME
;
}
else
{
}
else
{
filename
=
path
->
basename
;
filename
=
path
->
basename
;
...
@@ -393,35 +396,33 @@ bool git_attr_fnmatch__match(
...
@@ -393,35 +396,33 @@ bool git_attr_fnmatch__match(
}
}
if
((
match
->
flags
&
GIT_ATTR_FNMATCH_DIRECTORY
)
&&
!
path
->
is_dir
)
{
if
((
match
->
flags
&
GIT_ATTR_FNMATCH_DIRECTORY
)
&&
!
path
->
is_dir
)
{
int
matchval
;
bool
samename
;
char
*
matchpath
;
/* for attribute checks or root ignore checks, fail match */
/* for attribute checks or root ignore checks, fail match */
if
(
!
(
match
->
flags
&
GIT_ATTR_FNMATCH_IGNORE
)
||
if
(
!
(
match
->
flags
&
GIT_ATTR_FNMATCH_IGNORE
)
||
path
->
basename
==
path
->
path
)
path
->
basename
==
path
->
path
)
return
false
;
return
false
;
/* for ignore checks, use container of current item for check */
path
->
basename
[
-
1
]
=
'\0'
;
flags
|=
FNM_LEADING_DIR
;
flags
|=
FNM_LEADING_DIR
;
if
(
match
->
containing_dir
)
/* fail match if this is a file with same name as ignored folder */
matchpath
=
path
->
basename
;
samename
=
(
match
->
flags
&
GIT_ATTR_FNMATCH_ICASE
)
?
else
!
strcasecmp
(
match
->
pattern
,
relpath
)
:
matchpath
=
path
->
path
;
!
strcmp
(
match
->
pattern
,
relpath
)
;
matchval
=
p_fnmatch
(
match
->
pattern
,
matchpath
,
flags
);
if
(
samename
)
path
->
basename
[
-
1
]
=
'/'
;
return
false
;
return
(
matchval
!=
FNM_NOMATCH
);
return
(
p_fnmatch
(
match
->
pattern
,
relpath
,
flags
)
!=
FNM_NOMATCH
);
}
}
/* if path is a directory prefix of a negated pattern, then match */
/* if path is a directory prefix of a negated pattern, then match */
if
((
match
->
flags
&
GIT_ATTR_FNMATCH_NEGATIVE
)
&&
path
->
is_dir
)
{
if
((
match
->
flags
&
GIT_ATTR_FNMATCH_NEGATIVE
)
&&
path
->
is_dir
)
{
size_t
pathlen
=
strlen
(
path
->
path
);
size_t
pathlen
=
strlen
(
rel
path
);
bool
prefixed
=
(
pathlen
<=
match
->
length
)
&&
bool
prefixed
=
(
pathlen
<=
match
->
length
)
&&
((
match
->
flags
&
GIT_ATTR_FNMATCH_ICASE
)
?
((
match
->
flags
&
GIT_ATTR_FNMATCH_ICASE
)
?
!
strncasecmp
(
match
->
pattern
,
path
->
path
,
pathlen
)
:
!
strncasecmp
(
match
->
pattern
,
rel
path
,
pathlen
)
:
!
strncmp
(
match
->
pattern
,
path
->
path
,
pathlen
));
!
strncmp
(
match
->
pattern
,
rel
path
,
pathlen
));
if
(
prefixed
&&
git_path_at_end_of_segment
(
&
match
->
pattern
[
pathlen
]))
if
(
prefixed
&&
git_path_at_end_of_segment
(
&
match
->
pattern
[
pathlen
]))
return
true
;
return
true
;
...
@@ -640,7 +641,7 @@ int git_attr_fnmatch__parse(
...
@@ -640,7 +641,7 @@ int git_attr_fnmatch__parse(
}
}
if
(
context
)
{
if
(
context
)
{
char
*
slash
=
strchr
(
context
,
'/'
);
char
*
slash
=
str
r
chr
(
context
,
'/'
);
size_t
len
;
size_t
len
;
if
(
slash
)
{
if
(
slash
)
{
/* include the slash for easier matching */
/* include the slash for easier matching */
...
@@ -650,27 +651,7 @@ int git_attr_fnmatch__parse(
...
@@ -650,27 +651,7 @@ int git_attr_fnmatch__parse(
}
}
}
}
if
((
spec
->
flags
&
GIT_ATTR_FNMATCH_FULLPATH
)
!=
0
&&
spec
->
pattern
=
git_pool_strndup
(
pool
,
pattern
,
spec
->
length
);
context
!=
NULL
&&
git_path_root
(
pattern
)
<
0
)
{
/* use context path minus the trailing filename */
char
*
slash
=
strrchr
(
context
,
'/'
);
size_t
contextlen
=
slash
?
slash
-
context
+
1
:
0
;
/* given an unrooted fullpath match from a file inside a repo,
* prefix the pattern with the relative directory of the source file
*/
spec
->
pattern
=
git_pool_malloc
(
pool
,
(
uint32_t
)(
contextlen
+
spec
->
length
+
1
));
if
(
spec
->
pattern
)
{
memcpy
(
spec
->
pattern
,
context
,
contextlen
);
memcpy
(
spec
->
pattern
+
contextlen
,
pattern
,
spec
->
length
);
spec
->
length
+=
contextlen
;
spec
->
pattern
[
spec
->
length
]
=
'\0'
;
}
}
else
{
spec
->
pattern
=
git_pool_strndup
(
pool
,
pattern
,
spec
->
length
);
}
if
(
!
spec
->
pattern
)
{
if
(
!
spec
->
pattern
)
{
*
base
=
git__next_line
(
pattern
);
*
base
=
git__next_line
(
pattern
);
...
...
tests/attr/ignore.c
View file @
16d742eb
...
@@ -160,7 +160,7 @@ void test_attr_ignore__subdirectory_gitignore(void)
...
@@ -160,7 +160,7 @@ void test_attr_ignore__subdirectory_gitignore(void)
assert_is_ignored
(
true
,
"file1"
);
assert_is_ignored
(
true
,
"file1"
);
assert_is_ignored
(
true
,
"dir/file1"
);
assert_is_ignored
(
true
,
"dir/file1"
);
assert_is_ignored
(
true
,
"dir/file2"
);
/* in ignored dir */
assert_is_ignored
(
true
,
"dir/file2
/actual_file
"
);
/* in ignored dir */
assert_is_ignored
(
false
,
"dir/file3"
);
assert_is_ignored
(
false
,
"dir/file3"
);
}
}
...
@@ -191,3 +191,64 @@ void test_attr_ignore__expand_tilde_to_homedir(void)
...
@@ -191,3 +191,64 @@ void test_attr_ignore__expand_tilde_to_homedir(void)
assert_is_ignored
(
false
,
"example.global_with_tilde"
);
assert_is_ignored
(
false
,
"example.global_with_tilde"
);
}
}
/* Ensure that the .gitignore in the subdirectory only affects
* items in the subdirectory. */
void
test_attr_ignore__gitignore_in_subdir
(
void
)
{
cl_git_rmfile
(
"attr/.gitignore"
);
cl_must_pass
(
p_mkdir
(
"attr/dir1"
,
0777
));
cl_must_pass
(
p_mkdir
(
"attr/dir1/dir2"
,
0777
));
cl_must_pass
(
p_mkdir
(
"attr/dir1/dir2/dir3"
,
0777
));
cl_git_mkfile
(
"attr/dir1/dir2/dir3/.gitignore"
,
"dir1/
\n
dir1/subdir/"
);
assert_is_ignored
(
false
,
"dir1/file"
);
assert_is_ignored
(
false
,
"dir1/dir2/file"
);
assert_is_ignored
(
false
,
"dir1/dir2/dir3/file"
);
assert_is_ignored
(
true
,
"dir1/dir2/dir3/dir1/file"
);
assert_is_ignored
(
true
,
"dir1/dir2/dir3/dir1/subdir/foo"
);
if
(
cl_repo_get_bool
(
g_repo
,
"core.ignorecase"
))
{
cl_git_mkfile
(
"attr/dir1/dir2/dir3/.gitignore"
,
"DiR1/
\n
DiR1/subdir/
\n
"
);
assert_is_ignored
(
false
,
"dir1/file"
);
assert_is_ignored
(
false
,
"dir1/dir2/file"
);
assert_is_ignored
(
false
,
"dir1/dir2/dir3/file"
);
assert_is_ignored
(
true
,
"dir1/dir2/dir3/dir1/file"
);
assert_is_ignored
(
true
,
"dir1/dir2/dir3/dir1/subdir/foo"
);
}
}
/* Ensure that files do not match folder cases */
void
test_attr_ignore__dont_ignore_files_for_folder
(
void
)
{
cl_git_rmfile
(
"attr/.gitignore"
);
cl_git_mkfile
(
"attr/dir/.gitignore"
,
"test/
\n
"
);
/* Create "test" as a file; ensure it is not ignored. */
cl_git_mkfile
(
"attr/dir/test"
,
"This is a file."
);
assert_is_ignored
(
false
,
"dir/test"
);
if
(
cl_repo_get_bool
(
g_repo
,
"core.ignorecase"
))
assert_is_ignored
(
false
,
"dir/TeSt"
);
/* Create "test" as a directory; ensure it is ignored. */
cl_git_rmfile
(
"attr/dir/test"
);
cl_must_pass
(
p_mkdir
(
"attr/dir/test"
,
0777
));
assert_is_ignored
(
true
,
"dir/test"
);
if
(
cl_repo_get_bool
(
g_repo
,
"core.ignorecase"
))
assert_is_ignored
(
true
,
"dir/TeSt"
);
/* Remove "test" entirely; ensure it is not ignored.
* (As it doesn't exist, it is not a directory.)
*/
cl_must_pass
(
p_rmdir
(
"attr/dir/test"
));
assert_is_ignored
(
false
,
"dir/test"
);
if
(
cl_repo_get_bool
(
g_repo
,
"core.ignorecase"
))
assert_is_ignored
(
false
,
"dir/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