返回 CodeWhale
mod.rs
根目录 / crates / tui / src / snapshot / mod.rs
1 //! Workspace snapshots — pre/post-turn safety net.
2 //!
3 //! Each turn the engine takes a `pre-turn:<seq>` snapshot of the user's
4 //! workspace into a side git repo at
5 //! `~/.deepseek/snapshots/<project_hash>/<worktree_hash>/.git`, then a
6 //! matching `post-turn:<seq>` snapshot when the turn finishes. Users
7 //! can roll back via `/restore N` (slash command) or, when the model
8 //! recognises an "undo my last edit" intent, the `revert_turn` tool.
9 //!
10 //! ## Why a side repo?
11 //!
12 //! - The user's own `.git` is never touched. `--git-dir` and
13 //! `--work-tree` are *always* set together when we shell out to git;
14 //! that single invariant is what keeps snapshots and the user's repo
15 //! completely independent.
16 //! - Workspaces without git still get snapshots.
17 //! - `git`'s own deduplication (object packfiles) keeps the disk
18 //! footprint tractable — typical 100 MB workspace × 12 turns ≈ 1.2 GB
19 //! uncompressed but git's content-addressed storage usually brings
20 //! that down 10-30×. We mitigate further with:
21 //! - 7-day default retention (`session_manager` prunes at session
22 //! start via [`prune::prune_older_than`]).
23 //! - `gc.auto = 0` on the side repo (we don't want background gcs
24 //! firing mid-turn) plus an explicit `git gc --prune=now` after
25 //! prune.
26 //! - Startup cleanup for stale `tmp_pack_*` files left by interrupted
27 //! git pack operations.
28 //!
29 //! ## Failure model
30 //!
31 //! Pre/post-turn snapshot calls are **non-fatal**. If `git` is missing,
32 //! the disk is full, or the workspace is on a read-only filesystem, the
33 //! turn proceeds and the engine logs a warning. The snapshot is a
34 //! safety net, not a correctness gate.
35 //!
36 //! Workspaces over the configured size cap (`[snapshots] max_workspace_gb`,
37 //! default 2 GB of non-excluded content) skip snapshot init entirely. That
38 //! disable is intentionally loud: the operator is told once that undo is off
39 //! for the workspace, with the opt-in knobs (raise the cap, or set
40 //! `max_workspace_gb = 0` to disable the size gate). Scoped snapshot roots are
41 //! not yet a first-class config; the practical opt-in today is the cap override.
42
43 pub mod paths;
44 pub mod prune;
45 pub mod repo;
46
47 #[allow(unused_imports)]
48 pub use paths::{snapshot_dir_for, snapshot_git_dir};
49 pub use prune::{DEFAULT_MAX_AGE, prune_older_than};
50
51 /// Maximum snapshots kept per workspace side-repo. Oldest are pruned
52 /// after each new snapshot to cap disk usage (#1112).
53 pub const DEFAULT_MAX_SNAPSHOTS: usize = 50;
54 #[allow(unused_imports)]
55 pub use repo::{
56 DEFAULT_MAX_WORKSPACE_BYTES_FOR_SNAPSHOT, Snapshot, SnapshotId, SnapshotRepo,
57 estimate_workspace_size_bounded,
58 };
59
59 lines RUST