git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rafael Silva <rafaeloliveira.cs@gmail.com>
To: git@vger.kernel.org
Cc: Eric Sunshine <sunshine@sunshineco.com>,
	Rafael Silva <rafaeloliveira.cs@gmail.com>
Subject: [PATCH 4/7] worktree: teach `list` prunable annotation and verbose
Date: Mon,  4 Jan 2021 17:21:25 +0100	[thread overview]
Message-ID: <20210104162128.95281-5-rafaeloliveira.cs@gmail.com> (raw)
In-Reply-To: <20210104162128.95281-1-rafaeloliveira.cs@gmail.com>

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@gmail.com>
---
 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


  parent reply	other threads:[~2021-01-04 16:23 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-04 16:21 [PATCH 0/7] teach `worktree list` verbose mode and prunable annotations Rafael Silva
2021-01-04 16:21 ` [PATCH 1/7] worktree: move should_prune_worktree() to worktree.c Rafael Silva
2021-01-06  5:58   ` Eric Sunshine
2021-01-08  7:40     ` Rafael Silva
2021-01-06  6:55   ` Eric Sunshine
2021-01-07  7:24     ` Eric Sunshine
2021-01-08  7:41     ` Rafael Silva
2021-01-04 16:21 ` [PATCH 2/7] worktree: implement worktree_prune_reason() wrapper Rafael Silva
2021-01-06  7:08   ` Eric Sunshine
2021-01-08  7:42     ` Rafael Silva
2021-01-04 16:21 ` [PATCH 3/7] worktree: teach worktree_lock_reason() to gently handle main worktree Rafael Silva
2021-01-06  7:29   ` Eric Sunshine
2021-01-08  7:43     ` Rafael Silva
2021-01-04 16:21 ` Rafael Silva [this message]
2021-01-06  8:31   ` [PATCH 4/7] worktree: teach `list` prunable annotation and verbose Eric Sunshine
2021-01-08  7:45     ` Rafael Silva
2021-01-04 16:21 ` [PATCH 5/7] worktree: `list` escape lock reason in --porcelain Rafael Silva
2021-01-05 10:29   ` Phillip Wood
2021-01-05 11:02     ` [PATCH] worktree: add -z option for list subcommand Phillip Wood
2021-01-07  3:34       ` Eric Sunshine
2021-01-08 10:33         ` Phillip Wood
2021-01-10  7:27           ` Eric Sunshine
2021-01-06  9:07     ` [PATCH 5/7] worktree: `list` escape lock reason in --porcelain Eric Sunshine
2021-01-08  7:47     ` Rafael Silva
2021-01-06  8:59   ` Eric Sunshine
2021-01-04 16:21 ` [PATCH 6/7] worktree: add tests for `list` verbose and annotations Rafael Silva
2021-01-06  9:39   ` Eric Sunshine
2021-01-07  4:09     ` Eric Sunshine
2021-01-08  7:49     ` Rafael Silva
2021-01-04 16:21 ` [PATCH 7/7] worktree: document `list` verbose and prunable annotations Rafael Silva
2021-01-06  9:57   ` Eric Sunshine
2021-01-08  7:49     ` Rafael Silva
2021-01-06  5:36 ` [PATCH 0/7] teach `worktree list` verbose mode " Eric Sunshine
2021-01-08  7:38   ` Rafael Silva
2021-01-08  8:19     ` Eric Sunshine
2021-01-17 23:42 ` [PATCH v2 0/6] " Rafael Silva
2021-01-17 23:42   ` [PATCH v2 1/6] worktree: libify should_prune_worktree() Rafael Silva
2021-01-17 23:42   ` [PATCH v2 2/6] worktree: teach worktree to lazy-load "prunable" reason Rafael Silva
2021-01-18  2:57     ` Eric Sunshine
2021-01-19  7:57       ` Rafael Silva
2021-01-17 23:42   ` [PATCH v2 3/6] worktree: teach worktree_lock_reason() to gently handle main worktree Rafael Silva
2021-01-17 23:42   ` [PATCH v2 4/6] worktree: teach `list --porcelain` to annotate locked worktree Rafael Silva
2021-01-18  3:55     ` Eric Sunshine
2021-01-19  8:20       ` Rafael Silva
2021-01-19 17:16         ` Eric Sunshine
2021-01-17 23:42   ` [PATCH v2 5/6] worktree: teach `list` to annotate prunable worktree Rafael Silva
2021-01-18  4:45     ` Eric Sunshine
2021-01-19 10:26       ` Rafael Silva
2021-01-19 17:23         ` Eric Sunshine
2021-01-17 23:42   ` [PATCH v2 6/6] worktree: teach `list` verbose mode Rafael Silva
2021-01-18  5:15     ` Eric Sunshine
2021-01-18 19:40       ` Eric Sunshine
2021-01-18  5:33   ` [PATCH v2 0/6] teach `worktree list` verbose mode and prunable annotations Eric Sunshine
2021-01-19 16:44     ` Rafael Silva
2021-01-19 21:27   ` [PATCH v3 0/7] " Rafael Silva
2021-01-19 21:27     ` [PATCH v3 1/7] worktree: libify should_prune_worktree() Rafael Silva
2021-01-19 21:27     ` [PATCH v3 2/7] worktree: teach worktree to lazy-load "prunable" reason Rafael Silva
2021-01-19 21:27     ` [PATCH v3 3/7] worktree: teach worktree_lock_reason() to gently handle main worktree Rafael Silva
2021-01-19 21:27     ` [PATCH v3 4/7] t2402: ensure locked worktree is properly cleaned up Rafael Silva
2021-01-24  7:50       ` Eric Sunshine
2021-01-24 10:19         ` Rafael Silva
2021-01-19 21:27     ` [PATCH v3 5/7] worktree: teach `list --porcelain` to annotate locked worktree Rafael Silva
2021-01-20 11:00       ` Phillip Wood
2021-01-21  3:18         ` Junio C Hamano
2021-01-21 15:25         ` Rafael Silva
2021-01-24  8:24         ` Eric Sunshine
2021-01-24  8:10       ` Eric Sunshine
2021-01-24 10:20         ` Rafael Silva
2021-01-19 21:27     ` [PATCH v3 6/7] worktree: teach `list` to annotate prunable worktree Rafael Silva
2021-01-21  3:28       ` Junio C Hamano
2021-01-21 15:09         ` Rafael Silva
2021-01-21 22:18           ` Junio C Hamano
2021-01-19 21:27     ` [PATCH v3 7/7] worktree: teach `list` verbose mode Rafael Silva
2021-01-24  8:42       ` Eric Sunshine
2021-01-24 10:21         ` Rafael Silva
2021-01-24  8:51     ` [PATCH v3 0/7] teach `worktree list` verbose mode and prunable annotations Eric Sunshine
2021-01-27  8:08       ` Rafael Silva
2021-01-27  8:03     ` Rafael Silva
2021-01-27  8:03       ` [PATCH v4 1/7] worktree: libify should_prune_worktree() Rafael Silva
2021-01-27  8:03       ` [PATCH v4 2/7] worktree: teach worktree to lazy-load "prunable" reason Rafael Silva
2021-01-27  8:03       ` [PATCH v4 3/7] worktree: teach worktree_lock_reason() to gently handle main worktree Rafael Silva
2021-01-27  8:03       ` [PATCH v4 4/7] t2402: ensure locked worktree is properly cleaned up Rafael Silva
2021-01-27  8:03       ` [PATCH v4 5/7] worktree: teach `list --porcelain` to annotate locked worktree Rafael Silva
2021-01-27  8:03       ` [PATCH v4 6/7] worktree: teach `list` to annotate prunable worktree Rafael Silva
2021-01-27  8:03       ` [PATCH v4 7/7] worktree: teach `list` verbose mode Rafael Silva
2021-01-30  7:04       ` [PATCH v3 0/7] teach `worktree list` verbose mode and prunable annotations Eric Sunshine
2021-01-30  9:42         ` Rafael Silva
2021-01-30 17:50         ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210104162128.95281-5-rafaeloliveira.cs@gmail.com \
    --to=rafaeloliveira.cs@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).