trunk
Branches trunk
1 Branches 0 Tags
Go to file T
Code
.github ci(freebsd-smoke): wire 4 W09.7 smokes + rsync pkg dep
benches L01 chunk 6 close: fanotify mark FAN_EVENT_ON_CHILD + gate goes load-bearing
crates shim: canonicalize rename(from,to) for daemon-side path matching (W09.7)
packaging fix(packaging): wrappers use --target-argv=$v (equals) not --target-argv "$v" (space)
shell fix(shell/fish): quote tty value to survive BSD tty's 'not a tty' stdout
tests smoke: rsync-incremental-undo-fbsd.sh (W09.7 — discovered rename path-canonicalization)
tools workflow(linux-kernel-capture): wire vim-edit-undo smoke + add vim-nox dep
xtask xtask: skip /vendor in license-check (third-party crates have their own licenses)
.clippy.toml S20.13 follow-up: bump clippy.toml MSRV to 1.88 to match Cargo.toml + rust-toolchain.toml (was missed in the original MSRV bump)
.gitignore S20.13 / DR-60: tools/linux-bpf-vm — Ubuntu 24.04 arm64 cloud-init provisioning under qemu+HVF; adds bpf to LSM stack via grub cmdline edit
CLAUDE.md S20.13 audit fix: bump MSRV 1.85 -> 1.88 (helper.rs uses let-chains stabilized in 1.88; pre-bump pinned toolchain wouldn't build)
CONTRIBUTING.md scaffold: license, readme, contributing, gitignore
Cargo.lock feat(shit-helper): add serde_json dep for container inspect parsing
Cargo.toml shim: per-package strip=debuginfo to preserve .gnu.version symbol map
LICENSE scaffold: license, readme, contributing, gitignore
Makefile S20.7: Makefile — tracing-leak-check grep guard (wired into make ci)
README.md scaffold: license, readme, contributing, gitignore
rust-toolchain.toml S20.13 audit fix: bump MSRV 1.85 -> 1.88 (helper.rs uses let-chains stabilized in 1.88; pre-bump pinned toolchain wouldn't build)
rustfmt.toml scaffold: cargo workspace, 8 crate stubs, xtask license-check

shit

magic undo for the command line

You just made a mistake on the command line — an edit, a botched mv, a rm that took more than you meant — and you want to undo its effects. shit watches the right kernel surfaces, captures pre-images cheaply via your filesystem's native copy-on-write, and produces an approvable undo plan.

Status

Pre-1.0. APIs, wire formats, and on-disk layouts are unstable.

Install

Coming soon: brew install tenseleyFlow/tap/shit, AUR (shit-bin), FreeBSD ports, and a signed curl … | sh.

Dev quickstart

git clone https://github.com/tenseleyFlow/shit
cd shit
make dev    # cargo build --workspace
make test   # cargo test --workspace
make lint   # cargo clippy
make ci     # everything CI runs

How it works

shit is three binaries plus shell glue:

  • shit — the CLI: shit undo, shit redo, shit list, shit show, shit pin, shit doctor, …
  • shitd — a per-user daemon that owns the snapshot store, the sqlite index, the IPC sockets, and the undo planner.
  • shit-helper — a privileged helper that drives kernel-level capture: EndpointSecurity on macOS, fanotify-perm + eBPF-LSM on Linux, kqueue + an optional LD_PRELOAD shim on BSD.
  • shell hooks (bash, zsh, fish) that bracket each command with metadata events sent over a persistent Unix-domain-socket fd.

When a command writes, renames, unlinks, or otherwise mutates a file inside a tracked process subtree, the helper captures the pre-image before the kernel allows the syscall to complete — using clonefile (APFS), reflink (btrfs/XFS), zfs clone (ZFS), hardlink, or streaming copy, picking the cheapest tier the underlying filesystem supports. Blobs land in a content-addressed store (blake3 + zstd) under $XDG_STATE_HOME/shit/.

When you run shit undo, the daemon's planner walks the captured events, computes an inverse-op DAG, shows you exactly what it'll do, and applies it on your y.

Coverage

Beyond files, shit also captures:

  • File metadata (perms, ACLs, xattrs).
  • Tree operations (create/delete/rename/link).
  • Environment-variable mutations (per-shell).
  • Package-manager operations (apt, dpkg, pacman, dnf, brew, FreeBSD pkg) via each manager's native hook system.
  • systemd / launchd unit operations (via CLI wrappers).
  • Network / firewall / routing changes (iptables, nft, ufw, pfctl, ip, networksetup).
  • Process lifecycle (best-effort; shit show produces a restart suggestion you can confirm).

What's not undoable is documented honestly in each tier's design notes — we'd rather say "this was unrecoverable" than lie about it.

License

AGPLv3. See LICENSE.