git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v6 2/2] worktree: add 'list' command

From
Michael Rappazzo <rappazzo@gmail.com>
Date
Aug 30, 2015, 19:10 UTC
Message-ID
<1440961839-40575-3-git-send-email-rappazzo@gmail.com>
In-Reply-To
<1440961839-40575-1-git-send-email-rappazzo@gmail.com>

'git worktree list' uses the for_each_worktree function to iterate, and outputs the worktree dir. With the verbose option set, it also shows the branch or revision currently checked out in that worktree.

Signed-off-by: Michael Rappazzo <rappazzo@gmail.com>
---
 Documentation/git-worktree.txt |  10 ++++-
 builtin/worktree.c             |  42 +++++++++++++++++
 t/t2027-worktree-list.sh       | 100 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 150 insertions(+), 2 deletions(-)
 create mode 100755 t/t2027-worktree-list.sh
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index fb68156..867a24a 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git worktree add' [-f] [--detach] [-b <new-branch>] <path> [<branch>]
 'git worktree prune' [-n] [-v] [--expire <expire>]
+'git worktree list' [-v|--verbose]
 
 DESCRIPTION
 -----------
@@ -59,6 +60,10 @@ prune::
 
 Prune working tree information in $GIT_DIR/worktrees.
 
+list::
+
+List the main worktree followed by all of the linked worktrees.
+
 OPTIONS
 -------
 
@@ -88,11 +93,13 @@ OPTIONS
 
 -v::
 --verbose::
-	With `prune`, report all removals.
+	With `prune`, report all removals.  
+	With `list` show the branch or revision currently checked out in that worktree.
 
 --expire <time>::
 	With `prune`, only expire unused working trees older than <time>.
 
+
 DETAILS
 -------
 Each linked working tree has a private sub-directory in the repository's
@@ -167,7 +174,6 @@ performed manually, such as:
 - `remove` to remove a linked working tree and its administrative files (and
   warn if the working tree is dirty)
 - `mv` to move or rename a working tree and update its administrative files
-- `list` to list linked working trees
 - `lock` to prevent automatic pruning of administrative files (for instance,
   for a working tree on a portable device)
 
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 7b3cb96..6d96cdf 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -12,6 +12,7 @@
 static const char * const worktree_usage[] = {
 	N_("git worktree add [<options>] <path> <branch>"),
 	N_("git worktree prune [<options>]"),
+	N_("git worktree list [<options>]"),
 	NULL
 };
 
@@ -442,6 +443,45 @@ done:
 	return ret;
 }
 
+static int print_worktree_details(const char *path, const char *git_dir, void *cb_data)
+{
+	printf("%s", path);
+
+	if (verbose) {
+		enter_repo(git_dir, 1);
+		printf("  [");
+		unsigned char sha1[20];
+		int flag;
+
+		const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, &flag);
+		if (!(flag & REF_ISSYMREF)) {
+			printf("%s", find_unique_abbrev(sha1, DEFAULT_ABBREV));
+		} else {
+			refname = shorten_unambiguous_ref(refname, 0);
+			printf("%s", refname);
+		}
+
+		printf("]");
+	}
+	printf("\n");
+
+	return 0;
+}
+
+static int list(int ac, const char **av, const char *prefix)
+{
+	struct option options[] = {
+		OPT__VERBOSE(&verbose, N_("show the branch or revision currently checked out")),
+		OPT_END()
+	};
+
+	ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+	if (ac)
+		usage_with_options(worktree_usage, options);
+
+	return for_each_worktree(&print_worktree_details, NULL);
+}
+
 int cmd_worktree(int ac, const char **av, const char *prefix)
 {
 	struct option options[] = {
@@ -454,5 +494,7 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
 		return add(ac - 1, av + 1, prefix);
 	if (!strcmp(av[1], "prune"))
 		return prune(ac - 1, av + 1, prefix);
+	if (!strcmp(av[1], "list"))
+		return list(ac - 1, av + 1, prefix);
 	usage_with_options(worktree_usage, options);
 }
diff --git a/t/t2027-worktree-list.sh b/t/t2027-worktree-list.sh
new file mode 100755
index 0000000..85bd243
--- /dev/null
+++ b/t/t2027-worktree-list.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+test_description='test git worktree list'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	test_commit init
+'
+
+test_expect_success '"list" all worktrees from main' '
+	git rev-parse --show-toplevel >expect &&
+	git worktree add --detach here master &&
+	git -C here rev-parse --show-toplevel >>expect &&
+	git worktree list >actual &&
+	test_cmp expect actual &&
+	rm -rf here &&
+	git worktree prune
+'
+
+test_expect_success '"list" all worktrees from linked' '
+	git rev-parse --show-toplevel >expect &&
+	git worktree add --detach here master &&
+	git -C here rev-parse --show-toplevel >>expect &&
+	git -C here worktree list >actual &&
+	test_cmp expect actual &&
+	rm -rf here &&
+	git worktree prune
+'
+
+test_expect_success '"list" all worktrees --verbose from main' '
+	echo "$(git rev-parse --show-toplevel)  [$(git symbolic-ref --short HEAD)]" >expect &&
+	git worktree add --detach here master &&
+	echo "$(git -C here rev-parse --show-toplevel)  [$(git -C here rev-parse --short HEAD)]" >>expect &&
+	git worktree list --verbose >actual &&
+	test_cmp expect actual &&
+	rm -rf here &&
+	git worktree prune
+'
+
+test_expect_success '"list" all worktrees --verbose from linked' '
+	echo "$(git rev-parse --show-toplevel)  [$(git symbolic-ref --short HEAD)]" >expect &&
+	git worktree add --detach here master &&
+	echo "$(git -C here rev-parse --show-toplevel)  [$(git -C here rev-parse --short HEAD)]" >>expect &&
+	git -C here worktree list --verbose >actual &&
+	test_cmp expect actual &&
+	rm -rf here &&
+	git worktree prune
+'
+
+test_expect_success 'bare repo setup' '
+	git init --bare bare1 &&
+	echo "data" > file1 &&
+	git add file1 &&
+	git commit -m"File1: add data" &&
+	git push bare1 master &&
+	git reset --hard HEAD^
+'
+
+test_expect_success '"list" all worktrees from bare main' '
+	git -C bare1 worktree add --detach ../there master &&
+	echo "$(git -C there rev-parse --show-toplevel)" >expect &&
+	git -C bare1 worktree list >actual &&
+	test_cmp expect actual &&
+	rm -rf there &&
+	git -C bare1 worktree prune
+'
+
+test_expect_success '"list" all worktrees from worktree with a bare main' '
+	git -C bare1 worktree add --detach ../there master &&
+	echo "$(git -C there rev-parse --show-toplevel)" >expect &&
+	git -C there worktree list >actual &&
+	test_cmp expect actual &&
+	rm -rf there &&
+	git -C bare1 worktree prune
+'
+
+test_expect_success '"list" all worktrees --verbose from bare main' '
+	git -C bare1 worktree add --detach ../there master &&
+	echo "$(git -C there rev-parse --show-toplevel)  [$(git -C there rev-parse --short HEAD)]" >expect &&
+	git -C bare1 worktree list --verbose >actual &&
+	test_cmp expect actual &&
+	rm -rf there &&
+	git -C bare1 worktree prune
+'
+
+test_expect_success '"list" all worktrees --verbose from worktree with a bare main' '
+	git -C bare1 worktree add --detach ../there master &&
+	echo "$(git -C there rev-parse --show-toplevel)  [$(git -C there rev-parse --short HEAD)]" >expect &&
+	git -C there worktree list --verbose >actual &&
+	test_cmp expect actual &&
+	rm -rf there &&
+	git -C bare1 worktree prune
+'
+
+test_expect_success 'bare repo cleanup' '
+	rm -rf bare1
+'
+
+test_done
-- 
2.5.0
Previous: Eric SunshineNext: Eric Sunshine
Message 13 of 14 in “worktree: for-each function and list command”
  1. 0/2 worktree: for-each function and list commandMichael Rappazzo, Aug 30, 2015
  2. 1/2 worktree: add 'for_each_worktree' functionMichael Rappazzo, Aug 30, 2015
  3. Eric SunshineAug 31, 2015
  4. Junio C HamanoAug 31, 2015
  5. David TurnerAug 31, 2015
  6. Eric SunshineAug 31, 2015
  7. David TurnerAug 31, 2015
  8. Mike RappazzoAug 31, 2015
  9. Eric SunshineAug 31, 2015
  10. Eric SunshineAug 31, 2015
  11. Mike RappazzoAug 31, 2015
  12. Eric SunshineAug 31, 2015
  13. 2/2 worktree: add 'list' commandMichael Rappazzo, Aug 30, 2015
  14. Eric SunshineAug 31, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.