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
eff14d38
Commit
eff14d38
authored
Sep 10, 2012
by
Russell Belfer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #906 from nulltoken/topic/git_reference_peel
git reference peel
parents
17b06f4d
cf4c43ab
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
220 additions
and
42 deletions
+220
-42
include/git2/checkout.h
+12
-10
include/git2/errors.h
+1
-0
include/git2/refs.h
+20
-0
src/blob.c
+3
-1
src/checkout.c
+0
-6
src/clone.c
+0
-7
src/iterator.c
+2
-5
src/refs.c
+47
-0
src/repository.h
+15
-0
src/reset.c
+3
-2
tests-clar/object/peel.c
+25
-10
tests-clar/refs/peel.c
+91
-0
tests-clar/reset/mixed.c
+1
-1
No files found.
include/git2/checkout.h
View file @
eff14d38
...
...
@@ -40,13 +40,13 @@ typedef struct git_checkout_opts {
* @param repo repository to check out (must be non-bare)
* @param opts specifies checkout options (may be NULL)
* @param stats structure through which progress information is reported
* @return 0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)
* @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
* about the error)
*/
GIT_EXTERN
(
int
)
git_checkout_head
(
git_repository
*
repo
,
git_checkout_opts
*
opts
,
git_indexer_stats
*
stats
);
GIT_EXTERN
(
int
)
git_checkout_head
(
git_repository
*
repo
,
git_checkout_opts
*
opts
,
git_indexer_stats
*
stats
);
/**
* Updates files in the working tree to match a commit pointed to by a ref.
...
...
@@ -54,11 +54,13 @@ GIT_EXTERN(int) git_checkout_head(git_repository *repo,
* @param ref reference to follow to a commit
* @param opts specifies checkout options (may be NULL)
* @param stats structure through which progress information is reported
* @return 0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)
* @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
* about the error)
*/
GIT_EXTERN
(
int
)
git_checkout_reference
(
git_reference
*
ref
,
git_checkout_opts
*
opts
,
git_indexer_stats
*
stats
);
GIT_EXTERN
(
int
)
git_checkout_reference
(
git_reference
*
ref
,
git_checkout_opts
*
opts
,
git_indexer_stats
*
stats
);
/** @} */
...
...
include/git2/errors.h
View file @
eff14d38
...
...
@@ -26,6 +26,7 @@ enum {
GIT_EAMBIGUOUS
=
-
5
,
GIT_EBUFS
=
-
6
,
GIT_EUSER
=
-
7
,
GIT_EBAREREPO
=
-
8
,
GIT_PASSTHROUGH
=
-
30
,
GIT_ITEROVER
=
-
31
,
...
...
include/git2/refs.h
View file @
eff14d38
...
...
@@ -434,6 +434,26 @@ GIT_EXTERN(int) git_reference_normalize_name(
const
char
*
name
,
unsigned
int
flags
);
/**
* Recursively peel an reference until an object of the
* specified type is met.
*
* The retrieved `peeled` object is owned by the repository
* and should be closed with the `git_object_free` method.
*
* If you pass `GIT_OBJ_ANY` as the target type, then the object
* will be peeled until a non-tag object is met.
*
* @param peeled Pointer to the peeled git_object
* @param ref The reference to be processed
* @param target_type The type of the requested object
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_reference_peel
(
git_object
**
out
,
git_reference
*
ref
,
git_otype
type
);
/** @} */
GIT_END_DECL
#endif
src/blob.c
View file @
eff14d38
...
...
@@ -212,8 +212,10 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
const
char
*
workdir
;
int
error
;
if
((
error
=
git_repository__ensure_not_bare
(
repo
,
"create blob from file"
))
<
0
)
return
error
;
workdir
=
git_repository_workdir
(
repo
);
assert
(
workdir
);
/* error to call this on bare repo */
if
(
git_buf_joinpath
(
&
full_path
,
workdir
,
path
)
<
0
)
{
git_buf_free
(
&
full_path
);
...
...
src/checkout.c
View file @
eff14d38
...
...
@@ -22,9 +22,6 @@
#include "filter.h"
#include "blob.h"
GIT_BEGIN_DECL
typedef
struct
tree_walk_data
{
git_indexer_stats
*
stats
;
...
...
@@ -226,6 +223,3 @@ int git_checkout_reference(git_reference *ref,
git_reference_free
(
head
);
return
retcode
;
}
GIT_END_DECL
src/clone.c
View file @
eff14d38
...
...
@@ -26,8 +26,6 @@
#include "refs.h"
#include "path.h"
GIT_BEGIN_DECL
struct
HeadInfo
{
git_repository
*
repo
;
git_oid
remote_head_oid
;
...
...
@@ -247,8 +245,3 @@ int git_clone(git_repository **out,
return
retcode
;
}
GIT_END_DECL
src/iterator.c
View file @
eff14d38
...
...
@@ -659,11 +659,8 @@ int git_iterator_for_workdir_range(
assert
(
iter
&&
repo
);
if
(
git_repository_is_bare
(
repo
))
{
giterr_set
(
GITERR_INVALID
,
"Cannot scan working directory for bare repo"
);
return
-
1
;
}
if
((
error
=
git_repository__ensure_not_bare
(
repo
,
"scan working directory"
))
<
0
)
return
error
;
ITERATOR_BASE_INIT
(
wi
,
workdir
,
WORKDIR
);
...
...
src/refs.c
View file @
eff14d38
...
...
@@ -1844,3 +1844,50 @@ int git_reference_is_remote(git_reference *ref)
assert
(
ref
);
return
git__prefixcmp
(
ref
->
name
,
GIT_REFS_REMOTES_DIR
)
==
0
;
}
static
int
peel_error
(
int
error
,
git_reference
*
ref
,
const
char
*
msg
)
{
giterr_set
(
GITERR_INVALID
,
"The reference '%s' cannot be peeled - %s"
,
git_reference_name
(
ref
),
msg
);
return
error
;
}
static
int
reference_target
(
git_object
**
object
,
git_reference
*
ref
)
{
const
git_oid
*
oid
;
oid
=
git_reference_oid
(
ref
);
return
git_object_lookup
(
object
,
git_reference_owner
(
ref
),
oid
,
GIT_OBJ_ANY
);
}
int
git_reference_peel
(
git_object
**
peeled
,
git_reference
*
ref
,
git_otype
target_type
)
{
git_reference
*
resolved
=
NULL
;
git_object
*
target
=
NULL
;
int
error
;
assert
(
ref
);
if
((
error
=
git_reference_resolve
(
&
resolved
,
ref
))
<
0
)
return
peel_error
(
error
,
ref
,
"Cannot resolve reference"
);
if
((
error
=
reference_target
(
&
target
,
resolved
))
<
0
)
{
peel_error
(
error
,
ref
,
"Cannot retrieve reference target"
);
goto
cleanup
;
}
if
(
target_type
==
GIT_OBJ_ANY
&&
git_object_type
(
target
)
!=
GIT_OBJ_TAG
)
error
=
git_object__dup
(
peeled
,
target
);
else
error
=
git_object_peel
(
peeled
,
target
,
target_type
);
cleanup:
git_object_free
(
target
);
git_reference_free
(
resolved
);
return
error
;
}
src/repository.h
View file @
eff14d38
...
...
@@ -149,4 +149,19 @@ void git_repository__cvar_cache_clear(git_repository *repo);
*/
extern
void
git_submodule_config_free
(
git_repository
*
repo
);
GIT_INLINE
(
int
)
git_repository__ensure_not_bare
(
git_repository
*
repo
,
const
char
*
operation_name
)
{
if
(
!
git_repository_is_bare
(
repo
))
return
0
;
giterr_set
(
GITERR_REPOSITORY
,
"Cannot %s. This operation is not allowed against bare repositories."
,
operation_name
);
return
GIT_EBAREREPO
;
}
#endif
src/reset.c
View file @
eff14d38
...
...
@@ -34,8 +34,9 @@ int git_reset(
if
(
git_object_owner
(
target
)
!=
repo
)
return
reset_error_invalid
(
"The given target does not belong to this repository."
);
if
(
reset_type
==
GIT_RESET_MIXED
&&
git_repository_is_bare
(
repo
))
return
reset_error_invalid
(
"Mixed reset is not allowed in a bare repository."
);
if
(
reset_type
==
GIT_RESET_MIXED
&&
git_repository__ensure_not_bare
(
repo
,
"reset mixed"
)
<
0
)
return
GIT_EBAREREPO
;
if
(
git_object_peel
(
&
commit
,
target
,
GIT_OBJ_COMMIT
)
<
0
)
{
reset_error_invalid
(
"The given target does not resolve to a commit"
);
...
...
tests-clar/object/peel.c
View file @
eff14d38
...
...
@@ -12,7 +12,11 @@ void test_object_peel__cleanup(void)
git_repository_free
(
g_repo
);
}
static
void
assert_peel
(
const
char
*
expected_sha
,
const
char
*
sha
,
git_otype
requested_type
)
static
void
assert_peel
(
const
char
*
sha
,
git_otype
requested_type
,
const
char
*
expected_sha
,
git_otype
expected_type
)
{
git_oid
oid
,
expected_oid
;
git_object
*
obj
;
...
...
@@ -26,6 +30,8 @@ static void assert_peel(const char* expected_sha, const char *sha, git_otype req
cl_git_pass
(
git_oid_fromstr
(
&
expected_oid
,
expected_sha
));
cl_assert_equal_i
(
0
,
git_oid_cmp
(
&
expected_oid
,
git_object_id
(
peeled
)));
cl_assert_equal_i
(
expected_type
,
git_object_type
(
peeled
));
git_object_free
(
peeled
);
git_object_free
(
obj
);
}
...
...
@@ -46,21 +52,28 @@ static void assert_peel_error(int error, const char *sha, git_otype requested_ty
void
test_object_peel__peeling_an_object_into_its_own_type_returns_another_instance_of_it
(
void
)
{
assert_peel
(
"e90810b8df3e80c413d903f631643c716887138d"
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"7b4384978d2493e851f9cca7858815fac9b10980"
,
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_TAG
);
assert_peel
(
"53fc32d17276939fc79ed05badaef2db09990016"
,
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_TREE
);
assert_peel
(
"0266163a49e280c4f5ed1e08facd36a2bd716bcf"
,
"0266163a49e280c4f5ed1e08facd36a2bd716bcf"
,
GIT_OBJ_BLOB
);
assert_peel
(
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_COMMIT
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_TAG
,
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_TAG
);
assert_peel
(
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_TREE
,
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_TREE
);
assert_peel
(
"0266163a49e280c4f5ed1e08facd36a2bd716bcf"
,
GIT_OBJ_BLOB
,
"0266163a49e280c4f5ed1e08facd36a2bd716bcf"
,
GIT_OBJ_BLOB
);
}
void
test_object_peel__can_peel_a_tag
(
void
)
{
assert_peel
(
"e90810b8df3e80c413d903f631643c716887138d"
,
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"53fc32d17276939fc79ed05badaef2db09990016"
,
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_TREE
);
assert_peel
(
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_COMMIT
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_TREE
,
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_TREE
);
}
void
test_object_peel__can_peel_a_commit
(
void
)
{
assert_peel
(
"53fc32d17276939fc79ed05badaef2db09990016"
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_TREE
);
assert_peel
(
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_TREE
,
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_TREE
);
}
void
test_object_peel__cannot_peel_a_tree
(
void
)
...
...
@@ -76,10 +89,12 @@ void test_object_peel__cannot_peel_a_blob(void)
void
test_object_peel__target_any_object_for_type_change
(
void
)
{
/* tag to commit */
assert_peel
(
"e90810b8df3e80c413d903f631643c716887138d"
,
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_ANY
);
assert_peel
(
"7b4384978d2493e851f9cca7858815fac9b10980"
,
GIT_OBJ_ANY
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_COMMIT
);
/* commit to tree */
assert_peel
(
"53fc32d17276939fc79ed05badaef2db09990016"
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_ANY
);
assert_peel
(
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_ANY
,
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_TREE
);
/* fail to peel tree */
assert_peel_error
(
GIT_ERROR
,
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_ANY
);
...
...
tests-clar/refs/peel.c
0 → 100644
View file @
eff14d38
#include "clar_libgit2.h"
static
git_repository
*
g_repo
;
void
test_refs_peel__initialize
(
void
)
{
cl_git_pass
(
git_repository_open
(
&
g_repo
,
cl_fixture
(
"testrepo.git"
)));
}
void
test_refs_peel__cleanup
(
void
)
{
git_repository_free
(
g_repo
);
}
static
void
assert_peel
(
const
char
*
ref_name
,
git_otype
requested_type
,
const
char
*
expected_sha
,
git_otype
expected_type
)
{
git_oid
expected_oid
;
git_reference
*
ref
;
git_object
*
peeled
;
cl_git_pass
(
git_reference_lookup
(
&
ref
,
g_repo
,
ref_name
));
cl_git_pass
(
git_reference_peel
(
&
peeled
,
ref
,
requested_type
));
cl_git_pass
(
git_oid_fromstr
(
&
expected_oid
,
expected_sha
));
cl_assert_equal_i
(
0
,
git_oid_cmp
(
&
expected_oid
,
git_object_id
(
peeled
)));
cl_assert_equal_i
(
expected_type
,
git_object_type
(
peeled
));
git_object_free
(
peeled
);
git_reference_free
(
ref
);
}
static
void
assert_peel_error
(
int
error
,
const
char
*
ref_name
,
git_otype
requested_type
)
{
git_reference
*
ref
;
git_object
*
peeled
;
cl_git_pass
(
git_reference_lookup
(
&
ref
,
g_repo
,
ref_name
));
cl_assert_equal_i
(
error
,
git_reference_peel
(
&
peeled
,
ref
,
requested_type
));
git_reference_free
(
ref
);
}
void
test_refs_peel__can_peel_a_tag
(
void
)
{
assert_peel
(
"refs/tags/test"
,
GIT_OBJ_TAG
,
"b25fa35b38051e4ae45d4222e795f9df2e43f1d1"
,
GIT_OBJ_TAG
);
assert_peel
(
"refs/tags/test"
,
GIT_OBJ_COMMIT
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"refs/tags/test"
,
GIT_OBJ_TREE
,
"53fc32d17276939fc79ed05badaef2db09990016"
,
GIT_OBJ_TREE
);
assert_peel
(
"refs/tags/point_to_blob"
,
GIT_OBJ_BLOB
,
"1385f264afb75a56a5bec74243be9b367ba4ca08"
,
GIT_OBJ_BLOB
);
}
void
test_refs_peel__can_peel_a_branch
(
void
)
{
assert_peel
(
"refs/heads/master"
,
GIT_OBJ_COMMIT
,
"a65fedf39aefe402d3bb6e24df4d4f5fe4547750"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"refs/heads/master"
,
GIT_OBJ_TREE
,
"944c0f6e4dfa41595e6eb3ceecdb14f50fe18162"
,
GIT_OBJ_TREE
);
}
void
test_refs_peel__can_peel_a_symbolic_reference
(
void
)
{
assert_peel
(
"HEAD"
,
GIT_OBJ_COMMIT
,
"a65fedf39aefe402d3bb6e24df4d4f5fe4547750"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"HEAD"
,
GIT_OBJ_TREE
,
"944c0f6e4dfa41595e6eb3ceecdb14f50fe18162"
,
GIT_OBJ_TREE
);
}
void
test_refs_peel__cannot_peel_into_a_non_existing_target
(
void
)
{
assert_peel_error
(
GIT_ERROR
,
"refs/tags/point_to_blob"
,
GIT_OBJ_TAG
);
}
void
test_refs_peel__can_peel_into_any_non_tag_object
(
void
)
{
assert_peel
(
"refs/heads/master"
,
GIT_OBJ_ANY
,
"a65fedf39aefe402d3bb6e24df4d4f5fe4547750"
,
GIT_OBJ_COMMIT
);
assert_peel
(
"refs/tags/point_to_blob"
,
GIT_OBJ_ANY
,
"1385f264afb75a56a5bec74243be9b367ba4ca08"
,
GIT_OBJ_BLOB
);
assert_peel
(
"refs/tags/test"
,
GIT_OBJ_ANY
,
"e90810b8df3e80c413d903f631643c716887138d"
,
GIT_OBJ_COMMIT
);
}
tests-clar/reset/mixed.c
View file @
eff14d38
...
...
@@ -27,7 +27,7 @@ void test_reset_mixed__cannot_reset_in_a_bare_repository(void)
retrieve_target_from_oid
(
&
target
,
bare
,
KNOWN_COMMIT_IN_BARE_REPO
);
cl_
git_fail
(
git_reset
(
bare
,
target
,
GIT_RESET_MIXED
));
cl_
assert_equal_i
(
GIT_EBAREREPO
,
git_reset
(
bare
,
target
,
GIT_RESET_MIXED
));
git_repository_free
(
bare
);
}
...
...
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