On Fri, Sep 30 2022, SZEDER Gábor wrote: > When 'git rebase -i --update-refs' generates the todo list for the > rebased commit range, an 'update-ref' instruction is inserted for each > ref that points to one of those commits, except for the rebased branch > (because at the end of the rebase it will be updated anyway) and any > refs that are checked out in a worktree; for the latter a "Ref <ref> > checked out at '<worktree>'" comment is added. One of these comments > can be missing under some circumstances: if the oldest commit with a > ref pointing to it has multiple refs pointing to it, and at least one > of those refs is checked out in a worktree, and one of them (but not > the first) is checked out in the worktree associated with the last > directory entry in '.git/worktrees'. > > The culprit is the add_decorations_to_list() function, which calls > resolve_ref_unsafe() to figure out the refname of the rebased branch. > However, resolve_ref_unsafe() can (and in this case does) return a > pointer to a static buffer. Alas, add_decorations_to_list() holds on > that static buffer until the end of the function, using its contents > to compare refnames with the rebased branch, while it also calls a > function that invokes refs_resolve_ref_unsafe() internally [1], and > which overwrites the content of that static buffer, and messes up > subsequent refname comparisons. Good catch... > Use xstrdup_or_null() to keep a copy of resolve_ref_unsafe()'s return > value for the duration of add_decorations_to_list(). ...and this makes sense... > const struct name_decoration *decoration = get_name_decoration(&commit->object); > - const char *head_ref = resolve_ref_unsafe("HEAD", > + const char *head_ref = xstrdup_or_null(resolve_ref_unsafe("HEAD", ...but let's change this to a "char *" then... > RESOLVE_REF_READING, > NULL, > - NULL); > + NULL)); > > while (decoration) { > struct todo_item *item; > @@ -5965,6 +5965,7 @@ static int add_decorations_to_list(const struct commit *commit, > decoration = decoration->next; > } > > + free((char *)head_ref); ...so we don't need this cast...?