Commit 8480eef7 by Ben Straub

Implement unified git_revparse

parent 4d13d07a
......@@ -61,15 +61,17 @@ typedef enum {
/**
* Find an object or range of commits as specified by a revision string.
* See `man gitrevisions` or http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions
* for information on the syntax accepted.
* Parse a revision string for left, right, and intent. See `man gitrevisions` or
* http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for information
* on the syntax accepted.
*
* @param left buffer that receives the target of the left side of a range operator. If
* there is no range operator, this buffer receives the single target.
* @param right buffer that receives the target of the right side of a range operator.
* This is only filled in if `spec` specifies a range of commits
* @param flags buffer that receives a bitwise combination of `git_revparse_flag_t` values
* This is only filled in if `spec` specifies a range of commits. May
* be NULL.
* @param flags buffer that receives a bitwise combination of `git_revparse_flag_t` values.
* May be NULL.
* @param repo the repository to search in
* @param spec the rev-parse spec to parse
* @return 0 on success, GIT_INVALIDSPEC, GIT_ENOTFOUND, GIT_EAMBIGUOUS or an error code
......
......@@ -892,3 +892,55 @@ int git_revparse_rangelike(git_object **left, git_object **right, int *threedots
git__free(revspec);
return error;
}
int git_revparse(
git_oid *left,
git_oid *right,
unsigned int *flags,
git_repository *repo,
const char *spec)
{
unsigned int lflags = 0;
const char *dotdot;
int error = 0;
git_object *obj = NULL;
assert(left && repo && spec);
if ((dotdot = strstr(spec, "..")) != NULL) {
char *lstr;
const char *rstr;
lflags = GIT_REVPARSE_RANGE;
lstr = git__substrdup(spec, dotdot-spec);
rstr = dotdot + 2;
if (dotdot[2] == '.') {
lflags |= GIT_REVPARSE_MERGE_BASE;
rstr++;
}
if (!(error = git_revparse_single(&obj, repo, lstr))) {
git_oid_cpy(left, git_object_id(obj));
git_object_free(obj);
}
if (right && !(error = git_revparse_single(&obj, repo, rstr))) {
git_oid_cpy(right, git_object_id(obj));
git_object_free(obj);
}
git__free((void*)lstr);
} else {
lflags = GIT_REVPARSE_SINGLE;
if (!(error = git_revparse_single(&obj, repo, spec))) {
git_oid_cpy(left, git_object_id(obj));
git_object_free(obj);
}
}
if (flags)
*flags = lflags;
return error;
}
......@@ -27,6 +27,37 @@ static void test_object_inrepo(const char *spec, const char *expected_oid, git_r
git_object_free(obj);
}
static void test_id_inrepo(
const char *spec,
const char *expected_left,
const char *expected_right,
git_revparse_flag_t expected_flags,
git_repository *repo)
{
git_oid l = {{0}}, r = {{0}};
git_revparse_flag_t flags = 0;
int error = git_revparse(&l, &r, &flags, repo, spec);
if (expected_left) {
char str[64] = {0};
cl_assert_equal_i(0, error);
git_oid_fmt(str, &l);
cl_assert_equal_s(str, expected_left);
} else {
cl_assert_equal_i(GIT_ENOTFOUND, error);
}
if (expected_right) {
char str[64] = {0};
git_oid_fmt(str, &r);
cl_assert_equal_s(str, expected_right);
}
if (expected_flags)
cl_assert_equal_i(expected_flags, flags);
}
static void test_object(const char *spec, const char *expected_oid)
{
test_object_inrepo(spec, expected_oid, g_repo);
......@@ -59,6 +90,15 @@ static void test_rangelike(const char *rangelike,
}
static void test_id(
const char *spec,
const char *expected_left,
const char *expected_right,
git_revparse_flag_t expected_flags)
{
test_id_inrepo(spec, expected_left, expected_right, expected_flags, g_repo);
}
void test_refs_revparse__initialize(void)
{
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
......@@ -639,3 +679,22 @@ void test_refs_revparse__range(void)
test_rangelike("be3563a^1.be3563a", NULL, NULL, 0);
}
void test_refs_revparse__validates_args(void)
{
git_oid l={{0}}, r={{0}};
git_revparse_flag_t flags = 0;
cl_git_pass(git_revparse(&l,&r,NULL, g_repo, "HEAD"));
cl_git_pass(git_revparse(&l,NULL,&flags, g_repo, "HEAD"));
cl_assert_equal_i(GIT_EINVALIDSPEC, git_revparse(&l,&r,&flags, g_repo, "^&*("));
}
void test_refs_revparse__parses_range_operator(void)
{
test_id("HEAD", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVPARSE_SINGLE);
test_id("HEAD~3..HEAD", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_REVPARSE_RANGE);
test_id("HEAD~3...HEAD", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment