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:
- Restore everything — extracts the full snapshot via
git archive+ safe tar extraction; warns before overwrite; deletes the restored snapshot and all newer ones. - 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 extraction —
safe_extract_tar()blocks path traversal and symlink escapes beforeextractall. - 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 config —
yaml.safe_loadonly; 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
- Fork the repo
- Create a feature branch
- Run
poetry run pytest - Open a pull request
License
MIT © 2026 d4-snap Developers — see LICENSE.
Metadata
Release files for d4-snap 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| d4_snap-0.1.6.tar.gz | 24.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| d4_snap-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 52.9 kB
Release files / d4_snap-0.1.6.tar.gz
| Download URL | d4_snap-0.1.6.tar.gz |
|---|---|
| Size | 24.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1613c945700527d0e824981ada7d2860d4999960c0bbfe32f7805930f97a2a38
|
|
BLAKE2b-256 checksum How to use checksums |
49600b59366d969124767b7bd212adb945c691b2351e3de4aac0b378dda7483e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logRelease files / d4_snap-0.1.6-py3-none-any.whl
| Download URL | d4_snap-0.1.6-py3-none-any.whl |
|---|---|
| Size | 28.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6798fca7a53189bb8c7a01a277aa22b11af20529229b4febe144e9afc9ac9ffb
|
|
BLAKE2b-256 checksum How to use checksums |
738fc0df1116cb50802f76ff95038e18252a9443a071c01c834fbda9982199ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logSecurity for d4-snap 0.1.6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for d4_snap-0.1.6.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.