Skip to content

Commit e3acd37

Browse files
committed
branch: implement git_branch_is_checked_out
Implement a new function that is able to determine if a branch is checked out in any repository connected to the current repository. In particular, this is required to check if for a given repository and branch, there exists any working tree connected to that repository that is referencing this branch.
1 parent 4321595 commit e3acd37

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

include/git2/branch.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,18 @@ GIT_EXTERN(int) git_branch_upstream_name(
245245
GIT_EXTERN(int) git_branch_is_head(
246246
const git_reference *branch);
247247

248+
/**
249+
* Determine if the current branch is checked out in any linked
250+
* repository.
251+
*
252+
* @param branch Reference to the branch.
253+
*
254+
* @return 1 if branch is checked out, 0 if it isn't,
255+
* error code otherwise.
256+
*/
257+
GIT_EXTERN(int) git_branch_is_checked_out(
258+
const git_reference *branch);
259+
248260
/**
249261
* Return the name of remote that the remote tracking branch belongs to.
250262
*

src/branch.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "refs.h"
1414
#include "remote.h"
1515
#include "annotated_commit.h"
16+
#include "worktree.h"
1617

1718
#include "git2/branch.h"
1819

@@ -126,6 +127,62 @@ int git_branch_create_from_annotated(
126127
repository, branch_name, commit->commit, commit->description, force);
127128
}
128129

130+
int git_branch_is_checked_out(
131+
const git_reference *branch)
132+
{
133+
git_buf path = GIT_BUF_INIT, buf = GIT_BUF_INIT;
134+
git_strarray worktrees;
135+
git_reference *ref = NULL;
136+
git_repository *repo;
137+
const char *worktree;
138+
int found = false;
139+
size_t i;
140+
141+
assert(branch && git_reference_is_branch(branch));
142+
143+
repo = git_reference_owner(branch);
144+
145+
if (git_worktree_list(&worktrees, repo) < 0)
146+
return -1;
147+
148+
for (i = 0; i < worktrees.count; i++) {
149+
worktree = worktrees.strings[i];
150+
151+
if (git_repository_head_for_worktree(&ref, repo, worktree) < 0)
152+
continue;
153+
154+
if (git__strcmp(ref->name, branch->name) == 0) {
155+
found = true;
156+
git_reference_free(ref);
157+
break;
158+
}
159+
160+
git_reference_free(ref);
161+
}
162+
git_strarray_free(&worktrees);
163+
164+
if (found)
165+
return found;
166+
167+
/* Check HEAD of parent */
168+
if (git_buf_joinpath(&path, repo->commondir, GIT_HEAD_FILE) < 0)
169+
goto out;
170+
if (git_futils_readbuffer(&buf, path.ptr) < 0)
171+
goto out;
172+
if (git__prefixcmp(buf.ptr, "ref: ") == 0)
173+
git_buf_consume(&buf, buf.ptr + strlen("ref: "));
174+
git_buf_rtrim(&buf);
175+
176+
found = git__strcmp(buf.ptr, branch->name) == 0;
177+
178+
out:
179+
git_buf_free(&buf);
180+
git_buf_free(&path);
181+
182+
return found;
183+
}
184+
185+
129186
int git_branch_delete(git_reference *branch)
130187
{
131188
int is_head;

0 commit comments

Comments
 (0)