diff options
author | Patrick Steinhardt <ps@pks.im> | 2020-06-17 14:43:27 +0200 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2020-07-12 18:12:16 +0200 |
commit | ac5fbe31edac2f126b21df69672b76077ee66933 (patch) | |
tree | e2d13da0c3a56f5d398acd0e3bf4fe18ad6a993d | |
parent | 7216b048f5bd3cdad6416295d128f0173cb74533 (diff) | |
download | libgit2-ac5fbe31edac2f126b21df69672b76077ee66933.tar.gz |
branch: determine whether a branch is checked out via refdb
We currently determine whether a branch is checked out via
`git_repository_foreach_head`. As this function reads references
directly from the disk, it breaks our refdb abstraction in case the
repository uses a different reference backend implementation than the
filesystem-based one. So let's use `git_repository_foreach_worktree`
instead -- while it's less efficient, it is at least correct in all
corner cases.
-rw-r--r-- | src/branch.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/src/branch.c b/src/branch.c index 770c9a1ee..715f6cf99 100644 --- a/src/branch.c +++ b/src/branch.c @@ -134,39 +134,37 @@ int git_branch_create_from_annotated( repository, branch_name, commit->commit, commit->description, force); } -static int branch_equals(git_repository *repo, const char *path, void *payload) +static int branch_is_checked_out(git_repository *worktree, void *payload) { git_reference *branch = (git_reference *) payload; git_reference *head = NULL; - int equal = 0; + int error; - if (git_reference__read_head(&head, repo, path) < 0 || - git_reference_type(head) != GIT_REFERENCE_SYMBOLIC) - goto done; + if (git_repository_is_bare(worktree)) + return 0; - equal = !git__strcmp(head->target.symbolic, branch->name); + if ((error = git_reference_lookup(&head, worktree, GIT_HEAD_FILE)) < 0) { + if (error == GIT_ENOTFOUND) + error = 0; + goto out; + } -done: + if (git_reference_type(head) != GIT_REFERENCE_SYMBOLIC) + goto out; + + error = !git__strcmp(head->target.symbolic, branch->name); + +out: git_reference_free(head); - return equal; + return error; } int git_branch_is_checked_out(const git_reference *branch) { - git_repository *repo; - int flags = 0; - - assert(branch); - if (!git_reference_is_branch(branch)) return 0; - - repo = git_reference_owner(branch); - - if (git_repository_is_bare(repo)) - flags |= GIT_REPOSITORY_FOREACH_HEAD_SKIP_REPO; - - return git_repository_foreach_head(repo, branch_equals, flags, (void *) branch) == 1; + return git_repository_foreach_worktree(git_reference_owner(branch), + branch_is_checked_out, (void *)branch) == 1; } int git_branch_delete(git_reference *branch) |