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.