[email protected] writes:
> From: Nickolai Belakovski <[email protected]>
>
> Add an atom providing the path of the linked worktree where this ref is
> checked out, if it is checked out in any linked worktrees, and empty
> string otherwise.
> ---
Missing sign-off?
> +static int ref_to_worktree_map_cmpfnc(const void *unused_lookupdata, const
> void *existing_hashmap_entry_to_test,
> + const void *key, const void
> *keydata_aka_refname)
> +{
> + const struct ref_to_worktree_entry *e = existing_hashmap_entry_to_test;
> + const struct ref_to_worktree_entry *k = key;
> + return strcmp(e->wt->head_ref, keydata_aka_refname ?
> keydata_aka_refname : k->wt->head_ref);
Overlong line.
> +}
> +
> +static struct hashmap ref_to_worktree_map;
> +static struct worktree **worktrees = NULL;
No need to initialize static vars to 0/NULL.
> @@ -438,6 +456,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;
> +
> + 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;
> +}
It is kind of interesting that a function for parsing an "atom" in
"format" does not look at none of its arguments at all ;-) The fact
that "%(worktreepath)" atom got noticed by verify_ref_format() alone
is of interest for this function.
The helper iterates over all worktrees, registers them in a hashmap
ref_to_worktree_map, indexed by the head reference.
OK.
> +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;
> +
> + hashmap_entry_init(&entry, strhash(ref->refname));
> + lookup_result = hashmap_get(&ref_to_worktree_map, &entry, ref->refname);
> +
> + if (lookup_result)
> + strbuf_addstr(&val, lookup_result->wt->path);
> +
> + return strbuf_detach(&val, NULL);
> +}
We do not need a strbuf to do the above, do we?
hashmap_entry_init(...);
lookup_result = hashmap_get(...);
if (lookup_result)
return xstrdup(lookup_result->wt->path);
else
return xstrdup("");
or something like that, perhaps?
> @@ -1562,6 +1624,13 @@ 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")) {
> + if (ref->kind == FILTER_REFS_BRANCHES)
> + v->s = get_worktree_path(atom, ref);
> + else
> + v->s = xstrdup("");
> + continue;
> + }
I am wondering if get_worktree_path() being called should be the
triggering event for lazy initialization worktree_atom_parser() is
doing in this patch, instead of verify_ref_format() seeing the
"%(worktreepath)" atom. Is there any codepath that wants to make
sure the lazy initialization is done without/before populate_value()
sees a use of the "%(worktreepath)" atom? If so, such a plan would
not work, but otherwise, we can do the following:
- rename worktree_atom_parser() to lazy_init_worktrees() or
something, and remove all of its unused parameters.
- remove parser callback for "worktreepath" from valid_atom[].
- call lazy_inti_worktrees() at the beginning of
get_worktree_path().
Hmm?