Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mubshrx/git-snapshot/llms.txt

Use this file to discover all available pages before exploring further.

Snapshots are stored outside your Git repository in a XDG-compliant directory. This keeps them separate from your repository history and allows them to survive even if you delete the repository.

Storage location

All snapshots are stored in:
~/.local/share/git-snapshots/
This follows the XDG Base Directory Specification. If you’ve set $XDG_DATA_HOME, snapshots will use that:
${XDG_DATA_HOME:-$HOME/.local/share}/git-snapshots/

Why external storage?

Storing snapshots outside .git/ has several benefits:
  • Repository independence - Snapshots survive repository deletion
  • No Git interference - Won’t be included in commits, pushes, or Git operations
  • Centralized management - All snapshots in one place for backup
  • No .gitignore needed - Completely separate from your working directory

File format

Each snapshot is a gzipped tarball with a specific naming convention:
name.hash.snapshot
Examples:
  • my-feature.a1b2c3d4.snapshot (with custom name)
  • a1b2c3d4.snapshot (hash only)

File structure

Inside each .snapshot file:
.
├── metadata.json       # Snapshot metadata and file lists
├── staged/             # Full contents of staged files
│   └── [file tree]
├── unstaged/           # Full contents of unstaged files  
│   └── [file tree]
└── untracked/          # Full contents of untracked files
    └── [file tree]
Each directory (staged/, unstaged/, untracked/) preserves the complete file path structure from your repository.

Example snapshot contents

# View contents of a snapshot
tar -tzf ~/.local/share/git-snapshots/my-feature.a1b2c3d4.snapshot
./metadata.json
./staged/
./staged/src/
./staged/src/app.js
./unstaged/
./unstaged/src/
./unstaged/src/utils.js
./untracked/
./untracked/src/
./untracked/src/new-helper.js

Metadata structure

The metadata.json file contains all information about the snapshot:
{
  "name": "my-feature",
  "hash": "a1b2c3d4",
  "repo_remote": "git@github.com:user/project.git",
  "repo_path": "/home/user/projects/my-project",
  "branch": "main",
  "commit": "e5f6g7h8a9b0c1d2e3f4g5h6i7j8k9l0m1n2o3p4",
  "created_at": "2026-01-26T14:30:52Z",
  "staged_files": [
    "src/app.js",
    "src/components/Header.js"
  ],
  "unstaged_files": [
    "src/utils.js"
  ],
  "untracked_files": [
    "src/new-helper.js",
    "tests/new-test.js"
  ]
}

Metadata fields

FieldDescription
nameCustom name provided (empty string if none)
hash8-character unique identifier
repo_remoteGit remote URL (git config --get remote.origin.url)
repo_pathAbsolute path to repository root
branchBranch name when snapshot was created
commitFull commit SHA when snapshot was created
created_atISO 8601 timestamp (UTC)
staged_filesArray of staged file paths
unstaged_filesArray of unstaged file paths
untracked_filesArray of untracked file paths

Repository matching

When you list or restore snapshots, git-snapshot determines which snapshots belong to the current repository by:
  1. Matching remote URL (if both repos have one)
  2. Matching repository path (fallback if no remote)
This is implemented in the source at /home/daytona/workspace/source/src/git-snapshot:54-69:
# Match by remote if both have one
if [ -n "$current_remote" ] && [ -n "$snapshot_remote" ]; then
    [ "$current_remote" = "$snapshot_remote" ] && return 0 || return 1
fi

# Fallback to path match
[ "$current_path" = "$snapshot_path" ] && return 0 || return 1
If you move or clone a repository, snapshots will only match if the remote URL is the same. Path-based matching only works for the exact original location.

Hash generation

The 8-character hash is generated from the current timestamp and random data:
echo "$(date +%s%N)$RANDOM" | shasum | cut -c1-8
This ensures:
  • Uniqueness - Extremely unlikely to have collisions
  • Short identifiers - Easy to type and reference
  • No sequential patterns - Hashes are effectively random

Extracting snapshot data

You can manually inspect snapshot contents:

View metadata only

tar -xzf my-feature.a1b2c3d4.snapshot -O metadata.json | jq

Extract full snapshot

mkdir temp-snapshot
tar -xzf my-feature.a1b2c3d4.snapshot -C temp-snapshot
ls -la temp-snapshot/

View specific file content

# View a staged file
tar -xzf my-feature.a1b2c3d4.snapshot -O staged/src/app.js

# View an unstaged file
tar -xzf my-feature.a1b2c3d4.snapshot -O unstaged/src/utils.js

Storage considerations

Disk space

Because snapshots store full file contents (not diffs), they can consume significant disk space if you:
  • Create many snapshots
  • Have large binary files
  • Snapshot large codebases frequently
Snapshots are not automatically cleaned up. Use git-snapshot prune to delete all snapshots for the current repository, or git-snapshot delete <name> to remove specific ones.

Backup

Since snapshots live in ~/.local/share/git-snapshots/, you can:
  • Back up the entire directory independently
  • Copy snapshots between machines
  • Version control the directory itself (if desired)
# Backup all snapshots
tar -czf snapshots-backup.tar.gz ~/.local/share/git-snapshots/

# Restore on another machine
tar -xzf snapshots-backup.tar.gz -C ~/

Security

Snapshots are stored as plain files in your home directory:
  • Permissions - Same as your user’s normal file permissions
  • No encryption - Contents are not encrypted
  • No sensitive files filter - All files matching the criteria are saved
Be cautious about snapshotting files containing secrets. Snapshots respect .gitignore, but if you’ve tracked sensitive files, they’ll be included in snapshots.

Build docs developers (and LLMs) love