mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 13:04:42 +00:00
Implemented rev-parse's "^{}" syntax.
This commit is contained in:
parent
f597ea8978
commit
9d7bdf7119
@ -143,6 +143,9 @@ static git_object* dereference_object(git_object *obj)
|
||||
case GIT_OBJ_BLOB:
|
||||
break;
|
||||
case GIT_OBJ_TAG:
|
||||
if (0 == git_tag_target(&newobj, (git_tag*)obj)) {
|
||||
return newobj;
|
||||
}
|
||||
break;
|
||||
case GIT_OBJ_OFS_DELTA:
|
||||
break;
|
||||
@ -159,28 +162,36 @@ static git_object* dereference_object(git_object *obj)
|
||||
|
||||
static int dereference_to_type(git_object **out, git_object *obj, git_otype target_type)
|
||||
{
|
||||
git_otype this_type = git_object_type(obj);
|
||||
git_object *obj1 = obj, *obj2 = obj;
|
||||
|
||||
while (1) {
|
||||
git_otype this_type = git_object_type(obj1);
|
||||
|
||||
if (this_type == target_type) {
|
||||
*out = obj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this_type == GIT_OBJ_TAG) {
|
||||
git_tag_peel(&obj, (git_tag*)obj);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Dereference once, if possible. */
|
||||
obj = dereference_object(obj);
|
||||
|
||||
obj2 = dereference_object(obj1);
|
||||
if (obj2 != obj) {
|
||||
git_object_free(obj2);
|
||||
}
|
||||
obj1 = obj2;
|
||||
}
|
||||
}
|
||||
|
||||
static int handle_caret_syntax(git_object **out, git_object *start, const char *movement)
|
||||
static git_otype parse_obj_type(const char *str)
|
||||
{
|
||||
if (!strcmp(str, "{commit}")) return GIT_OBJ_COMMIT;
|
||||
if (!strcmp(str, "{tree}")) return GIT_OBJ_TREE;
|
||||
if (!strcmp(str, "{blob}")) return GIT_OBJ_BLOB;
|
||||
if (!strcmp(str, "{tag}")) return GIT_OBJ_TAG;
|
||||
return GIT_OBJ_BAD;
|
||||
}
|
||||
|
||||
static int handle_caret_syntax(git_object **out, git_object *obj, const char *movement)
|
||||
{
|
||||
git_object *obj;
|
||||
git_commit *commit;
|
||||
int n;
|
||||
|
||||
@ -189,15 +200,40 @@ static int handle_caret_syntax(git_object **out, git_object *start, const char *
|
||||
set_invalid_syntax_err(movement);
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
// TODO
|
||||
/* {/...} -> Walk all commits until we see a commit msg that matches the phrase. */
|
||||
|
||||
/* {} -> Dereference until we reach an object that isn't a tag. */
|
||||
if (strlen(movement) == 2) {
|
||||
git_object *newobj = obj;
|
||||
git_object *newobj2 = newobj;
|
||||
while (git_object_type(newobj2) == GIT_OBJ_TAG) {
|
||||
newobj2 = dereference_object(newobj);
|
||||
if (newobj != obj) git_object_free(newobj);
|
||||
if (!newobj2) {
|
||||
giterr_set(GITERR_REFERENCE, "Couldn't find object of target type.");
|
||||
return GIT_ERROR;
|
||||
}
|
||||
newobj = newobj;
|
||||
}
|
||||
*out = newobj2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* {/...} -> Walk all commits until we see a commit msg that matches the phrase. */
|
||||
if (movement[1] == '/') {
|
||||
// TODO
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
/* {...} -> Dereference until we reach an object of a certain type. */
|
||||
if (dereference_to_type(out, obj, parse_obj_type(movement)) < 0) {
|
||||
giterr_set(GITERR_REFERENCE, "Can't dereference to type");
|
||||
return GIT_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Dereference until we reach a commit. */
|
||||
if (dereference_to_type(&obj, start, GIT_OBJ_COMMIT) < 0) {
|
||||
if (dereference_to_type(&obj, obj, GIT_OBJ_COMMIT) < 0) {
|
||||
/* Can't dereference to a commit; fail */
|
||||
return GIT_ERROR;
|
||||
}
|
||||
@ -212,7 +248,7 @@ static int handle_caret_syntax(git_object **out, git_object *start, const char *
|
||||
|
||||
/* "^0" just returns the input */
|
||||
if (n == 0) {
|
||||
*out = (git_object*)commit;
|
||||
*out = obj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -259,7 +295,10 @@ int git_revparse_single(git_object **out, git_repository *repo, const char *spec
|
||||
|
||||
if (current_state != next_state) {
|
||||
/* Leaving INIT state, find the object specified, in case that state needs it */
|
||||
assert(!revparse_lookup_object(&next_obj, repo, git_buf_cstr(&specbuffer)));
|
||||
retcode = revparse_lookup_object(&next_obj, repo, git_buf_cstr(&specbuffer));
|
||||
if (retcode < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -292,6 +331,13 @@ int git_revparse_single(git_object **out, git_repository *repo, const char *spec
|
||||
break;
|
||||
|
||||
case REVPARSE_STATE_LINEAR:
|
||||
if (!*spec_cur) {
|
||||
} else if (*spec_cur == '~') {
|
||||
} else if (*spec_cur == '^') {
|
||||
} else {
|
||||
git_buf_putc(&stepbuffer, *spec_cur);
|
||||
}
|
||||
spec_cur++;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,11 @@ static git_object *g_obj;
|
||||
|
||||
|
||||
// Hepers
|
||||
static void oid_str_cmp(const git_oid *oid, const char *str)
|
||||
static void oid_str_cmp(const git_object *obj, const char *expected)
|
||||
{
|
||||
git_oid oid2;
|
||||
cl_git_pass(git_oid_fromstr(&oid2, str));
|
||||
cl_assert(0 == git_oid_cmp(oid, &oid2));
|
||||
char objstr[64] = {0};
|
||||
git_oid_to_string(objstr, 64, git_object_id(obj));
|
||||
cl_assert_equal_s(objstr, expected);
|
||||
}
|
||||
|
||||
|
||||
@ -28,64 +28,81 @@ void test_refs_revparse__cleanup(void)
|
||||
}
|
||||
|
||||
|
||||
void test_refs_revparse__nonexistant_object(void)
|
||||
{
|
||||
cl_git_fail(git_revparse_single(&g_obj, g_repo, "this doesn't exist"));
|
||||
}
|
||||
|
||||
void test_refs_revparse__shas(void)
|
||||
{
|
||||
// Full SHA should return a valid object
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
|
||||
oid_str_cmp(git_object_id(g_obj), "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
oid_str_cmp(g_obj, "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "c47800c"));
|
||||
oid_str_cmp(git_object_id(g_obj), "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
oid_str_cmp(g_obj, "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
}
|
||||
|
||||
void test_refs_revparse__head(void)
|
||||
{
|
||||
// Named head should return a valid object
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "HEAD"));
|
||||
oid_str_cmp(git_object_id(g_obj), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
|
||||
oid_str_cmp(g_obj, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
|
||||
}
|
||||
|
||||
void test_refs_revparse__full_refs(void)
|
||||
{
|
||||
// Fully-qualified refs should return valid objects
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "refs/heads/master"));
|
||||
oid_str_cmp(git_object_id(g_obj), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
|
||||
oid_str_cmp(g_obj, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "refs/heads/test"));
|
||||
oid_str_cmp(git_object_id(g_obj), "e90810b8df3e80c413d903f631643c716887138d");
|
||||
oid_str_cmp(g_obj, "e90810b8df3e80c413d903f631643c716887138d");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "refs/tags/test"));
|
||||
oid_str_cmp(git_object_id(g_obj), "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
|
||||
oid_str_cmp(g_obj, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
|
||||
}
|
||||
|
||||
void test_refs_revparse__partial_refs(void)
|
||||
{
|
||||
// Partially-qualified refs should return valid objects
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "point_to_blob"));
|
||||
oid_str_cmp(git_object_id(g_obj), "1385f264afb75a56a5bec74243be9b367ba4ca08");
|
||||
oid_str_cmp(g_obj, "1385f264afb75a56a5bec74243be9b367ba4ca08");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "packed-test"));
|
||||
oid_str_cmp(git_object_id(g_obj), "4a202b346bb0fb0db7eff3cffeb3c70babbd2045");
|
||||
oid_str_cmp(g_obj, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "br2"));
|
||||
oid_str_cmp(git_object_id(g_obj), "a4a7dce85cf63874e984719f4fdd239f5145052f");
|
||||
oid_str_cmp(g_obj, "a4a7dce85cf63874e984719f4fdd239f5145052f");
|
||||
}
|
||||
|
||||
void test_refs_revparse__describe_output(void)
|
||||
{
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "blah-7-gc47800c"));
|
||||
oid_str_cmp(git_object_id(g_obj), "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
oid_str_cmp(g_obj, "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
}
|
||||
|
||||
void test_refs_revparse__nth_parent(void)
|
||||
{
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "be3563a^1"));
|
||||
oid_str_cmp(git_object_id(g_obj), "9fd738e8f7967c078dceed8190330fc8648ee56a");
|
||||
oid_str_cmp(g_obj, "9fd738e8f7967c078dceed8190330fc8648ee56a");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "be3563a^"));
|
||||
oid_str_cmp(git_object_id(g_obj), "9fd738e8f7967c078dceed8190330fc8648ee56a");
|
||||
oid_str_cmp(g_obj, "9fd738e8f7967c078dceed8190330fc8648ee56a");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "be3563a^2"));
|
||||
oid_str_cmp(git_object_id(g_obj), "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
oid_str_cmp(g_obj, "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "be3563a^1^1"));
|
||||
oid_str_cmp(git_object_id(g_obj), "4a202b346bb0fb0db7eff3cffeb3c70babbd2045");
|
||||
oid_str_cmp(g_obj, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "be3563a^2^1"));
|
||||
oid_str_cmp(git_object_id(g_obj), "5b5b025afb0b4c913b4c338a42934a3863bf3644");
|
||||
oid_str_cmp(g_obj, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "be3563a^0"));
|
||||
oid_str_cmp(git_object_id(g_obj), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
|
||||
oid_str_cmp(g_obj, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
|
||||
}
|
||||
|
||||
void test_refs_revparse__not_tag(void)
|
||||
{
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "point_to_blob^{}"));
|
||||
oid_str_cmp(g_obj, "1385f264afb75a56a5bec74243be9b367ba4ca08");
|
||||
cl_git_pass(git_revparse_single(&g_obj, g_repo, "wrapped_tag^{}"));
|
||||
oid_str_cmp(g_obj, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
|
||||
}
|
||||
|
||||
void test_refs_revparse__to_type(void)
|
||||
{
|
||||
}
|
||||
|
||||
void test_refs_revparse__reflog(void)
|
||||
|
Binary file not shown.
BIN
tests/resources/testrepo.git/refs/tags/hard_tag
Normal file
BIN
tests/resources/testrepo.git/refs/tags/hard_tag
Normal file
Binary file not shown.
BIN
tests/resources/testrepo.git/refs/tags/wrapped_tag
Normal file
BIN
tests/resources/testrepo.git/refs/tags/wrapped_tag
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user