Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,12 @@ pub enum StageAction {
/// what it discarded first, and parks a recoverable copy in
/// `.hydrate/stage.discarded.json`. Purely local: no network call.
Discard,

/// Put back the stage `discard` most recently parked. Refuses if the
/// current stage is not empty (commit or discard it first) or if the
/// recovery slot was parked from a different branch than the one now
/// bound. Purely local: no network call. Consumes the recovery file.
Restore,
}

#[derive(Debug, Subcommand)]
Expand Down
27 changes: 27 additions & 0 deletions src/cmd/guide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ Editing in place
hydrate stage discard throw away everything staged (local; keeps a
recoverable copy). NOT the same as `clear`, which
stages deletions rather than undoing your edits
hydrate stage restore put back the stage the last discard parked;
refuses over a non-empty stage or onto a
different branch than the one it was parked from

Choosing a project
Commands resolve the project from --project <name|id>, else the HYD_PROJECT
Expand Down Expand Up @@ -162,6 +165,30 @@ mod tests {
}
}

#[test]
fn guide_documents_stage_restore_and_its_two_refusals() {
// `discard` promised recoverability from `.hydrate/stage.discarded.json`
// but nothing read it back — `restore` is what makes that true. Pin
// both places the guide claims a mistake is recoverable so the two
// verbs cannot drift apart.
assert!(
GUIDE.contains("hydrate stage restore"),
"guide never mentions `stage restore`"
);
let start = GUIDE
.find("hydrate stage restore")
.expect("stage restore line");
let line = &GUIDE[start..];
assert!(
line.contains("non-empty stage") || line.contains("refuses"),
"guide does not say restore refuses over live work: {line}"
);
assert!(
line.contains("different branch"),
"guide does not say restore refuses across branches: {line}"
);
}

#[test]
fn guide_does_not_restate_retired_rules() {
// The guide is the agent onboarding surface, so a stale rule here
Expand Down
1 change: 1 addition & 0 deletions src/cmd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub fn dispatch(cli: Cli) -> ExitCode {
},
Command::Stage { action } => match action {
StageAction::Discard => finish(stage::discard(mode), mode),
StageAction::Restore => finish(stage::restore(mode), mode),
},
Command::Status => finish(status::run(mode), mode),
Command::Diff => finish(diff::run(mode), mode),
Expand Down
Loading