> > @@ -280,12 +269,16 @@ static int name_ref(const char *path, const struct
> > object_id *oid, int flags, vo
> > if (o && o->type == OBJ_COMMIT) {
> > struct commit *commit = (struct commit *)o;
> > int from_tag = starts_with(path, "refs/tags/");
> > + const char *tip_name;
>
> This should not be const because you allocate the buffer it points to
> right here in the function, in each execution path.
Marking it as const indicates that this function doesn't modify the
buffer where the pointer points at.
> >
> > if (taggerdate == TIME_MAX)
> > taggerdate = commit->date;
> > path = name_ref_abbrev(path, can_abbreviate_output);
> > - name_rev(commit, xstrdup(path), taggerdate, 0, 0,
> > - from_tag, deref);
> > + if (deref)
> > + tip_name = xstrfmt("%s^0", path);
> > + else
> > + tip_name = xstrdup(path);
> > + name_rev(commit, tip_name, taggerdate, 0, 0, from_tag);
>
> tip_name should be free(3)'d here. Except we can't do that because
> name_rev() sometimes stores that pointer in a commit slab. Ugh.
>
> If the (re)introduced leak doesn't impact performance and memory
> usage too much then duplicating tip_name again in name_rev() or
> rather your new create_or_update_name() would likely make the
> lifetimes of those string buffers easier to manage.
Yeah, the easiest would be when each 'struct rev_name' in the commit
slab would have its own 'tip_name' string, but that would result in
a lot of duplicated strings and increased memory usage.