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
0e2fcca8
Commit
0e2fcca8
authored
Jun 29, 2012
by
Vicent Marti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tree: Bring back `entry_bypath`
Smaller, simpler, faster.
parent
cbc02c10
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
223 additions
and
164 deletions
+223
-164
include/git2/tree.h
+53
-14
src/index.c
+1
-1
src/notes.c
+1
-1
src/tree.c
+135
-100
src/tree.h
+3
-3
tests-clar/object/tree/frompath.c
+30
-45
No files found.
include/git2/tree.h
View file @
0e2fcca8
...
...
@@ -46,7 +46,11 @@ GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git
* @param len the length of the short identifier
* @return 0 or an error code
*/
GIT_INLINE
(
int
)
git_tree_lookup_prefix
(
git_tree
**
tree
,
git_repository
*
repo
,
const
git_oid
*
id
,
unsigned
int
len
)
GIT_INLINE
(
int
)
git_tree_lookup_prefix
(
git_tree
**
tree
,
git_repository
*
repo
,
const
git_oid
*
id
,
unsigned
int
len
)
{
return
git_object_lookup_prefix
((
git_object
**
)
tree
,
repo
,
id
,
len
,
GIT_OBJ_TREE
);
}
...
...
@@ -62,12 +66,33 @@ GIT_INLINE(int) git_tree_lookup_prefix(git_tree **tree, git_repository *repo, co
*
* @param tree the tree to close
*/
GIT_INLINE
(
void
)
git_tree_free
(
git_tree
*
tree
)
{
git_object_free
((
git_object
*
)
tree
);
}
/**
* Free a tree entry
*
* IMPORTANT: This function is only needed for tree
* entries owned by the user, such as the ones returned
* by `git_tree_entry_copy`.
*
* @param entry The entry to free
*/
GIT_EXTERN
(
void
)
git_tree_entry_free
(
git_tree_entry
*
entry
);
/**
* Duplicate a tree entry
*
* Create a copy of a tree entry. The returned copy is owned
* by the user, and must be freed manually with
* `git_tree_entry_free`.
*
* @param entry A tree entry to duplicate
* @return a copy of the original entry
*/
GIT_EXTERN
(
git_tree_entry
*
)
git_tree_entry_copy
(
const
git_tree_entry
*
entry
);
/**
* Get the id of a tree.
...
...
@@ -143,7 +168,10 @@ GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry);
* @param entry a tree entry
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_tree_entry_to_object
(
git_object
**
object_out
,
git_repository
*
repo
,
const
git_tree_entry
*
entry
);
GIT_EXTERN
(
int
)
git_tree_entry_to_object
(
git_object
**
object_out
,
git_repository
*
repo
,
const
git_tree_entry
*
entry
);
/**
* Write a tree to the ODB from the index file
...
...
@@ -231,7 +259,12 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, con
* @param attributes Folder attributes of the entry
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_treebuilder_insert
(
git_tree_entry
**
entry_out
,
git_treebuilder
*
bld
,
const
char
*
filename
,
const
git_oid
*
id
,
unsigned
int
attributes
);
GIT_EXTERN
(
int
)
git_treebuilder_insert
(
const
git_tree_entry
**
entry_out
,
git_treebuilder
*
bld
,
const
char
*
filename
,
const
git_oid
*
id
,
unsigned
int
attributes
);
/**
* Remove an entry from the builder by its filename
...
...
@@ -252,7 +285,10 @@ GIT_EXTERN(int) git_treebuilder_remove(git_treebuilder *bld, const char *filenam
* @param bld Tree builder
* @param filter Callback to filter entries
*/
GIT_EXTERN
(
void
)
git_treebuilder_filter
(
git_treebuilder
*
bld
,
int
(
*
filter
)(
const
git_tree_entry
*
,
void
*
),
void
*
payload
);
GIT_EXTERN
(
void
)
git_treebuilder_filter
(
git_treebuilder
*
bld
,
int
(
*
filter
)(
const
git_tree_entry
*
,
void
*
),
void
*
payload
);
/**
* Write the contents of the tree builder as a tree object
...
...
@@ -269,21 +305,24 @@ GIT_EXTERN(void) git_treebuilder_filter(git_treebuilder *bld, int (*filter)(cons
GIT_EXTERN
(
int
)
git_treebuilder_write
(
git_oid
*
oid
,
git_repository
*
repo
,
git_treebuilder
*
bld
);
/**
* Retrieve a
subtree contained in a tree, given its
* relative path.
* Retrieve a
tree entry contained in a tree or in any
*
of its subtrees, given its
relative path.
*
* The returned tree
is owned by the repository and
*
should be closed with the `git_object_free` method
.
* The returned tree
entry is owned by the user and must
*
be freed manually with `git_tree_entry_free`
.
*
* @param
subtree Pointer where to store the subtree
* @param
entry Pointer where to store the tree entry
* @param root A previously loaded tree which will be the root of the relative path
* @param subtree_path Path to the contained
subtree
* @return 0 on success; GIT_ENOTFOUND if the path does not
lead to a subtree
* @param subtree_path Path to the contained
entry
* @return 0 on success; GIT_ENOTFOUND if the path does not
exist
*/
GIT_EXTERN
(
int
)
git_tree_get_subtree
(
git_tree
**
subtree
,
git_tree
*
root
,
const
char
*
subtree_path
);
GIT_EXTERN
(
int
)
git_tree_entry_bypath
(
git_tree_entry
**
entry
,
git_tree
*
root
,
const
char
*
path
);
/** Callback for the tree traversal method */
typedef
int
(
*
git_treewalk_cb
)(
const
char
*
root
,
git_tree_entry
*
entry
,
void
*
payload
);
typedef
int
(
*
git_treewalk_cb
)(
const
char
*
root
,
const
git_tree_entry
*
entry
,
void
*
payload
);
/** Tree traversal modes */
enum
git_treewalk_mode
{
...
...
src/index.c
View file @
0e2fcca8
...
...
@@ -985,7 +985,7 @@ int git_index_entry_stage(const git_index_entry *entry)
return
(
entry
->
flags
&
GIT_IDXENTRY_STAGEMASK
)
>>
GIT_IDXENTRY_STAGESHIFT
;
}
static
int
read_tree_cb
(
const
char
*
root
,
git_tree_entry
*
tentry
,
void
*
data
)
static
int
read_tree_cb
(
const
char
*
root
,
const
git_tree_entry
*
tentry
,
void
*
data
)
{
git_index
*
index
=
data
;
git_index_entry
*
entry
=
NULL
;
...
...
src/notes.c
View file @
0e2fcca8
...
...
@@ -97,7 +97,7 @@ static int tree_write(
{
int
error
;
git_treebuilder
*
tb
=
NULL
;
git_tree_entry
*
entry
;
const
git_tree_entry
*
entry
;
git_oid
tree_oid
;
if
((
error
=
git_treebuilder_create
(
&
tb
,
source_tree
))
<
0
)
...
...
src/tree.c
View file @
0e2fcca8
...
...
@@ -35,6 +35,22 @@ static int entry_sort_cmp(const void *a, const void *b)
entry_b
->
filename
,
entry_b
->
filename_len
,
git_tree_entry__is_tree
(
entry_b
));
}
static
git_tree_entry
*
alloc_entry
(
const
char
*
filename
)
{
git_tree_entry
*
entry
=
NULL
;
size_t
filename_len
=
strlen
(
filename
);
entry
=
git__malloc
(
sizeof
(
git_tree_entry
)
+
filename_len
+
1
);
if
(
!
entry
)
return
NULL
;
memset
(
entry
,
0x0
,
sizeof
(
git_tree_entry
));
memcpy
(
entry
->
filename
,
filename
,
filename_len
);
entry
->
filename
[
filename_len
]
=
0
;
entry
->
filename_len
=
filename_len
;
return
entry
;
}
struct
tree_key_search
{
const
char
*
filename
;
...
...
@@ -76,7 +92,7 @@ static int homing_search_cmp(const void *key, const void *array_member)
* ambiguous because of folder vs file sorting, we look linearly
* around the area for our target file.
*/
static
int
tree_key_search
(
git_vector
*
entries
,
const
char
*
filename
)
static
int
tree_key_search
(
git_vector
*
entries
,
const
char
*
filename
,
size_t
filename_len
)
{
struct
tree_key_search
ksearch
;
const
git_tree_entry
*
entry
;
...
...
@@ -84,7 +100,7 @@ static int tree_key_search(git_vector *entries, const char *filename)
int
homing
,
i
;
ksearch
.
filename
=
filename
;
ksearch
.
filename_len
=
strlen
(
filename
)
;
ksearch
.
filename_len
=
filename_len
;
/* Initial homing search; find an entry on the tree with
* the same prefix as the filename we're looking for */
...
...
@@ -100,7 +116,8 @@ static int tree_key_search(git_vector *entries, const char *filename)
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
<
0
)
break
;
if
(
strcmp
(
filename
,
entry
->
filename
)
==
0
)
if
(
entry
->
filename_len
==
filename_len
&&
memcmp
(
filename
,
entry
->
filename
,
filename_len
)
==
0
)
return
i
;
}
...
...
@@ -112,7 +129,8 @@ static int tree_key_search(git_vector *entries, const char *filename)
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
>
0
)
break
;
if
(
strcmp
(
filename
,
entry
->
filename
)
==
0
)
if
(
entry
->
filename_len
==
filename_len
&&
memcmp
(
filename
,
entry
->
filename
,
filename_len
)
==
0
)
return
i
;
}
...
...
@@ -120,16 +138,35 @@ static int tree_key_search(git_vector *entries, const char *filename)
return
GIT_ENOTFOUND
;
}
void
git_tree_entry_free
(
git_tree_entry
*
entry
)
{
git__free
(
entry
);
}
git_tree_entry
*
git_tree_entry_copy
(
const
git_tree_entry
*
entry
)
{
size_t
total_size
;
git_tree_entry
*
copy
;
assert
(
entry
);
total_size
=
sizeof
(
git_tree_entry
)
+
entry
->
filename_len
+
1
;
copy
=
git__malloc
(
total_size
);
if
(
!
copy
)
return
NULL
;
memcpy
(
copy
,
entry
,
total_size
);
return
copy
;
}
void
git_tree__free
(
git_tree
*
tree
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
tree
->
entries
.
length
;
++
i
)
{
git_tree_entry
*
e
;
e
=
git_vector_get
(
&
tree
->
entries
,
i
);
git__free
(
e
->
filename
);
git__free
(
e
);
git_tree_entry
*
e
=
git_vector_get
(
&
tree
->
entries
,
i
);
git_tree_entry_free
(
e
);
}
git_vector_free
(
&
tree
->
entries
);
...
...
@@ -179,19 +216,21 @@ int git_tree_entry_to_object(
return
git_object_lookup
(
object_out
,
repo
,
&
entry
->
oid
,
GIT_OBJ_ANY
);
}
const
git_tree_entry
*
git_tree_entry_byname
(
git_tree
*
tree
,
const
char
*
filename
)
static
git_tree_entry
*
entry_fromname
(
git_tree
*
tree
,
const
char
*
name
,
size_t
name_len
)
{
int
idx
;
assert
(
tree
&&
filename
);
idx
=
tree_key_search
(
&
tree
->
entries
,
filename
);
if
(
idx
==
GIT_ENOTFOUND
)
int
idx
=
tree_key_search
(
&
tree
->
entries
,
name
,
name_len
);
if
(
idx
<
0
)
return
NULL
;
return
git_vector_get
(
&
tree
->
entries
,
idx
);
}
const
git_tree_entry
*
git_tree_entry_byname
(
git_tree
*
tree
,
const
char
*
filename
)
{
assert
(
tree
&&
filename
);
return
entry_fromname
(
tree
,
filename
,
strlen
(
filename
));
}
const
git_tree_entry
*
git_tree_entry_byindex
(
git_tree
*
tree
,
unsigned
int
idx
)
{
assert
(
tree
);
...
...
@@ -244,28 +283,28 @@ static int tree_parse_buffer(git_tree *tree, const char *buffer, const char *buf
while
(
buffer
<
buffer_end
)
{
git_tree_entry
*
entry
;
int
tmp
;
int
attr
;
entry
=
git__calloc
(
1
,
sizeof
(
git_tree_entry
));
GITERR_CHECK_ALLOC
(
entry
);
if
(
git_vector_insert
(
&
tree
->
entries
,
entry
)
<
0
)
return
-
1
;
if
(
git__strtol32
(
&
tmp
,
buffer
,
&
buffer
,
8
)
<
0
||
!
buffer
||
!
valid_attributes
(
tmp
))
if
(
git__strtol32
(
&
attr
,
buffer
,
&
buffer
,
8
)
<
0
||
!
buffer
||
!
valid_attributes
(
attr
))
return
tree_error
(
"Failed to parse tree. Can't parse attributes"
);
entry
->
attr
=
tmp
;
if
(
*
buffer
++
!=
' '
)
return
tree_error
(
"Failed to parse tree. Object is corrupted"
);
if
(
memchr
(
buffer
,
0
,
buffer_end
-
buffer
)
==
NULL
)
return
tree_error
(
"Failed to parse tree. Object is corrupted"
);
entry
->
filename
=
git__strdup
(
buffer
);
entry
->
filename_len
=
strlen
(
buffer
);
/** Allocate the entry and store it in the entries vector */
{
entry
=
alloc_entry
(
buffer
);
GITERR_CHECK_ALLOC
(
entry
);
if
(
git_vector_insert
(
&
tree
->
entries
,
entry
)
<
0
)
return
-
1
;
entry
->
attr
=
attr
;
}
while
(
buffer
<
buffer_end
&&
*
buffer
!=
0
)
buffer
++
;
...
...
@@ -303,16 +342,17 @@ static unsigned int find_next_dir(const char *dirname, git_index *index, unsigne
return
i
;
}
static
int
append_entry
(
git_treebuilder
*
bld
,
const
char
*
filename
,
const
git_oid
*
id
,
unsigned
int
attributes
)
static
int
append_entry
(
git_treebuilder
*
bld
,
const
char
*
filename
,
const
git_oid
*
id
,
unsigned
int
attributes
)
{
git_tree_entry
*
entry
;
entry
=
git__calloc
(
1
,
sizeof
(
git_tree_entry
)
);
entry
=
alloc_entry
(
filename
);
GITERR_CHECK_ALLOC
(
entry
);
entry
->
filename
=
git__strdup
(
filename
);
entry
->
filename_len
=
strlen
(
entry
->
filename
);
git_oid_cpy
(
&
entry
->
oid
,
id
);
entry
->
attr
=
attributes
;
...
...
@@ -488,7 +528,12 @@ on_error:
return
-
1
;
}
int
git_treebuilder_insert
(
git_tree_entry
**
entry_out
,
git_treebuilder
*
bld
,
const
char
*
filename
,
const
git_oid
*
id
,
unsigned
int
attributes
)
int
git_treebuilder_insert
(
const
git_tree_entry
**
entry_out
,
git_treebuilder
*
bld
,
const
char
*
filename
,
const
git_oid
*
id
,
unsigned
int
attributes
)
{
git_tree_entry
*
entry
;
int
pos
;
...
...
@@ -501,30 +546,28 @@ int git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, con
if
(
!
valid_entry_name
(
filename
))
return
tree_error
(
"Failed to insert entry. Invalid name for a tree entry"
);
pos
=
tree_key_search
(
&
bld
->
entries
,
filename
);
pos
=
tree_key_search
(
&
bld
->
entries
,
filename
,
strlen
(
filename
)
);
if
(
pos
>=
0
)
{
entry
=
git_vector_get
(
&
bld
->
entries
,
pos
);
if
(
entry
->
removed
)
entry
->
removed
=
0
;
}
else
{
entry
=
git__calloc
(
1
,
sizeof
(
git_tree_entry
)
);
entry
=
alloc_entry
(
filename
);
GITERR_CHECK_ALLOC
(
entry
);
entry
->
filename
=
git__strdup
(
filename
);
entry
->
filename_len
=
strlen
(
entry
->
filename
);
}
git_oid_cpy
(
&
entry
->
oid
,
id
);
entry
->
attr
=
attributes
;
if
(
pos
==
GIT_ENOTFOUND
)
{
if
(
pos
<
0
)
{
if
(
git_vector_insert
(
&
bld
->
entries
,
entry
)
<
0
)
return
-
1
;
}
if
(
entry_out
!=
NULL
)
if
(
entry_out
!=
NULL
)
{
*
entry_out
=
entry
;
}
return
0
;
}
...
...
@@ -536,7 +579,7 @@ static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filenam
assert
(
bld
&&
filename
);
idx
=
tree_key_search
(
&
bld
->
entries
,
filename
);
idx
=
tree_key_search
(
&
bld
->
entries
,
filename
,
strlen
(
filename
)
);
if
(
idx
<
0
)
return
NULL
;
...
...
@@ -625,8 +668,7 @@ void git_treebuilder_clear(git_treebuilder *bld)
for
(
i
=
0
;
i
<
bld
->
entries
.
length
;
++
i
)
{
git_tree_entry
*
e
=
bld
->
entries
.
contents
[
i
];
git__free
(
e
->
filename
);
git__free
(
e
);
git_tree_entry_free
(
e
);
}
git_vector_clear
(
&
bld
->
entries
);
...
...
@@ -642,85 +684,78 @@ void git_treebuilder_free(git_treebuilder *bld)
git__free
(
bld
);
}
static
int
tree_frompath
(
git_tree
**
parent_out
,
static
size_t
subpath_len
(
const
char
*
path
)
{
const
char
*
slash_pos
=
strchr
(
path
,
'/'
);
if
(
slash_pos
==
NULL
)
return
strlen
(
path
);
return
slash_pos
-
path
;
}
int
git_tree_entry_bypath
(
git_tree_entry
**
entry_out
,
git_tree
*
root
,
git_buf
*
treeentry_path
,
size_t
offset
)
const
char
*
path
)
{
char
*
slash_pos
=
NULL
;
const
git_tree_entry
*
entry
;
int
error
=
0
;
git_tree
*
subtree
;
const
git_tree_entry
*
entry
;
size_t
filename_len
;
if
(
!*
(
treeentry_path
->
ptr
+
offset
))
{
giterr_set
(
GITERR_INVALID
,
"Invalid relative path to a tree entry '%s'."
,
treeentry_path
->
ptr
);
return
-
1
;
}
slash_pos
=
(
char
*
)
strchr
(
treeentry_path
->
ptr
+
offset
,
'/'
);
/* Find how long is the current path component (i.e.
* the filename between two slashes */
filename_len
=
subpath_len
(
path
);
if
(
slash_pos
==
NULL
)
return
git_tree_lookup
(
parent_out
,
root
->
object
.
repo
,
git_object_id
((
const
git_object
*
)
root
)
);
if
(
slash_pos
==
treeentry_path
->
ptr
+
offset
)
{
giterr_set
(
GITERR_INVALID
,
"Invalid relative path to a tree entry '%s'."
,
treeentry_path
->
ptr
);
return
-
1
;
if
(
filename_len
==
0
)
{
giterr_set
(
GITERR_TREE
,
"Invalid tree path given"
);
return
GIT_ENOTFOUND
;
}
*
slash_pos
=
'\0'
;
entry
=
git_tree_entry_byname
(
root
,
treeentry_path
->
ptr
+
offset
);
if
(
slash_pos
!=
NULL
)
*
slash_pos
=
'/'
;
entry
=
entry_fromname
(
root
,
path
,
filename_len
);
if
(
entry
==
NULL
)
{
giterr_set
(
GITERR_TREE
,
"No tree entry can be found from "
"the given tree and relative path '%s'."
,
treeentry_path
->
ptr
);
"The path '%s' does not exist in the given tree"
,
path
);
return
GIT_ENOTFOUND
;
}
switch
(
path
[
filename_len
])
{
case
'/'
:
/* If there are more components in the path...
* then this entry *must* be a tree */
if
(
!
git_tree_entry__is_tree
(
entry
))
{
giterr_set
(
GITERR_TREE
,
"The path '%s' does not exist in the given tree"
,
path
);
return
-
1
;
}
/* If there's only a slash left in the path, we
* return the current entry; otherwise, we keep
* walking down the path */
if
(
path
[
filename_len
+
1
]
!=
'\0'
)
break
;
case
'\0'
:
/* If there are no more components in the path, return
* this entry */
*
entry_out
=
git_tree_entry_copy
(
entry
);
return
0
;
}
if
(
git_tree_lookup
(
&
subtree
,
root
->
object
.
repo
,
&
entry
->
oid
)
<
0
)
return
error
;
return
-
1
;
error
=
tree_from
path
(
parent
_out
,
error
=
git_tree_entry_by
path
(
entry
_out
,
subtree
,
treeentry_path
,
(
slash_pos
-
treeentry_path
->
ptr
)
+
1
path
+
filename_len
+
1
);
git_tree_free
(
subtree
);
return
error
;
}
int
git_tree_get_subtree
(
git_tree
**
subtree
,
git_tree
*
root
,
const
char
*
subtree_path
)
{
int
error
;
git_buf
buffer
=
GIT_BUF_INIT
;
assert
(
subtree
&&
root
&&
subtree_path
);
if
((
error
=
git_buf_sets
(
&
buffer
,
subtree_path
))
==
0
)
error
=
tree_frompath
(
subtree
,
root
,
&
buffer
,
0
);
git_buf_free
(
&
buffer
);
return
error
;
}
static
int
tree_walk_post
(
git_tree
*
tree
,
git_treewalk_cb
callback
,
...
...
src/tree.h
View file @
0e2fcca8
...
...
@@ -13,11 +13,11 @@
#include "vector.h"
struct
git_tree_entry
{
u
nsigned
int
attr
;
char
*
filename
;
u
int16_t
removed
;
uint16_t
attr
;
git_oid
oid
;
size_t
filename_len
;
int
removed
;
char
filename
[
1
]
;
};
struct
git_tree
{
...
...
tests-clar/object/tree/frompath.c
View file @
0e2fcca8
#include "clar_libgit2.h"
static
git_repository
*
repo
;
const
char
*
tree_with_subtrees_oid
=
"ae90f12eea699729ed24555e40b9fd669da12a12"
;
static
git_tree
*
tree
;
void
test_object_tree_frompath__initialize
(
void
)
{
git_oid
id
;
const
char
*
tree_with_subtrees_oid
=
"ae90f12eea699729ed24555e40b9fd669da12a12"
;
cl_fixture_sandbox
(
"testrepo.git"
);
cl_git_pass
(
git_repository_open
(
&
repo
,
"testrepo.git"
));
cl_git_pass
(
git_repository_open
(
&
repo
,
cl_fixture
(
"testrepo.git"
)));
cl_assert
(
repo
!=
NULL
);
cl_git_pass
(
git_oid_fromstr
(
&
id
,
tree_with_subtrees_oid
));
...
...
@@ -24,58 +23,44 @@ void test_object_tree_frompath__cleanup(void)
cl_fixture_cleanup
(
"testrepo.git"
);
}
static
void
assert_tree_from_path
(
git_tree
*
root
,
const
char
*
path
,
int
expected_result
,
const
char
*
expected_raw_oid
)
static
void
assert_tree_from_path
(
git_tree
*
root
,
const
char
*
path
,
const
char
*
expected_entry_name
)
{
git_tree
*
containing_tree
=
NULL
;
git_tree
_entry
*
entry
;
cl_assert
(
git_tree_get_subtree
(
&
containing_tree
,
root
,
path
)
==
expected_result
);
if
(
containing_tree
==
NULL
&&
expected_result
!=
0
)
return
;
cl_assert
(
containing_tree
!=
NULL
&&
expected_result
==
0
);
cl_git_pass
(
git_oid_streq
(
git_object_id
((
const
git_object
*
)
containing_tree
),
expected_raw_oid
));
git_tree_free
(
containing_tree
);
}
static
void
assert_tree_from_path_klass
(
git_tree
*
root
,
const
char
*
path
,
int
expected_result
,
const
char
*
expected_raw_oid
)
{
assert_tree_from_path
(
root
,
path
,
GIT_ERROR
,
expected_raw_oid
);
cl_assert
(
giterr_last
()
->
klass
==
expected_result
);
cl_git_pass
(
git_tree_entry_bypath
(
&
entry
,
root
,
path
));
cl_assert_equal_s
(
git_tree_entry_name
(
entry
),
expected_entry_name
);
git_tree_entry_free
(
entry
);
}
void
test_object_tree_frompath__retrieve_tree_from_path_to_treeentry
(
void
)
{
/* Will return self if given a one path segment... */
assert_tree_from_path
(
tree
,
"README"
,
0
,
tree_with_subtrees_oid
);
/* ...even one that lead to a non existent tree entry. */
assert_tree_from_path
(
tree
,
"i-do-not-exist.txt"
,
0
,
tree_with_subtrees_oid
);
/* Will return fgh tree oid given this following path... */
assert_tree_from_path
(
tree
,
"ab/de/fgh/1.txt"
,
0
,
"3259a6bd5b57fb9c1281bb7ed3167b50f224cb54"
);
/* ... and ab tree oid given this one. */
assert_tree_from_path
(
tree
,
"ab/de"
,
0
,
"f1425cef211cc08caa31e7b545ffb232acb098c3"
);
git_tree_entry
*
e
;
/* Will succeed if given a valid path which leads to a tree entry which doesn't exist */
assert_tree_from_path
(
tree
,
"ab/de/fgh/i-do-not-exist.txt"
,
0
,
"3259a6bd5b57fb9c1281bb7ed3167b50f224cb54"
);
}
assert_tree_from_path
(
tree
,
"README"
,
"README"
);
assert_tree_from_path
(
tree
,
"ab/de/fgh/1.txt"
,
"1.txt"
);
assert_tree_from_path
(
tree
,
"ab/de/fgh"
,
"fgh"
);
assert_tree_from_path
(
tree
,
"ab/de/fgh/"
,
"fgh"
);
assert_tree_from_path
(
tree
,
"ab/de"
,
"de"
);
assert_tree_from_path
(
tree
,
"ab/"
,
"ab"
);
assert_tree_from_path
(
tree
,
"ab/de/"
,
"de"
);
void
test_object_tree_frompath__fail_when_processing_an_unknown_tree_segment
(
void
)
{
assert_tree_from_path
(
tree
,
"nope/de/fgh/1.txt"
,
GIT_ENOTFOUND
,
NULL
);
assert_tree_from_path
(
tree
,
"ab/me-neither/fgh/2.txt"
,
GIT_ENOTFOUND
,
NULL
);
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"i-do-not-exist.txt"
));
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"README/"
));
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"ab/de/fgh/i-do-not-exist.txt"
));
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"nope/de/fgh/1.txt"
));
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"ab/me-neither/fgh/2.txt"
));
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"ab/me-neither/fgh/2.txt/"
));
}
void
test_object_tree_frompath__fail_when_processing_an_invalid_path
(
void
)
{
assert_tree_from_path_klass
(
tree
,
"/"
,
GITERR_INVALID
,
NULL
)
;
assert_tree_from_path_klass
(
tree
,
"/ab"
,
GITERR_INVALID
,
NULL
);
assert_tree_from_path_klass
(
tree
,
"/ab/de"
,
GITERR_INVALID
,
NULL
);
assert_tree_from_path_klass
(
tree
,
"ab/"
,
GITERR_INVALID
,
NULL
);
assert_tree_from_path_klass
(
tree
,
"ab//de"
,
GITERR_INVALID
,
NULL
);
assert_tree_from_path_klass
(
tree
,
"ab/de/"
,
GITERR_INVALID
,
NULL
);
git_tree_entry
*
e
;
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"/"
)
);
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"/ab"
)
);
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"/ab/de"
)
);
cl_must_fail
(
git_tree_entry_bypath
(
&
e
,
tree
,
"ab//de"
)
);
}
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