On a case-insensitive filesystem, secret mv --force Foo foo deletes the secret #78

Closed
opened 2026-10-04 02:58:57 +02:00 by clawbot · 2 comments
Collaborator

Found in the review of #76 (left out of that PR, which reads "same name" in #73 literally).

Problem

On a case-insensitive filesystem (the macOS default), secrets.d/Foo and secrets.d/foo are the same directory. secret mv --force Foo foo sees an existing destination, removes it with --force, and so removes the source: the secret and every version are gone. Without --force the move is refused as "already exists", so only the forced form loses data. The same applies to vault names that differ only in case in a cross-vault move.

Definition of done

  • Before removing an existing destination, a move checks whether the destination is the same directory as the source (for example os.SameFile on the two directories when the filesystem is the real one) and, if so, either rejects the move with a clear error or performs a plain rename to the new spelling without removing anything. Pick one and say which in the PR.
  • A rename that only changes letter case works on a case-sensitive filesystem exactly as before.
  • A test proves the same-directory case without needing a case-insensitive filesystem (for example by aliasing a vault directory with a symlink on the real filesystem in a temporary directory), and requires the state unchanged or the secret intact under its new name.
  • TODO.md updated in the same commit.

Sequencing

After #76 lands (same function).

Model: opus-5-5

Found in the review of https://git.eeqj.de/sneak/secret/pulls/76 (left out of that PR, which reads "same name" in https://git.eeqj.de/sneak/secret/issues/73 literally). ## Problem On a case-insensitive filesystem (the macOS default), `secrets.d/Foo` and `secrets.d/foo` are the same directory. `secret mv --force Foo foo` sees an existing destination, removes it with `--force`, and so removes the source: the secret and every version are gone. Without `--force` the move is refused as "already exists", so only the forced form loses data. The same applies to vault names that differ only in case in a cross-vault move. ## Definition of done - Before removing an existing destination, a move checks whether the destination is the same directory as the source (for example `os.SameFile` on the two directories when the filesystem is the real one) and, if so, either rejects the move with a clear error or performs a plain rename to the new spelling without removing anything. Pick one and say which in the PR. - A rename that only changes letter case works on a case-sensitive filesystem exactly as before. - A test proves the same-directory case without needing a case-insensitive filesystem (for example by aliasing a vault directory with a symlink on the real filesystem in a temporary directory), and requires the state unchanged or the secret intact under its new name. - `TODO.md` updated in the same commit. ## Sequencing After https://git.eeqj.de/sneak/secret/pulls/76 lands (same function). Model: opus-5-5
clawbot added the critical label 2026-10-04 02:58:57 +02:00
Author
Collaborator

Labelled critical: on macOS (case-insensitive by default), secret mv --force Foo foo removes the destination, which is the source, so the secret and all its versions are lost.

Model: opus-5-5

Labelled critical: on macOS (case-insensitive by default), `secret mv --force Foo foo` removes the destination, which is the source, so the secret and all its versions are lost. Model: opus-5-5
Author
Collaborator

#81 rejects a move, within a vault or between vaults, whose destination is the source under another name, with or without --force, before anything changes. On macOS, changing only the case of a secret's name now takes two moves through a third name.

Model: opus-5-5

https://git.eeqj.de/sneak/secret/pulls/81 rejects a move, within a vault or between vaults, whose destination is the source under another name, with or without `--force`, before anything changes. On macOS, changing only the case of a secret's name now takes two moves through a third name. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#78