Skip to main content

d4-snap

Local-only Git snapshot manager — save shadow checkpoints of your working tree, diff against them, and restore files or the full directory without touching main repo history.

Version: 0.1.4 · Python: 3.10+

Links

Quick start

pip install d4-snap

# Quick snapshot (creates checkpoint and exits)
d4-snap

# Interactive menu
d4-snap menu

From a dev checkout:

git clone https://github.com/internetics-net/d4-snap.git
cd d4-snap
poetry install
poetry run d4-snap menu

Run all commands from inside a Git repository.

Why d4-snap?

Developers often want to save progress without cluttering the main branch with WIP commits. d4-snap stores snapshots in an isolated bare Git repo under ~/.d4/d4_snap/<repo-name>-<hash>. Your primary repository history stays untouched; you can experiment, roll back, and clean up with confidence.

Features

Feature Description
Shadow snapshots Bare repo per project; no commits on your main branch
Quick save d4-snap with no args saves and exits
Full or partial restore Overwrite the working tree or restore a single file
Diff viewer Compare a snapshot to the current working directory
Metadata Favorites, rename, soft-delete via git notes
Auto-naming Timestamp format YYYYMMDD-HHMMSSMMM
AI notes Optional short summary of changed files per snapshot
Auto-cleanup Configurable retention on every run; favorites preserved
Safety Path validation, safe tar extraction, YAML safe-load

All operations are local-only — no remote pushes or pulls.

CLI

Command Description
d4-snap Create a snapshot and exit
d4-snap menu Interactive menu
d4-snap help Show help (--help, -h, /? also work)

Main menu

🚀 Git Checkpoint & Rollback Manager (Shadow Checkpoints)
========================================
1. Save Snapshot
2. List / Manage Snapshots
3. View Diff
4. Restore Snapshot
5. Cleanup Old Snapshots
0. Exit

Menu actions

Save snapshot — stages the working tree in the shadow repo, commits with an auto-generated name, and stores metadata (notes, favorite flag).

List / manage — browse snapshots by branch; toggle favorite, rename, or soft-delete. Favorites are never auto-deleted.

View diff — pick a snapshot, optionally a relative file path, and run git diff against the current tree.

Restore — two modes:

  1. Restore everything — extracts the full snapshot via git archive + safe tar extraction; warns before overwrite; deletes the restored snapshot and all newer ones.
  2. Restore specific file — enter a repo-relative path (e.g. src/d4_snap/cli.py); only that file is written back.

Cleanup — manual purge of snapshots older than the configured manual retention (default 30 days); favorites kept.

Configuration

Bundled defaults live in src/d4_snap/config/d4_snap.yaml. Menu labels, prompts, and cleanup behaviour are all configurable.

auto_cleanup:
  enabled: true
  auto_cleanup_days: 90    # runs after every d4-snap execution
  manual_cleanup_days: 30  # menu option 5
  • Automatic cleanup runs on every invocation unless enabled: false.
  • Favorites are always preserved.
  • UI strings (titles, prompts, success/error messages) can be customized in the same file.

Architecture

main.py          Entry point, argument validation, auto-cleanup hook
cli.py           Menu orchestration
snapshot_manager Snapshot create/restore/list/metadata
git_operations   Shadow repo, git commands, safe tar extract
path_safety      Relative-path validation and directory containment
ui.py / menu.py  Interactive prompts and display
tools.py         Config loading (yaml.safe_load)

Shadow repo path: ~/.d4/d4_snap/<repo-basename>-<md5-hash[:12]>

Security

d4-snap is designed for local use on your own machine. Key safeguards in 0.1.4:

  • Safe tar extractionsafe_extract_tar() blocks path traversal and symlink escapes before extractall.
  • Path validation — restore and diff reject absolute paths, .. segments, and unsafe characters (path_safety.py).
  • Atomic writes — single-file restore uses a temp file + os.replace.
  • Safe configyaml.safe_load only; no arbitrary code execution from config.
  • Subprocess — git commands run as argument lists (shell=False).
  • CLI args — whitelist validation in main.validate_argument().

User-supplied paths must be relative to the repository root (e.g. src/foo.py, not /etc/passwd or ../../outside).

Examples

Quick snapshot

$ d4-snap
Saving snapshot...
✅ Snapshot saved successfully! (Shadow hash: 0f7a40e)

List snapshots

No.  Fav  Hash     Branch               Description                    Notes
----------------------------------------------------------------------------------------------------
1    ⭐   0f7a40e  main                 My custom name                 Fixed auth bug in login
2         36f3ca7  feature-branch       20260221-225542076             Added profile settings

Restore everything

Choice (1-2): 1
WARNING: This will overwrite your current uncommitted changes with snapshot 36f3ca7. Continue? (y/n): y
✅ Restored working directory to snapshot 36f3ca7
Deleted 2 snapshot(s)

Testing

108 tests passing

poetry run pytest

# With coverage
poetry run pytest --cov=d4_snap --cov-report=html

# Single module
poetry run pytest tests/test_path_safety.py -v

Coverage includes CLI, git operations, snapshot manager, UI, config loading, and path/tar security guards.

FAQ

Question Answer
Do snapshots affect my Git history? No. They live in a separate bare repo under ~/.d4/d4_snap.
Can I share snapshots? Local only. Export the shadow folder or use git bundle on the bare repo.
What happens on full restore? The restored snapshot and all newer snapshots are deleted automatically.
How do I keep a snapshot forever? Mark it as a favorite in the manage menu.
Can I disable auto-cleanup? Set auto_cleanup.enabled: false in the YAML config.

Troubleshooting

Symptom Fix
d4-snap: command not found Ensure your Python scripts directory (e.g. ~/.local/bin) is on PATH.
fatal: not a git repository cd into a Git repo first.
Permission denied on ~/.d4/d4_snap Fix directory permissions (e.g. chmod -R 700 ~/.d4/d4_snap on Unix).
Restore rejected for a path Use a repo-relative path with no .. segments.

Contributing

  1. Fork the repo
  2. Create a feature branch
  3. Run poetry run pytest
  4. Open a pull request

License

MIT © 2026 d4-snap Developers — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

d4_snap-0.1.6.tar.gz (24.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

d4_snap-0.1.6-py3-none-any.whl (28.3 kB view details)

Uploaded Python 3

File details

Details for the file d4_snap-0.1.6.tar.gz.

File metadata

  • Download URL: d4_snap-0.1.6.tar.gz
  • Upload date:
  • Size: 24.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for d4_snap-0.1.6.tar.gz
Algorithm Hash digest
SHA256 1613c945700527d0e824981ada7d2860d4999960c0bbfe32f7805930f97a2a38
MD5 adab494b6486e4b7b2112423d7766a28
BLAKE2b-256 49600b59366d969124767b7bd212adb945c691b2351e3de4aac0b378dda7483e

See more details on using hashes here.

Provenance

The following attestation bundles were made for d4_snap-0.1.6.tar.gz:

Publisher: release.yml on internetics-net/d4-snap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file d4_snap-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: d4_snap-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 28.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for d4_snap-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 6798fca7a53189bb8c7a01a277aa22b11af20529229b4febe144e9afc9ac9ffb
MD5 de80ca65c186b7a9edb4715b364e0ecd
BLAKE2b-256 738fc0df1116cb50802f76ff95038e18252a9443a071c01c834fbda9982199ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for d4_snap-0.1.6-py3-none-any.whl:

Publisher: release.yml on internetics-net/d4-snap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 files

0.1.3

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page