Repository navigation
Conversation
A marker is stored only under the branch name. Deleting that branch outside wt leaves the key, so creating the name again showed the old marker in wt list. Skip it when no local branch has the name, and when the branch reflog says this name was created after the marker was set. The key stays in git config. Refs max-sixty#4683 Co-authored-by: Lixin2026 <2023Anita@users.noreply.github.com>
worktrunk-bot
left a comment
There was a problem hiding this comment.
Bare repos still show the old marker. In a bare repo git leaves core.logAllRefUpdates off by default, so logs/refs/heads/<branch> is never written. branch_created_at then returns None and the marker shows. Repos using the reftable backend behave the same way, because their reflogs live inside the tables. I reproduced it with this branch's build: in a bare repo with linked worktrees, git worktree add -b feature, wt config state marker set 🤖, then git worktree remove + git branch -D feature, then recreate feature. wt list still shows 🤖 on the new feature. The bare layout is one Worktrunk supports directly, so the #4683 repro still happens there. The new help sentence says it doesn't. The inline suggestion drops that sentence. AGENTS.md → Documentation also says "A correctness fix that preserves usage needs no new guide prose".
The fix parses git's on-disk reflog format. branch_created_at hard-codes the files-backend path, and creation_timestamp_from_reflog_line re-implements git's reflog line format (zero OID, tz validation, committer-name splitting). AGENTS.md → "Other Tools Own Their Conventions" asks to query the tool instead of encoding its file format. Git answers this directly, and on every ref backend: git log -g --date=unix --format='%gd %gs' refs/heads/<branch> prints entries newest first, so the last one is <branch>@{<unix>} branch: Created from …. That costs a subprocess per worktree row, which is the trade the PR avoided. Whether that cost is acceptable is part of the decision below.
The missing-branch check can't fire for wt list. compute_user_marker runs only for worktree rows, and git refuses branch -D on a branch checked out in any worktree. So a row's branch always exists, apart from an unborn --orphan branch, which has no ref yet and would wrongly lose its marker. All of the PR's effect comes from the reflog comparison.
This needs a maintainer decision. Altogether this is roughly 90 lines of production code plus a format parser, and it only helps non-bare repos on the files backend. The earlier comment on #4683 left the choice between suggestion 2 (this PR) and suggestion 3 (wt config state prune) to a maintainer. A prune command, or documenting marker clear --branch, works the same way on every layout. I'm holding the approval for that choice.
Ask git for the last `branch: Created from` reflog entry instead of parsing the files-backend log, so the marker comparison uses whatever creation time git recorded. Drop the help sentence that claimed a later branch of the same name always hides the marker. Co-authored-by: Lixin2026 <2023Anita@users.noreply.github.com>
worktrunk-bot
left a comment
There was a problem hiding this comment.
The PR description no longer matches the code. It still says wt list "skips a marker when no local branch has that name", and that unit tests cover "a missing branch" and "an empty reflog". This push removed that check and those tests. A deleted-but-not-recreated name now keeps its marker (gone.user_marker(Some("feature")) asserts Some("🤖")), and bare repos keep it unless core.logAllRefUpdates is on. A maintainer deciding between this and a prune command will read the description first, so please update it to match.
The approach question from the earlier review is still open on #4683, so I'm not giving an approval yet.
A hand-written marker stores set_at 0, and that value always keeps the marker, so git log -g was an extra subprocess on every wt list and statusline row. Return before asking git. Co-authored-by: Lixin2026 <2023Anita@users.noreply.github.com>
|
Thanks for working on this. Closing: it needs a
|
|
Opened #4704. |
A branch deleted outside `wt` (for example with `git branch -D`) leaves its `worktrunk.state.<branch>.marker` key in git config. A later `wt switch --create` with the same name then showed the old 🤖/💬. Now `wt switch --create` clears that branch's marker once `git worktree add -b` succeeds. #4684 already clears the marker on every `wt` deletion path. This is the follow-up the maintainer asked for when closing #4685. - The deletion helper from #4684 moves to `Repository::clear_branch_marker`, and both call sites use it. It is still best effort: a failed unset is logged at debug level, and only marker JSON is removed, so a `vars` entry named `marker` that shares the key is left alone. - Only `--create` clears the marker. Switching to an existing branch keeps its marker, and so does a DWIM checkout from a remote branch or a PR/MR ref. - A branch deleted and recreated with plain `git` still keeps its marker until `wt config state marker clear`. The marker help, its generated docs, and the help snapshot now say so. `test_switch_create_clears_stale_marker` sets a marker on a branch name that has no branch and on an existing branch. It then runs `wt switch --create` for the first and plain `wt switch` for the second. It fails without the change, because the stale marker survives, and passes with it. The existing `deletion_*` unit tests pass on the moved helper. Refs #4683 Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
|
Updated the description to match the current code: the missing-branch check is removed, bare repos are only covered when reflogs are on, and the approach choice vs. a prune command remains with the maintainer on #4683. |
Summary
wt listshowed a stale 🤖/💬 when a branch was deleted outside wt (git worktree remove,git branch -D) and the same name was created again. The marker lives atworktrunk.state.<branch>.marker, keyed only by branch name, so the key survived the deletion. #4684 already clears that key when wt itself deletes the branch.This is the outside-wt recreate case #4684 left open, and only that:
wt listskips a marker when git's branch reflog says the name was created after the marker'sset_at(delete-and-recreate).git log -g --date=unix(the oldestbranch: Created from …entry), so it works on any ref backend that git records a reflog for. No reflog file parsing.set_atof 0 (the documented hand-written form) keeps the marker and returns before runninggit log -g, so hand-written markers cost no extra subprocess.wt config state marker getstill returns it, andmarker clearstill removes it.worktrunk.state.<branch>.vars.*is unchanged.Limits
branch -Don a branch that a worktree has checked out. An unborn--orphanbranch has no ref yet. A deleted-but-not-recreated name keeps its marker.--orphanbranch, and bare repos, wherecore.logAllRefUpdatesis off by default. In a bare repo the fix only applies when reflogs are enabled.Whether this or a
wt config state prunecommand (suggestion 3) is the better approach is still open on #4683 for a maintainer.Reference #4683
Test
Integration:
test_list_hides_marker_recreated_outside_wtsets a marker, deletes the branch with plain git, recreates it, and checkswt listno longer shows the old marker.Unit tests cover a recreated branch, unknown branch age (
set_at: 0, an expired reflog, and reflogs off), an unborn--orphanbranch, a bare repo with and without a recorded reflog, and picking the oldestCreated fromentry fromgit log -goutput.