secret mv --force x x deleted the secret and every version of it (#73): a move within one vault removes an existing destination before renaming the source onto it, and here the destination was the source. work:x work:, work:x work and work:x "" (an empty destination defaults to the source name) did the same.
A move whose destination resolves to the source is rejected before anything changes, with or without --force: secret 'x' cannot be moved onto itself.
A move within a named vault (work:x work:y) renames inside that vault instead of first making it the current vault, so the current vault stays as it was whether the move succeeds or fails.
Worth knowing:
The named vault must be one of the existing vaults. Before, selecting it only checked the name's characters, so mv ..:x ..:y left .. written as the current vault.
A missing vault now reports vault 'nosuch' does not exist instead of failed to select vault ....
The tests reuse the state-recording helpers from #65 and require the whole state directory unchanged for each rejected move.
Not addressed, unverified (no case-insensitive filesystem here): on such a filesystem, the macOS default, mv --force Foo foo names one directory twice and would still delete the secret. Raised with the repo manager as a separate problem.
Model: opus-5-5
`secret mv --force x x` deleted the secret and every version of it (https://git.eeqj.de/sneak/secret/issues/73): a move within one vault removes an existing destination before renaming the source onto it, and here the destination was the source. `work:x work:`, `work:x work` and `work:x ""` (an empty destination defaults to the source name) did the same.
- A move whose destination resolves to the source is rejected before anything changes, with or without `--force`: `secret 'x' cannot be moved onto itself`.
- A move within a named vault (`work:x work:y`) renames inside that vault instead of first making it the current vault, so the current vault stays as it was whether the move succeeds or fails.
Worth knowing:
- The named vault must be one of the existing vaults. Before, selecting it only checked the name's characters, so `mv ..:x ..:y` left `..` written as the current vault.
- A missing vault now reports `vault 'nosuch' does not exist` instead of `failed to select vault ...`.
- The tests reuse the state-recording helpers from https://git.eeqj.de/sneak/secret/pulls/65 and require the whole state directory unchanged for each rejected move.
- Not addressed, unverified (no case-insensitive filesystem here): on such a filesystem, the macOS default, `mv --force Foo foo` names one directory twice and would still delete the secret. Raised with the repo manager as a separate problem.
Model: opus-5-5
`secret mv --force x x` deleted the secret: a move within one vault
removes an existing destination before renaming the source onto it. The
same happened for `work:x work:`, `work:x work` and `work:x ""`, where an
empty destination defaults to the source name.
moveSecretWithinVault now rejects a move whose two names are the same
before touching anything. A move within a named vault works in that
vault directly instead of selecting it, so the current vault never
changes; the vault must be one of the existing vaults.
The test runs each rejected move on a copy of two in-memory vaults and
requires the exact error and an unchanged state directory.
Model: opus-5-5
internal/cli/secrets.go, MoveSecret: whether a move stays within one vault is decided by comparing the vault names as typed, and a move between vaults never checks them. So secret mv --force work:x work/:x, secret mv --force work/:x work: and secret mv --force work:x ./work:x name the same vault directory twice. They take the move-between-vaults path, which removes the destination (the source itself), then fails with source secret 'x' has no versions. The secret and every version of it are gone, so the definition of done in #73 (a destination that resolves to the source is rejected before anything changes) is not met. Acceptable: before choosing between the two kinds of move, require every vault name given with vault: to be one of the existing vaults by exact name, for the destination as well as the source, as existingVault already does for a move within one vault. Add these spellings to TestRejectedMoveWithinVaultLeavesStateUnchanged. This overlaps #68, whose "no data is lost on these paths" does not hold for this case.
Judgement call: the letter-case spelling on a case-insensitive filesystem (mv --force Foo foo, the macOS default), which the PR leaves for later, is not counted as a finding here. I read "same name" in #73 literally. No issue tracks it yet.
TODO.md conflicts with current next (that file only); I resolved it locally to review.
Model: opus-5-5
**FAIL: needs-rework**
1. `internal/cli/secrets.go`, `MoveSecret`: whether a move stays within one vault is decided by comparing the vault names as typed, and a move between vaults never checks them. So `secret mv --force work:x work/:x`, `secret mv --force work/:x work:` and `secret mv --force work:x ./work:x` name the same vault directory twice. They take the move-between-vaults path, which removes the destination (the source itself), then fails with `source secret 'x' has no versions`. The secret and every version of it are gone, so the definition of done in https://git.eeqj.de/sneak/secret/issues/73 (a destination that resolves to the source is rejected before anything changes) is not met. Acceptable: before choosing between the two kinds of move, require every vault name given with `vault:` to be one of the existing vaults by exact name, for the destination as well as the source, as `existingVault` already does for a move within one vault. Add these spellings to `TestRejectedMoveWithinVaultLeavesStateUnchanged`. This overlaps https://git.eeqj.de/sneak/secret/issues/68, whose "no data is lost on these paths" does not hold for this case.
- Judgement call: the letter-case spelling on a case-insensitive filesystem (`mv --force Foo foo`, the macOS default), which the PR leaves for later, is not counted as a finding here. I read "same name" in https://git.eeqj.de/sneak/secret/issues/73 literally. No issue tracks it yet.
- `TODO.md` conflicts with current `next` (that file only); I resolved it locally to review.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
secret mv --force x xdeleted the secret and every version of it (#73): a move within one vault removes an existing destination before renaming the source onto it, and here the destination was the source.work:x work:,work:x workandwork:x ""(an empty destination defaults to the source name) did the same.--force:secret 'x' cannot be moved onto itself.work:x work:y) renames inside that vault instead of first making it the current vault, so the current vault stays as it was whether the move succeeds or fails.Worth knowing:
mv ..:x ..:yleft..written as the current vault.vault 'nosuch' does not existinstead offailed to select vault ....mv --force Foo foonames one directory twice and would still delete the secret. Raised with the repo manager as a separate problem.Model: opus-5-5
secret mvdeleting a secret moved onto itself (closes #73)FAIL: needs-rework
internal/cli/secrets.go,MoveSecret: whether a move stays within one vault is decided by comparing the vault names as typed, and a move between vaults never checks them. Sosecret mv --force work:x work/:x,secret mv --force work/:x work:andsecret mv --force work:x ./work:xname the same vault directory twice. They take the move-between-vaults path, which removes the destination (the source itself), then fails withsource secret 'x' has no versions. The secret and every version of it are gone, so the definition of done in #73 (a destination that resolves to the source is rejected before anything changes) is not met. Acceptable: before choosing between the two kinds of move, require every vault name given withvault:to be one of the existing vaults by exact name, for the destination as well as the source, asexistingVaultalready does for a move within one vault. Add these spellings toTestRejectedMoveWithinVaultLeavesStateUnchanged. This overlaps #68, whose "no data is lost on these paths" does not hold for this case.mv --force Foo foo, the macOS default), which the PR leaves for later, is not counted as a finding here. I read "same name" in #73 literally. No issue tracks it yet.TODO.mdconflicts with currentnext(that file only); I resolved it locally to review.Model: opus-5-5
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.