[PATCH 4/7] worktree: teach `list` prunable annotation and verbose

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The "git worktree list" command shows the absolute path to the worktree,
the commit that is checked out, the name of the branch, and a "locked"
annotation if the worktree is locked. It is not clear whether a worktree,
if any, is prunable. The "prune" command will remove a worktree in case
is a prunable candidate unless --dry-run option is specified. This could
lead to a worktree being removed without the user realizing before is to
late, in case the user forgets to pass --dry-run for instance.

If the "list" command shows which worktree is prunable, the user could
verify before running "git worktree prune" and hopefully prevents the
working tree to be removed "accidently" on the worse case scenario.

Let's teach "git worktree list" to show when a worktree is prunable by
appending "prunable" text to its output by default and show a prunable
label for the porcelain format followed by the reason, if the avaiable.
While at it, let's do the same for the "locked" annotation.

Also, the worktree_prune_reason() stores the reason why git is selecting
the worktree to be pruned, so let's leverage that and also display this
information to the user. However, the reason is human readable text that
can take virtually any size which might make harder to extend the "list"
command with additional annotations and not fit nicely on the screen.

In order to address this shortcoming, let's teach "git worktree list" to
take a verbose option that will output the prune reason on the next line
indented, if the reason is available, otherwise the annotation is kept on
the same line. While at it, let's do the same for the "locked"
annotation.

The output of "git worktree list" with verbose becomes like so:

    $ git worktree list --verbose
    /path/to/main	      aba123 [main]
    /path/to/locked           acb124 [branch-a] locked
    /path/to/locked-reason    acc125 [branch-b]
        locked: worktree with locked reason
    /path/to/prunable         acd126 [branch-c] prunable
    /path/to/prunable-reason  ace127 [branch-d]
        prunable: gitdir file points to non-existent location

And the output of the "git worktree list --porcelain" becomes like so:

    $ git worktree list --porcelain
    worktree /path/to/main
    HEAD abc1234abc1234abc1234abc1234abc1234abc12
    branch refs/heads/main

    worktree /path/to/linked
    HEAD 123abc456def789abc1234def5678abc9123abce
    branch refs/heads/linked

    worktree /path/to/locked
    HEAD 123abcdea123abcd123acbd123acbda123abcd12
    detached
    locked lock reason

    worktree /path/to/prunable
    HEAD def1234def1234def1234def1234def1234def1a
    detached
    prunable prunable reason

Signed-off-by: Rafael Silva <rafaeloliveira.cs@xxxxxxxxx>
---
 builtin/worktree.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index eeb3ffaed0..dedd4089e5 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -578,6 +578,20 @@ static void show_worktree_porcelain(struct worktree *wt)
 			printf("detached\n");
 		else if (wt->head_ref)
 			printf("branch %s\n", wt->head_ref);
+
+		if (worktree_lock_reason(wt)) {
+			if (*wt->lock_reason)
+				printf("locked %s\n", wt->lock_reason);
+			else
+				printf("locked\n");
+		}
+
+		if (worktree_prune_reason(wt, expire)) {
+			if (*wt->prune_reason)
+				printf("prunable %s\n", wt->prune_reason);
+			else
+				printf("prunable\n");
+		}
 	}
 	printf("\n");
 }
@@ -604,8 +618,19 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
 			strbuf_addstr(&sb, "(error)");
 	}
 
-	if (!is_main_worktree(wt) && worktree_lock_reason(wt))
-		strbuf_addstr(&sb, " locked");
+	if (worktree_lock_reason(wt)) {
+		if (verbose && *wt->lock_reason)
+			strbuf_addf(&sb, "\n\tlocked: %s", wt->lock_reason);
+		else
+			strbuf_addstr(&sb, " locked");
+	}
+
+	if (worktree_prune_reason(wt, expire)) {
+		if (verbose && *wt->prune_reason)
+			strbuf_addf(&sb, "\n\tprunable: %s", wt->prune_reason);
+		else
+			strbuf_addstr(&sb, " prunable");
+	}
 
 	printf("%s\n", sb.buf);
 	strbuf_release(&sb);
@@ -650,12 +675,18 @@ 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_("show working trees that is candidate to be pruned 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);
+	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;
-- 
2.30.0.391.g469bf2a980




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux