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
0ef0b71c
Commit
0ef0b71c
authored
Mar 21, 2016
by
Edward Thomson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iterator: refactor index iterator
parent
ba6f86eb
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
882 additions
and
258 deletions
+882
-258
src/iterator.c
+194
-200
tests/iterator/index.c
+644
-23
tests/iterator/iterator_helpers.c
+36
-0
tests/iterator/iterator_helpers.h
+8
-0
tests/iterator/workdir.c
+0
-35
No files found.
src/iterator.c
View file @
0ef0b71c
...
@@ -345,6 +345,7 @@ static int iterator_pathlist_init(git_iterator *iter, git_strarray *pathlist)
...
@@ -345,6 +345,7 @@ static int iterator_pathlist_init(git_iterator *iter, git_strarray *pathlist)
static
int
iterator_init_common
(
static
int
iterator_init_common
(
git_iterator
*
iter
,
git_iterator
*
iter
,
git_repository
*
repo
,
git_repository
*
repo
,
git_index
*
index
,
git_iterator_options
*
given_opts
)
git_iterator_options
*
given_opts
)
{
{
static
git_iterator_options
default_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
static
git_iterator_options
default_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
...
@@ -354,6 +355,7 @@ static int iterator_init_common(
...
@@ -354,6 +355,7 @@ static int iterator_init_common(
int
error
;
int
error
;
iter
->
repo
=
repo
;
iter
->
repo
=
repo
;
iter
->
index
=
index
;
iter
->
flags
=
options
->
flags
;
iter
->
flags
=
options
->
flags
;
if
((
iter
->
flags
&
GIT_ITERATOR_IGNORE_CASE
)
!=
0
)
{
if
((
iter
->
flags
&
GIT_ITERATOR_IGNORE_CASE
)
!=
0
)
{
...
@@ -495,14 +497,10 @@ static bool iterator_pathlist_next_is(git_iterator *iter, const char *path)
...
@@ -495,14 +497,10 @@ static bool iterator_pathlist_next_is(git_iterator *iter, const char *path)
*/
*/
if
(
p
[
cmp_len
]
==
'/'
&&
path
[
cmp_len
]
==
'/'
)
if
(
p
[
cmp_len
]
==
'/'
&&
path
[
cmp_len
]
==
'/'
)
return
true
;
return
true
;
/* examine the next character */
cmp
=
(
int
)((
const
unsigned
char
)
p
[
cmp_len
])
-
(
int
)((
const
unsigned
char
)
path
[
cmp_len
]);
}
}
/* this pathlist entry sorts before the given path, try the next */
/* this pathlist entry sorts before the given path, try the next */
if
(
cmp
<
0
)
{
else
if
(
cmp
<
0
)
{
iter
->
pathlist_walk_idx
++
;
iter
->
pathlist_walk_idx
++
;
continue
;
continue
;
}
}
...
@@ -1164,7 +1162,7 @@ int git_iterator_for_tree(
...
@@ -1164,7 +1162,7 @@ int git_iterator_for_tree(
iter
->
base
.
cb
=
&
callbacks
;
iter
->
base
.
cb
=
&
callbacks
;
if
((
error
=
iterator_init_common
(
&
iter
->
base
,
if
((
error
=
iterator_init_common
(
&
iter
->
base
,
git_tree_owner
(
tree
),
options
))
<
0
||
git_tree_owner
(
tree
),
NULL
,
options
))
<
0
||
(
error
=
git_tree_dup
(
&
iter
->
root
,
tree
))
<
0
||
(
error
=
git_tree_dup
(
&
iter
->
root
,
tree
))
<
0
||
(
error
=
tree_iterator_init
(
iter
))
<
0
)
(
error
=
tree_iterator_init
(
iter
))
<
0
)
goto
on_error
;
goto
on_error
;
...
@@ -2083,14 +2081,13 @@ static int iterator_for_filesystem(
...
@@ -2083,14 +2081,13 @@ static int iterator_for_filesystem(
iter
->
base
.
type
=
type
;
iter
->
base
.
type
=
type
;
iter
->
base
.
cb
=
&
callbacks
;
iter
->
base
.
cb
=
&
callbacks
;
if
((
error
=
iterator_init_common
(
&
iter
->
base
,
repo
,
index
,
options
))
<
0
)
if
((
error
=
iterator_init_common
(
&
iter
->
base
,
repo
,
options
))
<
0
)
goto
on_error
;
goto
on_error
;
if
(
tree
&&
(
error
=
git_tree_dup
(
&
iter
->
tree
,
tree
))
<
0
)
if
(
tree
&&
(
error
=
git_tree_dup
(
&
iter
->
tree
,
tree
))
<
0
)
goto
on_error
;
goto
on_error
;
if
(
(
iter
->
base
.
index
=
index
)
!=
NULL
&&
if
(
index
&&
(
error
=
git_index_snapshot_new
(
&
iter
->
index_snapshot
,
index
))
<
0
)
(
error
=
git_index_snapshot_new
(
&
iter
->
index_snapshot
,
index
))
<
0
)
goto
on_error
;
goto
on_error
;
...
@@ -2155,281 +2152,278 @@ int git_iterator_for_workdir_ext(
...
@@ -2155,281 +2152,278 @@ int git_iterator_for_workdir_ext(
typedef
struct
{
typedef
struct
{
git_iterator
base
;
git_iterator
base
;
git_iterator_callbacks
cb
;
git_vector
entries
;
git_vector
entries
;
git_vector_cmp
entry_srch
;
size_t
next_idx
;
size_t
current
;
/* when limiting with a pathlist, this is the current index into it */
/* the pseudotree entry */
size_t
pathlist_idx
;
/* when not in autoexpand mode, use these to represent "tree" state */
git_buf
partial
;
size_t
partial_pos
;
char
restore_terminator
;
git_index_entry
tree_entry
;
git_index_entry
tree_entry
;
git_buf
tree_buf
;
bool
skip_tree
;
const
git_index_entry
*
entry
;
}
index_iterator
;
}
index_iterator
;
static
const
git_index_entry
*
index_iterator__index_entry
(
index_iterator
*
ii
)
static
int
index_iterator_current
(
const
git_index_entry
**
out
,
git_iterator
*
i
)
{
{
const
git_index_entry
*
ie
=
git_vector_get
(
&
ii
->
entries
,
ii
->
current
)
;
index_iterator
*
iter
=
(
index_iterator
*
)
i
;
if
(
ie
!=
NULL
&&
iterator__past_end
(
ii
,
ie
->
path
))
{
if
(
!
iterator__has_been_accessed
(
i
))
ii
->
current
=
git_vector_length
(
&
ii
->
entries
);
return
iter
->
base
.
cb
->
advance
(
out
,
i
);
ie
=
NULL
;
if
(
iter
->
entry
==
NULL
)
{
*
out
=
NULL
;
return
GIT_ITEROVER
;
}
}
return
ie
;
*
out
=
iter
->
entry
;
return
0
;
}
}
static
const
git_index_entry
*
index_iterator__advance_over_unwanted
(
static
bool
index_iterator_create_pseudotree
(
index_iterator
*
ii
)
const
git_index_entry
**
out
,
index_iterator
*
iter
,
const
char
*
path
)
{
{
const
git_index_entry
*
ie
=
index_iterator__index_entry
(
ii
)
;
const
char
*
prev_path
,
*
relative_path
,
*
dirsep
;
bool
match
;
size_t
common_len
;
while
(
ie
)
{
prev_path
=
iter
->
entry
?
iter
->
entry
->
path
:
""
;
if
(
!
iterator__include_conflicts
(
ii
)
&&
git_index_entry_is_conflict
(
ie
))
{
ii
->
current
++
;
ie
=
index_iterator__index_entry
(
ii
);
continue
;
}
/* if we have a pathlist, this entry's path must be in it to be
* returned. walk the pathlist in unison with the index to
* compare paths.
*/
if
(
ii
->
base
.
pathlist
.
length
)
{
match
=
iterator_pathlist_walk__contains
(
&
ii
->
base
,
ie
->
path
);
if
(
!
match
)
{
ii
->
current
++
;
ie
=
index_iterator__index_entry
(
ii
);
continue
;
}
}
break
;
}
return
ie
;
}
static
void
index_iterator__next_prefix_tree
(
index_iterator
*
ii
)
/* determine if the new path is in a different directory from the old */
{
common_len
=
git_path_common_dirlen
(
prev_path
,
path
);
const
char
*
slash
;
relative_path
=
path
+
common_len
;
if
(
!
iterator__include_trees
(
ii
)
)
if
(
(
dirsep
=
strchr
(
relative_path
,
'/'
))
==
NULL
)
return
;
return
false
;
slash
=
strchr
(
&
ii
->
partial
.
ptr
[
ii
->
partial_pos
],
'/'
);
git_buf_clear
(
&
iter
->
tree_buf
);
git_buf_put
(
&
iter
->
tree_buf
,
path
,
(
dirsep
-
path
)
+
1
);
if
(
slash
!=
NULL
)
{
iter
->
tree_entry
.
mode
=
GIT_FILEMODE_TREE
;
ii
->
partial_pos
=
(
slash
-
ii
->
partial
.
ptr
)
+
1
;
iter
->
tree_entry
.
path
=
iter
->
tree_buf
.
ptr
;
ii
->
restore_terminator
=
ii
->
partial
.
ptr
[
ii
->
partial_pos
];
ii
->
partial
.
ptr
[
ii
->
partial_pos
]
=
'\0'
;
}
else
{
ii
->
partial_pos
=
ii
->
partial
.
size
;
}
if
(
index_iterator__index_entry
(
ii
)
==
NULL
)
*
out
=
&
iter
->
tree_entry
;
ii
->
partial_pos
=
ii
->
partial
.
siz
e
;
return
tru
e
;
}
}
static
int
index_iterator_
_first_prefix_tree
(
index_iterator
*
ii
)
static
int
index_iterator_
skip_pseudotree
(
index_iterator
*
iter
)
{
{
const
git_index_entry
*
ie
=
index_iterator__advance_over_unwanted
(
ii
);
assert
(
iterator__has_been_accessed
(
&
iter
->
base
)
);
const
char
*
scan
,
*
prior
,
*
slash
;
assert
(
S_ISDIR
(
iter
->
entry
->
mode
))
;
if
(
!
ie
||
!
iterator__include_trees
(
ii
))
while
(
true
)
{
return
0
;
const
git_index_entry
*
next_entry
=
NULL
;
/* find longest common prefix with prior index entry */
if
(
++
iter
->
next_idx
>=
iter
->
entries
.
length
)
for
(
scan
=
slash
=
ie
->
path
,
prior
=
ii
->
partial
.
ptr
;
return
GIT_ITEROVER
;
*
scan
&&
*
scan
==
*
prior
;
++
scan
,
++
prior
)
if
(
*
scan
==
'/'
)
slash
=
scan
;
if
(
git_buf_sets
(
&
ii
->
partial
,
ie
->
path
)
<
0
)
next_entry
=
iter
->
entries
.
contents
[
iter
->
next_idx
];
return
-
1
;
ii
->
partial_pos
=
(
slash
-
ie
->
path
)
+
1
;
if
(
iter
->
base
.
strncomp
(
iter
->
tree_buf
.
ptr
,
next_entry
->
path
,
index_iterator__next_prefix_tree
(
ii
);
iter
->
tree_buf
.
size
)
!=
0
)
break
;
}
iter
->
skip_tree
=
false
;
return
0
;
return
0
;
}
}
#define index_iterator__at_tree(I) \
static
int
index_iterator_advance
(
(iterator__include_trees(I) && (I)->partial_pos < (I)->partial.size)
const
git_index_entry
**
out
,
git_iterator
*
i
)
static
int
index_iterator__current
(
const
git_index_entry
**
entry
,
git_iterator
*
self
)
{
{
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
index_iterator
*
iter
=
(
index_iterator
*
)
i
;
const
git_index_entry
*
ie
=
git_vector_get
(
&
ii
->
entries
,
ii
->
current
);
const
git_index_entry
*
entry
=
NULL
;
int
error
=
0
;
if
(
ie
!=
NULL
&&
index_iterator__at_tree
(
ii
))
{
iter
->
base
.
flags
|=
GIT_ITERATOR_FIRST_ACCESS
;
ii
->
tree_entry
.
path
=
ii
->
partial
.
ptr
;
ie
=
&
ii
->
tree_entry
;
}
if
(
entry
)
while
(
true
)
{
*
entry
=
ie
;
if
(
iter
->
next_idx
>=
iter
->
entries
.
length
)
{
error
=
GIT_ITEROVER
;
break
;
}
ii
->
base
.
flags
|=
GIT_ITERATOR_FIRST_ACCESS
;
/* we were not asked to expand this pseudotree. advance over it. */
if
(
iter
->
skip_tree
)
{
index_iterator_skip_pseudotree
(
iter
);
continue
;
}
return
(
ie
!=
NULL
)
?
0
:
GIT_ITEROVER
;
entry
=
iter
->
entries
.
contents
[
iter
->
next_idx
];
}
static
int
index_iterator__at_end
(
git_iterator
*
self
)
if
(
!
iterator_has_started
(
&
iter
->
base
,
entry
->
path
))
{
{
iter
->
next_idx
++
;
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
continue
;
return
(
ii
->
current
>=
git_vector_length
(
&
ii
->
entries
));
}
}
static
int
index_iterator__advance
(
if
(
iterator_has_ended
(
&
iter
->
base
,
entry
->
path
))
{
const
git_index_entry
**
entry
,
git_iterator
*
self
)
error
=
GIT_ITEROVER
;
{
break
;
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
}
size_t
entrycount
=
git_vector_length
(
&
ii
->
entries
);
const
git_index_entry
*
ie
;
if
(
!
iterator__has_been_accessed
(
ii
))
/* if we have a list of paths we're interested in, examine it */
return
index_iterator__current
(
entry
,
self
);
if
(
!
iterator_pathlist_next_is
(
&
iter
->
base
,
entry
->
path
))
{
iter
->
next_idx
++
;
continue
;
}
if
(
index_iterator__at_tree
(
ii
))
{
/* if this is a conflict, skip it unless we're including conflicts */
if
(
iterator__do_autoexpand
(
ii
))
{
if
(
git_index_entry_is_conflict
(
entry
)
&&
ii
->
partial
.
ptr
[
ii
->
partial_pos
]
=
ii
->
restore_terminator
;
!
iterator__include_conflicts
(
&
iter
->
base
))
{
index_iterator__next_prefix_tree
(
ii
);
iter
->
next_idx
++
;
}
else
{
continue
;
/* advance to sibling tree (i.e. find entry with new prefix) */
}
while
(
ii
->
current
<
entrycount
)
{
ii
->
current
++
;
if
(
!
(
ie
=
git_vector_get
(
&
ii
->
entries
,
ii
->
current
))
||
/* we've found what will be our next _file_ entry. but if we are
ii
->
base
.
prefixcomp
(
ie
->
path
,
ii
->
partial
.
ptr
)
!=
0
)
* returning trees entries, we may need to return a pseudotree
break
;
* entry that will contain this. don't advance over this entry,
}
* though, we still need to return it on the next `advance`.
*/
if
(
iterator__include_trees
(
&
iter
->
base
)
&&
index_iterator_create_pseudotree
(
&
entry
,
iter
,
entry
->
path
))
{
if
(
index_iterator__first_prefix_tree
(
ii
)
<
0
)
/* Note whether this pseudo tree should be expanded or not */
return
-
1
;
iter
->
skip_tree
=
iterator__dont_autoexpand
(
&
iter
->
base
);
break
;
}
}
}
else
{
if
(
ii
->
current
<
entrycount
)
ii
->
current
++
;
i
f
(
index_iterator__first_prefix_tree
(
ii
)
<
0
)
i
ter
->
next_idx
++
;
return
-
1
;
break
;
}
}
return
index_iterator__current
(
entry
,
self
);
iter
->
entry
=
(
error
==
0
)
?
entry
:
NULL
;
if
(
out
)
*
out
=
iter
->
entry
;
return
error
;
}
}
static
int
index_iterator_
_
advance_into
(
static
int
index_iterator_advance_into
(
const
git_index_entry
**
entry
,
git_iterator
*
self
)
const
git_index_entry
**
out
,
git_iterator
*
i
)
{
{
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
index_iterator
*
iter
=
(
index_iterator
*
)
i
;
const
git_index_entry
*
ie
=
git_vector_get
(
&
ii
->
entries
,
ii
->
current
);
if
(
ie
!=
NULL
&&
index_iterator__at_tree
(
ii
))
{
if
(
!
S_ISDIR
(
iter
->
tree_entry
.
mode
))
{
if
(
ii
->
restore_terminator
)
*
out
=
NULL
;
ii
->
partial
.
ptr
[
ii
->
partial_pos
]
=
ii
->
restore_terminator
;
return
0
;
index_iterator__next_prefix_tree
(
ii
);
}
}
return
index_iterator__current
(
entry
,
self
);
iter
->
skip_tree
=
false
;
return
index_iterator_advance
(
out
,
i
);
}
}
static
int
index_iterator__reset
(
git_iterator
*
self
)
static
int
index_iterator_advance_over
(
const
git_index_entry
**
out
,
git_iterator_status_t
*
status
,
git_iterator
*
i
)
{
{
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
index_iterator
*
iter
=
(
index_iterator
*
)
i
;
const
git_index_entry
*
ie
;
const
git_index_entry
*
entry
;
int
error
;
ii
->
current
=
0
;
ii
->
base
.
flags
&=
~
GIT_ITERATOR_FIRST_ACCESS
;
iterator_pathlist_walk__reset
(
self
);
if
((
error
=
index_iterator_current
(
&
entry
,
i
))
<
0
)
return
error
;
/* if we're given a start prefix, find it; if we're given a pathlist, find
if
(
S_ISDIR
(
entry
->
mode
))
* the first of those. start at the later of the two.
index_iterator_skip_pseudotree
(
iter
);
*/
if
(
ii
->
base
.
start
)
git_index_snapshot_find
(
&
ii
->
current
,
&
ii
->
entries
,
ii
->
entry_srch
,
ii
->
base
.
start
,
0
,
0
);
if
((
ie
=
index_iterator__advance_over_unwanted
(
ii
))
==
NULL
)
*
status
=
GIT_ITERATOR_STATUS_NORMAL
;
return
0
;
return
index_iterator_advance
(
out
,
i
);
}
if
(
git_buf_sets
(
&
ii
->
partial
,
ie
->
path
)
<
0
)
static
void
index_iterator_clear
(
index_iterator
*
iter
)
return
-
1
;
{
iterator_clear
(
&
iter
->
base
);
}
ii
->
partial_pos
=
0
;
static
int
index_iterator_init
(
index_iterator
*
iter
)
{
iter
->
base
.
flags
&=
~
GIT_ITERATOR_FIRST_ACCESS
;
iter
->
next_idx
=
0
;
iter
->
skip_tree
=
false
;
return
0
;
}
if
(
ii
->
base
.
start
)
{
static
int
index_iterator_reset
(
git_iterator
*
i
)
size_t
startlen
=
strlen
(
ii
->
base
.
start
);
{
index_iterator
*
iter
=
(
index_iterator
*
)
i
;
ii
->
partial_pos
=
(
startlen
>
ii
->
partial
.
size
)
?
index_iterator_clear
(
iter
);
ii
->
partial
.
size
:
startlen
;
return
index_iterator_init
(
iter
)
;
}
}
index_iterator__next_prefix_tree
(
ii
);
static
int
index_iterator_reset_range
(
git_iterator
*
i
,
const
char
*
start
,
const
char
*
end
)
{
if
(
iterator_range_reset
(
i
,
start
,
end
)
<
0
)
return
-
1
;
return
0
;
return
index_iterator_reset
(
i
)
;
}
}
static
int
index_iterator__reset_range
(
static
int
index_iterator_at_end
(
git_iterator
*
i
)
git_iterator
*
self
,
const
char
*
start
,
const
char
*
end
)
{
{
if
(
iterator__reset_range
(
self
,
start
,
end
)
<
0
)
index_iterator
*
iter
=
(
index_iterator
*
)
i
;
return
-
1
;
return
index_iterator__reset
(
self
);
return
(
iter
->
entry
==
NULL
);
}
}
static
void
index_iterator_
_free
(
git_iterator
*
self
)
static
void
index_iterator_
free
(
git_iterator
*
i
)
{
{
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
index_iterator
*
iter
=
(
index_iterator
*
)
i
;
git_index_snapshot_release
(
&
ii
->
entries
,
ii
->
base
.
index
);
ii
->
base
.
index
=
NULL
;
git_index_snapshot_release
(
&
iter
->
entries
,
iter
->
base
.
index
);
git_buf_free
(
&
ii
->
partial
);
}
}
int
git_iterator_for_index
(
int
git_iterator_for_index
(
git_iterator
**
iter
,
git_iterator
**
out
,
git_repository
*
repo
,
git_repository
*
repo
,
git_index
*
index
,
git_index
*
index
,
git_iterator_options
*
options
)
git_iterator_options
*
options
)
{
{
int
error
=
0
;
index_iterator
*
iter
;
index_iterator
*
ii
=
git__calloc
(
1
,
sizeof
(
index_iterator
));
int
error
;
GITERR_CHECK_ALLOC
(
ii
);
if
((
error
=
git_index_snapshot_new
(
&
ii
->
entries
,
index
))
<
0
)
{
static
git_iterator_callbacks
callbacks
=
{
git__free
(
ii
);
index_iterator_current
,
return
error
;
index_iterator_advance
,
}
index_iterator_advance_into
,
ii
->
base
.
index
=
index
;
index_iterator_advance_over
,
index_iterator_reset
,
index_iterator_reset_range
,
index_iterator_at_end
,
index_iterator_free
};
ITERATOR_BASE_INIT
(
ii
,
index
,
INDEX
,
repo
)
;
*
out
=
NULL
;
if
((
error
=
iterator__update_ignore_case
((
git_iterator
*
)
ii
,
options
?
options
->
flags
:
0
))
<
0
)
{
if
(
index
==
NULL
)
git_iterator_free
((
git_iterator
*
)
ii
);
return
git_iterator_for_nothing
(
out
,
options
);
return
error
;
}
i
i
->
entry_srch
=
iterator__ignore_case
(
ii
)
?
i
ter
=
git__calloc
(
1
,
sizeof
(
index_iterator
));
git_index_entry_isrch
:
git_index_entry_srch
;
GITERR_CHECK_ALLOC
(
iter
)
;
git_vector_set_cmp
(
&
ii
->
entries
,
iterator__ignore_case
(
ii
)
?
iter
->
base
.
type
=
GIT_ITERATOR_TYPE_INDEX
;
git_index_entry_icmp
:
git_index_entry_cmp
);
iter
->
base
.
cb
=
&
callbacks
;
git_vector_sort
(
&
ii
->
entries
);
git_buf_init
(
&
ii
->
partial
,
0
);
if
((
error
=
iterator_init_common
(
&
iter
->
base
,
repo
,
index
,
options
))
<
0
||
ii
->
tree_entry
.
mode
=
GIT_FILEMODE_TREE
;
(
error
=
git_index_snapshot_new
(
&
iter
->
entries
,
index
))
<
0
||
(
error
=
index_iterator_init
(
iter
))
<
0
)
goto
on_error
;
index_iterator__reset
((
git_iterator
*
)
ii
);
/* TODO: make sure this keeps the entries sort if they were already */
git_vector_set_cmp
(
&
iter
->
entries
,
iterator__ignore_case
(
&
iter
->
base
)
?
git_index_entry_icmp
:
git_index_entry_cmp
);
git_vector_sort
(
&
iter
->
entries
);
*
iter
=
(
git_iterator
*
)
ii
;
*
out
=
&
iter
->
base
;
return
0
;
return
0
;
on_error:
git_iterator_free
(
&
iter
->
base
);
return
error
;
}
}
...
...
tests/iterator/index.c
View file @
0ef0b71c
...
@@ -466,8 +466,6 @@ void test_iterator_index__pathlist(void)
...
@@ -466,8 +466,6 @@ void test_iterator_index__pathlist(void)
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_index
*
index
;
git_index
*
index
;
git_vector
filelist
;
git_vector
filelist
;
int
default_icase
;
int
expect
;
cl_git_pass
(
git_vector_init
(
&
filelist
,
100
,
&
git__strcmp_cb
));
cl_git_pass
(
git_vector_init
(
&
filelist
,
100
,
&
git__strcmp_cb
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"a"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"a"
));
...
@@ -483,35 +481,251 @@ void test_iterator_index__pathlist(void)
...
@@ -483,35 +481,251 @@ void test_iterator_index__pathlist(void)
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
/* In this test we DO NOT force a case setting on the index. */
default_icase
=
((
git_index_caps
(
index
)
&
GIT_INDEXCAP_IGNORE_CASE
)
!=
0
);
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
/* All iterator tests are "autoexpand with no tree entries" */
/* Case sensitive */
{
const
char
*
expected
[]
=
{
"B"
,
"D"
,
"L/1"
,
"a"
,
"c"
,
"e"
,
"k/1"
,
"k/a"
};
size_t
expected_len
=
8
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
))
;
i_opts
.
start
=
NULL
;
expect_iterator_items
(
i
,
8
,
NULL
,
8
,
NULL
)
;
i_opts
.
end
=
NULL
;
git_iterator_free
(
i
)
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
i_opts
.
start
=
"c"
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
i_opts
.
end
=
NULL
;
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
/* Case INsensitive */
/* (c D e k/1 k/a L ==> 6) vs (c e k/1 k/a ==> 4) */
{
expect
=
((
default_icase
)
?
6
:
4
);
const
char
*
expected
[]
=
{
expect_iterator_items
(
i
,
expect
,
NULL
,
expect
,
NULL
)
;
"a"
,
"B"
,
"c"
,
"D"
,
"e"
,
"k/1"
,
"k/a"
,
"L/1"
}
;
git_iterator_free
(
i
)
;
size_t
expected_len
=
8
;
i_opts
.
start
=
NULL
;
i_opts
.
start
=
NULL
;
i_opts
.
end
=
"e"
;
i_opts
.
end
=
NULL
;
i_opts
.
flags
=
GIT_ITERATOR_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
/* (a B c D e ==> 5) vs (B D L/1 a c e ==> 6) */
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
expect
=
((
default_icase
)
?
5
:
6
);
git_iterator_free
(
i
);
expect_iterator_items
(
i
,
expect
,
NULL
,
expect
,
NULL
);
}
git_iterator_free
(
i
);
/* Set a start, but no end. Case sensitive. */
{
const
char
*
expected
[]
=
{
"c"
,
"e"
,
"k/1"
,
"k/a"
};
size_t
expected_len
=
4
;
i_opts
.
start
=
"c"
;
i_opts
.
end
=
NULL
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Set a start, but no end. Case INsensitive. */
{
const
char
*
expected
[]
=
{
"c"
,
"D"
,
"e"
,
"k/1"
,
"k/a"
,
"L/1"
};
size_t
expected_len
=
6
;
i_opts
.
start
=
"c"
;
i_opts
.
end
=
NULL
;
i_opts
.
flags
=
GIT_ITERATOR_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Set no start, but an end. Case sensitive. */
{
const
char
*
expected
[]
=
{
"B"
,
"D"
,
"L/1"
,
"a"
,
"c"
,
"e"
};
size_t
expected_len
=
6
;
i_opts
.
start
=
NULL
;
i_opts
.
end
=
"e"
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Set no start, but an end. Case INsensitive. */
{
const
char
*
expected
[]
=
{
"a"
,
"B"
,
"c"
,
"D"
,
"e"
};
size_t
expected_len
=
5
;
i_opts
.
start
=
NULL
;
i_opts
.
end
=
"e"
;
i_opts
.
flags
=
GIT_ITERATOR_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Start and an end, case sensitive */
{
const
char
*
expected
[]
=
{
"c"
,
"e"
,
"k/1"
};
size_t
expected_len
=
3
;
i_opts
.
start
=
"c"
;
i_opts
.
end
=
"k/D"
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Start and an end, case sensitive */
{
const
char
*
expected
[]
=
{
"k/1"
};
size_t
expected_len
=
1
;
i_opts
.
start
=
"k"
;
i_opts
.
end
=
"k/D"
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Start and an end, case INsensitive */
{
const
char
*
expected
[]
=
{
"c"
,
"D"
,
"e"
,
"k/1"
,
"k/a"
};
size_t
expected_len
=
5
;
i_opts
.
start
=
"c"
;
i_opts
.
end
=
"k/D"
;
i_opts
.
flags
=
GIT_ITERATOR_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Start and an end, case INsensitive */
{
const
char
*
expected
[]
=
{
"k/1"
,
"k/a"
};
size_t
expected_len
=
2
;
i_opts
.
start
=
"k"
;
i_opts
.
end
=
"k/D"
;
i_opts
.
flags
=
GIT_ITERATOR_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
git_index_free
(
index
);
git_vector_free
(
&
filelist
);
}
void
test_iterator_index__pathlist_with_dirs
(
void
)
{
git_iterator
*
i
;
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_index
*
index
;
git_vector
filelist
;
cl_git_pass
(
git_vector_init
(
&
filelist
,
5
,
NULL
));
g_repo
=
cl_git_sandbox_init
(
"icase"
);
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
/* Test that a prefix `k` matches folders, even without trailing slash */
{
const
char
*
expected
[]
=
{
"k/1"
,
"k/B"
,
"k/D"
,
"k/a"
,
"k/c"
};
size_t
expected_len
=
5
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"k"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Test that a `k/` matches a folder */
{
const
char
*
expected
[]
=
{
"k/1"
,
"k/B"
,
"k/D"
,
"k/a"
,
"k/c"
};
size_t
expected_len
=
5
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"k/"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* When the iterator is case sensitive, ensure we can't lookup the
* directory with the wrong case.
*/
{
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"K/"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
cl_git_fail_with
(
GIT_ITEROVER
,
git_iterator_advance
(
NULL
,
i
));
git_iterator_free
(
i
);
}
/* Test that case insensitive matching works. */
{
const
char
*
expected
[]
=
{
"k/1"
,
"k/a"
,
"k/B"
,
"k/c"
,
"k/D"
};
size_t
expected_len
=
5
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"K/"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Test that case insensitive matching works without trailing slash. */
{
const
char
*
expected
[]
=
{
"k/1"
,
"k/a"
,
"k/B"
,
"k/c"
,
"k/D"
};
size_t
expected_len
=
5
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"K"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
git_index_free
(
index
);
git_index_free
(
index
);
git_vector_free
(
&
filelist
);
git_vector_free
(
&
filelist
);
...
@@ -729,3 +943,410 @@ void test_iterator_index__pathlist_with_directory(void)
...
@@ -729,3 +943,410 @@ void test_iterator_index__pathlist_with_directory(void)
git_vector_free
(
&
filelist
);
git_vector_free
(
&
filelist
);
}
}
static
void
create_paths
(
git_index
*
index
,
const
char
*
root
,
int
depth
)
{
git_buf
fullpath
=
GIT_BUF_INIT
;
git_index_entry
entry
;
size_t
root_len
;
int
i
;
if
(
root
)
{
cl_git_pass
(
git_buf_puts
(
&
fullpath
,
root
));
cl_git_pass
(
git_buf_putc
(
&
fullpath
,
'/'
));
}
root_len
=
fullpath
.
size
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
bool
file
=
(
depth
==
0
||
(
i
%
2
)
==
0
);
git_buf_truncate
(
&
fullpath
,
root_len
);
cl_git_pass
(
git_buf_printf
(
&
fullpath
,
"item%d"
,
i
));
if
(
file
)
{
memset
(
&
entry
,
0
,
sizeof
(
git_index_entry
));
entry
.
path
=
fullpath
.
ptr
;
entry
.
mode
=
GIT_FILEMODE_BLOB
;
git_oid_fromstr
(
&
entry
.
id
,
"d44e18fb93b7107b5cd1b95d601591d77869a1b6"
);
cl_git_pass
(
git_index_add
(
index
,
&
entry
));
}
else
if
(
depth
>
0
)
{
create_paths
(
index
,
fullpath
.
ptr
,
(
depth
-
1
));
}
}
git_buf_free
(
&
fullpath
);
}
void
test_iterator_index__pathlist_for_deeply_nested_item
(
void
)
{
git_iterator
*
i
;
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_index
*
index
;
git_vector
filelist
;
cl_git_pass
(
git_vector_init
(
&
filelist
,
5
,
NULL
));
g_repo
=
cl_git_sandbox_init
(
"icase"
);
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
create_paths
(
index
,
NULL
,
3
);
/* Ensure that we find the single path we're interested in */
{
const
char
*
expected
[]
=
{
"item1/item3/item5/item7"
};
size_t
expected_len
=
1
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item1/item3/item5/item7"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
{
const
char
*
expected
[]
=
{
"item1/item3/item5/item0"
,
"item1/item3/item5/item1"
,
"item1/item3/item5/item2"
,
"item1/item3/item5/item3"
,
"item1/item3/item5/item4"
,
"item1/item3/item5/item5"
,
"item1/item3/item5/item6"
,
"item1/item3/item5/item7"
,
};
size_t
expected_len
=
8
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item1/item3/item5/"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
{
const
char
*
expected
[]
=
{
"item1/item3/item0"
,
"item1/item3/item1/item0"
,
"item1/item3/item1/item1"
,
"item1/item3/item1/item2"
,
"item1/item3/item1/item3"
,
"item1/item3/item1/item4"
,
"item1/item3/item1/item5"
,
"item1/item3/item1/item6"
,
"item1/item3/item1/item7"
,
"item1/item3/item2"
,
"item1/item3/item3/item0"
,
"item1/item3/item3/item1"
,
"item1/item3/item3/item2"
,
"item1/item3/item3/item3"
,
"item1/item3/item3/item4"
,
"item1/item3/item3/item5"
,
"item1/item3/item3/item6"
,
"item1/item3/item3/item7"
,
"item1/item3/item4"
,
"item1/item3/item5/item0"
,
"item1/item3/item5/item1"
,
"item1/item3/item5/item2"
,
"item1/item3/item5/item3"
,
"item1/item3/item5/item4"
,
"item1/item3/item5/item5"
,
"item1/item3/item5/item6"
,
"item1/item3/item5/item7"
,
"item1/item3/item6"
,
"item1/item3/item7/item0"
,
"item1/item3/item7/item1"
,
"item1/item3/item7/item2"
,
"item1/item3/item7/item3"
,
"item1/item3/item7/item4"
,
"item1/item3/item7/item5"
,
"item1/item3/item7/item6"
,
"item1/item3/item7/item7"
,
};
size_t
expected_len
=
36
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item1/item3/"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
/* Ensure that we find the single path we're interested in, and we find
* it efficiently, and don't stat the entire world to get there.
*/
{
const
char
*
expected
[]
=
{
"item0"
,
"item1/item2"
,
"item5/item7/item4"
,
"item6"
,
"item7/item3/item1/item6"
};
size_t
expected_len
=
5
;
git_vector_clear
(
&
filelist
);
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item7/item3/item1/item6"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item6"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item5/item7/item4"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item1/item2"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item0"
));
/* also add some things that don't exist or don't match the right type */
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item2/"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"itemN"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item1/itemA"
));
cl_git_pass
(
git_vector_insert
(
&
filelist
,
"item5/item3/item4/"
));
i_opts
.
pathlist
.
strings
=
(
char
**
)
filelist
.
contents
;
i_opts
.
pathlist
.
count
=
filelist
.
length
;
i_opts
.
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_iterator_items
(
i
,
expected_len
,
expected
,
expected_len
,
expected
);
git_iterator_free
(
i
);
}
git_index_free
(
index
);
git_vector_free
(
&
filelist
);
}
void
test_iterator_index__advance_over
(
void
)
{
git_iterator
*
i
;
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_index
*
index
;
i_opts
.
flags
|=
GIT_ITERATOR_DONT_IGNORE_CASE
|
GIT_ITERATOR_DONT_AUTOEXPAND
;
g_repo
=
cl_git_sandbox_init
(
"icase"
);
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
create_paths
(
index
,
NULL
,
1
);
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_advance_over
(
i
,
"B"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"D"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"F"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"H"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"J"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"L/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"a"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"c"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"e"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"g"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"i"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item0"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item1/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item2"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item3/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item4"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item5/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item6"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item7/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"k/"
,
GIT_ITERATOR_STATUS_NORMAL
);
cl_git_fail_with
(
GIT_ITEROVER
,
git_iterator_advance
(
NULL
,
i
));
git_iterator_free
(
i
);
git_index_free
(
index
);
}
void
test_iterator_index__advance_into
(
void
)
{
git_iterator
*
i
;
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_index
*
index
;
g_repo
=
cl_git_sandbox_init
(
"icase"
);
i_opts
.
flags
|=
GIT_ITERATOR_DONT_IGNORE_CASE
|
GIT_ITERATOR_DONT_AUTOEXPAND
;
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_advance_into
(
i
,
"B"
);
expect_advance_into
(
i
,
"D"
);
expect_advance_into
(
i
,
"F"
);
expect_advance_into
(
i
,
"H"
);
expect_advance_into
(
i
,
"J"
);
expect_advance_into
(
i
,
"L/"
);
expect_advance_into
(
i
,
"L/1"
);
expect_advance_into
(
i
,
"L/B"
);
expect_advance_into
(
i
,
"L/D"
);
expect_advance_into
(
i
,
"L/a"
);
expect_advance_into
(
i
,
"L/c"
);
expect_advance_into
(
i
,
"a"
);
expect_advance_into
(
i
,
"c"
);
expect_advance_into
(
i
,
"e"
);
expect_advance_into
(
i
,
"g"
);
expect_advance_into
(
i
,
"i"
);
expect_advance_into
(
i
,
"k/"
);
expect_advance_into
(
i
,
"k/1"
);
expect_advance_into
(
i
,
"k/B"
);
expect_advance_into
(
i
,
"k/D"
);
expect_advance_into
(
i
,
"k/a"
);
expect_advance_into
(
i
,
"k/c"
);
cl_git_fail_with
(
GIT_ITEROVER
,
git_iterator_advance
(
NULL
,
i
));
git_iterator_free
(
i
);
git_index_free
(
index
);
}
void
test_iterator_index__advance_into_and_over
(
void
)
{
git_iterator
*
i
;
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_index
*
index
;
g_repo
=
cl_git_sandbox_init
(
"icase"
);
i_opts
.
flags
|=
GIT_ITERATOR_DONT_IGNORE_CASE
|
GIT_ITERATOR_DONT_AUTOEXPAND
;
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
create_paths
(
index
,
NULL
,
2
);
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_advance_into
(
i
,
"B"
);
expect_advance_into
(
i
,
"D"
);
expect_advance_into
(
i
,
"F"
);
expect_advance_into
(
i
,
"H"
);
expect_advance_into
(
i
,
"J"
);
expect_advance_into
(
i
,
"L/"
);
expect_advance_into
(
i
,
"L/1"
);
expect_advance_into
(
i
,
"L/B"
);
expect_advance_into
(
i
,
"L/D"
);
expect_advance_into
(
i
,
"L/a"
);
expect_advance_into
(
i
,
"L/c"
);
expect_advance_into
(
i
,
"a"
);
expect_advance_into
(
i
,
"c"
);
expect_advance_into
(
i
,
"e"
);
expect_advance_into
(
i
,
"g"
);
expect_advance_into
(
i
,
"i"
);
expect_advance_into
(
i
,
"item0"
);
expect_advance_into
(
i
,
"item1/"
);
expect_advance_into
(
i
,
"item1/item0"
);
expect_advance_into
(
i
,
"item1/item1/"
);
expect_advance_into
(
i
,
"item1/item1/item0"
);
expect_advance_into
(
i
,
"item1/item1/item1"
);
expect_advance_into
(
i
,
"item1/item1/item2"
);
expect_advance_into
(
i
,
"item1/item1/item3"
);
expect_advance_into
(
i
,
"item1/item1/item4"
);
expect_advance_into
(
i
,
"item1/item1/item5"
);
expect_advance_into
(
i
,
"item1/item1/item6"
);
expect_advance_into
(
i
,
"item1/item1/item7"
);
expect_advance_into
(
i
,
"item1/item2"
);
expect_advance_over
(
i
,
"item1/item3/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item1/item4"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item1/item5/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item1/item6"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item1/item7/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_into
(
i
,
"item2"
);
expect_advance_over
(
i
,
"item3/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item4"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item5/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item6"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"item7/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_into
(
i
,
"k/"
);
expect_advance_into
(
i
,
"k/1"
);
expect_advance_into
(
i
,
"k/B"
);
expect_advance_into
(
i
,
"k/D"
);
expect_advance_into
(
i
,
"k/a"
);
expect_advance_into
(
i
,
"k/c"
);
cl_git_fail_with
(
GIT_ITEROVER
,
git_iterator_advance
(
NULL
,
i
));
git_iterator_free
(
i
);
git_index_free
(
index
);
}
static
void
add_conflict
(
git_index
*
index
,
const
char
*
ancestor_path
,
const
char
*
our_path
,
const
char
*
their_path
)
{
git_index_entry
ancestor
=
{{
0
}},
ours
=
{{
0
}},
theirs
=
{{
0
}};
ancestor
.
path
=
ancestor_path
;
ancestor
.
mode
=
GIT_FILEMODE_BLOB
;
git_oid_fromstr
(
&
ancestor
.
id
,
"d44e18fb93b7107b5cd1b95d601591d77869a1b6"
);
GIT_IDXENTRY_STAGE_SET
(
&
ancestor
,
1
);
ours
.
path
=
our_path
;
ours
.
mode
=
GIT_FILEMODE_BLOB
;
git_oid_fromstr
(
&
ours
.
id
,
"d44e18fb93b7107b5cd1b95d601591d77869a1b6"
);
GIT_IDXENTRY_STAGE_SET
(
&
ours
,
2
);
theirs
.
path
=
their_path
;
theirs
.
mode
=
GIT_FILEMODE_BLOB
;
git_oid_fromstr
(
&
theirs
.
id
,
"d44e18fb93b7107b5cd1b95d601591d77869a1b6"
);
GIT_IDXENTRY_STAGE_SET
(
&
theirs
,
3
);
cl_git_pass
(
git_index_conflict_add
(
index
,
&
ancestor
,
&
ours
,
&
theirs
));
}
void
test_iterator_index__include_conflicts
(
void
)
{
git_iterator
*
i
;
git_iterator_options
i_opts
=
GIT_ITERATOR_OPTIONS_INIT
;
git_index
*
index
;
i_opts
.
flags
|=
GIT_ITERATOR_DONT_IGNORE_CASE
|
GIT_ITERATOR_DONT_AUTOEXPAND
;
g_repo
=
cl_git_sandbox_init
(
"icase"
);
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
add_conflict
(
index
,
"CONFLICT1"
,
"CONFLICT1"
,
"CONFLICT1"
);
add_conflict
(
index
,
"ZZZ-CONFLICT2.ancestor"
,
"ZZZ-CONFLICT2.ours"
,
"ZZZ-CONFLICT2.theirs"
);
add_conflict
(
index
,
"ancestor.conflict3"
,
"ours.conflict3"
,
"theirs.conflict3"
);
add_conflict
(
index
,
"zzz-conflict4"
,
"zzz-conflict4"
,
"zzz-conflict4"
);
/* Iterate the index, ensuring that conflicts are not included */
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_advance_over
(
i
,
"B"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"D"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"F"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"H"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"J"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"L/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"a"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"c"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"e"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"g"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"i"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"k/"
,
GIT_ITERATOR_STATUS_NORMAL
);
cl_git_fail_with
(
GIT_ITEROVER
,
git_iterator_advance
(
NULL
,
i
));
git_iterator_free
(
i
);
/* Try again, returning conflicts */
i_opts
.
flags
|=
GIT_ITERATOR_INCLUDE_CONFLICTS
;
cl_git_pass
(
git_iterator_for_index
(
&
i
,
g_repo
,
index
,
&
i_opts
));
expect_advance_over
(
i
,
"B"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"CONFLICT1"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"CONFLICT1"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"CONFLICT1"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"D"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"F"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"H"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"J"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"L/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"ZZZ-CONFLICT2.ancestor"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"ZZZ-CONFLICT2.ours"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"ZZZ-CONFLICT2.theirs"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"a"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"ancestor.conflict3"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"c"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"e"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"g"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"i"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"k/"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"ours.conflict3"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"theirs.conflict3"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"zzz-conflict4"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"zzz-conflict4"
,
GIT_ITERATOR_STATUS_NORMAL
);
expect_advance_over
(
i
,
"zzz-conflict4"
,
GIT_ITERATOR_STATUS_NORMAL
);
cl_git_fail_with
(
GIT_ITEROVER
,
git_iterator_advance
(
NULL
,
i
));
git_iterator_free
(
i
);
git_index_free
(
index
);
}
tests/iterator/iterator_helpers.c
View file @
0ef0b71c
...
@@ -108,3 +108,39 @@ void expect_iterator_items(
...
@@ -108,3 +108,39 @@ void expect_iterator_items(
cl_assert_equal_i
(
expected_total
,
count
);
cl_assert_equal_i
(
expected_total
,
count
);
}
}
void
expect_advance_over
(
git_iterator
*
i
,
const
char
*
expected_path
,
git_iterator_status_t
expected_status
)
{
const
git_index_entry
*
entry
;
git_iterator_status_t
status
;
int
error
;
cl_git_pass
(
git_iterator_current
(
&
entry
,
i
));
cl_assert_equal_s
(
expected_path
,
entry
->
path
);
error
=
git_iterator_advance_over
(
&
entry
,
&
status
,
i
);
cl_assert
(
!
error
||
error
==
GIT_ITEROVER
);
cl_assert_equal_i
(
expected_status
,
status
);
}
void
expect_advance_into
(
git_iterator
*
i
,
const
char
*
expected_path
)
{
const
git_index_entry
*
entry
;
int
error
;
cl_git_pass
(
git_iterator_current
(
&
entry
,
i
));
cl_assert_equal_s
(
expected_path
,
entry
->
path
);
if
(
S_ISDIR
(
entry
->
mode
))
error
=
git_iterator_advance_into
(
&
entry
,
i
);
else
error
=
git_iterator_advance
(
&
entry
,
i
);
cl_assert
(
!
error
||
error
==
GIT_ITEROVER
);
}
tests/iterator/iterator_helpers.h
View file @
0ef0b71c
...
@@ -6,3 +6,11 @@ extern void expect_iterator_items(
...
@@ -6,3 +6,11 @@ extern void expect_iterator_items(
int
expected_total
,
int
expected_total
,
const
char
**
expected_total_paths
);
const
char
**
expected_total_paths
);
extern
void
expect_advance_over
(
git_iterator
*
i
,
const
char
*
expected_path
,
git_iterator_status_t
expected_status
);
void
expect_advance_into
(
git_iterator
*
i
,
const
char
*
expected_path
);
tests/iterator/workdir.c
View file @
0ef0b71c
...
@@ -1243,23 +1243,6 @@ void test_iterator_workdir__bounded_submodules(void)
...
@@ -1243,23 +1243,6 @@ void test_iterator_workdir__bounded_submodules(void)
git_tree_free
(
head
);
git_tree_free
(
head
);
}
}
static
void
expect_advance_over
(
git_iterator
*
i
,
const
char
*
expected_path
,
git_iterator_status_t
expected_status
)
{
const
git_index_entry
*
entry
;
git_iterator_status_t
status
;
int
error
;
cl_git_pass
(
git_iterator_current
(
&
entry
,
i
));
cl_assert_equal_s
(
expected_path
,
entry
->
path
);
error
=
git_iterator_advance_over
(
&
entry
,
&
status
,
i
);
cl_assert
(
!
error
||
error
==
GIT_ITEROVER
);
cl_assert_equal_i
(
expected_status
,
status
);
}
void
test_iterator_workdir__advance_over
(
void
)
void
test_iterator_workdir__advance_over
(
void
)
{
{
git_iterator
*
i
;
git_iterator
*
i
;
...
@@ -1380,24 +1363,6 @@ void test_iterator_workdir__advance_over_with_pathlist(void)
...
@@ -1380,24 +1363,6 @@ void test_iterator_workdir__advance_over_with_pathlist(void)
git_vector_free
(
&
pathlist
);
git_vector_free
(
&
pathlist
);
}
}
static
void
expect_advance_into
(
git_iterator
*
i
,
const
char
*
expected_path
)
{
const
git_index_entry
*
entry
;
int
error
;
cl_git_pass
(
git_iterator_current
(
&
entry
,
i
));
cl_assert_equal_s
(
expected_path
,
entry
->
path
);
if
(
S_ISDIR
(
entry
->
mode
))
error
=
git_iterator_advance_into
(
&
entry
,
i
);
else
error
=
git_iterator_advance
(
&
entry
,
i
);
cl_assert
(
!
error
||
error
==
GIT_ITEROVER
);
}
void
test_iterator_workdir__advance_into
(
void
)
void
test_iterator_workdir__advance_into
(
void
)
{
{
git_iterator
*
i
;
git_iterator
*
i
;
...
...
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