Commit f7367993cba7b6a3c72da0b4a09c0ae88c7446c0

Carlos Martín Nieto 2012-02-27T22:22:45

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.

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);
+}