revwalk: Parse revision ranges All the hard work is already in revparse. Signed-off-by: Greg Price <price@mit.edu>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h
index 0af8062..8bfe0b5 100644
--- a/include/git2/revwalk.h
+++ b/include/git2/revwalk.h
@@ -217,6 +217,21 @@ GIT_EXTERN(int) git_revwalk_next(git_oid *out, git_revwalk *walk);
GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode);
/**
+ * Push and hide the respective endpoints of the given range.
+ *
+ * The range should be of the form
+ * <commit>..<commit>
+ * where each <commit> is in the form accepted by 'git_revparse_single'.
+ * The left-hand commit will be hidden and the right-hand commit pushed.
+ *
+ * @param walk the walker being used for the traversal
+ * @param range the range
+ * @return 0 or an error code
+ *
+ */
+GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range);
+
+/**
* Free a revision walker previously allocated.
*
* @param walk traversal handle to close. If NULL nothing occurs.
diff --git a/src/revwalk.c b/src/revwalk.c
index 02834ab..c107184 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -11,6 +11,7 @@
#include "pool.h"
#include "revwalk.h"
+#include "git2/revparse.h"
#include "merge.h"
#include <regex.h>
@@ -228,6 +229,30 @@ int git_revwalk_push_ref(git_revwalk *walk, const char *refname)
return push_ref(walk, refname, 0);
}
+int git_revwalk_push_range(git_revwalk *walk, const char *range)
+{
+ git_object *left, *right;
+ int threedots;
+ int error = 0;
+
+ if ((error = git_revparse_rangelike(&left, &right, &threedots, walk->repo, range)))
+ return error;
+ if (threedots) {
+ /* TODO: support "<commit>...<commit>" */
+ giterr_set(GITERR_INVALID, "Symmetric differences not implemented in revwalk");
+ return GIT_EINVALIDSPEC;
+ }
+
+ if ((error = push_commit(walk, git_object_id(left), 1)))
+ goto out;
+ error = push_commit(walk, git_object_id(right), 0);
+
+ out:
+ git_object_free(left);
+ git_object_free(right);
+ return error;
+}
+
int git_revwalk_hide_ref(git_revwalk *walk, const char *refname)
{
assert(walk && refname);
diff --git a/tests-clar/revwalk/basic.c b/tests-clar/revwalk/basic.c
index 2f1f817..e827762 100644
--- a/tests-clar/revwalk/basic.c
+++ b/tests-clar/revwalk/basic.c
@@ -38,6 +38,10 @@ static const int commit_sorting_time_reverse[][6] = {
{4, 5, 2, 1, 3, 0}
};
+static const int commit_sorting_segment[][6] = {
+ {1, 2, -1, -1, -1, -1}
+};
+
#define commit_count 6
static const int result_bytes = 24;
@@ -192,3 +196,11 @@ void test_revwalk_basic__disallow_non_commit(void)
cl_git_pass(git_oid_fromstr(&oid, "521d87c1ec3aef9824daf6d96cc0ae3710766d91"));
cl_git_fail(git_revwalk_push(_walk, &oid));
}
+
+void test_revwalk_basic__push_range(void)
+{
+ git_revwalk_reset(_walk);
+ git_revwalk_sorting(_walk, 0);
+ cl_git_pass(git_revwalk_push_range(_walk, "9fd738e~2..9fd738e"));
+ cl_git_pass(test_walk_only(_walk, commit_sorting_segment, 1));
+}