mirror of
https://git.proxmox.com/git/libgit2
synced 2025-12-29 17:08:46 +00:00
Implement unified git_revparse
This commit is contained in:
parent
4d13d07ab2
commit
8480eef7ee
@ -51,35 +51,37 @@ GIT_EXTERN(int) git_revparse_rangelike(git_object **left, git_object **right, in
|
||||
* git_revparse.
|
||||
*/
|
||||
typedef enum {
|
||||
/** The spec targeted a single object. */
|
||||
GIT_REVPARSE_SINGLE = 1 << 0,
|
||||
/** The spec targeted a range of commits. */
|
||||
GIT_REVPARSE_RANGE = 1 << 1,
|
||||
/** The spec used the '...' operator, which invokes special semantics. */
|
||||
GIT_REVPARSE_MERGE_BASE = 1 << 2,
|
||||
/** The spec targeted a single object. */
|
||||
GIT_REVPARSE_SINGLE = 1 << 0,
|
||||
/** The spec targeted a range of commits. */
|
||||
GIT_REVPARSE_RANGE = 1 << 1,
|
||||
/** The spec used the '...' operator, which invokes special semantics. */
|
||||
GIT_REVPARSE_MERGE_BASE = 1 << 2,
|
||||
} git_revparse_flag_t;
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
GIT_EXTERN(int) git_revparse(
|
||||
git_oid *left,
|
||||
git_oid *right,
|
||||
unsigned int *flags,
|
||||
git_repository *repo,
|
||||
const char *spec);
|
||||
git_oid *left,
|
||||
git_oid *right,
|
||||
unsigned int *flags,
|
||||
git_repository *repo,
|
||||
const char *spec);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
@ -107,7 +107,7 @@ static int build_regex(regex_t *regex, const char *pattern)
|
||||
error = regcomp(regex, pattern, REG_EXTENDED);
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
|
||||
error = giterr_set_regex(regex, error);
|
||||
|
||||
regfree(regex);
|
||||
@ -125,7 +125,7 @@ static int maybe_describe(git_object**out, git_repository *repo, const char *spe
|
||||
|
||||
if (substr == NULL)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
|
||||
if (build_regex(®ex, ".+-[0-9]+-g[0-9a-fA-F]+") < 0)
|
||||
return -1;
|
||||
|
||||
@ -358,7 +358,7 @@ static int retrieve_remote_tracking_reference(git_reference **base_ref, const ch
|
||||
|
||||
if ((error = git_branch_tracking(&tracking, ref)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
||||
*base_ref = tracking;
|
||||
|
||||
cleanup:
|
||||
@ -508,7 +508,7 @@ static int walk_and_search(git_object **out, git_revwalk *walk, regex_t *regex)
|
||||
int error;
|
||||
git_oid oid;
|
||||
git_object *obj;
|
||||
|
||||
|
||||
while (!(error = git_revwalk_next(&oid, walk))) {
|
||||
|
||||
error = git_object_lookup(&obj, git_revwalk_repository(walk), &oid, GIT_OBJ_COMMIT);
|
||||
@ -537,7 +537,7 @@ static int handle_grep_syntax(git_object **out, git_repository *repo, const git_
|
||||
|
||||
if ((error = build_regex(&preg, pattern)) < 0)
|
||||
return error;
|
||||
|
||||
|
||||
if ((error = git_revwalk_new(&walk, repo)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -551,7 +551,7 @@ static int handle_grep_syntax(git_object **out, git_repository *repo, const git_
|
||||
goto cleanup;
|
||||
|
||||
error = walk_and_search(out, walk, &preg);
|
||||
|
||||
|
||||
cleanup:
|
||||
regfree(&preg);
|
||||
git_revwalk_free(walk);
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user