Synced from monorepo
Synced from monorepo Changes: - Temporarily disable session share link creation in the TUI - Do not approve plan on empty Enter from the revise prompt - Expose chat product Skills via ACP available_commands_update - Return immediately from a blocking wait on an already-completed ACP task - Split headless pager module for clearer structure - Stop git worktree prune from removing user registrations on resume - Use compaction sampler tokenizer for item token counts - Opt-in extra root CAs via GROK_EXTRA_CA_BUNDLE - Cancel all session subagents when the user stops - Let the session persistence actor exit when its session ends - Make fullscreen terminal resize much cheaper on long sessions - Report honestly from kill_task when an ACP task does not exist - Hide /usage for external-auth deployments - Forward the history-load trailer’s computer_reason to the client - Remove ineffective no-op tool reminder - Declare slash-command screen-mode support in one place - Keep settings enum picker on the committed value until Enter - Reap a PTY’s full process tree - Stream tool calls from headless mode over ACP - Bridge gateway task lifecycle to ACP for chat session background tasks - Don’t warn about truncated history on a suppressed replay - Fit full-replace summarizer input and recover on context-length errors - Stop dropping agents over an unrecognized frontmatter color - Add /undo as a slash alias for /rewind - Harden sleep/wake token-refresh paths against forced re-login - Add session/list ACP method - Give each sampling backend its own conversion module - Treat an unenrolled child process as a lint error - Suppress the cancelled marker on send-now wake turns - Stop tearing down Roslyn on every edit, and read C# diagnostics Source-Revision: 2a28b4a86cfc4a4c133c35b7fc2a6a9964387c39
This commit is contained in:
parent
500129c714
commit
dd04f397b1
367 changed files with 29489 additions and 10051 deletions
|
|
@ -445,10 +445,6 @@ fn rehydrate_worktree_from_ref_inner(
|
|||
) -> Result<WorktreeReport> {
|
||||
let dest_str = dest.to_string_lossy();
|
||||
|
||||
// A previously-disposed worktree can leave a stale registration for this
|
||||
// path; prune it so re-adding the original `subagent-<id>` dir succeeds.
|
||||
snapshot_git(source_repo, &["worktree", "prune"], &[])?;
|
||||
|
||||
// The snapshot's first parent is the original base. Resolve it, then confirm
|
||||
// the object is actually present — a parent-repo `git reset --hard` + gc can
|
||||
// leave the parent pointer dangling, which `rev-parse` alone would not catch.
|
||||
|
|
@ -478,11 +474,14 @@ fn rehydrate_worktree_from_ref_inner(
|
|||
// A prior rehydrate may have failed after `worktree add` and left a partial dir; remove it so this attempt starts clean (worktree add fails on an existing path).
|
||||
if dest.exists() {
|
||||
let _ = crate::remove_worktree(dest);
|
||||
let _ = snapshot_git(source_repo, &["worktree", "prune"], &[]);
|
||||
if dest.exists() {
|
||||
let _ = std::fs::remove_dir_all(dest);
|
||||
}
|
||||
}
|
||||
// `git worktree add` refuses a path another registration still claims,
|
||||
// so scrub `dest`'s stale registration (previously-disposed worktree, or
|
||||
// the raw `remove_dir_all` fallback above) before adding.
|
||||
crate::git::remove_stale_worktree_registration(source_repo, dest);
|
||||
snapshot_git(
|
||||
source_repo,
|
||||
&[
|
||||
|
|
@ -509,7 +508,7 @@ fn rehydrate_worktree_from_ref_inner(
|
|||
Err(e) => {
|
||||
// Best-effort cleanup; preserve the original error.
|
||||
let _ = crate::remove_worktree(dest);
|
||||
let _ = snapshot_git(source_repo, &["worktree", "prune"], &[]);
|
||||
crate::git::remove_stale_worktree_registration(source_repo, dest);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
|
@ -1121,6 +1120,50 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
/// Rehydrate must clear its own stale registration (so re-adding the
|
||||
/// same path succeeds) while leaving every other entry alone — its
|
||||
/// cleanup once pruned repo-wide and destroyed user registrations whose
|
||||
/// paths were not visible from the container mount namespace.
|
||||
#[test]
|
||||
fn test_rehydrate_clears_only_its_own_stale_registration() {
|
||||
xai_test_utils::require_git!();
|
||||
let temp = TempDir::new().unwrap();
|
||||
let (repo_path, wt) = repo_with_worktree(&temp);
|
||||
|
||||
std::fs::write(wt.join("tracked.txt"), "edited").unwrap();
|
||||
let snap = snapshot_worktree_to_ref(&wt, "refs/grok/snapshots/stalereg", "stale").unwrap();
|
||||
crate::remove_worktree(&wt).unwrap();
|
||||
|
||||
rehydrate_worktree_from_ref(&wt, &repo_path, &snap, None).unwrap();
|
||||
let registration = repo_path
|
||||
.join(".git")
|
||||
.join("worktrees")
|
||||
.join(wt.file_name().unwrap());
|
||||
assert!(registration.is_dir(), "linked registration expected");
|
||||
|
||||
let user_wt = temp.path().join("user-wt");
|
||||
git_capture_in(
|
||||
&repo_path,
|
||||
&["worktree", "add", "--detach", user_wt.to_str().unwrap()],
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
std::fs::rename(&user_wt, temp.path().join("user-wt-hidden")).unwrap();
|
||||
|
||||
std::fs::remove_dir_all(&wt).unwrap();
|
||||
|
||||
let report = rehydrate_worktree_from_ref(&wt, &repo_path, &snap, None).unwrap();
|
||||
assert_eq!(report.worktree_path, wt);
|
||||
assert_eq!(
|
||||
std::fs::read_to_string(wt.join("tracked.txt")).unwrap(),
|
||||
"edited"
|
||||
);
|
||||
assert!(
|
||||
repo_path.join(".git/worktrees/user-wt").exists(),
|
||||
"user registration must survive rehydrate even when its path is hidden"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transfer_snapshot_to_repo_makes_standalone_ref_durable() {
|
||||
xai_test_utils::require_git!();
|
||||
|
|
|
|||
Loading…
Reference in a new issue