Skip to content

Commit ac5fbe3

Browse files
committed
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.
1 parent 7216b04 commit ac5fbe3

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

src/branch.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,39 +134,37 @@ int git_branch_create_from_annotated(
134134
repository, branch_name, commit->commit, commit->description, force);
135135
}
136136

137-
static int branch_equals(git_repository *repo, const char *path, void *payload)
137+
static int branch_is_checked_out(git_repository *worktree, void *payload)
138138
{
139139
git_reference *branch = (git_reference *) payload;
140140
git_reference *head = NULL;
141-
int equal = 0;
141+
int error;
142142

143-
if (git_reference__read_head(&head, repo, path) < 0 ||
144-
git_reference_type(head) != GIT_REFERENCE_SYMBOLIC)
145-
goto done;
143+
if (git_repository_is_bare(worktree))
144+
return 0;
146145

147-
equal = !git__strcmp(head->target.symbolic, branch->name);
146+
if ((error = git_reference_lookup(&head, worktree, GIT_HEAD_FILE)) < 0) {
147+
if (error == GIT_ENOTFOUND)
148+
error = 0;
149+
goto out;
150+
}
148151

149-
done:
152+
if (git_reference_type(head) != GIT_REFERENCE_SYMBOLIC)
153+
goto out;
154+
155+
error = !git__strcmp(head->target.symbolic, branch->name);
156+
157+
out:
150158
git_reference_free(head);
151-
return equal;
159+
return error;
152160
}
153161

154162
int git_branch_is_checked_out(const git_reference *branch)
155163
{
156-
git_repository *repo;
157-
int flags = 0;
158-
159-
assert(branch);
160-
161164
if (!git_reference_is_branch(branch))
162165
return 0;
163-
164-
repo = git_reference_owner(branch);
165-
166-
if (git_repository_is_bare(repo))
167-
flags |= GIT_REPOSITORY_FOREACH_HEAD_SKIP_REPO;
168-
169-
return git_repository_foreach_head(repo, branch_equals, flags, (void *) branch) == 1;
166+
return git_repository_foreach_worktree(git_reference_owner(branch),
167+
branch_is_checked_out, (void *)branch) == 1;
170168
}
171169

172170
int git_branch_delete(git_reference *branch)

0 commit comments

Comments
 (0)