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 @@ -159,6 +159,26 @@ GIT_INLINE(git_attr_cache *) git_repository_attr_cache(git_repository *repo) 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. *