All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Turner <dturner@twopensource.com>
To: Michael Rappazzo <rappazzo@gmail.com>
Cc: gitster@pobox.com, sunshine@sunshineco.com, git@vger.kernel.org
Subject: Re: [PATCH 2/2 v4] worktree: add 'list' command
Date: Thu, 13 Aug 2015 15:26:29 -0400	[thread overview]
Message-ID: <1439493989.8855.18.camel@twopensource.com> (raw)
In-Reply-To: <1439490739-9361-3-git-send-email-rappazzo@gmail.com>

On Thu, 2015-08-13 at 14:32 -0400, Michael Rappazzo wrote:
> 'git worktree list' uses the for_each_worktree function to iterate,
> and outputs in the format: '<worktree>  (<short-ref>)'

I'm not sure I'm going to have time to review the whole thing, but I
think we ought to have tests with both bare and non-bare main repos.

> Signed-off-by: Michael Rappazzo <rappazzo@gmail.com>
> ---
>  Documentation/git-worktree.txt | 11 ++++++++-
>  builtin/worktree.c             | 55 ++++++++++++++++++++++++++++++++++++++++++
>  t/t2027-worktree-list.sh       | 51 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+), 1 deletion(-)
>  create mode 100755 t/t2027-worktree-list.sh
> 
> diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
> index fb68156..e953b4e 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' [--path-only]
>  
>  DESCRIPTION
>  -----------
> @@ -59,6 +60,12 @@ prune::
>  
>  Prune working tree information in $GIT_DIR/worktrees.
>  
> +list::
> +
> +List the main worktree followed by all of the linked worktrees.  The default
> +format of the list includes the full path to the worktree and the branch or
> +revision that the head of that worktree is currently pointing to.
> +
>  OPTIONS
>  -------
>  
> @@ -93,6 +100,9 @@ OPTIONS
>  --expire <time>::
>  	With `prune`, only expire unused working trees older than <time>.
>  
> +--path-only
> +	With `list`, only show the worktree path
> +
>  DETAILS
>  -------
>  Each linked working tree has a private sub-directory in the repository's
> @@ -167,7 +177,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 a43e360..b39ecbd 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
>  };
>  
> @@ -443,6 +444,58 @@ done:
>  	return ret;
>  }
>  
> +/* list callback data */
> +struct list_opts {
> +	int path_only;
> +};
> +
> +static int print_worktree_details(const char *path, const char *git_dir, void *cb_data)
> +{
> +	struct strbuf head_file = STRBUF_INIT;
> +	struct strbuf head_ref = STRBUF_INIT;
> +	struct stat st;
> +	struct list_opts *opts = cb_data;
> +	const char *ref_prefix = "ref: refs/heads/";
> +
> +	strbuf_addf(&head_file, "%s/HEAD", git_dir);
> +	if (!opts->path_only && !stat(head_file.buf, &st)) {
> +		strbuf_read_file(&head_ref, head_file.buf, st.st_size);
> +		strbuf_strip_suffix(&head_ref, "\n");
> +
> +		if (starts_with(head_ref.buf, ref_prefix)) {
> +			/* branch checked out */
> +			strbuf_remove(&head_ref, 0, strlen(ref_prefix));
> +		/* } else {
> +		 *  headless -- no-op
> +		 */
> +		}
> +		printf("%s  (%s)\n", path, head_ref.buf);
> +	} else {
> +		printf("%s\n", path);
> +	}
> +
> +	strbuf_release(&head_ref);
> +	strbuf_release(&head_file);
> +	return 0;
> +}
> +
> +static int list(int ac, const char **av, const char *prefix)
> +{
> +	struct list_opts opts;
> +	struct option options[] = {
> +		OPT_BOOL(0, "path-only", &opts.path_only, N_("only show the path of the worktree")),
> +		OPT_END()
> +	};
> +
> +	opts.path_only = 0;
> +
> +	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, &opts);
> +}
> +
>  int cmd_worktree(int ac, const char **av, const char *prefix)
>  {
>  	struct option options[] = {
> @@ -455,5 +508,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..220f98e
> --- /dev/null
> +++ b/t/t2027-worktree-list.sh
> @@ -0,0 +1,51 @@
> +#!/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' '
> +	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 HEAD))" >>expect &&
> +	git worktree list >actual &&
> +	test_cmp expect actual &&
> +	rm -rf here &&
> +	git worktree prune
> +'
> +
> +test_expect_success '"list" all worktrees 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 HEAD))" >>expect &&
> +	git -C here worktree list >actual &&
> +	test_cmp expect actual &&
> +	rm -rf here &&
> +	git worktree prune
> +'
> +
> +test_expect_success '"list" all worktrees from main --path-only' '
> +	git rev-parse --show-toplevel >expect &&
> +	git worktree add --detach here master &&
> +	git -C here rev-parse --show-toplevel >>expect &&
> +	git worktree list --path-only >actual &&
> +	test_cmp expect actual &&
> +	rm -rf here &&
> +	git worktree prune
> +'
> +
> +test_expect_success '"list" all worktrees from linked --path-only' '
> +	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 --path-only >actual &&
> +	test_cmp expect actual &&
> +	rm -rf here &&
> +	git worktree prune
> +'
> +
> +test_done

      reply	other threads:[~2015-08-13 19:26 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-13 18:32 [PATCH 0/2 v4] worktree: for_each_worktree and list Michael Rappazzo
2015-08-13 18:32 ` [PATCH 1/2 v4] worktree: add 'for_each_worktree' function Michael Rappazzo
2015-08-13 19:23   ` David Turner
2015-08-13 23:32     ` Mike Rappazzo
2015-08-13 18:32 ` [PATCH 2/2 v4] worktree: add 'list' command Michael Rappazzo
2015-08-13 19:26   ` David Turner [this message]

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=1439493989.8855.18.camel@twopensource.com \
    --to=dturner@twopensource.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=rappazzo@gmail.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.