summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2017-04-04 18:44:29 +0200
committerPatrick Steinhardt <ps@pks.im>2017-04-05 13:50:38 +0200
commit74511aa2041b16b856932b53565c6a1127d0f8be (patch)
treef16e0c99e8883678aaef113680d1bd7019b31a35
parent3e84aa506d8f3160aa8cda77f97e27a463c778b0 (diff)
downloadlibgit2-74511aa2041b16b856932b53565c6a1127d0f8be.tar.gz
repository: add function to iterate over all HEADs
While we already provide functions to get the current repository's HEAD, it is quite involved to iterate over HEADs of both the repository and all linked work trees. This commit implements a function `git_repository_foreach_head`, which accepts a callback which is then called for all HEAD files.
-rw-r--r--src/repository.c32
-rw-r--r--src/repository.h20
2 files changed, 52 insertions, 0 deletions
diff --git a/src/repository.c b/src/repository.c
index 7eb5bed80..707b7b7bd 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -2137,6 +2137,38 @@ out:
return error;
}
+int git_repository_foreach_head(git_repository *repo, git_repository_foreach_head_cb cb, void *payload)
+{
+ git_strarray worktrees = GIT_VECTOR_INIT;
+ git_buf path = GIT_BUF_INIT;
+ int error;
+ size_t i;
+
+ /* Execute callback for HEAD of commondir */
+ if ((error = git_buf_joinpath(&path, repo->commondir, GIT_HEAD_FILE)) < 0 ||
+ (error = cb(repo, path.ptr, payload) != 0))
+ goto out;
+
+ if ((error = git_worktree_list(&worktrees, repo)) < 0) {
+ error = 0;
+ goto out;
+ }
+
+ /* Execute callback for all worktree HEADs */
+ for (i = 0; i < worktrees.count; i++) {
+ if (get_worktree_file_path(&path, repo, worktrees.strings[i], GIT_HEAD_FILE) < 0)
+ continue;
+
+ if ((error = cb(repo, path.ptr, payload)) != 0)
+ goto out;
+ }
+
+out:
+ git_buf_free(&path);
+ git_strarray_free(&worktrees);
+ return error;
+}
+
int git_repository_head_unborn(git_repository *repo)
{
git_reference *ref = NULL;
diff --git a/src/repository.h b/src/repository.h
index 33adfa60a..f922d00f2 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -160,6 +160,26 @@ int git_repository_head_tree(git_tree **tree, git_repository *repo);
int git_repository_create_head(const char *git_dir, const char *ref_name);
/*
+ * Called for each HEAD.
+ *
+ * Can return either 0, causing the iteration over HEADs to
+ * continue, or a non-0 value causing the iteration to abort. The
+ * return value is passed back to the caller of
+ * `git_repository_foreach_head`
+ */
+typedef int (*git_repository_foreach_head_cb)(git_repository *repo, const char *path, void *payload);
+
+/*
+ * Iterate over repository and all worktree HEADs.
+ *
+ * This function will be called for the repository HEAD and for
+ * all HEADS of linked worktrees. For each HEAD, the callback is
+ * executed with the given payload. The return value equals the
+ * return value of the last executed callback function.
+ */
+int git_repository_foreach_head(git_repository *repo, git_repository_foreach_head_cb cb, void *payload);
+
+/*
* Weak pointers to repository internals.
*
* The returned pointers do not need to be freed. Do not keep