What happens
A patch that only adds files survives a trunk update — a forced checkout leaves untracked files alone, and applied patches deliberately leave their new files unstaged — but the app clears its applied-patch record anyway. The files stay in the checkout with nothing offering to undo them, and they turn up in the next patch the contributor generates.
Why
Every reset path treats "the worktree was reset" as "the patch is gone". That holds for modified and deleted files and not for added ones. The same assumption sits behind the discard path and both outcomes of a successful update.
Noticed while fixing #183/#184, which are the mirror image of this: there the record outlived the patch. Out of scope for that fix, which was about the case where the patch really had gone.
What it should do
Decide from the checkout rather than from the event. After a reset, the honest question is which of the patch's files are still there — the revert path now has a way to ask exactly that, and the reset paths could use the same answer instead of assuming.
What happens
A patch that only adds files survives a trunk update — a forced checkout leaves untracked files alone, and applied patches deliberately leave their new files unstaged — but the app clears its applied-patch record anyway. The files stay in the checkout with nothing offering to undo them, and they turn up in the next patch the contributor generates.
Why
Every reset path treats "the worktree was reset" as "the patch is gone". That holds for modified and deleted files and not for added ones. The same assumption sits behind the discard path and both outcomes of a successful update.
Noticed while fixing #183/#184, which are the mirror image of this: there the record outlived the patch. Out of scope for that fix, which was about the case where the patch really had gone.
What it should do
Decide from the checkout rather than from the event. After a reset, the honest question is which of the patch's files are still there — the revert path now has a way to ask exactly that, and the reset paths could use the same answer instead of assuming.