]> git.proxmox.com Git - libgit2.git/commitdiff
revwalk: Parse revision ranges
authorGreg Price <price@mit.edu>
Mon, 4 Mar 2013 04:54:23 +0000 (20:54 -0800)
committerGreg Price <price@mit.edu>
Sun, 7 Apr 2013 03:51:16 +0000 (20:51 -0700)
All the hard work is already in revparse.

Signed-off-by: Greg Price <price@mit.edu>
include/git2/revwalk.h
src/revwalk.c
tests-clar/revwalk/basic.c

index 0af80625e316ce84c16995dc13b6707bf8bc0b38..8bfe0b502da9c1a9008910302d08dbd2b145d2dc 100644 (file)
@@ -216,6 +216,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.
  *
index 02834ab36597aa78111b71965f3c57b75b83847a..c1071843b2f8913f6e4004c30a74911f3ec95b60 100644 (file)
@@ -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);
index 2f1f817c93b85400a9b7cb478d158e389430e5c8..e8277626059b2135b8182ef75dc50332d8b3d939 100644 (file)
@@ -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));
+}