The worktree id is relatively hidden from the user, however, there may be times where a user or script needs to determine the worktree id for a linked worktree (e.g., to manually operate on some refs). While the id is stored in the worktree `.git` file, it would be nice if there was an easier method of obtaining it. This teaches Git to output the worktree id (for linked worktrees) in the `worktree list` verbose and porcelain modes. Signed-off-by: Caleb White <cdwhite3@xxxxx> --- Documentation/git-worktree.txt | 12 +++++++++++- builtin/worktree.c | 5 +++++ t/t2402-worktree-list.sh | 16 ++++++++++------ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index e0604b043361828f94b58f676a5ed4f15b116348..2bd8118852a97251fc1081d19ea9756428d190f4 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -428,16 +428,21 @@ $ git worktree list For these annotations, a reason might also be available and this can be seen using the verbose mode. The annotation is then moved to the next line -indented followed by the additional information. +indented followed by the additional information. In verbose mode, the worktree +id is also shown on the next line if available. ------------ $ git worktree list --verbose /path/to/linked-worktree abcd1234 [master] + id: linked-worktree-12345678 /path/to/locked-worktree-no-reason abcd5678 (detached HEAD) locked + id: locked-worktree-no-reason-89765464 /path/to/locked-worktree-with-reason 1234abcd (brancha) locked: worktree path is mounted on a portable device + id: locked-worktree-with-reason-41564654 /path/to/prunable-worktree 5678abc1 (detached HEAD) prunable: gitdir file points to non-existent location + id: prunable-worktree-98454651 ------------ Note that the annotation is moved to the next line if the additional @@ -461,24 +466,29 @@ worktree /path/to/bare-source bare worktree /path/to/linked-worktree +id linked-worktree-12345678 HEAD abcd1234abcd1234abcd1234abcd1234abcd1234 branch refs/heads/master worktree /path/to/other-linked-worktree +id other-linked-worktree-879456466 HEAD 1234abc1234abc1234abc1234abc1234abc1234a detached worktree /path/to/linked-worktree-locked-no-reason +id locked-worktree-no-reason-89765464 HEAD 5678abc5678abc5678abc5678abc5678abc5678c branch refs/heads/locked-no-reason locked worktree /path/to/linked-worktree-locked-with-reason +id locked-worktree-with-reason-41564654 HEAD 3456def3456def3456def3456def3456def3456b branch refs/heads/locked-with-reason locked reason why is locked worktree /path/to/linked-worktree-prunable +id prunable-worktree-98454651 HEAD 1233def1234def1234def1234def1234def1234b detached prunable gitdir file points to non-existent location diff --git a/builtin/worktree.c b/builtin/worktree.c index 36235546b492803707707ff208b13fe777bff1b4..fca8a9cda51643e434b5f8905e32e537c6b4418b 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -944,6 +944,8 @@ static void show_worktree_porcelain(struct worktree *wt, int line_terminator) const char *reason; printf("worktree %s%c", wt->path, line_terminator); + if (!is_main_worktree(wt)) + printf("id %s%c", wt->id, line_terminator); if (wt->is_bare) printf("bare%c", line_terminator); else { @@ -1009,6 +1011,9 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len) else if (reason) strbuf_addstr(&sb, " prunable"); + if (verbose && !is_main_worktree(wt)) + strbuf_addf(&sb, "\n\tid: %s", wt->id); + printf("%s\n", sb.buf); strbuf_release(&sb); } diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index 780daa6cd6351f8fa9434619cc212aade8f01420..502d35cabb837121d178937673b580cd767d17aa 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -56,8 +56,9 @@ test_expect_success '"list" all worktrees --porcelain' ' echo "branch $(git symbolic-ref HEAD)" >>expect && echo >>expect && test_when_finished "rm -rf here actual expect && git worktree prune" && - git worktree add --detach here main && + GIT_TEST_WORKTREE_SUFFIX=123 git worktree add --detach here main && echo "worktree $(git -C here rev-parse --show-toplevel)" >>expect && + echo "id here-123" >>expect && echo "HEAD $(git rev-parse HEAD)" >>expect && echo "detached" >>expect && echo >>expect && @@ -71,9 +72,10 @@ test_expect_success '"list" all worktrees --porcelain -z' ' printf "worktree %sQHEAD %sQbranch %sQQ" \ "$(git rev-parse --show-toplevel)" \ $(git rev-parse HEAD --symbolic-full-name HEAD) >expect && - git worktree add --detach here main && - printf "worktree %sQHEAD %sQdetachedQQ" \ + GIT_TEST_WORKTREE_SUFFIX=456 git worktree add --detach here main && + printf "worktree %sQid %sQHEAD %sQdetachedQQ" \ "$(git -C here rev-parse --show-toplevel)" \ + "here-456" \ "$(git rev-parse HEAD)" >>expect && git worktree list --porcelain -z >_actual && nul_to_q <_actual >actual && @@ -166,16 +168,17 @@ test_expect_success '"list" --verbose and --porcelain mutually exclusive' ' test_expect_success '"list" all worktrees --verbose with locked' ' test_when_finished "rm -rf locked1 locked2 out actual expect && git worktree prune" && git worktree add locked1 --detach && - git worktree add locked2 --detach && + GIT_TEST_WORKTREE_SUFFIX=456 git worktree add locked2 --detach && git worktree lock locked1 && test_when_finished "git worktree unlock locked1" && git worktree lock locked2 --reason "with reason" && test_when_finished "git worktree unlock locked2" && echo "$(git -C locked2 rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >expect && printf "\tlocked: with reason\n" >>expect && + printf "\tid: locked2-456\n" >>expect && git worktree list --verbose >out && grep "/locked1 *[0-9a-f].* locked$" out && - sed -n "s/ */ /g;/\/locked2 *[0-9a-f].*$/,/locked: .*$/p" <out >actual && + sed -n "s/ */ /g;/\/locked2 *[0-9a-f].*$/,/id: .*$/p" <out >actual && test_cmp actual expect ' @@ -211,11 +214,12 @@ test_expect_success '"list" all worktrees from bare main' ' test_expect_success '"list" all worktrees --porcelain from bare main' ' test_when_finished "rm -rf there actual expect && git -C bare1 worktree prune" && - git -C bare1 worktree add --detach ../there main && + GIT_TEST_WORKTREE_SUFFIX=456 git -C bare1 worktree add --detach ../there main && echo "worktree $(pwd)/bare1" >expect && echo "bare" >>expect && echo >>expect && echo "worktree $(git -C there rev-parse --show-toplevel)" >>expect && + echo "id there-456" >>expect && echo "HEAD $(git -C there rev-parse HEAD)" >>expect && echo "detached" >>expect && echo >>expect && -- 2.47.0