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
f5753999
Commit
f5753999
authored
Mar 04, 2014
by
Russell Belfer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add exists_prefix to ODB backend and ODB API
parent
0a62caf4
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
138 additions
and
10 deletions
+138
-10
include/git2/odb.h
+13
-0
include/git2/sys/odb_backend.h
+5
-5
src/odb.c
+55
-0
src/odb_loose.c
+25
-4
src/odb_pack.c
+18
-0
tests/odb/loose.c
+4
-0
tests/odb/mixed.c
+18
-1
No files found.
include/git2/odb.h
View file @
f5753999
...
@@ -159,6 +159,19 @@ GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_od
...
@@ -159,6 +159,19 @@ GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_od
GIT_EXTERN
(
int
)
git_odb_exists
(
git_odb
*
db
,
const
git_oid
*
id
);
GIT_EXTERN
(
int
)
git_odb_exists
(
git_odb
*
db
,
const
git_oid
*
id
);
/**
/**
* Determine if objects can be found in the object database from a short OID.
*
* @param out The full OID of the found object if just one is found.
* @param db The database to be searched for the given object.
* @param short_id A prefix of the id of the object to read.
* @param len The length of the prefix.
* @return 0 if found, GIT_ENOTFOUND if not found, GIT_EAMBIGUOUS if multiple
* matches were found, other value < 0 if there was a read error.
*/
GIT_EXTERN
(
int
)
git_odb_exists_prefix
(
git_oid
*
out
,
git_odb
*
db
,
const
git_oid
*
short_id
,
size_t
len
);
/**
* Refresh the object database to load newly added files.
* Refresh the object database to load newly added files.
*
*
* If the object databases have changed on disk while the library
* If the object databases have changed on disk while the library
...
...
include/git2/sys/odb_backend.h
View file @
f5753999
...
@@ -35,11 +35,8 @@ struct git_odb_backend {
...
@@ -35,11 +35,8 @@ struct git_odb_backend {
int
(
*
read
)(
int
(
*
read
)(
void
**
,
size_t
*
,
git_otype
*
,
git_odb_backend
*
,
const
git_oid
*
);
void
**
,
size_t
*
,
git_otype
*
,
git_odb_backend
*
,
const
git_oid
*
);
/* To find a unique object given a prefix
/* To find a unique object given a prefix of its oid. The oid given
* of its oid.
* must be so that the remaining (GIT_OID_HEXSZ - len)*4 bits are 0s.
* The oid given must be so that the
* remaining (GIT_OID_HEXSZ - len)*4 bits
* are 0s.
*/
*/
int
(
*
read_prefix
)(
int
(
*
read_prefix
)(
git_oid
*
,
void
**
,
size_t
*
,
git_otype
*
,
git_oid
*
,
void
**
,
size_t
*
,
git_otype
*
,
...
@@ -64,6 +61,9 @@ struct git_odb_backend {
...
@@ -64,6 +61,9 @@ struct git_odb_backend {
int
(
*
exists
)(
int
(
*
exists
)(
git_odb_backend
*
,
const
git_oid
*
);
git_odb_backend
*
,
const
git_oid
*
);
int
(
*
exists_prefix
)(
git_oid
*
,
git_odb_backend
*
,
const
git_oid
*
,
size_t
);
/**
/**
* If the backend implements a refreshing mechanism, it should be exposed
* If the backend implements a refreshing mechanism, it should be exposed
* through this endpoint. Each call to `git_odb_refresh()` will invoke it.
* through this endpoint. Each call to `git_odb_refresh()` will invoke it.
...
...
src/odb.c
View file @
f5753999
...
@@ -635,6 +635,61 @@ int git_odb_exists(git_odb *db, const git_oid *id)
...
@@ -635,6 +635,61 @@ int git_odb_exists(git_odb *db, const git_oid *id)
return
(
int
)
found
;
return
(
int
)
found
;
}
}
int
git_odb_exists_prefix
(
git_oid
*
out
,
git_odb
*
db
,
const
git_oid
*
short_id
,
size_t
len
)
{
int
error
=
GIT_ENOTFOUND
,
num_found
=
0
;
size_t
i
;
git_oid
last_found
=
{{
0
}},
found
;
assert
(
db
&&
short_id
);
if
(
len
<
GIT_OID_MINPREFIXLEN
)
return
git_odb__error_ambiguous
(
"prefix length too short"
);
if
(
len
>
GIT_OID_HEXSZ
)
len
=
GIT_OID_HEXSZ
;
if
(
len
==
GIT_OID_HEXSZ
)
{
if
(
git_odb_exists
(
db
,
short_id
))
{
if
(
out
)
git_oid_cpy
(
out
,
short_id
);
return
0
;
}
else
{
return
git_odb__error_notfound
(
"no match for id prefix"
,
short_id
);
}
}
for
(
i
=
0
;
i
<
db
->
backends
.
length
;
++
i
)
{
backend_internal
*
internal
=
git_vector_get
(
&
db
->
backends
,
i
);
git_odb_backend
*
b
=
internal
->
backend
;
if
(
!
b
->
exists_prefix
)
continue
;
error
=
b
->
exists_prefix
(
&
found
,
b
,
short_id
,
len
);
if
(
error
==
GIT_ENOTFOUND
||
error
==
GIT_PASSTHROUGH
)
continue
;
if
(
error
)
return
error
;
/* make sure found item doesn't introduce ambiguity */
if
(
num_found
)
{
if
(
git_oid__cmp
(
&
last_found
,
&
found
))
return
git_odb__error_ambiguous
(
"multiple matches for prefix"
);
}
else
{
git_oid_cpy
(
&
last_found
,
&
found
);
num_found
++
;
}
}
if
(
!
num_found
)
return
git_odb__error_notfound
(
"no match for id prefix"
,
short_id
);
if
(
out
)
git_oid_cpy
(
out
,
&
last_found
);
return
error
;
}
int
git_odb_read_header
(
size_t
*
len_p
,
git_otype
*
type_p
,
git_odb
*
db
,
const
git_oid
*
id
)
int
git_odb_read_header
(
size_t
*
len_p
,
git_otype
*
type_p
,
git_odb
*
db
,
const
git_oid
*
id
)
{
{
int
error
;
int
error
;
...
...
src/odb_loose.c
View file @
f5753999
...
@@ -519,11 +519,11 @@ static int locate_object_short_oid(
...
@@ -519,11 +519,11 @@ static int locate_object_short_oid(
loose_locate_object_state
state
;
loose_locate_object_state
state
;
int
error
;
int
error
;
/* prealloc memory for OBJ_DIR/xx/ */
/* prealloc memory for OBJ_DIR/xx/
xx..38x..xx
*/
if
(
git_buf_grow
(
object_location
,
dir_len
+
5
)
<
0
)
if
(
git_buf_grow
(
object_location
,
dir_len
+
3
+
GIT_OID_HEXSZ
)
<
0
)
return
-
1
;
return
-
1
;
git_buf_set
s
(
object_location
,
objects_dir
);
git_buf_set
(
object_location
,
objects_dir
,
dir_len
);
git_path_to_dir
(
object_location
);
git_path_to_dir
(
object_location
);
/* save adjusted position at end of dir so it can be restored later */
/* save adjusted position at end of dir so it can be restored later */
...
@@ -533,8 +533,9 @@ static int locate_object_short_oid(
...
@@ -533,8 +533,9 @@ static int locate_object_short_oid(
git_oid_fmt
((
char
*
)
state
.
short_oid
,
short_oid
);
git_oid_fmt
((
char
*
)
state
.
short_oid
,
short_oid
);
/* Explore OBJ_DIR/xx/ where xx is the beginning of hex formatted short oid */
/* Explore OBJ_DIR/xx/ where xx is the beginning of hex formatted short oid */
if
(
git_buf_p
rintf
(
object_location
,
"%.2s/"
,
state
.
short_oid
)
<
0
)
if
(
git_buf_p
ut
(
object_location
,
(
char
*
)
state
.
short_oid
,
3
)
<
0
)
return
-
1
;
return
-
1
;
object_location
->
ptr
[
object_location
->
size
-
1
]
=
'/'
;
/* Check that directory exists */
/* Check that directory exists */
if
(
git_path_isdir
(
object_location
->
ptr
)
==
false
)
if
(
git_path_isdir
(
object_location
->
ptr
)
==
false
)
...
@@ -691,6 +692,25 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid)
...
@@ -691,6 +692,25 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid)
return
!
error
;
return
!
error
;
}
}
static
int
loose_backend__exists_prefix
(
git_oid
*
out
,
git_odb_backend
*
backend
,
const
git_oid
*
short_id
,
size_t
len
)
{
git_buf
object_path
=
GIT_BUF_INIT
;
int
error
;
assert
(
backend
&&
out
&&
short_id
);
if
(
len
<
GIT_OID_MINPREFIXLEN
)
return
git_odb__error_ambiguous
(
"prefix length too short"
);
error
=
locate_object_short_oid
(
&
object_path
,
out
,
(
loose_backend
*
)
backend
,
short_id
,
len
);
git_buf_free
(
&
object_path
);
return
error
;
}
struct
foreach_state
{
struct
foreach_state
{
size_t
dir_len
;
size_t
dir_len
;
git_odb_foreach_cb
cb
;
git_odb_foreach_cb
cb
;
...
@@ -939,6 +959,7 @@ int git_odb_backend_loose(
...
@@ -939,6 +959,7 @@ int git_odb_backend_loose(
backend
->
parent
.
read_header
=
&
loose_backend__read_header
;
backend
->
parent
.
read_header
=
&
loose_backend__read_header
;
backend
->
parent
.
writestream
=
&
loose_backend__stream
;
backend
->
parent
.
writestream
=
&
loose_backend__stream
;
backend
->
parent
.
exists
=
&
loose_backend__exists
;
backend
->
parent
.
exists
=
&
loose_backend__exists
;
backend
->
parent
.
exists_prefix
=
&
loose_backend__exists_prefix
;
backend
->
parent
.
foreach
=
&
loose_backend__foreach
;
backend
->
parent
.
foreach
=
&
loose_backend__foreach
;
backend
->
parent
.
free
=
&
loose_backend__free
;
backend
->
parent
.
free
=
&
loose_backend__free
;
...
...
src/odb_pack.c
View file @
f5753999
...
@@ -493,6 +493,23 @@ static int pack_backend__exists(git_odb_backend *backend, const git_oid *oid)
...
@@ -493,6 +493,23 @@ static int pack_backend__exists(git_odb_backend *backend, const git_oid *oid)
return
pack_entry_find
(
&
e
,
(
struct
pack_backend
*
)
backend
,
oid
)
==
0
;
return
pack_entry_find
(
&
e
,
(
struct
pack_backend
*
)
backend
,
oid
)
==
0
;
}
}
static
int
pack_backend__exists_prefix
(
git_oid
*
out
,
git_odb_backend
*
backend
,
const
git_oid
*
short_id
,
size_t
len
)
{
int
error
;
struct
pack_backend
*
pb
=
(
struct
pack_backend
*
)
backend
;
struct
git_pack_entry
e
=
{
0
};
error
=
pack_entry_find_prefix
(
&
e
,
pb
,
short_id
,
len
);
if
(
error
==
GIT_ENOTFOUND
&&
!
(
error
=
pack_backend__refresh
(
backend
)))
error
=
pack_entry_find_prefix
(
&
e
,
pb
,
short_id
,
len
);
git_oid_cpy
(
out
,
&
e
.
sha1
);
return
error
;
}
static
int
pack_backend__foreach
(
git_odb_backend
*
_backend
,
git_odb_foreach_cb
cb
,
void
*
data
)
static
int
pack_backend__foreach
(
git_odb_backend
*
_backend
,
git_odb_foreach_cb
cb
,
void
*
data
)
{
{
int
error
;
int
error
;
...
@@ -612,6 +629,7 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size)
...
@@ -612,6 +629,7 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size)
backend
->
parent
.
read_prefix
=
&
pack_backend__read_prefix
;
backend
->
parent
.
read_prefix
=
&
pack_backend__read_prefix
;
backend
->
parent
.
read_header
=
&
pack_backend__read_header
;
backend
->
parent
.
read_header
=
&
pack_backend__read_header
;
backend
->
parent
.
exists
=
&
pack_backend__exists
;
backend
->
parent
.
exists
=
&
pack_backend__exists
;
backend
->
parent
.
exists_prefix
=
&
pack_backend__exists_prefix
;
backend
->
parent
.
refresh
=
&
pack_backend__refresh
;
backend
->
parent
.
refresh
=
&
pack_backend__refresh
;
backend
->
parent
.
foreach
=
&
pack_backend__foreach
;
backend
->
parent
.
foreach
=
&
pack_backend__foreach
;
backend
->
parent
.
writepack
=
&
pack_backend__writepack
;
backend
->
parent
.
writepack
=
&
pack_backend__writepack
;
...
...
tests/odb/loose.c
View file @
f5753999
...
@@ -76,9 +76,13 @@ void test_odb_loose__exists(void)
...
@@ -76,9 +76,13 @@ void test_odb_loose__exists(void)
cl_assert
(
git_odb_exists
(
odb
,
&
id
));
cl_assert
(
git_odb_exists
(
odb
,
&
id
));
cl_assert
(
git_odb_exists_prefix
(
&
id2
,
odb
,
&
id
,
8
));
cl_assert
(
git_oid_equal
(
&
id
,
&
id2
));
/* Test for a non-existant object */
/* Test for a non-existant object */
cl_git_pass
(
git_oid_fromstr
(
&
id2
,
"8b137891791fe96927ad78e64b0aad7bded08baa"
));
cl_git_pass
(
git_oid_fromstr
(
&
id2
,
"8b137891791fe96927ad78e64b0aad7bded08baa"
));
cl_assert
(
!
git_odb_exists
(
odb
,
&
id2
));
cl_assert
(
!
git_odb_exists
(
odb
,
&
id2
));
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_odb_exists_prefix
(
NULL
,
odb
,
&
id2
,
8
));
git_odb_free
(
odb
);
git_odb_free
(
odb
);
}
}
...
...
tests/odb/mixed.c
View file @
f5753999
...
@@ -23,9 +23,14 @@ void test_odb_mixed__dup_oid(void) {
...
@@ -23,9 +23,14 @@ void test_odb_mixed__dup_oid(void) {
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
hex
));
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
hex
));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
GIT_OID_HEXSZ
));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
GIT_OID_HEXSZ
));
git_odb_object_free
(
obj
);
git_odb_object_free
(
obj
);
cl_git_pass
(
git_odb_exists_prefix
(
NULL
,
_odb
,
&
oid
,
GIT_OID_HEXSZ
));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
short_hex
,
sizeof
(
short_hex
)
-
1
));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
short_hex
,
sizeof
(
short_hex
)
-
1
));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
sizeof
(
short_hex
)
-
1
));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
sizeof
(
short_hex
)
-
1
));
git_odb_object_free
(
obj
);
git_odb_object_free
(
obj
);
cl_git_pass
(
git_odb_exists_prefix
(
NULL
,
_odb
,
&
oid
,
sizeof
(
short_hex
)
-
1
));
}
}
/* some known sha collisions of file content:
/* some known sha collisions of file content:
...
@@ -37,7 +42,7 @@ void test_odb_mixed__dup_oid(void) {
...
@@ -37,7 +42,7 @@ void test_odb_mixed__dup_oid(void) {
void
test_odb_mixed__dup_oid_prefix_0
(
void
)
{
void
test_odb_mixed__dup_oid_prefix_0
(
void
)
{
char
hex
[
10
];
char
hex
[
10
];
git_oid
oid
;
git_oid
oid
,
found
;
git_odb_object
*
obj
;
git_odb_object
*
obj
;
/* ambiguous in the same pack file */
/* ambiguous in the same pack file */
...
@@ -46,10 +51,14 @@ void test_odb_mixed__dup_oid_prefix_0(void) {
...
@@ -46,10 +51,14 @@ void test_odb_mixed__dup_oid_prefix_0(void) {
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_assert_equal_i
(
cl_assert_equal_i
(
GIT_EAMBIGUOUS
,
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
GIT_EAMBIGUOUS
,
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_assert_equal_i
(
GIT_EAMBIGUOUS
,
git_odb_exists_prefix
(
&
found
,
_odb
,
&
oid
,
strlen
(
hex
)));
strncpy
(
hex
,
"dea509d09"
,
sizeof
(
hex
));
strncpy
(
hex
,
"dea509d09"
,
sizeof
(
hex
));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_exists_prefix
(
&
found
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_assert
(
git_oid_equal
(
&
found
,
git_odb_object_id
(
obj
)));
git_odb_object_free
(
obj
);
git_odb_object_free
(
obj
);
strncpy
(
hex
,
"dea509d0b"
,
sizeof
(
hex
));
strncpy
(
hex
,
"dea509d0b"
,
sizeof
(
hex
));
...
@@ -63,10 +72,14 @@ void test_odb_mixed__dup_oid_prefix_0(void) {
...
@@ -63,10 +72,14 @@ void test_odb_mixed__dup_oid_prefix_0(void) {
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_assert_equal_i
(
cl_assert_equal_i
(
GIT_EAMBIGUOUS
,
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
GIT_EAMBIGUOUS
,
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_assert_equal_i
(
GIT_EAMBIGUOUS
,
git_odb_exists_prefix
(
&
found
,
_odb
,
&
oid
,
strlen
(
hex
)));
strncpy
(
hex
,
"81b5bff5b"
,
sizeof
(
hex
));
strncpy
(
hex
,
"81b5bff5b"
,
sizeof
(
hex
));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_exists_prefix
(
&
found
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_assert
(
git_oid_equal
(
&
found
,
git_odb_object_id
(
obj
)));
git_odb_object_free
(
obj
);
git_odb_object_free
(
obj
);
strncpy
(
hex
,
"81b5bff5f"
,
sizeof
(
hex
));
strncpy
(
hex
,
"81b5bff5f"
,
sizeof
(
hex
));
...
@@ -80,10 +93,14 @@ void test_odb_mixed__dup_oid_prefix_0(void) {
...
@@ -80,10 +93,14 @@ void test_odb_mixed__dup_oid_prefix_0(void) {
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_assert_equal_i
(
cl_assert_equal_i
(
GIT_EAMBIGUOUS
,
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
GIT_EAMBIGUOUS
,
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_assert_equal_i
(
GIT_EAMBIGUOUS
,
git_odb_exists_prefix
(
&
found
,
_odb
,
&
oid
,
strlen
(
hex
)));
strncpy
(
hex
,
"0ddeaded9"
,
sizeof
(
hex
));
strncpy
(
hex
,
"0ddeaded9"
,
sizeof
(
hex
));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_oid_fromstrn
(
&
oid
,
hex
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_read_prefix
(
&
obj
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_git_pass
(
git_odb_exists_prefix
(
&
found
,
_odb
,
&
oid
,
strlen
(
hex
)));
cl_assert
(
git_oid_equal
(
&
found
,
git_odb_object_id
(
obj
)));
git_odb_object_free
(
obj
);
git_odb_object_free
(
obj
);
strncpy
(
hex
,
"0ddeadede"
,
sizeof
(
hex
));
strncpy
(
hex
,
"0ddeadede"
,
sizeof
(
hex
));
...
...
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