> > @@ -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.