revwalk: add convenience function to push/hide HEAD It's not unusual to want the walker to act on HEAD, so add a convencience function for the case that the user doesn't already have a resolved HEAD reference.
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 97 98 99 100 101
diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h
index 020c898..e7ec2ab 100644
--- a/include/git2/revwalk.h
+++ b/include/git2/revwalk.h
@@ -117,6 +117,14 @@ GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid);
GIT_EXTERN(int) git_revwalk_push_glob(git_revwalk *walk, const char *glob);
/**
+ * Push the repository's HEAD
+ *
+ * @param walk the walker being used for the traversal
+ * @return GIT_SUCCESS or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
+
+/**
* Mark a commit (and its ancestors) uninteresting for the output.
*
* The given OID must belong to a commit on the walked
@@ -148,6 +156,14 @@ GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid);
GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob);
/**
+ * Hide the repository's HEAD
+ *
+ * @param walk the walker being used for the traversal
+ * @return GIT_SUCCESS or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
+
+/**
* Get the next commit from the revision walk.
*
* The initial call to this method is *not* blocking when
diff --git a/src/revwalk.c b/src/revwalk.c
index 8f818b8..cd971b5 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -391,6 +391,39 @@ int git_revwalk_hide_glob(git_revwalk *walk, const char *glob)
return push_glob(walk, glob, 1);
}
+static int push_head(git_revwalk *walk, int hide)
+{
+ git_reference *ref, *resolved;
+ int error;
+
+ error = git_reference_lookup(&ref, walk->repo, "HEAD");
+ if (error < GIT_SUCCESS) {
+ return error;
+ }
+ error = git_reference_resolve(&resolved, ref);
+ if (error < GIT_SUCCESS) {
+ return error;
+ }
+ git_reference_free(ref);
+
+ error = push_commit(walk, git_reference_oid(resolved), hide);
+
+ git_reference_free(resolved);
+ return error;
+}
+
+int git_revwalk_push_head(git_revwalk *walk)
+{
+ assert(walk);
+ return push_head(walk, 0);
+}
+
+int git_revwalk_hide_head(git_revwalk *walk)
+{
+ assert(walk);
+ return push_head(walk, 1);
+}
+
static int revwalk_enqueue_timesort(git_revwalk *walk, commit_object *commit)
{
return git_pqueue_insert(&walk->iterator_time, commit);
diff --git a/tests-clar/revwalk/basic.c b/tests-clar/revwalk/basic.c
index f013945..fff93ec 100644
--- a/tests-clar/revwalk/basic.c
+++ b/tests-clar/revwalk/basic.c
@@ -132,3 +132,18 @@ void test_revwalk_basic__glob_heads(void)
/* git log --branches --oneline | wc -l => 13 */
cl_assert(i == 13);
}
+
+void test_revwalk_basic__push_head(void)
+{
+ int i = 0;
+ git_oid oid;
+
+ cl_git_pass(git_revwalk_push_head(_walk));
+
+ while (git_revwalk_next(&oid, _walk) == GIT_SUCCESS) {
+ i++;
+ }
+
+ /* git log HEAD --oneline | wc -l => 7 */
+ cl_assert(i == 7);
+}