branch: update output to include worktree info

The output of git branch is modified to mark branches checked out in a linked worktree with a "+" and color them in cyan (in contrast to the current branch, which will still be denoted with a "*" and colored in green) This is meant to communicate to the user that the branches that are marked or colored will behave differently from other branches if the user attempts to check them out or delete them, since branches checked out in another worktree cannot be checked out or deleted. Signed-off-by: Nickolai Belakovski <nbelakovski@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nickolai Belakovski committed Apr 28, 2019 at 22:19 UTC ab3138146f9ce1d819cefab4515965604de76d9d
4 files changed +45 -13
Documentation/git-branch.txt
+4 -2
@@ -26,8 +26,10 @@ DESCRIPTION
26 -----------
27
28 If `--list` is given, or if there are no non-option arguments, existing
29 -branches are listed; the current branch will be highlighted with an
30 -asterisk. Option `-r` causes the remote-tracking branches to be listed,
29 +branches are listed; the current branch will be highlighted in green and
30 +marked with an asterisk. Any branches checked out in linked worktrees will
31 +be highlighted in cyan and marked with a plus sign. Option `-r` causes the
32 +remote-tracking branches to be listed,
33 and option `-a` shows both local and remote branches. If a `<pattern>`
34 is given, it is used as a shell wildcard to restrict the output to
35 matching branches. If multiple patterns are given, a branch is shown if
builtin/branch.c
+8 -4
@@ -47,6 +47,7 @@ static char branch_colors[][COLOR_MAXLEN] = {
47 GIT_COLOR_NORMAL, /* LOCAL */
48 GIT_COLOR_GREEN, /* CURRENT */
49 GIT_COLOR_BLUE, /* UPSTREAM */
50 + GIT_COLOR_CYAN, /* WORKTREE */
51 };
52 enum color_branch {
53 BRANCH_COLOR_RESET = 0,
@@ -54,7 +55,8 @@ enum color_branch {
55 BRANCH_COLOR_REMOTE = 2,
56 BRANCH_COLOR_LOCAL = 3,
57 BRANCH_COLOR_CURRENT = 4,
57 - BRANCH_COLOR_UPSTREAM = 5
58 + BRANCH_COLOR_UPSTREAM = 5,
59 + BRANCH_COLOR_WORKTREE = 6
60 };
61
62 static const char *color_branch_slots[] = {
@@ -64,6 +66,7 @@ static const char *color_branch_slots[] = {
66 [BRANCH_COLOR_LOCAL] = "local",
67 [BRANCH_COLOR_CURRENT] = "current",
68 [BRANCH_COLOR_UPSTREAM] = "upstream",
69 + [BRANCH_COLOR_WORKTREE] = "worktree",
70 };
71
72 static struct string_list output = STRING_LIST_INIT_DUP;
@@ -342,9 +345,10 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
345 struct strbuf local = STRBUF_INIT;
346 struct strbuf remote = STRBUF_INIT;
347
345 - strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else) %s%%(end)",
346 - branch_get_color(BRANCH_COLOR_CURRENT),
347 - branch_get_color(BRANCH_COLOR_LOCAL));
348 + strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else)%%(if)%%(worktreepath)%%(then)+ %s%%(else) %s%%(end)%%(end)",
349 + branch_get_color(BRANCH_COLOR_CURRENT),
350 + branch_get_color(BRANCH_COLOR_WORKTREE),
351 + branch_get_color(BRANCH_COLOR_LOCAL));
352 strbuf_addf(&remote, " %s",
353 branch_get_color(BRANCH_COLOR_REMOTE));
354
t/t3200-branch.sh
+11 -5
@@ -202,18 +202,22 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
202 git worktree add -f bazdir2 baz &&
203 git branch -M baz bam &&
204 test $(git -C bazdir rev-parse --abbrev-ref HEAD) = bam &&
205 - test $(git -C bazdir2 rev-parse --abbrev-ref HEAD) = bam
205 + test $(git -C bazdir2 rev-parse --abbrev-ref HEAD) = bam &&
206 + rm -r bazdir bazdir2 &&
207 + git worktree prune
208 '
209
210 test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' '
211 git checkout -b baz &&
210 - git worktree add -f bazdir3 baz &&
212 + git worktree add -f bazdir baz &&
213 (
212 - cd bazdir3 &&
214 + cd bazdir &&
215 git branch -M baz bam &&
216 test $(git rev-parse --abbrev-ref HEAD) = bam
217 ) &&
216 - test $(git rev-parse --abbrev-ref HEAD) = bam
218 + test $(git rev-parse --abbrev-ref HEAD) = bam &&
219 + rm -r bazdir &&
220 + git worktree prune
221 '
222
223 test_expect_success 'git branch -M master should work when master is checked out' '
@@ -774,7 +778,9 @@ test_expect_success 'test deleting branch without config' '
778 test_expect_success 'deleting currently checked out branch fails' '
779 git worktree add -b my7 my7 &&
780 test_must_fail git -C my7 branch -d my7 &&
777 - test_must_fail git branch -d my7
781 + test_must_fail git branch -d my7 &&
782 + rm -r my7 &&
783 + git worktree prune
784 '
785
786 test_expect_success 'test --track without .fetch entries' '
t/t3203-branch-output.sh
+22 -2
@@ -136,11 +136,13 @@ test_expect_success 'git branch `--show-current` works properly with worktrees'
136 branch-two
137 EOF
138 git checkout branch-one &&
139 - git worktree add worktree branch-two &&
139 + git worktree add worktree_dir branch-two &&
140 {
141 git branch --show-current &&
142 - git -C worktree branch --show-current
142 + git -C worktree_dir branch --show-current
143 } >actual &&
144 + rm -r worktree_dir &&
145 + git worktree prune &&
146 test_cmp expect actual
147 '
148
@@ -284,6 +286,24 @@ test_expect_success 'git branch --format option' '
286 test_i18ncmp expect actual
287 '
288
289 +test_expect_success 'worktree colors correct' '
290 + cat >expect <<-EOF &&
291 + * <GREEN>(HEAD detached from fromtag)<RESET>
292 + ambiguous<RESET>
293 + branch-one<RESET>
294 + + <CYAN>branch-two<RESET>
295 + master<RESET>
296 + ref-to-branch<RESET> -> branch-one
297 + ref-to-remote<RESET> -> origin/branch-one
298 + EOF
299 + git worktree add worktree_dir branch-two &&
300 + git branch --color >actual.raw &&
301 + rm -r worktree_dir &&
302 + git worktree prune &&
303 + test_decode_color <actual.raw >actual &&
304 + test_i18ncmp expect actual
305 +'
306 +
307 test_expect_success "set up color tests" '
308 echo "<RED>master<RESET>" >expect.color &&
309 echo "master" >expect.bare &&