summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2013-02-03 08:41:47 -0800
committerVicent Martí <vicent@github.com>2013-02-03 08:41:47 -0800
commit3261a3e980b00cf19b971c078d09bc0660ce1f81 (patch)
treed87fc32b4cd9d8435cb51f2d00ed098f891a283b
parente963166019de3dca72d18bd4ee8f81519e97fdf3 (diff)
parent0e8e5a6189b84b2817d5916948e963e97d8f3641 (diff)
downloadlibgit2-3261a3e980b00cf19b971c078d09bc0660ce1f81.tar.gz
Merge pull request #1307 from nulltoken/fix/revparse_describe
revparse: Lookup branch before described tag
-rw-r--r--src/revparse.c35
-rw-r--r--tests-clar/refs/revparse.c109
2 files changed, 138 insertions, 6 deletions
diff --git a/src/revparse.c b/src/revparse.c
index 05ee1c57d..884879975 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -67,10 +67,9 @@ cleanup:
return error;
}
-static int maybe_sha_or_abbrev(git_object**out, git_repository *repo, const char *spec)
+static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const char *spec, size_t speclen)
{
git_oid oid;
- size_t speclen = strlen(spec);
if (git_oid_fromstrn(&oid, spec, speclen) < 0)
return GIT_ENOTFOUND;
@@ -78,6 +77,23 @@ static int maybe_sha_or_abbrev(git_object**out, git_repository *repo, const char
return git_object_lookup_prefix(out, repo, &oid, speclen, GIT_OBJ_ANY);
}
+static int maybe_sha(git_object** out, git_repository *repo, const char *spec)
+{
+ size_t speclen = strlen(spec);
+
+ if (speclen != GIT_OID_HEXSZ)
+ return GIT_ENOTFOUND;
+
+ return maybe_sha_or_abbrev(out, repo, spec, speclen);
+}
+
+static int maybe_abbrev(git_object** out, git_repository *repo, const char *spec)
+{
+ size_t speclen = strlen(spec);
+
+ return maybe_sha_or_abbrev(out, repo, spec, speclen);
+}
+
static int build_regex(regex_t *regex, const char *pattern)
{
int error;
@@ -118,7 +134,7 @@ static int maybe_describe(git_object**out, git_repository *repo, const char *spe
if (error)
return GIT_ENOTFOUND;
- return maybe_sha_or_abbrev(out, repo, substr+2);
+ return maybe_abbrev(out, repo, substr+2);
}
static int revparse_lookup_object(git_object **out, git_repository *repo, const char *spec)
@@ -126,7 +142,7 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const
int error;
git_reference *ref;
- error = maybe_describe(out, repo, spec);
+ error = maybe_sha(out, repo, spec);
if (!error)
return 0;
@@ -143,7 +159,14 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const
if (error < 0 && error != GIT_ENOTFOUND)
return error;
- error = maybe_sha_or_abbrev(out, repo, spec);
+ error = maybe_abbrev(out, repo, spec);
+ if (!error)
+ return 0;
+
+ if (error < 0 && error != GIT_ENOTFOUND)
+ return error;
+
+ error = maybe_describe(out, repo, spec);
if (!error)
return 0;
@@ -217,7 +240,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out,
if (error < 0 && error != GIT_ENOTFOUND)
goto cleanup;
- error = maybe_sha_or_abbrev(out, repo, git_buf_cstr(&buf));
+ error = maybe_abbrev(out, repo, git_buf_cstr(&buf));
goto cleanup;
}
diff --git a/tests-clar/refs/revparse.c b/tests-clar/refs/revparse.c
index 81a6bc469..be92c1956 100644
--- a/tests-clar/refs/revparse.c
+++ b/tests-clar/refs/revparse.c
@@ -486,3 +486,112 @@ void test_refs_revparse__issue_994(void)
git_reference_free(head);
cl_git_sandbox_cleanup();
}
+
+/**
+ * $ git rev-parse blah-7-gc47800c
+ * c47800c7266a2be04c571c04d5a6614691ea99bd
+ *
+ * $ git rev-parse HEAD~3
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ *
+ * $ git branch blah-7-gc47800c HEAD~3
+ *
+ * $ git rev-parse blah-7-gc47800c
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ */
+void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void)
+{
+ git_repository *repo;
+ git_reference *branch;
+ git_object *target;
+ char sha[GIT_OID_HEXSZ + 1];
+
+ repo = cl_git_sandbox_init("testrepo.git");
+
+ test_object_inrepo("blah-7-gc47800c", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo);
+
+ cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
+ cl_git_pass(git_branch_create(&branch, repo, "blah-7-gc47800c", (git_commit *)target, 0));
+
+ git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target));
+
+ test_object_inrepo("blah-7-gc47800c", sha, repo);
+
+ git_reference_free(branch);
+ git_object_free(target);
+ cl_git_sandbox_cleanup();
+}
+
+/**
+ * $ git rev-parse a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ *
+ * $ git rev-parse HEAD~3
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ *
+ * $ git branch a65fedf39aefe402d3bb6e24df4d4f5fe4547750 HEAD~3
+ *
+ * $ git rev-parse a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ *
+ * $ git rev-parse heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ */
+void test_refs_revparse__try_to_retrieve_sha_before_branch(void)
+{
+ git_repository *repo;
+ git_reference *branch;
+ git_object *target;
+ char sha[GIT_OID_HEXSZ + 1];
+
+ repo = cl_git_sandbox_init("testrepo.git");
+
+ test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+
+ cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
+ cl_git_pass(git_branch_create(&branch, repo, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", (git_commit *)target, 0));
+
+ git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target));
+
+ test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+ test_object_inrepo("heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750", sha, repo);
+
+ git_reference_free(branch);
+ git_object_free(target);
+ cl_git_sandbox_cleanup();
+}
+
+/**
+ * $ git rev-parse c47800
+ * c47800c7266a2be04c571c04d5a6614691ea99bd
+ *
+ * $ git rev-parse HEAD~3
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ *
+ * $ git branch c47800 HEAD~3
+ *
+ * $ git rev-parse c47800
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ */
+void test_refs_revparse__try_to_retrieve_branch_before_abbrev_sha(void)
+{
+ git_repository *repo;
+ git_reference *branch;
+ git_object *target;
+ char sha[GIT_OID_HEXSZ + 1];
+
+ repo = cl_git_sandbox_init("testrepo.git");
+
+ test_object_inrepo("c47800", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo);
+
+ cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
+ cl_git_pass(git_branch_create(&branch, repo, "c47800", (git_commit *)target, 0));
+
+ git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target));
+
+ test_object_inrepo("c47800", sha, repo);
+
+ git_reference_free(branch);
+ git_object_free(target);
+ cl_git_sandbox_cleanup();
+}