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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
diff --git a/include/git2/branch.h b/include/git2/branch.h
index 34354f4..88fe723 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -246,6 +246,18 @@ GIT_EXTERN(int) git_branch_is_head(
const git_reference *branch);
/**
+ * Determine if the current branch is checked out in any linked
+ * repository.
+ *
+ * @param branch Reference to the branch.
+ *
+ * @return 1 if branch is checked out, 0 if it isn't,
+ * error code otherwise.
+ */
+GIT_EXTERN(int) git_branch_is_checked_out(
+ const git_reference *branch);
+
+/**
* Return the name of remote that the remote tracking branch belongs to.
*
* @param out Pointer to the user-allocated git_buf which will be filled with the name of the remote.
diff --git a/src/branch.c b/src/branch.c
index 7ddcb3d..e48cb1f 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -13,6 +13,7 @@
#include "refs.h"
#include "remote.h"
#include "annotated_commit.h"
+#include "worktree.h"
#include "git2/branch.h"
@@ -126,6 +127,62 @@ int git_branch_create_from_annotated(
repository, branch_name, commit->commit, commit->description, force);
}
+int git_branch_is_checked_out(
+ const git_reference *branch)
+{
+ git_buf path = GIT_BUF_INIT, buf = GIT_BUF_INIT;
+ git_strarray worktrees;
+ git_reference *ref = NULL;
+ git_repository *repo;
+ const char *worktree;
+ int found = false;
+ size_t i;
+
+ assert(branch && git_reference_is_branch(branch));
+
+ repo = git_reference_owner(branch);
+
+ if (git_worktree_list(&worktrees, repo) < 0)
+ return -1;
+
+ for (i = 0; i < worktrees.count; i++) {
+ worktree = worktrees.strings[i];
+
+ if (git_repository_head_for_worktree(&ref, repo, worktree) < 0)
+ continue;
+
+ if (git__strcmp(ref->name, branch->name) == 0) {
+ found = true;
+ git_reference_free(ref);
+ break;
+ }
+
+ git_reference_free(ref);
+ }
+ git_strarray_free(&worktrees);
+
+ if (found)
+ return found;
+
+ /* Check HEAD of parent */
+ if (git_buf_joinpath(&path, repo->commondir, GIT_HEAD_FILE) < 0)
+ goto out;
+ if (git_futils_readbuffer(&buf, path.ptr) < 0)
+ goto out;
+ if (git__prefixcmp(buf.ptr, "ref: ") == 0)
+ git_buf_consume(&buf, buf.ptr + strlen("ref: "));
+ git_buf_rtrim(&buf);
+
+ found = git__strcmp(buf.ptr, branch->name) == 0;
+
+out:
+ git_buf_free(&buf);
+ git_buf_free(&path);
+
+ return found;
+}
+
+
int git_branch_delete(git_reference *branch)
{
int is_head;