summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-worktree.txt26
-rw-r--r--builtin/worktree.c10
-rwxr-xr-xt/t2402-worktree-list.sh32
3 files changed, 66 insertions, 2 deletions
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 426e9b4..240c3fd 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -97,8 +97,9 @@ list::
List details of each working tree. The main working tree is listed first,
followed by each of the linked working trees. The output details include
whether the working tree is bare, the revision currently checked out, the
-branch currently checked out (or "detached HEAD" if none), and "locked" if
-the worktree is locked.
+branch currently checked out (or "detached HEAD" if none), "locked" if
+the worktree is locked, "prunable" if the worktree can be pruned by `prune`
+command.
lock::
@@ -234,6 +235,9 @@ This can also be set up as the default behaviour by using the
--expire <time>::
With `prune`, only expire unused working trees older than `<time>`.
++
+With `list`, annotate missing working trees as prunable if they are
+older than `<time>`.
--reason <string>::
With `lock`, an explanation why the working tree is locked.
@@ -372,6 +376,19 @@ $ git worktree list
/path/to/other-linked-worktree 1234abc (detached HEAD)
------------
+The command also shows annotations for each working tree, according to its state.
+These annotations are:
+
+ * `locked`, if the working tree is locked.
+ * `prunable`, if the working tree can be pruned via `git worktree prune`.
+
+------------
+$ git worktree list
+/path/to/linked-worktree abcd1234 [master]
+/path/to/locked-worktreee acbd5678 (brancha) locked
+/path/to/prunable-worktree 5678abc (detached HEAD) prunable
+------------
+
Porcelain Format
~~~~~~~~~~~~~~~~
The porcelain format has a line per attribute. Attributes are listed with a
@@ -405,6 +422,11 @@ HEAD 3456def3456def3456def3456def3456def3456b
branch refs/heads/locked-with-reason
locked reason why is locked
+worktree /path/to/linked-worktree-prunable
+HEAD 1233def1234def1234def1234def1234def1234b
+detached
+prunable gitdir file points to non-existent location
+
------------
If the lock reason contains "unusual" characters such as newline, they
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 98177f9..20944c2 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -592,6 +592,10 @@ static void show_worktree_porcelain(struct worktree *wt)
} else if (reason)
printf("locked\n");
+ reason = worktree_prune_reason(wt, expire);
+ if (reason)
+ printf("prunable %s\n", reason);
+
printf("\n");
}
@@ -620,6 +624,9 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
if (worktree_lock_reason(wt))
strbuf_addstr(&sb, " locked");
+ if (worktree_prune_reason(wt, expire))
+ strbuf_addstr(&sb, " prunable");
+
printf("%s\n", sb.buf);
strbuf_release(&sb);
}
@@ -663,9 +670,12 @@ static int list(int ac, const char **av, const char *prefix)
struct option options[] = {
OPT_BOOL(0, "porcelain", &porcelain, N_("machine-readable output")),
+ OPT_EXPIRY_DATE(0, "expire", &expire,
+ N_("add 'prunable' annotation to worktrees older than <time>")),
OPT_END()
};
+ expire = TIME_MAX;
ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
if (ac)
usage_with_options(worktree_usage, options);
diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh
index 39596e4..69342b7 100755
--- a/t/t2402-worktree-list.sh
+++ b/t/t2402-worktree-list.sh
@@ -104,6 +104,38 @@ test_expect_success '"list" all worktrees --porcelain with locked reason newline
test_cmp expect actual
'
+test_expect_success '"list" all worktrees with prunable annotation' '
+ test_when_finished "rm -rf prunable unprunable out && git worktree prune" &&
+ git worktree add --detach prunable &&
+ git worktree add --detach unprunable &&
+ rm -rf prunable &&
+ git worktree list >out &&
+ grep "/prunable *[0-9a-f].* prunable$" out &&
+ ! grep "/unprunable *[0-9a-f].* prunable$"
+'
+
+test_expect_success '"list" all worktrees --porcelain with prunable' '
+ test_when_finished "rm -rf prunable out && git worktree prune" &&
+ git worktree add --detach prunable &&
+ rm -rf prunable &&
+ git worktree list --porcelain >out &&
+ sed -n "/^worktree .*\/prunable$/,/^$/p" <out >only_prunable &&
+ test_i18ngrep "^prunable gitdir file points to non-existent location$" only_prunable
+'
+
+test_expect_success '"list" all worktrees with prunable consistent with "prune"' '
+ test_when_finished "rm -rf prunable unprunable out && git worktree prune" &&
+ git worktree add --detach prunable &&
+ git worktree add --detach unprunable &&
+ rm -rf prunable &&
+ git worktree list >out &&
+ grep "/prunable *[0-9a-f].* prunable$" out &&
+ ! grep "/unprunable *[0-9a-f].* unprunable$" out &&
+ git worktree prune --verbose >out &&
+ test_i18ngrep "^Removing worktrees/prunable" out &&
+ test_i18ngrep ! "^Removing worktrees/unprunable" out
+'
+
test_expect_success 'bare repo setup' '
git init --bare bare1 &&
echo "data" >file1 &&