diff options
-rw-r--r-- | Documentation/git-worktree.txt | 20 | ||||
-rw-r--r-- | builtin/worktree.c | 14 | ||||
-rwxr-xr-x | t/t2402-worktree-list.sh | 31 |
3 files changed, 63 insertions, 2 deletions
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 240c3fd76b..f1bb1fa5f5 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -232,6 +232,8 @@ This can also be set up as the default behaviour by using the -v:: --verbose:: With `prune`, report all removals. ++ +With `list`, output additional information about worktrees (see below). --expire <time>:: With `prune`, only expire unused working trees older than `<time>`. @@ -389,6 +391,24 @@ $ git worktree list /path/to/prunable-worktree 5678abc (detached HEAD) prunable ------------ +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. + +------------ +$ git worktree list --verbose +/path/to/linked-worktree abcd1234 [master] +/path/to/locked-worktree-no-reason abcd5678 (detached HEAD) locked +/path/to/locked-worktree-with-reason 1234abcd (brancha) + locked: working tree path is mounted on a portable device +/path/to/prunable-worktree 5678abc1 (detached HEAD) + prunable: gitdir file points to non-existent location +------------ + +Note that the annotation is moved to the next line if the additional +information is available, otherwise it stays on the same line as the +working tree itself. + Porcelain Format ~~~~~~~~~~~~~~~~ The porcelain format has a line per attribute. Attributes are listed with a diff --git a/builtin/worktree.c b/builtin/worktree.c index 20944c266e..1cd5c2016e 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -604,6 +604,7 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len) struct strbuf sb = STRBUF_INIT; int cur_path_len = strlen(wt->path); int path_adj = cur_path_len - utf8_strwidth(wt->path); + const char *reason; strbuf_addf(&sb, "%-*s ", 1 + path_maxlen + path_adj, wt->path); if (wt->is_bare) @@ -621,10 +622,16 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len) strbuf_addstr(&sb, "(error)"); } - if (worktree_lock_reason(wt)) + reason = worktree_lock_reason(wt); + if (verbose && reason && *reason) + strbuf_addf(&sb, "\n\tlocked: %s", reason); + else if (reason) strbuf_addstr(&sb, " locked"); - if (worktree_prune_reason(wt, expire)) + reason = worktree_prune_reason(wt, expire); + if (verbose && reason) + strbuf_addf(&sb, "\n\tprunable: %s", reason); + else if (reason) strbuf_addstr(&sb, " prunable"); printf("%s\n", sb.buf); @@ -670,6 +677,7 @@ static int list(int ac, const char **av, const char *prefix) struct option options[] = { OPT_BOOL(0, "porcelain", &porcelain, N_("machine-readable output")), + OPT__VERBOSE(&verbose, N_("show extended annotations and reasons, if available")), OPT_EXPIRY_DATE(0, "expire", &expire, N_("add 'prunable' annotation to worktrees older than <time>")), OPT_END() @@ -679,6 +687,8 @@ static int list(int ac, const char **av, const char *prefix) ac = parse_options(ac, av, prefix, options, worktree_usage, 0); if (ac) usage_with_options(worktree_usage, options); + else if (verbose && porcelain) + die(_("--verbose and --porcelain are mutually exclusive")); else { struct worktree **worktrees = get_worktrees(); int path_maxlen = 0, abbrev = DEFAULT_ABBREV, i; diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index 69342b7280..39a339e636 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -136,6 +136,37 @@ test_expect_success '"list" all worktrees with prunable consistent with "prune"' test_i18ngrep ! "^Removing worktrees/unprunable" out ' +test_expect_success '"list" --verbose and --porcelain mutually exclusive' ' + test_must_fail git worktree list --verbose --porcelain +' + +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 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 && + git worktree list --verbose >out && + grep "/locked1 *[0-9a-f].* locked$" out && + sed -n "s/ */ /g;/\/locked2 *[0-9a-f].*$/,/locked: .*$/p" <out >actual && + test_cmp actual expect +' + +test_expect_success '"list" all worktrees --verbose with prunable' ' + test_when_finished "rm -rf prunable out actual expect && git worktree prune" && + git worktree add prunable --detach && + echo "$(git -C prunable rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >expect && + printf "\tprunable: gitdir file points to non-existent location\n" >>expect && + rm -rf prunable && + git worktree list --verbose >out && + sed -n "s/ */ /g;/\/prunable *[0-9a-f].*$/,/prunable: .*$/p" <out >actual && + test_i18ncmp actual expect +' + test_expect_success 'bare repo setup' ' git init --bare bare1 && echo "data" >file1 && |