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
55325efa
Commit
55325efa
authored
Dec 10, 2012
by
Vicent Martí
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1133 from arrbee/more-iterator-cleanup
More iterator cleanup
parents
4cbe9a1b
91e7d263
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
311 additions
and
154 deletions
+311
-154
include/git2/tree.h
+8
-0
src/checkout.c
+1
-2
src/diff.c
+11
-10
src/diff.h
+6
-0
src/index.c
+1
-2
src/iterator.c
+156
-108
src/iterator.h
+18
-10
src/notes.c
+1
-1
src/path.c
+31
-4
src/path.h
+19
-4
src/submodule.c
+1
-1
src/tree.c
+10
-2
src/tree.h
+4
-0
src/util.c
+10
-2
tests-clar/diff/iterator.c
+34
-8
No files found.
include/git2/tree.h
View file @
55325efa
...
@@ -81,6 +81,14 @@ GIT_INLINE(void) git_tree_free(git_tree *tree)
...
@@ -81,6 +81,14 @@ GIT_INLINE(void) git_tree_free(git_tree *tree)
GIT_EXTERN
(
const
git_oid
*
)
git_tree_id
(
const
git_tree
*
tree
);
GIT_EXTERN
(
const
git_oid
*
)
git_tree_id
(
const
git_tree
*
tree
);
/**
/**
* Get the repository that contains the tree.
*
* @param tree A previously loaded tree.
* @return Repository that contains this tree.
*/
GIT_EXTERN
(
git_repository
*
)
git_tree_owner
(
const
git_tree
*
tree
);
/**
* Get the number of entries listed in a tree
* Get the number of entries listed in a tree
*
*
* @param tree a previously loaded tree.
* @param tree a previously loaded tree.
...
...
src/checkout.c
View file @
55325efa
...
@@ -448,8 +448,7 @@ static int checkout_get_actions(
...
@@ -448,8 +448,7 @@ static int checkout_get_actions(
!
(
error
==
GIT_ENOTFOUND
||
error
==
GIT_EORPHANEDHEAD
))
!
(
error
==
GIT_ENOTFOUND
||
error
==
GIT_EORPHANEDHEAD
))
return
-
1
;
return
-
1
;
if
((
error
=
git_iterator_for_tree_range
(
if
((
error
=
git_iterator_for_tree_range
(
&
hiter
,
head
,
pfx
,
pfx
))
<
0
)
&
hiter
,
data
->
repo
,
head
,
pfx
,
pfx
))
<
0
)
goto
fail
;
goto
fail
;
if
((
diff
->
opts
.
flags
&
GIT_DIFF_DELTAS_ARE_ICASE
)
!=
0
&&
if
((
diff
->
opts
.
flags
&
GIT_DIFF_DELTAS_ARE_ICASE
)
!=
0
&&
...
...
src/diff.c
View file @
55325efa
...
@@ -570,7 +570,7 @@ static int diff_list_init_from_iterators(
...
@@ -570,7 +570,7 @@ static int diff_list_init_from_iterators(
return
0
;
return
0
;
}
}
static
int
diff
_from_iterators
(
int
git_diff_
_from_iterators
(
git_diff_list
**
diff_ptr
,
git_diff_list
**
diff_ptr
,
git_repository
*
repo
,
git_repository
*
repo
,
git_iterator
*
old_iter
,
git_iterator
*
old_iter
,
...
@@ -610,9 +610,10 @@ static int diff_from_iterators(
...
@@ -610,9 +610,10 @@ static int diff_from_iterators(
/* run iterators building diffs */
/* run iterators building diffs */
while
(
oitem
||
nitem
)
{
while
(
oitem
||
nitem
)
{
int
cmp
=
oitem
?
(
nitem
?
diff
->
entrycomp
(
oitem
,
nitem
)
:
-
1
)
:
1
;
/* create DELETED records for old items not matched in new */
/* create DELETED records for old items not matched in new */
if
(
oitem
&&
(
!
nitem
||
diff
->
entrycomp
(
oitem
,
nitem
)
<
0
)
)
{
if
(
cmp
<
0
)
{
if
(
diff_delta__from_one
(
diff
,
GIT_DELTA_DELETED
,
oitem
)
<
0
)
if
(
diff_delta__from_one
(
diff
,
GIT_DELTA_DELETED
,
oitem
)
<
0
)
goto
fail
;
goto
fail
;
...
@@ -637,7 +638,7 @@ static int diff_from_iterators(
...
@@ -637,7 +638,7 @@ static int diff_from_iterators(
/* create ADDED, TRACKED, or IGNORED records for new items not
/* create ADDED, TRACKED, or IGNORED records for new items not
* matched in old (and/or descend into directories as needed)
* matched in old (and/or descend into directories as needed)
*/
*/
else
if
(
nitem
&&
(
!
oitem
||
diff
->
entrycomp
(
oitem
,
nitem
)
>
0
)
)
{
else
if
(
cmp
>
0
)
{
git_delta_t
delta_type
=
GIT_DELTA_UNTRACKED
;
git_delta_t
delta_type
=
GIT_DELTA_UNTRACKED
;
/* check if contained in ignored parent directory */
/* check if contained in ignored parent directory */
...
@@ -733,7 +734,7 @@ static int diff_from_iterators(
...
@@ -733,7 +734,7 @@ static int diff_from_iterators(
* (or ADDED and DELETED pair if type changed)
* (or ADDED and DELETED pair if type changed)
*/
*/
else
{
else
{
assert
(
oitem
&&
nitem
&&
diff
->
entrycomp
(
oitem
,
nitem
)
==
0
);
assert
(
oitem
&&
nitem
&&
cmp
==
0
);
if
(
maybe_modified
(
old_iter
,
oitem
,
new_iter
,
nitem
,
diff
)
<
0
||
if
(
maybe_modified
(
old_iter
,
oitem
,
new_iter
,
nitem
,
diff
)
<
0
||
git_iterator_advance
(
old_iter
,
&
oitem
)
<
0
||
git_iterator_advance
(
old_iter
,
&
oitem
)
<
0
||
...
@@ -759,8 +760,8 @@ fail:
...
@@ -759,8 +760,8 @@ fail:
git_iterator *a = NULL, *b = NULL; \
git_iterator *a = NULL, *b = NULL; \
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL; \
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL; \
GITERR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options"); \
GITERR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options"); \
if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
error =
diff
_from_iterators(diff, repo, a, b, opts); \
error =
git_diff_
_from_iterators(diff, repo, a, b, opts); \
git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
} while (0)
} while (0)
...
@@ -776,8 +777,8 @@ int git_diff_tree_to_tree(
...
@@ -776,8 +777,8 @@ int git_diff_tree_to_tree(
assert
(
diff
&&
repo
);
assert
(
diff
&&
repo
);
DIFF_FROM_ITERATORS
(
DIFF_FROM_ITERATORS
(
git_iterator_for_tree_range
(
&
a
,
repo
,
old_tree
,
pfx
,
pfx
),
git_iterator_for_tree_range
(
&
a
,
old_tree
,
pfx
,
pfx
),
git_iterator_for_tree_range
(
&
b
,
repo
,
new_tree
,
pfx
,
pfx
)
git_iterator_for_tree_range
(
&
b
,
new_tree
,
pfx
,
pfx
)
);
);
return
error
;
return
error
;
...
@@ -798,7 +799,7 @@ int git_diff_index_to_tree(
...
@@ -798,7 +799,7 @@ int git_diff_index_to_tree(
return
error
;
return
error
;
DIFF_FROM_ITERATORS
(
DIFF_FROM_ITERATORS
(
git_iterator_for_tree_range
(
&
a
,
repo
,
old_tree
,
pfx
,
pfx
),
git_iterator_for_tree_range
(
&
a
,
old_tree
,
pfx
,
pfx
),
git_iterator_for_index_range
(
&
b
,
index
,
pfx
,
pfx
)
git_iterator_for_index_range
(
&
b
,
index
,
pfx
,
pfx
)
);
);
...
@@ -838,7 +839,7 @@ int git_diff_workdir_to_tree(
...
@@ -838,7 +839,7 @@ int git_diff_workdir_to_tree(
assert
(
diff
&&
repo
);
assert
(
diff
&&
repo
);
DIFF_FROM_ITERATORS
(
DIFF_FROM_ITERATORS
(
git_iterator_for_tree_range
(
&
a
,
repo
,
old_tree
,
pfx
,
pfx
),
git_iterator_for_tree_range
(
&
a
,
old_tree
,
pfx
,
pfx
),
git_iterator_for_workdir_range
(
&
b
,
repo
,
pfx
,
pfx
)
git_iterator_for_workdir_range
(
&
b
,
repo
,
pfx
,
pfx
)
);
);
...
...
src/diff.h
View file @
55325efa
...
@@ -61,6 +61,12 @@ extern bool git_diff_delta__should_skip(
...
@@ -61,6 +61,12 @@ extern bool git_diff_delta__should_skip(
extern
int
git_diff__oid_for_file
(
extern
int
git_diff__oid_for_file
(
git_repository
*
,
const
char
*
,
uint16_t
,
git_off_t
,
git_oid
*
);
git_repository
*
,
const
char
*
,
uint16_t
,
git_off_t
,
git_oid
*
);
extern
int
git_diff__from_iterators
(
git_diff_list
**
diff_ptr
,
git_repository
*
repo
,
git_iterator
*
old_iter
,
git_iterator
*
new_iter
,
const
git_diff_options
*
opts
);
#endif
#endif
src/index.c
View file @
55325efa
...
@@ -1641,8 +1641,7 @@ int git_index_read_tree_match(
...
@@ -1641,8 +1641,7 @@ int git_index_read_tree_match(
pfx = git_pathspec_prefix(strspec);
pfx = git_pathspec_prefix(strspec);
if ((error = git_iterator_for_tree_range(
if ((error = git_iterator_for_tree_range(&iter, tree, pfx, pfx)) < 0 ||
&iter, INDEX_OWNER(index), tree, pfx, pfx)) < 0 ||
(error = git_iterator_current(iter, &entry)) < 0)
(error = git_iterator_current(iter, &entry)) < 0)
goto cleanup;
goto cleanup;
...
...
src/iterator.c
View file @
55325efa
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
(P)->base.type = GIT_ITERATOR_ ## NAME_UC; \
(P)->base.type = GIT_ITERATOR_ ## NAME_UC; \
(P)->base.start = start ? git__strdup(start) : NULL; \
(P)->base.start = start ? git__strdup(start) : NULL; \
(P)->base.end = end ? git__strdup(end) : NULL; \
(P)->base.end = end ? git__strdup(end) : NULL; \
(P)->base.ignore_case =
0
; \
(P)->base.ignore_case =
false
; \
(P)->base.current = NAME_LC ## _iterator__current; \
(P)->base.current = NAME_LC ## _iterator__current; \
(P)->base.at_end = NAME_LC ## _iterator__at_end; \
(P)->base.at_end = NAME_LC ## _iterator__at_end; \
(P)->base.advance = NAME_LC ## _iterator__advance; \
(P)->base.advance = NAME_LC ## _iterator__advance; \
...
@@ -29,6 +29,25 @@
...
@@ -29,6 +29,25 @@
return -1; \
return -1; \
} while (0)
} while (0)
static
int
iterator__reset_range
(
git_iterator
*
iter
,
const
char
*
start
,
const
char
*
end
)
{
if
(
start
)
{
if
(
iter
->
start
)
git__free
(
iter
->
start
);
iter
->
start
=
git__strdup
(
start
);
GITERR_CHECK_ALLOC
(
iter
->
start
);
}
if
(
end
)
{
if
(
iter
->
end
)
git__free
(
iter
->
end
);
iter
->
end
=
git__strdup
(
end
);
GITERR_CHECK_ALLOC
(
iter
->
end
);
}
return
0
;
}
static
int
empty_iterator__no_item
(
static
int
empty_iterator__no_item
(
git_iterator
*
iter
,
const
git_index_entry
**
entry
)
git_iterator
*
iter
,
const
git_index_entry
**
entry
)
...
@@ -44,16 +63,16 @@ static int empty_iterator__at_end(git_iterator *iter)
...
@@ -44,16 +63,16 @@ static int empty_iterator__at_end(git_iterator *iter)
return
1
;
return
1
;
}
}
static
int
empty_iterator__noop
(
git_iterator
*
iter
)
static
int
empty_iterator__reset
(
git_iterator
*
iter
,
const
char
*
start
,
const
char
*
end
)
{
{
GIT_UNUSED
(
iter
);
GIT_UNUSED
(
iter
);
GIT_UNUSED
(
start
);
GIT_UNUSED
(
end
);
return
0
;
return
0
;
}
}
static
int
empty_iterator__seek
(
git_iterator
*
iter
,
const
char
*
prefix
)
static
int
empty_iterator__seek
(
git_iterator
*
iter
,
const
char
*
prefix
)
{
{
GIT_UNUSED
(
iter
);
GIT_UNUSED
(
iter
);
GIT_UNUSED
(
prefix
);
GIT_UNUSED
(
prefix
);
return
-
1
;
return
-
1
;
}
}
...
@@ -72,7 +91,7 @@ int git_iterator_for_nothing(git_iterator **iter)
...
@@ -72,7 +91,7 @@ int git_iterator_for_nothing(git_iterator **iter)
i
->
at_end
=
empty_iterator__at_end
;
i
->
at_end
=
empty_iterator__at_end
;
i
->
advance
=
empty_iterator__no_item
;
i
->
advance
=
empty_iterator__no_item
;
i
->
seek
=
empty_iterator__seek
;
i
->
seek
=
empty_iterator__seek
;
i
->
reset
=
empty_iterator__
noop
;
i
->
reset
=
empty_iterator__
reset
;
i
->
free
=
empty_iterator__free
;
i
->
free
=
empty_iterator__free
;
*
iter
=
i
;
*
iter
=
i
;
...
@@ -91,17 +110,15 @@ struct tree_iterator_frame {
...
@@ -91,17 +110,15 @@ struct tree_iterator_frame {
typedef
struct
{
typedef
struct
{
git_iterator
base
;
git_iterator
base
;
git_repository
*
repo
;
tree_iterator_frame
*
stack
,
*
tail
;
tree_iterator_frame
*
stack
,
*
tail
;
git_index_entry
entry
;
git_index_entry
entry
;
git_buf
path
;
git_buf
path
;
bool
path_has_filename
;
bool
path_has_filename
;
}
tree_iterator
;
}
tree_iterator
;
static
const
git_tree_entry
*
tree_iterator__tree_entry
(
tree_iterator
*
ti
)
GIT_INLINE
(
const
git_tree_entry
*
)
tree_iterator__tree_entry
(
tree_iterator
*
ti
)
{
{
return
(
ti
->
stack
==
NULL
)
?
NULL
:
return
git_tree_entry_byindex
(
ti
->
stack
->
tree
,
ti
->
stack
->
index
);
git_tree_entry_byindex
(
ti
->
stack
->
tree
,
ti
->
stack
->
index
);
}
}
static
char
*
tree_iterator__current_filename
(
static
char
*
tree_iterator__current_filename
(
...
@@ -116,25 +133,34 @@ static char *tree_iterator__current_filename(
...
@@ -116,25 +133,34 @@ static char *tree_iterator__current_filename(
return
ti
->
path
.
ptr
;
return
ti
->
path
.
ptr
;
}
}
static
void
tree_iterator__
pop_frame
(
tree_iterator
*
ti
)
static
void
tree_iterator__
free_frame
(
tree_iterator_frame
*
tf
)
{
{
tree_iterator_frame
*
tf
=
ti
->
stack
;
if
(
!
tf
)
ti
->
stack
=
tf
->
next
;
return
;
if
(
ti
->
stack
!=
NULL
)
{
git_tree_free
(
tf
->
tree
);
git_tree_free
(
tf
->
tree
);
/* don't free the initial tree */
ti
->
stack
->
prev
=
NULL
;
/* disconnect prev */
}
git__free
(
tf
);
git__free
(
tf
);
}
}
static
int
tree_iterator__to_end
(
tree_iterator
*
ti
)
static
bool
tree_iterator__pop_frame
(
tree_iterator
*
ti
)
{
{
while
(
ti
->
stack
&&
ti
->
stack
->
next
)
tree_iterator_frame
*
tf
=
ti
->
stack
;
tree_iterator__pop_frame
(
ti
);
if
(
ti
->
stack
)
/* don't free the initial tree/frame */
ti
->
stack
->
index
=
git_tree_entrycount
(
ti
->
stack
->
tree
);
if
(
!
tf
->
next
)
return
false
;
ti
->
stack
=
tf
->
next
;
ti
->
stack
->
prev
=
NULL
;
tree_iterator__free_frame
(
tf
);
return
true
;
}
static
int
tree_iterator__to_end
(
tree_iterator
*
ti
)
{
while
(
tree_iterator__pop_frame
(
ti
))
/* pop all */
;
ti
->
stack
->
index
=
git_tree_entrycount
(
ti
->
stack
->
tree
);
return
0
;
return
0
;
}
}
...
@@ -205,7 +231,7 @@ static int tree_iterator__expand_tree(tree_iterator *ti)
...
@@ -205,7 +231,7 @@ static int tree_iterator__expand_tree(tree_iterator *ti)
git__prefixcmp
(
ti
->
path
.
ptr
,
ti
->
base
.
end
)
>
0
)
git__prefixcmp
(
ti
->
path
.
ptr
,
ti
->
base
.
end
)
>
0
)
return
tree_iterator__to_end
(
ti
);
return
tree_iterator__to_end
(
ti
);
if
((
error
=
git_tree_lookup
(
&
subtree
,
ti
->
repo
,
&
te
->
oid
))
<
0
)
if
((
error
=
git_tree_lookup
(
&
subtree
,
ti
->
base
.
repo
,
&
te
->
oid
))
<
0
)
return
error
;
return
error
;
relpath
=
NULL
;
relpath
=
NULL
;
...
@@ -247,12 +273,13 @@ static int tree_iterator__advance(
...
@@ -247,12 +273,13 @@ static int tree_iterator__advance(
ti
->
path_has_filename
=
false
;
ti
->
path_has_filename
=
false
;
}
}
while
(
ti
->
stack
!=
NULL
)
{
while
(
1
)
{
te
=
git_tree_entry_byindex
(
ti
->
stack
->
tree
,
++
ti
->
stack
->
index
);
te
=
git_tree_entry_byindex
(
ti
->
stack
->
tree
,
++
ti
->
stack
->
index
);
if
(
te
!=
NULL
)
if
(
te
!=
NULL
)
break
;
break
;
tree_iterator__pop_frame
(
ti
);
if
(
!
tree_iterator__pop_frame
(
ti
))
break
;
/* no frames left to pop */
git_buf_rtruncate_at_char
(
&
ti
->
path
,
'/'
);
git_buf_rtruncate_at_char
(
&
ti
->
path
,
'/'
);
}
}
...
@@ -279,30 +306,36 @@ static int tree_iterator__seek(git_iterator *self, const char *prefix)
...
@@ -279,30 +306,36 @@ static int tree_iterator__seek(git_iterator *self, const char *prefix)
static
void
tree_iterator__free
(
git_iterator
*
self
)
static
void
tree_iterator__free
(
git_iterator
*
self
)
{
{
tree_iterator
*
ti
=
(
tree_iterator
*
)
self
;
tree_iterator
*
ti
=
(
tree_iterator
*
)
self
;
while
(
ti
->
stack
!=
NULL
)
tree_iterator__pop_frame
(
ti
);
while
(
tree_iterator__pop_frame
(
ti
))
/* pop all */
;
tree_iterator__free_frame
(
ti
->
stack
);
ti
->
stack
=
ti
->
tail
=
NULL
;
git_buf_free
(
&
ti
->
path
);
git_buf_free
(
&
ti
->
path
);
}
}
static
int
tree_iterator__reset
(
git_iterator
*
self
)
static
int
tree_iterator__reset
(
git_iterator
*
self
,
const
char
*
start
,
const
char
*
end
)
{
{
tree_iterator
*
ti
=
(
tree_iterator
*
)
self
;
tree_iterator
*
ti
=
(
tree_iterator
*
)
self
;
while
(
ti
->
stack
&&
ti
->
stack
->
next
)
while
(
tree_iterator__pop_frame
(
ti
))
/* pop all */
;
tree_iterator__pop_frame
(
ti
);
if
(
ti
->
stack
)
if
(
iterator__reset_range
(
self
,
start
,
end
)
<
0
)
ti
->
stack
->
index
=
return
-
1
;
git_tree__prefix_position
(
ti
->
stack
->
tree
,
ti
->
base
.
start
);
ti
->
stack
->
index
=
git_tree__prefix_position
(
ti
->
stack
->
tree
,
ti
->
base
.
start
);
git_buf_clear
(
&
ti
->
path
);
git_buf_clear
(
&
ti
->
path
);
ti
->
path_has_filename
=
false
;
return
tree_iterator__expand_tree
(
ti
);
return
tree_iterator__expand_tree
(
ti
);
}
}
int
git_iterator_for_tree_range
(
int
git_iterator_for_tree_range
(
git_iterator
**
iter
,
git_iterator
**
iter
,
git_repository
*
repo
,
git_tree
*
tree
,
git_tree
*
tree
,
const
char
*
start
,
const
char
*
start
,
const
char
*
end
)
const
char
*
end
)
...
@@ -313,9 +346,12 @@ int git_iterator_for_tree_range(
...
@@ -313,9 +346,12 @@ int git_iterator_for_tree_range(
if
(
tree
==
NULL
)
if
(
tree
==
NULL
)
return
git_iterator_for_nothing
(
iter
);
return
git_iterator_for_nothing
(
iter
);
if
((
error
=
git_tree__dup
(
&
tree
,
tree
))
<
0
)
return
error
;
ITERATOR_BASE_INIT
(
ti
,
tree
,
TREE
);
ITERATOR_BASE_INIT
(
ti
,
tree
,
TREE
);
ti
->
repo
=
repo
;
ti
->
base
.
repo
=
git_tree_owner
(
tree
)
;
ti
->
stack
=
ti
->
tail
=
tree_iterator__alloc_frame
(
tree
,
ti
->
base
.
start
);
ti
->
stack
=
ti
->
tail
=
tree_iterator__alloc_frame
(
tree
,
ti
->
base
.
start
);
if
((
error
=
tree_iterator__expand_tree
(
ti
))
<
0
)
if
((
error
=
tree_iterator__expand_tree
(
ti
))
<
0
)
...
@@ -396,9 +432,12 @@ static int index_iterator__seek(git_iterator *self, const char *prefix)
...
@@ -396,9 +432,12 @@ static int index_iterator__seek(git_iterator *self, const char *prefix)
return
-
1
;
return
-
1
;
}
}
static
int
index_iterator__reset
(
git_iterator
*
self
)
static
int
index_iterator__reset
(
git_iterator
*
self
,
const
char
*
start
,
const
char
*
end
)
{
{
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
index_iterator
*
ii
=
(
index_iterator
*
)
self
;
if
(
iterator__reset_range
(
self
,
start
,
end
)
<
0
)
return
-
1
;
ii
->
current
=
ii
->
base
.
start
?
ii
->
current
=
ii
->
base
.
start
?
git_index__prefix_position
(
ii
->
index
,
ii
->
base
.
start
)
:
0
;
git_index__prefix_position
(
ii
->
index
,
ii
->
base
.
start
)
:
0
;
index_iterator__skip_conflicts
(
ii
);
index_iterator__skip_conflicts
(
ii
);
...
@@ -424,9 +463,10 @@ int git_iterator_for_index_range(
...
@@ -424,9 +463,10 @@ int git_iterator_for_index_range(
ITERATOR_BASE_INIT
(
ii
,
index
,
INDEX
);
ITERATOR_BASE_INIT
(
ii
,
index
,
INDEX
);
ii
->
index
=
index
;
ii
->
index
=
index
;
ii
->
base
.
repo
=
git_index_owner
(
index
);
ii
->
base
.
ignore_case
=
ii
->
index
->
ignore_case
;
ii
->
base
.
ignore_case
=
ii
->
index
->
ignore_case
;
index_iterator__reset
((
git_iterator
*
)
ii
);
index_iterator__reset
((
git_iterator
*
)
ii
,
NULL
,
NULL
);
*
iter
=
(
git_iterator
*
)
ii
;
*
iter
=
(
git_iterator
*
)
ii
;
...
@@ -456,36 +496,19 @@ struct workdir_iterator_frame {
...
@@ -456,36 +496,19 @@ struct workdir_iterator_frame {
workdir_iterator_frame
*
next
;
workdir_iterator_frame
*
next
;
git_vector
entries
;
git_vector
entries
;
size_t
index
;
size_t
index
;
char
*
start
;
};
};
typedef
struct
{
typedef
struct
{
git_iterator
base
;
git_iterator
base
;
git_repository
*
repo
;
size_t
root_len
;
workdir_iterator_frame
*
stack
;
workdir_iterator_frame
*
stack
;
int
(
*
entrycmp
)(
const
void
*
pfx
,
const
void
*
item
);
git_ignores
ignores
;
git_ignores
ignores
;
git_index_entry
entry
;
git_index_entry
entry
;
git_buf
path
;
git_buf
path
;
size_t
root_len
;
int
is_ignored
;
int
is_ignored
;
}
workdir_iterator
;
}
workdir_iterator
;
static
int
git_path_with_stat_cmp_case
(
const
void
*
a
,
const
void
*
b
)
{
const
git_path_with_stat
*
path_with_stat_a
=
a
;
const
git_path_with_stat
*
path_with_stat_b
=
b
;
return
strcmp
(
path_with_stat_a
->
path
,
path_with_stat_b
->
path
);
}
static
int
git_path_with_stat_cmp_icase
(
const
void
*
a
,
const
void
*
b
)
{
const
git_path_with_stat
*
path_with_stat_a
=
a
;
const
git_path_with_stat
*
path_with_stat_b
=
b
;
return
strcasecmp
(
path_with_stat_a
->
path
,
path_with_stat_b
->
path
);
}
GIT_INLINE
(
bool
)
path_is_dotgit
(
const
git_path_with_stat
*
ps
)
GIT_INLINE
(
bool
)
path_is_dotgit
(
const
git_path_with_stat
*
ps
)
{
{
if
(
!
ps
)
if
(
!
ps
)
...
@@ -494,26 +517,34 @@ GIT_INLINE(bool) path_is_dotgit(const git_path_with_stat *ps)
...
@@ -494,26 +517,34 @@ GIT_INLINE(bool) path_is_dotgit(const git_path_with_stat *ps)
const
char
*
path
=
ps
->
path
;
const
char
*
path
=
ps
->
path
;
size_t
len
=
ps
->
path_len
;
size_t
len
=
ps
->
path_len
;
return
len
>=
4
&&
if
(
len
<
4
)
tolower
(
path
[
len
-
1
])
==
't'
&&
return
false
;
tolower
(
path
[
len
-
2
])
==
'i'
&&
if
(
path
[
len
-
1
]
==
'/'
)
tolower
(
path
[
len
-
3
])
==
'g'
&&
len
--
;
path
[
len
-
4
]
==
'.'
&&
if
(
tolower
(
path
[
len
-
1
])
!=
't'
||
(
len
==
4
||
path
[
len
-
5
]
==
'/'
);
tolower
(
path
[
len
-
2
])
!=
'i'
||
tolower
(
path
[
len
-
3
])
!=
'g'
||
tolower
(
path
[
len
-
4
])
!=
'.'
)
return
false
;
return
(
len
==
4
||
path
[
len
-
5
]
==
'/'
);
}
}
}
}
static
workdir_iterator_frame
*
workdir_iterator__alloc_frame
(
workdir_iterator
*
wi
)
static
workdir_iterator_frame
*
workdir_iterator__alloc_frame
(
workdir_iterator
*
wi
)
{
{
workdir_iterator_frame
*
wf
=
git__calloc
(
1
,
sizeof
(
workdir_iterator_frame
));
workdir_iterator_frame
*
wf
=
git__calloc
(
1
,
sizeof
(
workdir_iterator_frame
));
git_vector_cmp
entry_compare
=
CASESELECT
(
wi
->
base
.
ignore_case
,
git_path_with_stat_cmp_icase
,
git_path_with_stat_cmp_case
);
git_vector_cmp
entry_compare
=
CASESELECT
(
wi
->
base
.
ignore_case
,
git_path_with_stat_cmp_icase
,
git_path_with_stat_cmp
);
if
(
wf
==
NULL
)
if
(
wf
==
NULL
)
return
NULL
;
return
NULL
;
if
(
git_vector_init
(
&
wf
->
entries
,
0
,
entry_compare
)
!=
0
)
{
if
(
git_vector_init
(
&
wf
->
entries
,
0
,
entry_compare
)
!=
0
)
{
git__free
(
wf
);
git__free
(
wf
);
return
NULL
;
return
NULL
;
}
}
return
wf
;
return
wf
;
}
}
...
@@ -530,16 +561,32 @@ static void workdir_iterator__free_frame(workdir_iterator_frame *wf)
...
@@ -530,16 +561,32 @@ static void workdir_iterator__free_frame(workdir_iterator_frame *wf)
static
int
workdir_iterator__update_entry
(
workdir_iterator
*
wi
);
static
int
workdir_iterator__update_entry
(
workdir_iterator
*
wi
);
static
int
workdir_iterator__entry_cmp_case
(
const
void
*
p
refi
x
,
const
void
*
item
)
static
int
workdir_iterator__entry_cmp_case
(
const
void
*
p
f
x
,
const
void
*
item
)
{
{
const
git_path_with_stat
*
ps
=
item
;
const
git_path_with_stat
*
ps
=
item
;
return
git__prefixcmp
((
const
char
*
)
p
refi
x
,
ps
->
path
);
return
git__prefixcmp
((
const
char
*
)
p
f
x
,
ps
->
path
);
}
}
static
int
workdir_iterator__entry_cmp_icase
(
const
void
*
p
refi
x
,
const
void
*
item
)
static
int
workdir_iterator__entry_cmp_icase
(
const
void
*
p
f
x
,
const
void
*
item
)
{
{
const
git_path_with_stat
*
ps
=
item
;
const
git_path_with_stat
*
ps
=
item
;
return
git__prefixcmp_icase
((
const
char
*
)
prefix
,
ps
->
path
);
return
git__prefixcmp_icase
((
const
char
*
)
pfx
,
ps
->
path
);
}
static
void
workdir_iterator__seek_frame_start
(
workdir_iterator
*
wi
,
workdir_iterator_frame
*
wf
)
{
if
(
!
wf
)
return
;
if
(
wi
->
base
.
start
)
git_vector_bsearch3
(
&
wf
->
index
,
&
wf
->
entries
,
wi
->
entrycmp
,
wi
->
base
.
start
);
else
wf
->
index
=
0
;
if
(
path_is_dotgit
(
git_vector_get
(
&
wf
->
entries
,
wf
->
index
)))
wf
->
index
++
;
}
}
static
int
workdir_iterator__expand_dir
(
workdir_iterator
*
wi
)
static
int
workdir_iterator__expand_dir
(
workdir_iterator
*
wi
)
...
@@ -548,39 +595,26 @@ static int workdir_iterator__expand_dir(workdir_iterator *wi)
...
@@ -548,39 +595,26 @@ static int workdir_iterator__expand_dir(workdir_iterator *wi)
workdir_iterator_frame
*
wf
=
workdir_iterator__alloc_frame
(
wi
);
workdir_iterator_frame
*
wf
=
workdir_iterator__alloc_frame
(
wi
);
GITERR_CHECK_ALLOC
(
wf
);
GITERR_CHECK_ALLOC
(
wf
);
error
=
git_path_dirload_with_stat
(
wi
->
path
.
ptr
,
wi
->
root_len
,
&
wf
->
entries
);
error
=
git_path_dirload_with_stat
(
wi
->
path
.
ptr
,
wi
->
root_len
,
wi
->
base
.
ignore_case
,
wi
->
base
.
start
,
wi
->
base
.
end
,
&
wf
->
entries
);
if
(
error
<
0
||
wf
->
entries
.
length
==
0
)
{
if
(
error
<
0
||
wf
->
entries
.
length
==
0
)
{
workdir_iterator__free_frame
(
wf
);
workdir_iterator__free_frame
(
wf
);
return
GIT_ENOTFOUND
;
return
GIT_ENOTFOUND
;
}
}
git_vector_sort
(
&
wf
->
entries
);
workdir_iterator__seek_frame_start
(
wi
,
wf
);
if
(
!
wi
->
stack
)
wf
->
start
=
wi
->
base
.
start
;
else
if
(
wi
->
stack
->
start
&&
ITERATOR_PREFIXCMP
(
wi
->
base
,
wi
->
stack
->
start
,
wi
->
path
.
ptr
+
wi
->
root_len
)
==
0
)
wf
->
start
=
wi
->
stack
->
start
;
if
(
wf
->
start
)
git_vector_bsearch3
(
&
wf
->
index
,
&
wf
->
entries
,
CASESELECT
(
wi
->
base
.
ignore_case
,
workdir_iterator__entry_cmp_icase
,
workdir_iterator__entry_cmp_case
),
wf
->
start
);
if
(
path_is_dotgit
(
git_vector_get
(
&
wf
->
entries
,
wf
->
index
)))
wf
->
index
++
;
wf
->
next
=
wi
->
stack
;
wi
->
stack
=
wf
;
/* only push new ignores if this is not top level directory */
/* only push new ignores if this is not top level directory */
if
(
wi
->
stack
->
next
!=
NULL
)
{
if
(
wi
->
stack
!=
NULL
)
{
ssize_t
slash_pos
=
git_buf_rfind_next
(
&
wi
->
path
,
'/'
);
ssize_t
slash_pos
=
git_buf_rfind_next
(
&
wi
->
path
,
'/'
);
(
void
)
git_ignore__push_dir
(
&
wi
->
ignores
,
&
wi
->
path
.
ptr
[
slash_pos
+
1
]);
(
void
)
git_ignore__push_dir
(
&
wi
->
ignores
,
&
wi
->
path
.
ptr
[
slash_pos
+
1
]);
}
}
wf
->
next
=
wi
->
stack
;
wi
->
stack
=
wf
;
return
workdir_iterator__update_entry
(
wi
);
return
workdir_iterator__update_entry
(
wi
);
}
}
...
@@ -611,8 +645,10 @@ static int workdir_iterator__advance(
...
@@ -611,8 +645,10 @@ static int workdir_iterator__advance(
if
(
wi
->
entry
.
path
==
NULL
)
if
(
wi
->
entry
.
path
==
NULL
)
return
0
;
return
0
;
while
((
wf
=
wi
->
stack
)
!=
NULL
)
{
while
(
1
)
{
wf
=
wi
->
stack
;
next
=
git_vector_get
(
&
wf
->
entries
,
++
wf
->
index
);
next
=
git_vector_get
(
&
wf
->
entries
,
++
wf
->
index
);
if
(
next
!=
NULL
)
{
if
(
next
!=
NULL
)
{
/* match git's behavior of ignoring anything named ".git" */
/* match git's behavior of ignoring anything named ".git" */
if
(
path_is_dotgit
(
next
))
if
(
path_is_dotgit
(
next
))
...
@@ -621,15 +657,15 @@ static int workdir_iterator__advance(
...
@@ -621,15 +657,15 @@ static int workdir_iterator__advance(
break
;
break
;
}
}
/* pop workdir directory stack */
/* pop stack if anything is left to pop */
wi
->
stack
=
wf
->
next
;
if
(
!
wf
->
next
)
{
workdir_iterator__free_frame
(
wf
);
git_ignore__pop_dir
(
&
wi
->
ignores
);
if
(
wi
->
stack
==
NULL
)
{
memset
(
&
wi
->
entry
,
0
,
sizeof
(
wi
->
entry
));
memset
(
&
wi
->
entry
,
0
,
sizeof
(
wi
->
entry
));
return
0
;
return
0
;
}
}
wi
->
stack
=
wf
->
next
;
workdir_iterator__free_frame
(
wf
);
git_ignore__pop_dir
(
&
wi
->
ignores
);
}
}
error
=
workdir_iterator__update_entry
(
wi
);
error
=
workdir_iterator__update_entry
(
wi
);
...
@@ -650,18 +686,24 @@ static int workdir_iterator__seek(git_iterator *self, const char *prefix)
...
@@ -650,18 +686,24 @@ static int workdir_iterator__seek(git_iterator *self, const char *prefix)
return
0
;
return
0
;
}
}
static
int
workdir_iterator__reset
(
git_iterator
*
self
)
static
int
workdir_iterator__reset
(
git_iterator
*
self
,
const
char
*
start
,
const
char
*
end
)
{
{
workdir_iterator
*
wi
=
(
workdir_iterator
*
)
self
;
workdir_iterator
*
wi
=
(
workdir_iterator
*
)
self
;
while
(
wi
->
stack
!=
NULL
&&
wi
->
stack
->
next
!=
NULL
)
{
while
(
wi
->
stack
!=
NULL
&&
wi
->
stack
->
next
!=
NULL
)
{
workdir_iterator_frame
*
wf
=
wi
->
stack
;
workdir_iterator_frame
*
wf
=
wi
->
stack
;
wi
->
stack
=
wf
->
next
;
wi
->
stack
=
wf
->
next
;
workdir_iterator__free_frame
(
wf
);
workdir_iterator__free_frame
(
wf
);
git_ignore__pop_dir
(
&
wi
->
ignores
);
git_ignore__pop_dir
(
&
wi
->
ignores
);
}
}
if
(
wi
->
stack
)
wi
->
stack
->
index
=
0
;
if
(
iterator__reset_range
(
self
,
start
,
end
)
<
0
)
return
0
;
return
-
1
;
workdir_iterator__seek_frame_start
(
wi
,
wi
->
stack
);
return
workdir_iterator__update_entry
(
wi
);
}
}
static
void
workdir_iterator__free
(
git_iterator
*
self
)
static
void
workdir_iterator__free
(
git_iterator
*
self
)
...
@@ -680,7 +722,8 @@ static void workdir_iterator__free(git_iterator *self)
...
@@ -680,7 +722,8 @@ static void workdir_iterator__free(git_iterator *self)
static
int
workdir_iterator__update_entry
(
workdir_iterator
*
wi
)
static
int
workdir_iterator__update_entry
(
workdir_iterator
*
wi
)
{
{
git_path_with_stat
*
ps
=
git_vector_get
(
&
wi
->
stack
->
entries
,
wi
->
stack
->
index
);
git_path_with_stat
*
ps
=
git_vector_get
(
&
wi
->
stack
->
entries
,
wi
->
stack
->
index
);
git_buf_truncate
(
&
wi
->
path
,
wi
->
root_len
);
git_buf_truncate
(
&
wi
->
path
,
wi
->
root_len
);
memset
(
&
wi
->
entry
,
0
,
sizeof
(
wi
->
entry
));
memset
(
&
wi
->
entry
,
0
,
sizeof
(
wi
->
entry
));
...
@@ -691,8 +734,8 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
...
@@ -691,8 +734,8 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
if
(
git_buf_put
(
&
wi
->
path
,
ps
->
path
,
ps
->
path_len
)
<
0
)
if
(
git_buf_put
(
&
wi
->
path
,
ps
->
path
,
ps
->
path_len
)
<
0
)
return
-
1
;
return
-
1
;
if
(
wi
->
base
.
end
&&
if
(
wi
->
base
.
end
&&
ITERATOR_PREFIXCMP
(
ITERATOR_PREFIXCMP
(
wi
->
base
,
wi
->
path
.
ptr
+
wi
->
root_len
,
wi
->
base
.
end
)
>
0
)
wi
->
base
,
wi
->
path
.
ptr
+
wi
->
root_len
,
wi
->
base
.
end
)
>
0
)
return
0
;
return
0
;
wi
->
entry
.
path
=
ps
->
path
;
wi
->
entry
.
path
=
ps
->
path
;
...
@@ -716,7 +759,7 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
...
@@ -716,7 +759,7 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
/* detect submodules */
/* detect submodules */
if
(
S_ISDIR
(
wi
->
entry
.
mode
))
{
if
(
S_ISDIR
(
wi
->
entry
.
mode
))
{
int
res
=
git_submodule_lookup
(
NULL
,
wi
->
repo
,
wi
->
entry
.
path
);
int
res
=
git_submodule_lookup
(
NULL
,
wi
->
base
.
repo
,
wi
->
entry
.
path
);
bool
is_submodule
=
(
res
==
0
);
bool
is_submodule
=
(
res
==
0
);
if
(
res
==
GIT_ENOTFOUND
)
if
(
res
==
GIT_ENOTFOUND
)
giterr_clear
();
giterr_clear
();
...
@@ -750,10 +793,10 @@ int git_iterator_for_workdir_range(
...
@@ -750,10 +793,10 @@ int git_iterator_for_workdir_range(
return
error
;
return
error
;
ITERATOR_BASE_INIT
(
wi
,
workdir
,
WORKDIR
);
ITERATOR_BASE_INIT
(
wi
,
workdir
,
WORKDIR
);
wi
->
repo
=
repo
;
wi
->
base
.
repo
=
repo
;
if
((
error
=
git_repository_index__weakptr
(
&
index
,
repo
))
<
0
)
{
if
((
error
=
git_repository_index__weakptr
(
&
index
,
repo
))
<
0
)
{
git_
_free
(
wi
);
git_
iterator_free
((
git_iterator
*
)
wi
);
return
error
;
return
error
;
}
}
...
@@ -769,6 +812,8 @@ int git_iterator_for_workdir_range(
...
@@ -769,6 +812,8 @@ int git_iterator_for_workdir_range(
}
}
wi
->
root_len
=
wi
->
path
.
size
;
wi
->
root_len
=
wi
->
path
.
size
;
wi
->
entrycmp
=
wi
->
base
.
ignore_case
?
workdir_iterator__entry_cmp_icase
:
workdir_iterator__entry_cmp_case
;
if
((
error
=
workdir_iterator__expand_dir
(
wi
))
<
0
)
{
if
((
error
=
workdir_iterator__expand_dir
(
wi
))
<
0
)
{
if
(
error
==
GIT_ENOTFOUND
)
if
(
error
==
GIT_ENOTFOUND
)
...
@@ -837,10 +882,13 @@ static int spoolandsort_iterator__seek(git_iterator *self, const char *prefix)
...
@@ -837,10 +882,13 @@ static int spoolandsort_iterator__seek(git_iterator *self, const char *prefix)
return
-
1
;
return
-
1
;
}
}
static
int
spoolandsort_iterator__reset
(
git_iterator
*
self
)
static
int
spoolandsort_iterator__reset
(
git_iterator
*
self
,
const
char
*
start
,
const
char
*
end
)
{
{
spoolandsort_iterator
*
si
=
(
spoolandsort_iterator
*
)
self
;
spoolandsort_iterator
*
si
=
(
spoolandsort_iterator
*
)
self
;
GIT_UNUSED
(
start
);
GIT_UNUSED
(
end
);
si
->
position
=
0
;
si
->
position
=
0
;
return
0
;
return
0
;
...
...
src/iterator.h
View file @
55325efa
...
@@ -28,32 +28,33 @@ typedef enum {
...
@@ -28,32 +28,33 @@ typedef enum {
struct
git_iterator
{
struct
git_iterator
{
git_iterator_type_t
type
;
git_iterator_type_t
type
;
git_repository
*
repo
;
char
*
start
;
char
*
start
;
char
*
end
;
char
*
end
;
bool
ignore_case
;
int
(
*
current
)(
git_iterator
*
,
const
git_index_entry
**
);
int
(
*
current
)(
git_iterator
*
,
const
git_index_entry
**
);
int
(
*
at_end
)(
git_iterator
*
);
int
(
*
at_end
)(
git_iterator
*
);
int
(
*
advance
)(
git_iterator
*
,
const
git_index_entry
**
);
int
(
*
advance
)(
git_iterator
*
,
const
git_index_entry
**
);
int
(
*
seek
)(
git_iterator
*
,
const
char
*
prefix
);
int
(
*
seek
)(
git_iterator
*
,
const
char
*
prefix
);
int
(
*
reset
)(
git_iterator
*
);
int
(
*
reset
)(
git_iterator
*
,
const
char
*
start
,
const
char
*
end
);
void
(
*
free
)(
git_iterator
*
);
void
(
*
free
)(
git_iterator
*
);
unsigned
int
ignore_case
:
1
;
};
};
extern
int
git_iterator_for_nothing
(
git_iterator
**
iter
);
extern
int
git_iterator_for_nothing
(
git_iterator
**
iter
);
extern
int
git_iterator_for_tree_range
(
extern
int
git_iterator_for_tree_range
(
git_iterator
**
iter
,
git_
repository
*
repo
,
git_
tree
*
tree
,
git_iterator
**
iter
,
git_tree
*
tree
,
const
char
*
start
,
const
char
*
end
);
const
char
*
start
,
const
char
*
end
);
GIT_INLINE
(
int
)
git_iterator_for_tree
(
GIT_INLINE
(
int
)
git_iterator_for_tree
(
git_iterator
**
iter
,
git_
repository
*
repo
,
git_
tree
*
tree
)
git_iterator
**
iter
,
git_tree
*
tree
)
{
{
return
git_iterator_for_tree_range
(
iter
,
repo
,
tree
,
NULL
,
NULL
);
return
git_iterator_for_tree_range
(
iter
,
tree
,
NULL
,
NULL
);
}
}
extern
int
git_iterator_for_index_range
(
extern
int
git_iterator_for_index_range
(
git_iterator
**
iter
,
git_index
*
index
,
git_iterator
**
iter
,
git_index
*
index
,
const
char
*
start
,
const
char
*
end
);
const
char
*
start
,
const
char
*
end
);
GIT_INLINE
(
int
)
git_iterator_for_index
(
GIT_INLINE
(
int
)
git_iterator_for_index
(
git_iterator
**
iter
,
git_index
*
index
)
git_iterator
**
iter
,
git_index
*
index
)
...
@@ -90,7 +91,8 @@ GIT_INLINE(int) git_iterator_spoolandsort(
...
@@ -90,7 +91,8 @@ GIT_INLINE(int) git_iterator_spoolandsort(
git_iterator
**
iter
,
git_iterator
*
towrap
,
git_iterator
**
iter
,
git_iterator
*
towrap
,
git_vector_cmp
comparer
,
bool
ignore_case
)
git_vector_cmp
comparer
,
bool
ignore_case
)
{
{
return
git_iterator_spoolandsort_range
(
iter
,
towrap
,
comparer
,
ignore_case
,
NULL
,
NULL
);
return
git_iterator_spoolandsort_range
(
iter
,
towrap
,
comparer
,
ignore_case
,
NULL
,
NULL
);
}
}
/* Entry is not guaranteed to be fully populated. For a tree iterator,
/* Entry is not guaranteed to be fully populated. For a tree iterator,
...
@@ -124,9 +126,10 @@ GIT_INLINE(int) git_iterator_seek(
...
@@ -124,9 +126,10 @@ GIT_INLINE(int) git_iterator_seek(
return
iter
->
seek
(
iter
,
prefix
);
return
iter
->
seek
(
iter
,
prefix
);
}
}
GIT_INLINE
(
int
)
git_iterator_reset
(
git_iterator
*
iter
)
GIT_INLINE
(
int
)
git_iterator_reset
(
git_iterator
*
iter
,
const
char
*
start
,
const
char
*
end
)
{
{
return
iter
->
reset
(
iter
);
return
iter
->
reset
(
iter
,
start
,
end
);
}
}
GIT_INLINE
(
void
)
git_iterator_free
(
git_iterator
*
iter
)
GIT_INLINE
(
void
)
git_iterator_free
(
git_iterator
*
iter
)
...
@@ -149,6 +152,11 @@ GIT_INLINE(git_iterator_type_t) git_iterator_type(git_iterator *iter)
...
@@ -149,6 +152,11 @@ GIT_INLINE(git_iterator_type_t) git_iterator_type(git_iterator *iter)
return
iter
->
type
;
return
iter
->
type
;
}
}
GIT_INLINE
(
git_repository
*
)
git_iterator_owner
(
git_iterator
*
iter
)
{
return
iter
->
repo
;
}
extern
int
git_iterator_current_tree_entry
(
extern
int
git_iterator_current_tree_entry
(
git_iterator
*
iter
,
const
git_tree_entry
**
tree_entry
);
git_iterator
*
iter
,
const
git_tree_entry
**
tree_entry
);
...
...
src/notes.c
View file @
55325efa
...
@@ -593,7 +593,7 @@ int git_note_foreach(
...
@@ -593,7 +593,7 @@ int git_note_foreach(
if
(
!
(
error
=
retrieve_note_tree_and_commit
(
if
(
!
(
error
=
retrieve_note_tree_and_commit
(
&
tree
,
&
commit
,
repo
,
&
notes_ref
))
&&
&
tree
,
&
commit
,
repo
,
&
notes_ref
))
&&
!
(
error
=
git_iterator_for_tree
(
&
iter
,
repo
,
tree
)))
!
(
error
=
git_iterator_for_tree
(
&
iter
,
tree
)))
error
=
git_iterator_current
(
iter
,
&
item
);
error
=
git_iterator_current
(
iter
,
&
item
);
while
(
!
error
&&
item
)
{
while
(
!
error
&&
item
)
{
...
...
src/path.c
View file @
55325efa
...
@@ -770,18 +770,30 @@ int git_path_dirload(
...
@@ -770,18 +770,30 @@ int git_path_dirload(
int
git_path_with_stat_cmp
(
const
void
*
a
,
const
void
*
b
)
int
git_path_with_stat_cmp
(
const
void
*
a
,
const
void
*
b
)
{
{
const
git_path_with_stat
*
psa
=
a
,
*
psb
=
b
;
const
git_path_with_stat
*
psa
=
a
,
*
psb
=
b
;
return
git__strcmp_cb
(
psa
->
path
,
psb
->
path
);
return
strcmp
(
psa
->
path
,
psb
->
path
);
}
int
git_path_with_stat_cmp_icase
(
const
void
*
a
,
const
void
*
b
)
{
const
git_path_with_stat
*
psa
=
a
,
*
psb
=
b
;
return
strcasecmp
(
psa
->
path
,
psb
->
path
);
}
}
int
git_path_dirload_with_stat
(
int
git_path_dirload_with_stat
(
const
char
*
path
,
const
char
*
path
,
size_t
prefix_len
,
size_t
prefix_len
,
bool
ignore_case
,
const
char
*
start_stat
,
const
char
*
end_stat
,
git_vector
*
contents
)
git_vector
*
contents
)
{
{
int
error
;
int
error
;
unsigned
int
i
;
unsigned
int
i
;
git_path_with_stat
*
ps
;
git_path_with_stat
*
ps
;
git_buf
full
=
GIT_BUF_INIT
;
git_buf
full
=
GIT_BUF_INIT
;
int
(
*
strncomp
)(
const
char
*
a
,
const
char
*
b
,
size_t
sz
);
size_t
start_len
=
start_stat
?
strlen
(
start_stat
)
:
0
;
size_t
end_len
=
end_stat
?
strlen
(
end_stat
)
:
0
,
cmp_len
;
if
(
git_buf_set
(
&
full
,
path
,
prefix_len
)
<
0
)
if
(
git_buf_set
(
&
full
,
path
,
prefix_len
)
<
0
)
return
-
1
;
return
-
1
;
...
@@ -793,11 +805,23 @@ int git_path_dirload_with_stat(
...
@@ -793,11 +805,23 @@ int git_path_dirload_with_stat(
return
error
;
return
error
;
}
}
strncomp
=
ignore_case
?
git__strncasecmp
:
git__strncmp
;
/* stat struct at start of git_path_with_stat, so shift path text */
git_vector_foreach
(
contents
,
i
,
ps
)
{
git_vector_foreach
(
contents
,
i
,
ps
)
{
size_t
path_len
=
strlen
((
char
*
)
ps
);
size_t
path_len
=
strlen
((
char
*
)
ps
);
memmove
(
ps
->
path
,
ps
,
path_len
+
1
);
memmove
(
ps
->
path
,
ps
,
path_len
+
1
);
ps
->
path_len
=
path_len
;
ps
->
path_len
=
path_len
;
}
git_vector_foreach
(
contents
,
i
,
ps
)
{
/* skip if before start_stat or after end_stat */
cmp_len
=
min
(
start_len
,
ps
->
path_len
);
if
(
cmp_len
&&
strncomp
(
ps
->
path
,
start_stat
,
cmp_len
)
<
0
)
continue
;
cmp_len
=
min
(
end_len
,
ps
->
path_len
);
if
(
cmp_len
&&
strncomp
(
ps
->
path
,
end_stat
,
cmp_len
)
>
0
)
continue
;
if
((
error
=
git_buf_joinpath
(
&
full
,
full
.
ptr
,
ps
->
path
))
<
0
||
if
((
error
=
git_buf_joinpath
(
&
full
,
full
.
ptr
,
ps
->
path
))
<
0
||
(
error
=
git_path_lstat
(
full
.
ptr
,
&
ps
->
st
))
<
0
)
(
error
=
git_path_lstat
(
full
.
ptr
,
&
ps
->
st
))
<
0
)
...
@@ -806,11 +830,14 @@ int git_path_dirload_with_stat(
...
@@ -806,11 +830,14 @@ int git_path_dirload_with_stat(
git_buf_truncate
(
&
full
,
prefix_len
);
git_buf_truncate
(
&
full
,
prefix_len
);
if
(
S_ISDIR
(
ps
->
st
.
st_mode
))
{
if
(
S_ISDIR
(
ps
->
st
.
st_mode
))
{
ps
->
path
[
p
ath_len
]
=
'/'
;
ps
->
path
[
p
s
->
path_len
++
]
=
'/'
;
ps
->
path
[
p
ath_len
+
1
]
=
'\0'
;
ps
->
path
[
p
s
->
path_len
]
=
'\0'
;
}
}
}
}
/* sort now that directory suffix is added */
git_vector_sort
(
contents
);
git_buf_free
(
&
full
);
git_buf_free
(
&
full
);
return
error
;
return
error
;
...
...
src/path.h
View file @
55325efa
...
@@ -321,18 +321,33 @@ typedef struct {
...
@@ -321,18 +321,33 @@ typedef struct {
}
git_path_with_stat
;
}
git_path_with_stat
;
extern
int
git_path_with_stat_cmp
(
const
void
*
a
,
const
void
*
b
);
extern
int
git_path_with_stat_cmp
(
const
void
*
a
,
const
void
*
b
);
extern
int
git_path_with_stat_cmp_icase
(
const
void
*
a
,
const
void
*
b
);
/**
/**
* Load all directory entries along with stat info into a vector.
* Load all directory entries along with stat info into a vector.
*
*
* This is just like git_path_dirload except that each entry in the
* This adds four things on top of plain `git_path_dirload`:
* vector is a git_path_with_stat structure that contains both the
*
* path and the stat info, plus directories will have a / suffixed
* 1. Each entry in the vector is a `git_path_with_stat` struct that
* to their path name.
* contains both the path and the stat info
* 2. The entries will be sorted alphabetically
* 3. Entries that are directories will be suffixed with a '/'
* 4. Optionally, you can be a start and end prefix and only elements
* after the start and before the end (inclusively) will be stat'ed.
*
* @param path The directory to read from
* @param prefix_len The trailing part of path to prefix to entry paths
* @param ignore_case How to sort and compare paths with start/end limits
* @param start_stat As optimization, only stat values after this prefix
* @param end_stat As optimization, only stat values before this prefix
* @param contents Vector to fill with git_path_with_stat structures
*/
*/
extern
int
git_path_dirload_with_stat
(
extern
int
git_path_dirload_with_stat
(
const
char
*
path
,
const
char
*
path
,
size_t
prefix_len
,
size_t
prefix_len
,
bool
ignore_case
,
const
char
*
start_stat
,
const
char
*
end_stat
,
git_vector
*
contents
);
git_vector
*
contents
);
#endif
#endif
src/submodule.c
View file @
55325efa
...
@@ -1156,7 +1156,7 @@ static int load_submodule_config_from_head(
...
@@ -1156,7 +1156,7 @@ static int load_submodule_config_from_head(
if
((
error
=
git_repository_head_tree
(
&
head
,
repo
))
<
0
)
if
((
error
=
git_repository_head_tree
(
&
head
,
repo
))
<
0
)
return
error
;
return
error
;
if
((
error
=
git_iterator_for_tree
(
&
i
,
repo
,
head
))
<
0
)
{
if
((
error
=
git_iterator_for_tree
(
&
i
,
head
))
<
0
)
{
git_tree_free
(
head
);
git_tree_free
(
head
);
return
error
;
return
error
;
}
}
...
...
src/tree.c
View file @
55325efa
...
@@ -207,9 +207,14 @@ void git_tree__free(git_tree *tree)
...
@@ -207,9 +207,14 @@ void git_tree__free(git_tree *tree)
git__free
(
tree
);
git__free
(
tree
);
}
}
const
git_oid
*
git_tree_id
(
const
git_tree
*
c
)
const
git_oid
*
git_tree_id
(
const
git_tree
*
t
)
{
{
return
git_object_id
((
const
git_object
*
)
c
);
return
git_object_id
((
const
git_object
*
)
t
);
}
git_repository
*
git_tree_owner
(
const
git_tree
*
t
)
{
return
git_object_owner
((
const
git_object
*
)
t
);
}
}
git_filemode_t
git_tree_entry_filemode
(
const
git_tree_entry
*
entry
)
git_filemode_t
git_tree_entry_filemode
(
const
git_tree_entry
*
entry
)
...
@@ -296,6 +301,9 @@ int git_tree__prefix_position(git_tree *tree, const char *path)
...
@@ -296,6 +301,9 @@ int git_tree__prefix_position(git_tree *tree, const char *path)
struct
tree_key_search
ksearch
;
struct
tree_key_search
ksearch
;
size_t
at_pos
;
size_t
at_pos
;
if
(
!
path
)
return
0
;
ksearch
.
filename
=
path
;
ksearch
.
filename
=
path
;
ksearch
.
filename_len
=
strlen
(
path
);
ksearch
.
filename_len
=
strlen
(
path
);
...
...
src/tree.h
View file @
55325efa
...
@@ -29,6 +29,10 @@ struct git_treebuilder {
...
@@ -29,6 +29,10 @@ struct git_treebuilder {
git_vector
entries
;
git_vector
entries
;
};
};
GIT_INLINE
(
int
)
git_tree__dup
(
git_tree
**
dest
,
git_tree
*
source
)
{
return
git_object__dup
((
git_object
**
)
dest
,
(
git_object
*
)
source
);
}
GIT_INLINE
(
bool
)
git_tree_entry__is_tree
(
const
struct
git_tree_entry
*
e
)
GIT_INLINE
(
bool
)
git_tree_entry__is_tree
(
const
struct
git_tree_entry
*
e
)
{
{
...
...
src/util.c
View file @
55325efa
...
@@ -199,9 +199,17 @@ int git__strncmp(const char *a, const char *b, size_t sz)
...
@@ -199,9 +199,17 @@ int git__strncmp(const char *a, const char *b, size_t sz)
int
git__strncasecmp
(
const
char
*
a
,
const
char
*
b
,
size_t
sz
)
int
git__strncasecmp
(
const
char
*
a
,
const
char
*
b
,
size_t
sz
)
{
{
while
(
sz
&&
*
a
&&
*
b
&&
tolower
(
*
a
)
==
tolower
(
*
b
))
int
al
,
bl
;
while
(
sz
&&
*
a
&&
*
b
)
{
al
=
(
unsigned
char
)
tolower
(
*
a
);
bl
=
(
unsigned
char
)
tolower
(
*
b
);
if
(
al
!=
bl
)
break
;
--
sz
,
++
a
,
++
b
;
--
sz
,
++
a
,
++
b
;
return
!
sz
?
0
:
(
tolower
(
*
a
)
-
tolower
(
*
b
));
}
return
!
sz
?
0
:
al
-
bl
;
}
}
void
git__strntolower
(
char
*
str
,
size_t
len
)
void
git__strntolower
(
char
*
str
,
size_t
len
)
...
...
tests-clar/diff/iterator.c
View file @
55325efa
...
@@ -31,25 +31,35 @@ static void tree_iterator_test(
...
@@ -31,25 +31,35 @@ static void tree_iterator_test(
git_tree
*
t
;
git_tree
*
t
;
git_iterator
*
i
;
git_iterator
*
i
;
const
git_index_entry
*
entry
;
const
git_index_entry
*
entry
;
int
count
=
0
;
int
count
=
0
,
count_post_reset
=
0
;
git_repository
*
repo
=
cl_git_sandbox_init
(
sandbox
);
git_repository
*
repo
=
cl_git_sandbox_init
(
sandbox
);
cl_assert
(
t
=
resolve_commit_oid_to_tree
(
repo
,
treeish
));
cl_assert
(
t
=
resolve_commit_oid_to_tree
(
repo
,
treeish
));
cl_git_pass
(
git_iterator_for_tree_range
(
&
i
,
repo
,
t
,
start
,
end
));
cl_git_pass
(
git_iterator_for_tree_range
(
&
i
,
t
,
start
,
end
));
cl_git_pass
(
git_iterator_current
(
i
,
&
entry
));
/* test loop */
cl_git_pass
(
git_iterator_current
(
i
,
&
entry
));
while
(
entry
!=
NULL
)
{
while
(
entry
!=
NULL
)
{
if
(
expected_values
!=
NULL
)
if
(
expected_values
!=
NULL
)
cl_assert_equal_s
(
expected_values
[
count
],
entry
->
path
);
cl_assert_equal_s
(
expected_values
[
count
],
entry
->
path
);
count
++
;
count
++
;
cl_git_pass
(
git_iterator_advance
(
i
,
&
entry
));
}
/* test reset */
cl_git_pass
(
git_iterator_reset
(
i
,
NULL
,
NULL
));
cl_git_pass
(
git_iterator_current
(
i
,
&
entry
));
while
(
entry
!=
NULL
)
{
if
(
expected_values
!=
NULL
)
cl_assert_equal_s
(
expected_values
[
count_post_reset
],
entry
->
path
);
count_post_reset
++
;
cl_git_pass
(
git_iterator_advance
(
i
,
&
entry
));
cl_git_pass
(
git_iterator_advance
(
i
,
&
entry
));
}
}
git_iterator_free
(
i
);
git_iterator_free
(
i
);
cl_assert
(
expected_count
==
count
);
cl_assert_equal_i
(
expected_count
,
count
);
cl_assert_equal_i
(
count
,
count_post_reset
);
git_tree_free
(
t
);
git_tree_free
(
t
);
}
}
...
@@ -294,7 +304,7 @@ void test_diff_iterator__tree_special_functions(void)
...
@@ -294,7 +304,7 @@ void test_diff_iterator__tree_special_functions(void)
repo
,
"24fa9a9fc4e202313e24b648087495441dab432b"
);
repo
,
"24fa9a9fc4e202313e24b648087495441dab432b"
);
cl_assert
(
t
!=
NULL
);
cl_assert
(
t
!=
NULL
);
cl_git_pass
(
git_iterator_for_tree_range
(
&
i
,
repo
,
t
,
NULL
,
NULL
));
cl_git_pass
(
git_iterator_for_tree_range
(
&
i
,
t
,
NULL
,
NULL
));
cl_git_pass
(
git_iterator_current
(
i
,
&
entry
));
cl_git_pass
(
git_iterator_current
(
i
,
&
entry
));
while
(
entry
!=
NULL
)
{
while
(
entry
!=
NULL
)
{
...
@@ -520,7 +530,7 @@ static void workdir_iterator_test(
...
@@ -520,7 +530,7 @@ static void workdir_iterator_test(
{
{
git_iterator
*
i
;
git_iterator
*
i
;
const
git_index_entry
*
entry
;
const
git_index_entry
*
entry
;
int
count
=
0
,
count_all
=
0
;
int
count
=
0
,
count_all
=
0
,
count_all_post_reset
=
0
;
git_repository
*
repo
=
cl_git_sandbox_init
(
sandbox
);
git_repository
*
repo
=
cl_git_sandbox_init
(
sandbox
);
cl_git_pass
(
git_iterator_for_workdir_range
(
&
i
,
repo
,
start
,
end
));
cl_git_pass
(
git_iterator_for_workdir_range
(
&
i
,
repo
,
start
,
end
));
...
@@ -547,10 +557,26 @@ static void workdir_iterator_test(
...
@@ -547,10 +557,26 @@ static void workdir_iterator_test(
cl_git_pass
(
git_iterator_advance
(
i
,
&
entry
));
cl_git_pass
(
git_iterator_advance
(
i
,
&
entry
));
}
}
cl_git_pass
(
git_iterator_reset
(
i
,
NULL
,
NULL
));
cl_git_pass
(
git_iterator_current
(
i
,
&
entry
));
while
(
entry
!=
NULL
)
{
if
(
S_ISDIR
(
entry
->
mode
))
{
cl_git_pass
(
git_iterator_advance_into_directory
(
i
,
&
entry
));
continue
;
}
if
(
expected_names
!=
NULL
)
cl_assert_equal_s
(
expected_names
[
count_all_post_reset
],
entry
->
path
);
count_all_post_reset
++
;
cl_git_pass
(
git_iterator_advance
(
i
,
&
entry
));
}
git_iterator_free
(
i
);
git_iterator_free
(
i
);
cl_assert_equal_i
(
expected_count
,
count
);
cl_assert_equal_i
(
expected_count
,
count
);
cl_assert_equal_i
(
expected_count
+
expected_ignores
,
count_all
);
cl_assert_equal_i
(
expected_count
+
expected_ignores
,
count_all
);
cl_assert_equal_i
(
count_all
,
count_all_post_reset
);
}
}
void
test_diff_iterator__workdir_0
(
void
)
void
test_diff_iterator__workdir_0
(
void
)
...
...
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