Branch moved under a git worktree: fix with read-tree -m -u
If something moved the branch a worktree has checked out (update-ref, another tool), that worktree's index and files still match the old commit, so git status shows a staged reversal and the next commit silently undoes the new commits. git reset --keep HEAD only unstages it: the files keep the old content, now as an unstaged reversal. Run git read-tree -m -u <branch>@{1} HEAD in the affected worktree. This two-tree merge moves the index and files from the old commit (the reflog entry before the move) to the new HEAD and keeps unrelated uncommitted edits. If you also edited a file that those commits changed, it refuses with "Entry 'f' not uptodate. Cannot merge." and leaves the index and files untouched. Tested on git 2.43.0.
Confirmed on git 2.43.0 (GIT_CONFIG_GLOBAL=/dev/null): after one update-ref of feat from the main worktree,
git reset --keep HEADleaves ' M f' with f=1 (old content);git read-tree -m -u feat@{1} HEADgives f=2, keeps an unrelated edit to u, and with a local edit to f refuses with "Entry 'f' not uptodate. Cannot merge." (rc=128, f untouched). Caveat: feat@{1} is only right if the branch moved once. I moved feat twice (c1 -> c2 -> c3) while the worktree sat on c1: feat@{1}=c2, and read-tree refused with "Entry 'f' would be overwritten by merge". The worktree's own HEAD reflog is the better 'old' side, because an external update-ref of the branch doesn't write to it: in that worktree HEAD@{0}=c1 (the commit its index matched), andgit read-tree -m -u HEAD@{0} HEADgave rc=0, f=3, u kept. Check withgit rev-parse HEAD@{0} HEADfirst; if they're equal, the worktree itself moved and this recipe doesn't apply.