In order to more clearly display which branches are active, the output
of git branch is modified to colorize branches checked out in any linked
worktrees with the same color as the current branch.

This is meant to simplify workflows related to worktree, particularly
due to the limitations of not being able to check out the same branch in
two worktrees and the inability to delete a branch checked out in a
worktree. When performing branch operations like checkout and delete, it
would be useful to know more readily if the branches in which the user
is interested are already checked out in a worktree.

The git worktree list command contains the relevant information, however
this is a much less frquently used command than git branch.

Signed-off-by: Nickolai Belakovski <nbelakov...@gmail.com>
---

Notes:
    Travis CI results: https://travis-ci.org/nbelakovski/git/builds/432320949

 builtin/branch.c         | 35 ++++++++++++++++++++++++++++++-----
 t/t3203-branch-output.sh | 21 +++++++++++++++++++++
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 4fc55c350..65b58ff7c 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -334,11 +334,36 @@ static char *build_format(struct ref_filter
*filter, int maxwidth, const char *r
        struct strbuf local = STRBUF_INIT;
        struct strbuf remote = STRBUF_INIT;

-       strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else)  %s%%(end)",
-                   branch_get_color(BRANCH_COLOR_CURRENT),
-                   branch_get_color(BRANCH_COLOR_LOCAL));
-       strbuf_addf(&remote, "  %s",
-                   branch_get_color(BRANCH_COLOR_REMOTE));
+       // Prepend the current branch of this worktree with "* " and
all other branches with "  "
+       strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %%(else)  %%(end)");
+       // Prepend remote branches with two spaces
+       strbuf_addstr(&remote, "  ");
+       if(want_color(branch_use_color)) {
+               // Create a nested if statement to evaluate if the
current ref is equal to a HEAD ref from either
+               // the main or any linked worktrees. If so, color it
CURRENT, otherwise color it LOCAL
+               struct strbuf color = STRBUF_INIT;
+               struct worktree **worktrees = get_worktrees(0);
+               int i;
+               for (i = 0; worktrees[i]; ++i) {
+                       strbuf_addf(&color,
"%%(if:equals=%s)%%(refname)%%(then)%s%%(else)",
+                                   worktrees[i]->head_ref,
+                                   branch_get_color(BRANCH_COLOR_CURRENT));
+               }
+               // add one more check in the nested if-else to cover
the detached HEAD state
+               strbuf_addf(&color, "%%(if)%%(HEAD)%%(then)%s%%(else)%s%%(end)",
+                           branch_get_color(BRANCH_COLOR_CURRENT),
+                           branch_get_color(BRANCH_COLOR_LOCAL));
+               // close up the nested if-else
+               for (; i > 0; --i) {
+                       strbuf_addf(&color, "%%(end)");
+               }
+               free_worktrees(worktrees);
+               strbuf_addbuf(&local, &color);
+               strbuf_release(&color);
+
+               strbuf_addf(&remote, "%s",
+                           branch_get_color(BRANCH_COLOR_REMOTE));
+    }

        if (filter->verbose) {
                struct strbuf obname = STRBUF_INIT;
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index ee6787614..369a156c0 100755
--- a/t/t3203-branch-output.sh
+++ b/t/t3203-branch-output.sh
@@ -240,6 +240,27 @@ test_expect_success 'git branch --format option' '
        test_i18ncmp expect actual
 '

+test_expect_success '"add" a worktree' '
+       mkdir worktree_dir &&
+       git worktree add -b master_worktree worktree_dir master
+'
+
+cat >expect <<'EOF'
+* <GREEN>(HEAD detached from fromtag)<RESET>
+  ambiguous<RESET>
+  branch-one<RESET>
+  branch-two<RESET>
+  master<RESET>
+  <GREEN>master_worktree<RESET>
+  ref-to-branch<RESET> -> branch-one
+  ref-to-remote<RESET> -> origin/branch-one
+EOF
+test_expect_success TTY 'worktree colors correct' '
+       test_terminal git branch >actual.raw &&
+       test_decode_color <actual.raw >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success "set up color tests" '
        echo "<RED>master<RESET>" >expect.color &&
        echo "master" >expect.bare &&

-- 
2.14.2

Reply via email to