summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlosmn@github.com>2017-05-20 14:13:27 +0200
committerGitHub <noreply@github.com>2017-05-20 14:13:27 +0200
commit119bdd86582b3e98a107531def666c8ac7bb15b1 (patch)
tree3ea399a45cccfc2ef2bfe53890382d5bfbc4cbe8
parent924f5d129ea826b9ce93dc62eb1a8d445788d832 (diff)
parent8b107dc5e1cd0745628e2bfb473477342c719f25 (diff)
downloadlibgit2-119bdd86582b3e98a107531def666c8ac7bb15b1.tar.gz
Merge pull request #4231 from wabain/open-revrange
revparse: support open-ended ranges
-rw-r--r--src/revparse.c25
-rw-r--r--tests/refs/revparse.c35
2 files changed, 57 insertions, 3 deletions
diff --git a/src/revparse.c b/src/revparse.c
index d5511b47b..fd6bd1ea6 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -892,6 +892,17 @@ int git_revparse(
const char *rstr;
revspec->flags = GIT_REVPARSE_RANGE;
+ /*
+ * Following git.git, don't allow '..' because it makes command line
+ * arguments which can be either paths or revisions ambiguous when the
+ * path is almost certainly intended. The empty range '...' is still
+ * allowed.
+ */
+ if (!git__strcmp(spec, "..")) {
+ giterr_set(GITERR_INVALID, "Invalid pattern '..'");
+ return GIT_EINVALIDSPEC;
+ }
+
lstr = git__substrdup(spec, dotdot - spec);
rstr = dotdot + 2;
if (dotdot[2] == '.') {
@@ -899,9 +910,17 @@ int git_revparse(
rstr++;
}
- error = git_revparse_single(&revspec->from, repo, lstr);
- if (!error)
- error = git_revparse_single(&revspec->to, repo, rstr);
+ error = git_revparse_single(
+ &revspec->from,
+ repo,
+ *lstr == '\0' ? "HEAD" : lstr);
+
+ if (!error) {
+ error = git_revparse_single(
+ &revspec->to,
+ repo,
+ *rstr == '\0' ? "HEAD" : rstr);
+ }
git__free((void*)lstr);
} else {
diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c
index c22c30440..459188cf7 100644
--- a/tests/refs/revparse.c
+++ b/tests/refs/revparse.c
@@ -122,6 +122,14 @@ static void test_id(
test_id_inrepo(spec, expected_left, expected_right, expected_flags, g_repo);
}
+static void test_invalid_revspec(const char* invalid_spec)
+{
+ git_revspec revspec;
+
+ cl_assert_equal_i(
+ GIT_EINVALIDSPEC, git_revparse(&revspec, g_repo, invalid_spec));
+}
+
void test_refs_revparse__initialize(void)
{
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
@@ -749,6 +757,33 @@ void test_refs_revparse__parses_range_operator(void)
"4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
+
+ test_id("HEAD~3..",
+ "4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ GIT_REVPARSE_RANGE);
+
+ test_id("HEAD~3...",
+ "4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
+
+ test_id("..HEAD~3",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ "4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+ GIT_REVPARSE_RANGE);
+
+ test_id("...HEAD~3",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ "4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+ GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
+
+ test_id("...",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
+
+ test_invalid_revspec("..");
}
void test_refs_revparse__ext_retrieves_both_the_reference_and_its_target(void)