huskies: merge 651_bug_remove_git_reset_clean_behaviour_from_bug_645_s_recovery_path_uncommitted_work_in_worktrees_is_never_junk
This commit is contained in:
+52
-13
@@ -43,22 +43,47 @@ pub(crate) fn worktree_has_committed_work(wt_path: &Path) -> bool {
|
||||
|
||||
/// Run `cargo check` in the given worktree directory to verify committed code compiles.
|
||||
///
|
||||
/// Resets any dirty (uncommitted) files first via `git checkout .` so that only
|
||||
/// the committed state is evaluated. Used as part of the "work survived" check
|
||||
/// when an agent crashes mid-output (bug 645).
|
||||
/// Stashes any dirty (uncommitted) files first so that only the committed state
|
||||
/// is evaluated, then restores them afterward. Uncommitted work in worktrees is
|
||||
/// never junk — it may be the next agent session's starting point (bug 651).
|
||||
///
|
||||
/// Used as part of the "work survived" check when an agent crashes mid-output
|
||||
/// (bug 645).
|
||||
pub(crate) fn cargo_check_in_worktree(wt_path: &Path) -> bool {
|
||||
// Reset uncommitted changes so cargo check evaluates only committed code.
|
||||
let _ = Command::new("git")
|
||||
.args(["checkout", "."])
|
||||
// Stash uncommitted changes (including untracked files) so cargo check
|
||||
// evaluates only committed code. We restore them afterward.
|
||||
let stashed = Command::new("git")
|
||||
.args([
|
||||
"stash",
|
||||
"push",
|
||||
"--include-untracked",
|
||||
"-m",
|
||||
"cargo-check-temp",
|
||||
])
|
||||
.current_dir(wt_path)
|
||||
.output();
|
||||
.output()
|
||||
.map(|o| {
|
||||
o.status.success()
|
||||
&& !String::from_utf8_lossy(&o.stdout).contains("No local changes to save")
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
Command::new("cargo")
|
||||
let result = Command::new("cargo")
|
||||
.args(["check"])
|
||||
.current_dir(wt_path)
|
||||
.output()
|
||||
.map(|o| o.status.success())
|
||||
.unwrap_or(false)
|
||||
.unwrap_or(false);
|
||||
|
||||
// Restore stashed uncommitted changes.
|
||||
if stashed {
|
||||
let _ = Command::new("git")
|
||||
.args(["stash", "pop"])
|
||||
.current_dir(wt_path)
|
||||
.output();
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Check whether the given directory has any uncommitted git changes.
|
||||
@@ -457,9 +482,10 @@ mod tests {
|
||||
|
||||
// ── cargo_check_in_worktree tests ────────────────────────────────────────
|
||||
|
||||
/// Bug 645: cargo_check_in_worktree resets dirty files before checking.
|
||||
/// Bug 645 + 651: cargo_check_in_worktree stashes dirty files before
|
||||
/// checking committed code and restores them afterward.
|
||||
#[test]
|
||||
fn cargo_check_in_worktree_resets_dirty_files() {
|
||||
fn cargo_check_in_worktree_stashes_and_restores_dirty_files() {
|
||||
use std::fs;
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let project_root = tmp.path().join("project");
|
||||
@@ -530,11 +556,24 @@ mod tests {
|
||||
|
||||
// Now simulate a crash leaving dirty files (broken syntax).
|
||||
fs::write(wt_path.join("src/lib.rs"), "THIS IS BROKEN SYNTAX!!!\n").unwrap();
|
||||
// Also add an untracked file.
|
||||
fs::write(wt_path.join("crash_residue.txt"), "untracked junk").unwrap();
|
||||
|
||||
// cargo_check_in_worktree should reset dirty files and check committed code.
|
||||
// cargo_check_in_worktree should stash dirty files, check committed code, and restore.
|
||||
assert!(
|
||||
cargo_check_in_worktree(&wt_path),
|
||||
"cargo check should pass on committed code after resetting dirty files"
|
||||
"cargo check should pass on committed code after stashing dirty files"
|
||||
);
|
||||
|
||||
// Bug 651: dirty files must be restored after cargo check.
|
||||
assert_eq!(
|
||||
fs::read_to_string(wt_path.join("src/lib.rs")).unwrap(),
|
||||
"THIS IS BROKEN SYNTAX!!!\n",
|
||||
"modified tracked file should be restored after cargo check"
|
||||
);
|
||||
assert!(
|
||||
wt_path.join("crash_residue.txt").exists(),
|
||||
"untracked file should be restored after cargo check"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user