Repository navigation
feat(remove): back up uncommitted changes before --force discards them - #4545
Open
worktrunk-bot wants to merge 3 commits into
Open
worktrunk-bot wants to merge 3 commits into
worktrunk-bot wants to merge 3 commits into
Conversation
`wt remove --force` now saves the worktree's staged, unstaged and untracked changes (ignored files excepted) as a commit under `refs/wt-backup/<branch>` before removing it, the same ref and reflog the squash backup uses, and prints a `wt switch --create --base <sha>` command to recover them. The snapshot is built through a temporary index, so the real index is untouched; its parent is the worktree's HEAD, which keeps the branch tip reachable after `-D`. A failed backup refuses the removal rather than lose the changes. Closes #4544 Co-Authored-By: Claude <noreply@anthropic.com>
worktrunk-bot
commented
Oct 21, 2026
worktrunk-bot
left a comment
Collaborator
Author
There was a problem hiding this comment.
Two small follow-ups, which I'll push as one commit:
…dule exception Move the backup/recovery hint block into SafetyBackup::print_recovery_hints so wt remove --force and wt step squash print the same thing, and name changes inside submodules alongside ignored files as not saved by the --force backup. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Oct 21, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
wt remove --forcenow saves a worktree's uncommitted changes before discarding them, using the samerefs/wt-backup/<branch>ref and reflog that the squash backup inwt merge/wt step squashalready uses. The output then prints the backup and a recovery command:Closes #4544.
What gets saved
git add -Awould stage. The snapshot is built through aTempIndex, so the real index and the stash list are left alone.HEAD, so the branch tip also stays reachable after-Ddeletes the branch. On an unborn branch the commit has no parent.--forceactually discards something. A clean--forceremoval creates no ref.Decisions for review
-floses nothing you can't get back.Failed to back up uncommitted changes; worktree not removed. That follows the data-safety guidance in AGENTS.md, but it also meanswt remove -fcan no longer remove a worktree that git can't snapshot (for example, a corrupt index). The alternative is to warn and continue.refs/wt-backup/today, and this PR doesn't change that.Code
create_safety_backupand the newcreate_removal_backup(src/git/repository/working_tree.rs) share arecord_backuphelper for thecommit-tree/update-refstep. The helper looks up the branch name without the cache, and falls back tosymbolic-refso an unborn branch is still named. The removal side lives instage_worktree_removal(src/git/remove.rs). That function runs right before the worktree is renamed into trash, so it coverswt remove,wt merge --remove, and the foreground path.Tests
test_remove_force_with_untracked_filesnow checks that the backup ref holds the untracked file's content, that its parent is the removed branch tip, and that an ignored file is excluded.remove_force_with_*snapshots and thewt remove --helpsnapshot gain the new lines. The docs (wt removehelp, FAQ) mention the backup.