git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: nbelakovski@gmail.com
Cc: git@vger.kernel.org, peff@peff.net, rafa.almas@gmail.com,
	avarab@gmail.com
Subject: Re: [PATCH v5 1/3] ref-filter: add worktreepath atom
Date: Mon, 07 Jan 2019 10:20:39 -0800	[thread overview]
Message-ID: <xmqq5zv09vns.fsf@gitster-ct.c.googlers.com> (raw)
In-Reply-To: <20190106002619.54741-2-nbelakovski@gmail.com> (nbelakovski's message of "Sat, 5 Jan 2019 16:26:17 -0800")

nbelakovski@gmail.com writes:

> +static struct hashmap ref_to_worktree_map;
> +static struct worktree **worktrees = NULL;
> +
>  /*
>   * An atom is a valid field atom listed below, possibly prefixed with
>   * a "*" to denote deref_tag().
> @@ -420,6 +438,34 @@ static int head_atom_parser(const struct ref_format *format, struct used_atom *a
>  	return 0;
>  }
>  
> +static int worktree_atom_parser(const struct ref_format *format,
> +				struct used_atom *atom,
> +				const char *arg,
> +				struct strbuf *unused_err)
> +{
> +	int i;
> +
> +	if (worktrees)
> +		return 0;

OK, so verify_ref_format() etc. will trigger this to be called via
valid_atom[].parser when "%(worktreepath)" is seen in the user
format, and then this grabs all the worktrees and record their paths
in the hashmap.  This if() statement makes sure that it happens only
once.

> +	worktrees = get_worktrees(0);
> +
> +	hashmap_init(&ref_to_worktree_map, ref_to_worktree_map_cmpfnc, NULL, 0);
> +
> +	for (i = 0; worktrees[i]; i++) {
> +		if (worktrees[i]->head_ref) {
> +			struct ref_to_worktree_entry *entry;
> +			entry = xmalloc(sizeof(*entry));
> +			entry->wt = worktrees[i];
> +			hashmap_entry_init(entry, strhash(worktrees[i]->head_ref));
> +
> +			hashmap_add(&ref_to_worktree_map, entry);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static struct {
>  	const char *name;
>  	info_source source;
> @@ -461,6 +507,7 @@ static struct {
>  	{ "flag", SOURCE_NONE },
>  	{ "HEAD", SOURCE_NONE, FIELD_STR, head_atom_parser },
>  	{ "color", SOURCE_NONE, FIELD_STR, color_atom_parser },
> +	{ "worktreepath", SOURCE_NONE, FIELD_STR, worktree_atom_parser },
>  	{ "align", SOURCE_NONE, FIELD_STR, align_atom_parser },
>  	{ "end", SOURCE_NONE },
>  	{ "if", SOURCE_NONE, FIELD_STR, if_atom_parser },
> @@ -1500,6 +1547,21 @@ static int get_object(struct ref_array_item *ref, int deref, struct object **obj
>  	return 0;
>  }
>  
> +static char *get_worktree_path(const struct used_atom *atom, const struct ref_array_item *ref)
> +{
> +	struct strbuf val = STRBUF_INIT;
> +	struct hashmap_entry entry;
> +	struct ref_to_worktree_entry *lookup_result;

And then this will be called from populate_value() for each of the
ref.  It looks up the worktree that has checked out this branch, if
any, from the hashmap, and yields the path to it.

When seeing a tag or note ref, by definition that's not something we
can have checked out in any worktree.  I wonder if it is worth to
optimize further by omitting this lookup when ref is not a local
branch?

IOW, with a typical number of worktrees and refs, how costly would ...

> +	hashmap_entry_init(&entry, strhash(ref->refname));
> +	lookup_result = hashmap_get(&ref_to_worktree_map, &entry, ref->refname);

... this sequence of calls be.

> +
> +	if (lookup_result)
> +		strbuf_addstr(&val, lookup_result->wt->path);
> +
> +	return strbuf_detach(&val, NULL);
> +}
> +
>  /*
>   * Parse the object referred by ref, and grab needed value.
>   */
> @@ -1537,6 +1599,10 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
>  
>  		if (starts_with(name, "refname"))
>  			refname = get_refname(atom, ref);
> +		else if (starts_with(name, "worktreepath")) {
> +			v->s = get_worktree_path(atom, ref);
> +			continue;
> +		}
>  		else if (starts_with(name, "symref"))
>  			refname = get_symref(atom, ref);
>  		else if (starts_with(name, "upstream")) {
> @@ -2020,6 +2086,11 @@ void ref_array_clear(struct ref_array *array)
>  		free_array_item(array->items[i]);
>  	FREE_AND_NULL(array->items);
>  	array->nr = array->alloc = 0;
> +	if (worktrees)
> +	{

Have this opening brace at the end of the previous line, i.e.

	if (worktrees) {

> +		hashmap_free(&ref_to_worktree_map, 1);
> +		free_worktrees(worktrees);
> +	}
>  }

What's the point of ref_array_clear()?  What does the caller of this
function really want?  Is it merely to release the resources
consumed?  If so, then this is good enough, but then the existing
calls to FREE_AND_NULL() for releasing resources in the function is
overkill.

Or is it envisioned that we are preparing a clean slate so that
another call, possibly after the external environment changed, can
be made into this machinery (i.e. imagine we lift ref-filter.c code
and link it to a long running service process; after serving one
for-each-ref request, a new worktree or a new branch may get
created, and then we may get another for-each-ref request)?  If that
is the case, then the added code breaks that hope, as it leaves a
dangling pointer in the worktrees variable.

>  static void do_merge_filter(struct ref_filter_cbdata *ref_cbdata)
> diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
> index fc067ed672..87e0222ea1 100755
> --- a/t/t6302-for-each-ref-filter.sh
> +++ b/t/t6302-for-each-ref-filter.sh
> @@ -441,4 +441,19 @@ test_expect_success '--merged is incompatible with --no-merged' '
>  	test_must_fail git for-each-ref --merged HEAD --no-merged HEAD
>  '
>  
> +test_expect_success '"add" a worktree' '
> +	mkdir worktree_dir &&
> +	git worktree add -b master_worktree worktree_dir master
> +'
> +
> +test_expect_success 'validate worktree atom' '
> +	cat >expect <<-EOF &&
> +	master: $(pwd)
> +	master_worktree: $(pwd)/worktree_dir
> +	side: not checked out
> +	EOF
> +	git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
> +	test_cmp expect actual
> +'
> +
>  test_done

  reply	other threads:[~2019-01-07 18:20 UTC|newest]

Thread overview: 125+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <"<CAC05386q2iGoiJ_fRgwoOTF23exEN2D1+oh4VjajEvYQ58O1TQ@mail.gmail.com>
2018-09-27 15:13 ` [PATCH] branch: colorize branches checked out in a linked working tree the same way as the current branch is colorized Nickolai Belakovski
2018-09-27 15:33   ` Ævar Arnfjörð Bjarmason
2018-09-27 17:46     ` Nickolai Belakovski
     [not found]     ` <CAC05387S9P+w8yqqcjkQDnURYSgQmqtukxS4KvqJu-kDA+_o0g@mail.gmail.com>
2018-09-27 17:59       ` Ævar Arnfjörð Bjarmason
2018-10-02 20:41         ` Johannes Schindelin
2018-09-27 17:58   ` Duy Nguyen
2018-09-27 18:17   ` Jeff King
2018-09-27 18:39     ` Nickolai Belakovski
2018-09-27 18:51       ` Jeff King
2018-09-27 19:28     ` Rafael Ascensão
2018-09-27 19:35       ` Jeff King
2018-09-27 19:41         ` Jeff King
2018-09-27 21:22           ` Junio C Hamano
2018-09-28  1:05             ` Jeff King
2018-09-28  1:28               ` Junio C Hamano
2018-09-27 21:35         ` Rafael Ascensão
2018-09-28  1:07           ` Jeff King
2018-09-27 20:02       ` Ævar Arnfjörð Bjarmason
2018-09-27 20:16         ` Nickolai Belakovski
2018-09-27 20:40           ` Rafael Ascensão
2018-11-11 23:58             ` [PATCH v2 0/2] refactoring branch colorization to ref-filter nbelakovski
2018-11-11 23:58               ` [PATCH v2 1/2] ref-filter: add worktree atom nbelakovski
2018-11-12 10:11                 ` Junio C Hamano
2018-11-12 12:22                   ` Jeff King
2018-11-13  1:38                     ` Junio C Hamano
2018-11-21 14:05                       ` Nickolai Belakovski
2018-11-21 14:08                         ` Jeff King
2018-11-12 12:23                 ` Jeff King
2018-11-11 23:58               ` [PATCH v2 2/2] branch: Mark and colorize a branch differently if it is checked out in a linked worktree nbelakovski
2018-11-12 10:20                 ` Junio C Hamano
2018-11-12 12:14                   ` Jeff King
2018-11-12 18:07                     ` Rafael Ascensão
2018-11-13  1:45                       ` Junio C Hamano
2018-11-13 14:49                       ` Jeff King
2018-11-21 14:07                         ` Nickolai Belakovski
2018-12-16 21:57               ` [PATCH v3 0/3] nbelakovski
2018-12-16 21:57                 ` [PATCH v3 1/3] ref-filter: add worktreepath atom nbelakovski
2018-12-18 17:22                   ` Jeff King
2018-12-20  7:09                     ` Nickolai Belakovski
2018-12-20 14:59                       ` Jeff King
2018-12-24  8:47                         ` [PATCH v4 0/3] nbelakovski
2018-12-24  8:47                           ` [PATCH v4 1/3] ref-filter: add worktreepath atom nbelakovski
2019-01-03  5:40                             ` Jeff King
2019-01-03  9:31                               ` Eric Sunshine
2018-12-24  8:47                           ` [PATCH v4 2/3] branch: Mark and color a branch differently if it is checked out in a linked worktree nbelakovski
2018-12-24  8:47                           ` [PATCH v4 3/3] branch: Add an extra verbose output displaying worktree path for refs " nbelakovski
2019-01-03  5:42                             ` Jeff King
2019-01-03  5:22                           ` [PATCH v4 0/3] Jeff King
2018-12-16 21:57                 ` [PATCH v3 2/3] branch: Mark and color a branch differently if it is checked out in a linked worktree nbelakovski
2018-12-16 21:57                 ` [PATCH v3 3/3] branch: Add an extra verbose output displaying worktree path for refs " nbelakovski
2018-12-18 17:25                 ` [PATCH v3 0/3] Jeff King
2019-01-06  0:26   ` [PATCH v5 0/3] nbelakovski
2019-01-06  0:26     ` [PATCH v5 1/3] ref-filter: add worktreepath atom nbelakovski
2019-01-07 18:20       ` Junio C Hamano [this message]
2019-01-18 22:17         ` Nickolai Belakovski
2019-01-18 22:20           ` Nickolai Belakovski
2019-01-06  0:26     ` [PATCH v5 2/3] branch: Mark and color a branch differently if it is checked out in a linked worktree nbelakovski
2019-01-07 19:04       ` Junio C Hamano
2019-01-10 21:42         ` Philip Oakley
2019-01-13  1:41           ` Nickolai Belakovski
2019-01-14 18:18             ` Junio C Hamano
2019-01-18 22:18               ` Nickolai Belakovski
2019-01-06  0:26     ` [PATCH v5 3/3] branch: Add an extra verbose output displaying worktree path for refs " nbelakovski
2019-01-07 19:09       ` Junio C Hamano
2019-01-22 23:22   ` [PATCH v6 0/3] nbelakovski
2019-01-22 23:22     ` [PATCH v6 1/3] ref-filter: add worktreepath atom nbelakovski
2019-01-23 18:57       ` Junio C Hamano
2019-01-23 23:34         ` Nickolai Belakovski
2019-01-24 18:26           ` Junio C Hamano
2019-01-24 18:32             ` Jeff King
2019-01-24 19:27               ` Junio C Hamano
2019-01-24 19:34                 ` Jeff King
2019-01-24 19:30               ` Junio C Hamano
2019-01-24 21:26                 ` Jeff King
2019-01-31 20:53                   ` Nickolai Belakovski
2019-01-31 23:21                     ` Jeff King
2019-01-31 21:42                   ` Junio C Hamano
2019-01-31 23:20                     ` Jeff King
2019-01-22 23:23     ` [PATCH v6 2/3] branch: Mark and color a branch differently if it is checked out in a linked worktree nbelakovski
2019-01-22 23:23     ` [PATCH v6 3/3] branch: Add an extra verbose output displaying worktree path for refs " nbelakovski
2019-02-01 22:04   ` [PATCH v7 0/3] nbelakovski
2019-02-01 22:28     ` Junio C Hamano
2019-02-01 23:31       ` Nickolai Belakovski
2019-02-01 22:04   ` [PATCH v7 1/3] ref-filter: add worktreepath atom nbelakovski
2019-02-01 22:20     ` Eric Sunshine
2019-02-01 22:41       ` Nickolai Belakovski
2019-02-04 18:14         ` Junio C Hamano
2019-02-18 10:09           ` Nickolai Belakovski
2019-02-01 22:31     ` Junio C Hamano
2019-02-01 22:04   ` [PATCH v7 2/3] branch: Mark and color a branch differently if it is checked out in a linked worktree nbelakovski
2019-02-01 22:34     ` Junio C Hamano
2019-02-01 23:12       ` Nickolai Belakovski
2019-02-04 18:18         ` Junio C Hamano
2019-02-01 22:04   ` [PATCH v7 3/3] branch: Add an extra verbose output displaying worktree path for refs " nbelakovski
2019-02-01 22:27     ` Eric Sunshine
2019-02-01 22:45       ` Nickolai Belakovski
2019-02-01 22:53     ` Junio C Hamano
2019-02-01 23:06       ` Nickolai Belakovski
2019-02-02  1:22         ` [RFC] Sample of test for git branch -vv nbelakovski
2019-02-19  8:31   ` [PATCH v8 0/3] nbelakovski
2019-02-19  8:31     ` [PATCH v8 1/3] ref-filter: add worktreepath atom nbelakovski
2019-02-19  8:31     ` [PATCH v8 2/3] branch: update output to include worktree info nbelakovski
2019-02-21 12:44       ` Jeff King
2019-03-14  5:45         ` Nickolai Belakovski
2019-02-19  8:31     ` [PATCH v8 3/3] branch: add worktree info on verbose output nbelakovski
2019-02-21 12:59       ` Jeff King
2019-03-14  5:58         ` Nickolai Belakovski
2019-03-18  2:12           ` Junio C Hamano
2019-02-21 12:36     ` [PATCH v8 0/3] Jeff King
2019-03-14  6:10       ` Nickolai Belakovski
2019-03-16  1:38   ` [PATCH v9 0/3] nbelakovski
2019-03-16  1:38     ` [PATCH v9 1/3] ref-filter: add worktreepath atom nbelakovski
2019-03-16  1:38     ` [PATCH v9 2/3] branch: update output to include worktree info nbelakovski
2019-03-16  1:38     ` [PATCH v9 3/3] branch: add worktree info on verbose output nbelakovski
2019-03-18 12:10       ` SZEDER Gábor
2019-03-18  5:30     ` [PATCH v9 0/3] Junio C Hamano
2019-04-29  5:19   ` [PATCH v10 0/3] nbelakovski
2019-04-29  5:19     ` [PATCH v10 1/3] ref-filter: add worktreepath atom nbelakovski
2019-04-29  5:19     ` [PATCH v10 2/3] branch: update output to include worktree info nbelakovski
2019-04-29  5:19     ` [PATCH v10 3/3] branch: add worktree info on verbose output nbelakovski
2019-04-29 14:12     ` [PATCH v10 0/3] SZEDER Gábor
2019-04-29 19:27       ` Nickolai Belakovski
2019-04-29 20:57     ` Johannes Schindelin
2019-04-29 21:33       ` Nickolai Belakovski
     [not found]       ` <CAC05385Mc7pqiCd5mb+1c4WM+v7K=h=GMHuvkw9xizhRFJXXBA@mail.gmail.com>
2019-04-30 21:46         ` Johannes Schindelin

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=xmqq5zv09vns.fsf@gitster-ct.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=nbelakovski@gmail.com \
    --cc=peff@peff.net \
    --cc=rafa.almas@gmail.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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).