mirror of
https://git.proxmox.com/git/libgit2
synced 2025-12-31 20:20:15 +00:00
Rev-parse: implement ":/foo" syntax.
This commit is contained in:
parent
2497106f91
commit
734efe4b8e
@ -432,9 +432,6 @@ static int handle_caret_syntax(git_object **out, git_repository *repo, git_objec
|
||||
} else {
|
||||
while(!git_revwalk_next(&oid, walk)) {
|
||||
git_object *walkobj;
|
||||
char str[41];
|
||||
git_oid_fmt(str, &oid);
|
||||
str[40] = 0;
|
||||
|
||||
/* Fetch the commit object, and check for matches in the message */
|
||||
if (!git_object_lookup(&walkobj, repo, &oid, GIT_OBJ_COMMIT)) {
|
||||
@ -580,6 +577,49 @@ static int handle_colon_syntax(git_object **out,
|
||||
return git_tree_entry_2object(out, repo, entry);
|
||||
}
|
||||
|
||||
static int git__revparse_global_grep(git_object **out, git_repository *repo, const char *pattern)
|
||||
{
|
||||
git_revwalk *walk;
|
||||
int retcode = GIT_ERROR;
|
||||
|
||||
if (!git_revwalk_new(&walk, repo)) {
|
||||
regex_t preg;
|
||||
int reg_error;
|
||||
git_oid oid;
|
||||
|
||||
git_revwalk_sorting(walk, GIT_SORT_TIME);
|
||||
git_revwalk_push_glob(walk, "refs/heads/*");
|
||||
|
||||
reg_error = regcomp(&preg, pattern, REG_EXTENDED);
|
||||
if (reg_error != 0) {
|
||||
giterr_set_regex(&preg, reg_error);
|
||||
} else {
|
||||
git_object *walkobj = NULL, *resultobj = NULL;
|
||||
while(!git_revwalk_next(&oid, walk)) {
|
||||
/* Fetch the commit object, and check for matches in the message */
|
||||
if (walkobj != resultobj) git_object_free(walkobj);
|
||||
if (!git_object_lookup(&walkobj, repo, &oid, GIT_OBJ_COMMIT)) {
|
||||
if (!regexec(&preg, git_commit_message((git_commit*)walkobj), 0, NULL, 0)) {
|
||||
/* Match! */
|
||||
resultobj = walkobj;
|
||||
retcode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!resultobj) {
|
||||
giterr_set(GITERR_REFERENCE, "Couldn't find a match for %s", pattern);
|
||||
} else {
|
||||
*out = resultobj;
|
||||
}
|
||||
regfree(&preg);
|
||||
git_revwalk_free(walk);
|
||||
}
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int git_revparse_single(git_object **out, git_repository *repo, const char *spec)
|
||||
{
|
||||
revparse_state current_state = REVPARSE_STATE_INIT, next_state = REVPARSE_STATE_INIT;
|
||||
@ -591,8 +631,10 @@ int git_revparse_single(git_object **out, git_repository *repo, const char *spec
|
||||
assert(out && repo && spec);
|
||||
|
||||
if (spec[0] == ':') {
|
||||
/* Either a global grep (":/foo") or a merge-stage path lookup (":2:Makefile").
|
||||
Neither of these are handled just yet. */
|
||||
if (spec[1] == '/') {
|
||||
return git__revparse_global_grep(out, repo, spec+2);
|
||||
}
|
||||
/* TODO: support merge-stage path lookup (":2:Makefile"). */
|
||||
giterr_set(GITERR_INVALID, "Unimplemented");
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
@ -156,11 +156,15 @@ void test_refs_revparse__date(void)
|
||||
|
||||
void test_refs_revparse__colon(void)
|
||||
{
|
||||
cl_git_fail(git_revparse_single(&g_obj, g_repo, ":/foo"));
|
||||
cl_git_fail(git_revparse_single(&g_obj, g_repo, ":/"));
|
||||
cl_git_fail(git_revparse_single(&g_obj, g_repo, ":/not found in any commit"));
|
||||
cl_git_fail(git_revparse_single(&g_obj, g_repo, ":2:README"));
|
||||
|
||||
test_object("subtrees:ab/4.txt", "d6c93164c249c8000205dd4ec5cbca1b516d487f");
|
||||
test_object("subtrees:ab/de/fgh/1.txt", "1f67fc4386b2d171e0d21be1c447e12660561f9b");
|
||||
test_object("master:README", "a8233120f6ad708f843d861ce2b7228ec4e3dec6");
|
||||
test_object("master:new.txt", "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd");
|
||||
test_object(":/Merge", "a4a7dce85cf63874e984719f4fdd239f5145052f");
|
||||
test_object(":/one", "c47800c7266a2be04c571c04d5a6614691ea99bd");
|
||||
test_object(":/packed commit t", "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9");
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user