]> git.proxmox.com Git - libgit2.git/commitdiff
branch: implement `git_branch_is_checked_out`
authorPatrick Steinhardt <ps@pks.im>
Fri, 6 Nov 2015 11:08:15 +0000 (12:08 +0100)
committerPatrick Steinhardt <ps@pks.im>
Mon, 13 Feb 2017 10:04:57 +0000 (11:04 +0100)
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.

include/git2/branch.h
src/branch.c

index 34354f4e571008037df136f8fc82d813d0288982..88fe723a0a5a52baab714054acc6487e9f4e2741 100644 (file)
@@ -245,6 +245,18 @@ GIT_EXTERN(int) git_branch_upstream_name(
 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.
  *
index 7ddcb3da707ecfa1e1433896187c9e6e79dedb9c..e48cb1f68043323094df0aa88ff6366d9352227a 100644 (file)
@@ -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;