Clean, safe, professional snapshot manager
Project description
d4-snap – Snapshot & Rollback Manager
Never lose your work again, d4-snap saves instant snapshots of your code so you can roll back to any moment with one command.
d4-snap is a lightweight, local-only Git helper that gives you a simple, reproducible way to:
- Keep shadow checkpoints – isolated snapshots that don't touch your main repo history
- Quickly save your progress locally without making official Git commits
- Restore your entire working directory or specific files to a previous snapshot
- View diffs between snapshots and your current state
- Manage snapshots with favorites, renaming, and deletion
- Automatic snapshot cleanup when restoring
- Automatic cleanup of snapshots older than 90 days on every exit
- AI-powered Notes for each snapshot (up to 30 words summary of changed files)
Why d4-snap? The tool was built for developers who want a quick, interactive workflow to seamlessly save code iterations without cluttering the main repo. All operations happen locally in a hidden bare repo, so you can experiment freely and clean up with confidence.
Table of Contents
- Features
- Installation
- Usage
- Commands & Options
- Examples
- Testing
- FAQ
- Troubleshooting
- Contributing
- License
Features
| Feature | Description |
|---|---|
| Snapshot Storage | Stores snapshots as a bare Git repo in ~/.d4_snap/.d4_snap/<repo-name>-<hash>. |
| Metadata | Uses git notes to store: favorite, renamed, notes, deleted. |
| Auto-naming | Snapshots are automatically named with timestamp format YYYYMMDD-HHMMSSMMM. |
| Snapshot Management | Save, restore, view diff, list, rename, delete, toggle favorite. |
| Auto-deletion | When restoring a snapshot, automatically deletes that snapshot and all newer ones. |
| Automatic Cleanup | Automatically cleans up old snapshots on every d4-snap execution (configurable). |
| AI Notes | NEW: Automatically generates up to 30-word summaries of changed files for each snapshot. |
| Manual Cleanup | Manual cleanup option from menu with configurable retention period. |
| Configurable | Customize cleanup behavior through YAML configuration file. |
All commands are local-only – no remote pushes or pulls are involved.
Configuration
d4-snap can be configured through src/d4_snap/config/d4_snap.yaml. The most important configuration is for automatic cleanup:
# Cleanup configuration
auto_cleanup:
enabled: true # Enable/disable automatic cleanup
auto_cleanup_days: 90 # Days for automatic cleanup (runs on every execution)
manual_cleanup_days: 30 # Days for manual cleanup from menu option
Cleanup Behavior
- Automatic Cleanup: Runs every time d4-snap executes (unless disabled)
- 90-Day Rule: Automatically deletes snapshots older than 90 days on exit
- Manual Cleanup: Available through menu option 5
- Favorites Protected: Snapshots marked as favorites are never deleted
- Configurable: Set different retention periods for auto vs manual cleanup
AI Notes Feature
- Automatic Generation: Each snapshot automatically gets an AI-generated summary
- 30-Word Limit: Concise summaries of changed files and their purposes
- Storage: Stored as metadata using Git notes
- Display: Shown in snapshot listings alongside other metadata
Installation
Prerequisites
- Python 3.8+
- Git (≥ 2.20)
pip
pip install d4-snap
From source
git clone https://github.com/yourorg/d4-snap.git
cd d4-snap
python -m pip install .
Note: The package installs a console script named
d4-snapthat will be available in your PATH.
Usage
d4-snap provides both a quick snapshot mode and an interactive menu-driven interface.
Quick Snapshot Mode
# Create a snapshot of current project and exit
# Automatic cleanup runs after snapshot (configurable)
d4-snap
Interactive Menu Mode
# Show interactive menu
d4-snap menu
Help
# Show help information
d4-snap help
d4-snap --help
d4-snap /?
All commands should be run from within a Git repository. Automatic cleanup runs after every operation unless disabled in configuration.
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
Commands & Options
1. Save Snapshot
- Saves the current working directory, including all files, into the shadow repo
- Automatically generates a timestamp-based name (format:
YYYYMMDD-HHMMSSMMM) - Creates a commit in the isolated shadow repository
- Stores metadata using Git notes
2. List / Manage Snapshots
Displays all snapshots with:
- Snapshot number
- Favorite indicator (⭐)
- Commit hash (short)
- Branch name
- Description/name
- NEW: AI-generated Notes (30-word summary of changes)
Management options:
- Toggle Favorite status - Mark/unmark snapshots as favorites (prevents auto-deletion)
- Rename a snapshot - Give snapshots custom names
- Delete a snapshot - Soft-delete snapshots (cannot delete favorites)
- View Notes - See the AI-generated summary of changed files
3. View Diff
- Select a snapshot from the list
- Choose to view diff for all files or a specific file/folder
- Shows
git diffbetween the snapshot and current working directory
4. Restore Snapshot
Two restore options:
Option 1: Restore everything
- Extracts all files from the snapshot to your working directory
- Automatically deletes the restored snapshot and all newer snapshots
- Provides a warning before overwriting current changes
Option 2: Restore specific file/folder
- Enter the relative path to restore (e.g.,
src/d4_snap/cli.py) - Only restores the specified file/folder
- Does not trigger automatic snapshot deletion
5. Cleanup Old Snapshots
- Runs
git reflog expire --expire=30.daysandgit gc --prune=30.days - Removes snapshots older than 30 days that are not marked as favorites
- Favorites are always preserved
Examples
Saving a Snapshot
Select an option (0-5): 1
--- Save Work Snapshot (Shadow Repo) ---
Saving snapshot...
✅ Snapshot saved successfully! (Shadow hash: 0f7a40e)
Listing Snapshots
Select an option (0-5): 2
--- Shadow Snapshots ---
No. Fav Hash Branch Description Notes
---------------------------------------------------------------------------------------------------------------------------------
1 ⭐ 0f7a40e main My custom name Fixed authentication bug in login module
2 36f3ca7 feature-branch 20260221-225542076 Added user profile settings page
3 ffa0250 main 20260221-224736433 Updated dependencies and fixed imports
Restoring a Snapshot
Select an option (0-5): 4
--- Restore Snapshot (Shadow Repo) ---
Enter snapshot number to restore: 2
Restore Options:
1. Restore everything (Overwrite current working directory)
2. Restore specific file/folder
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
Deleting 2 snapshot(s)...
✅ Deleted 2 snapshot(s)
Managing Snapshots
Select an option (0-5): 2
--- Manage Snapshots ---
1. Toggle Favorite status
2. Rename a snapshot
3. Delete a snapshot
0. Back to main menu
Choice (0-3): 2
Enter snapshot number: 1
Enter new name for snapshot (current: 20260221-225555884): My custom name
✅ Snapshot renamed to 'My custom name'
Testing
Test Suite Status
✅ 96 tests passing ⚠️ 0 warnings (with proper configuration)
Test Coverage
The test suite covers the following areas:
✅ Fully Covered
- Module imports and basic functionality (test_simple.py)
- CLI argument parsing and help system (test_main.py)
- Configuration file loading (test_simple.py)
- Menu manager operations (test_simple.py)
- CLI operations and main loop (test_cli.py)
- Git operations (test_git_operations.py)
- Snapshot management (test_snapshot_manager.py)
- User interface components (test_ui.py)
- Tool utilities (test_tools.py)
Test Infrastructure
- Fixtures: Temporary directories, mock Git repositories, mock configuration files
- Configuration: pytest settings in
pyproject.toml - Quality: Proper mocking, comprehensive coverage, clear organization
Running Tests
# Run all tests
poetry run pytest
# Run with coverage
poetry run pytest --cov=d4_snap --cov-report=html
# Run specific test file
poetry run pytest tests/test_simple.py -v
# Run with verbose output
poetry run pytest -v
Test Quality
- ✅ Good use of mocking to isolate units
- ✅ Comprehensive functionality coverage
- ✅ Proper fixture setup
- ✅ Clear test organization
- ✅ Zero warnings with proper configuration
- ✅ All 96 tests passing
FAQ
| Question | Answer |
|---|---|
| Do snapshots affect my Git history? | No. Snapshots are stored in a bare repo under ~/.d4_snap/.d4_snap/.... Your main repo stays untouched. |
| Can I share snapshots with teammates? | They are local only. To share, export the snapshot folder or use git bundle on the bare repo. |
| How to remove old snapshots? | Automatic: d4-snap automatically cleans up old snapshots after every operation (configurable). Manual: Run option 5 (Cleanup Old Snapshots) from the main menu. Favorites are always preserved. |
| What happens when I restore a snapshot? | When you restore everything (option 1), the snapshot and all newer snapshots are automatically deleted. This prevents confusion about which state you're in. |
| Can I prevent a snapshot from being deleted? | Yes! Mark it as a favorite using the "Toggle Favorite status" option in the Manage Snapshots menu. Favorites are never auto-deleted. |
| What does the "Notes" flag mean? | NEW: AI-generated summary of changed files (up to 30 words). Automatically created for each snapshot to help you quickly understand what was changed. |
| How do I configure cleanup behavior? | Edit src/d4_snap/config/d4_snap.yaml to set cleanup days and enable/disable automatic cleanup. |
| Can I disable automatic cleanup? | Yes! Set enabled: false in the auto_cleanup section of the configuration file. |
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
d4-snap: command not found |
pip did not add the script to PATH |
Ensure ~/.local/bin (or your Python bin directory) is in $PATH. |
fatal: not a git repository |
You’re not inside a Git repo | cd to a repo first. |
Permission denied on ~/.d4_snap |
Permissions issue | Run chmod -R 700 ~/.d4_snap (or adjust as needed). |
Configuration
All menu texts are externalized in src/d4_snap/config/d4_snap.yaml for easy customization. You can modify:
- Menu titles
- Option labels
- Prompts
- Success/error messages
Contributing
- Fork the repo
- Create a feature branch
- Run the test suite (if available)
- Submit a pull request
We welcome issues, feature requests, and PRs.
License
MIT © 2026 d4-snap Developers See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file d4_snap-0.1.3.tar.gz.
File metadata
- Download URL: d4_snap-0.1.3.tar.gz
- Upload date:
- Size: 25.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d340646e269566f7fb43105e3373565b8d99b2c42d275c6b6113fc1ed02bc8aa
|
|
| MD5 |
795b65858c389a5c64aed6e8b123dd94
|
|
| BLAKE2b-256 |
742488fb981e52c756d6b776e30893fed8409a3e154cd8d1a7c7621af9b6b0e2
|
Provenance
The following attestation bundles were made for d4_snap-0.1.3.tar.gz:
Publisher:
release.yml on internetics-net/d4-snap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
d4_snap-0.1.3.tar.gz -
Subject digest:
d340646e269566f7fb43105e3373565b8d99b2c42d275c6b6113fc1ed02bc8aa - Sigstore transparency entry: 1032553896
- Sigstore integration time:
-
Permalink:
internetics-net/d4-snap@0b59f0128d13742add43228c82dc34000e6720fb -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/internetics-net
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b59f0128d13742add43228c82dc34000e6720fb -
Trigger Event:
push
-
Statement type:
File details
Details for the file d4_snap-0.1.3-py3-none-any.whl.
File metadata
- Download URL: d4_snap-0.1.3-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64ceedf706baf2a92e9da9f2f89a0d0341e05a37f5a8974bf0492a7a056ca449
|
|
| MD5 |
0b20655471acb18f0939ad7d8cfa0441
|
|
| BLAKE2b-256 |
29572639cc322b40defa53ea061748edca195a836ac8abe73543ad8a6950e274
|
Provenance
The following attestation bundles were made for d4_snap-0.1.3-py3-none-any.whl:
Publisher:
release.yml on internetics-net/d4-snap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
d4_snap-0.1.3-py3-none-any.whl -
Subject digest:
64ceedf706baf2a92e9da9f2f89a0d0341e05a37f5a8974bf0492a7a056ca449 - Sigstore transparency entry: 1032553975
- Sigstore integration time:
-
Permalink:
internetics-net/d4-snap@0b59f0128d13742add43228c82dc34000e6720fb -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/internetics-net
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b59f0128d13742add43228c82dc34000e6720fb -
Trigger Event:
push
-
Statement type: