claude-code-sync
Rust CLI tool for syncing Claude Code conversation history across machines using git repositories.
claude-code-sync
A Rust CLI tool for syncing Claude Code conversation history across machines using git repositories.
Documentation
📚 View API Documentation - Complete API reference and code documentation
To build and view documentation locally:
# Build and open documentation in your browser
cargo doc --open --no-deps --all-features
Features
| Feature | Description |
|---|---|
| Smart Merge | Automatically combines non-conflicting conversation changes |
| Bidirectional Sync | Pull and push changes in one command with sync |
| Interactive Onboarding | First-time setup wizard guides you through configuration |
| Non-Interactive Init | Config file support for CI/CD and automation |
| Smart Conflict Resolution | Interactive TUI for resolving conflicts with preview |
| Selective Sync | Filter by project, date, or exclude attachments |
| Git LFS Support | Efficiently store large conversation files with Git LFS |
| Mercurial Support | Use Mercurial (hg) as an alternative to Git |
| Undo Operations | Rollback pull/push with automatic snapshots |
| Operation History | Track and review past sync operations |
| Branch Management | Sync to different branches, manage remotes |
| Detailed Logging | Console and file logging with configurable levels |
| Conflict Tracking | Comprehensive conflict reports in JSON/Markdown |
| Flexible Configuration | TOML-based config with CLI overrides |
Overview
claude-code-sync helps you backup and synchronize your Claude Code conversation history by pushing it to a git repository. This enables:
- Backup: Never lose your Claude Code conversations
- Multi-machine sync: Keep conversation history consistent across multiple computers
- Version control: Track changes to your conversations over time
- Conflict resolution: Automatically handles divergent conversation histories
How It Works
Claude Code stores conversation history locally in ~/.claude/projects/ as JSONL (JSON Lines) files. Each project has its own directory, and each conversation is a separate .jsonl file.
claude-code-sync:
- Discovers all conversation files in your local Claude Code history
- Copies them to a git repository
- Commits and optionally pushes to a remote
- On pull, merges remote changes with local history
- Detects conflicts (same session modified on different machines)
- Resolves conflicts by keeping both versions with renamed files
Installation
From Source
git clone https://github.com/perfectra1n/claude-code-sync
cd claude-code-sync
cargo build --release
cargo install --path .
claude-code-sync --help
Using Cargo
cargo install --path .
Quick Start
First-Time Setup (Interactive Onboarding)
When you run claude-code-sync for the first time, an interactive onboarding wizard will guide you through setup:
# Simply run any command - onboarding starts automatically
claude-code-sync sync
# Or explicitly run onboarding
claude-code-sync init
The onboarding wizard will ask you:
- Whether to use a remote repository or local directory
- Where to store your sync repository
- Remote URL (for remote repos) or path (for local)
- Whether to exclude file attachments (images, PDFs, etc.)
- How old conversations to sync (e.g., last 30 days)
Benefits of Interactive Onboarding:
- ✅ Step-by-step guidance for first-time users
- ✅ Validates Git repository URLs and paths
- ✅ Automatically clones remote repositories
- ✅ Sets up sensible defaults based on your choices
- ✅ No need to remember command-line flags
Manual Initialization (Advanced)
If you prefer to skip onboarding, you can initialize manually:
# Create a local sync repository
claude-code-sync init --repo ~/claude-history-backup
# Or with a remote git repository
claude-code-sync init --repo ~/claude-history-backup --remote [email protected]:username/claude-history.git
2. Sync Your History
# Bidirectional sync (pull then push) - RECOMMENDED
claude-code-sync sync
# Or manually:
# Push all conversation history
claude-code-sync push
# Pull from remote
claude-code-sync pull
3. Advanced Usage
# Exclude attachments (images, PDFs, etc.) - only sync .jsonl files
claude-code-sync push --exclude-attachments
# Push to specific branch
claude-code-sync push --branch main
# Sync with custom message and exclude attachments
claude-code-sync sync --message "Daily backup" --exclude-attachments
Commands
init
Initialize a new sync repository.
claude-code-sync init --repo <path> [--remote <url>]
Options:
--repo, -r <PATH>: Path to the git repository for storing history--remote <URL>: Optional remote git URL for pushing/pulling--config <PATH>: Load configuration from TOML file (for non-interactive init)
Example:
claude-code-sync init --repo ~/claude-backup --remote [email protected]:user/claude-history.git
Non-Interactive Initialization (CI/CD)
For automation and headless environments, use a config file:
# Use explicit config file
claude-code-sync init --config /path/to/init-config.toml
# Or use default config file locations (checked in order):
# 1. $CLAUDE_CODE_SYNC_INIT_CONFIG environment variable
# 2. ~/.claude-code-sync-init.toml
# 3. <config-dir>/init.toml
claude-code-sync init
Example config file (~/.claude-code-sync-init.toml):
repo_path = "~/claude-history-sync"
remote_url = "https://github.com/user/repo.git"
clone = true
exclude_attachments = true
enable_lfs = true
scm_backend = "git"
sync_subdirectory = "projects"
sync
NEW! Bidirectional sync (pull remote changes, then push local changes).
claude-code-sync sync [OPTIONS]
Options:
--message, -m <MSG>: Custom commit message for push--branch, -b <BRANCH>: Branch to sync with (default: current branch)--exclude-attachments: Only sync .jsonl files, exclude images/PDFs/etc.
Example:
claude-code-sync sync -m "Daily sync" --exclude-attachments
push
Push local Claude Code history to the sync repository.
claude-code-sync push [OPTIONS]
Options:
--message, -m <MSG>: Custom commit message--push-remote: Push to remote after committing (default: true)--branch, -b <BRANCH>: Branch to push to (default: current branch)--exclude-attachments: Only sync .jsonl files, exclude images/PDFs/etc.
Examples:
# Basic push
claude-code-sync push -m "Weekly backup"
# Push to specific branch, excluding attachments
claude-code-sync push --branch backup --exclude-attachments
pull
Pull and merge history from the sync repository.
claude-code-sync pull [OPTIONS]
Options:
--fetch-remote: Pull from remote before merging (default: true)--branch, -b <BRANCH>: Branch to pull from (default: current branch)
Example:
claude-code-sync pull --branch main
status
Show sync status and information.
claude-code-sync status [--show-conflicts] [--show-files]
Options:
--show-conflicts: Show detailed conflict information--show-files: Show which files would be synced
Example:
claude-code-sync status --show-conflicts --show-files
config
Configure sync filters and settings.
claude-code-sync config [OPTIONS] [--show]
Options:
--exclude-older-than <DAYS>: Exclude projects older than N days--include-projects <PATTERNS>: Include only specific project paths (comma-separated)--exclude-projects <PATTERNS>: Exclude specific project paths (comma-separated)--exclude-attachments <true|false>: Exclude file attachments (images, PDFs, etc.)--enable-lfs <true|false>: Enable Git LFS for large files--lfs-patterns <PATTERNS>: File patterns to track with LFS (comma-separated, default:*.jsonl)--scm-backend <BACKEND>: SCM backend to use:gitormercurial(default:git)--sync-subdirectory <DIR>: Subdirectory within sync repo for projects (default:projects)--show: Show current configuration
Examples:
# Exclude conversations older than 30 days
claude-code-sync config --exclude-older-than 30
# Include only specific projects
claude-code-sync config --include-projects "*my-project*,*important-work*"
# Exclude test projects
claude-code-sync config --exclude-projects "*test*,*temp*"
# Permanently exclude attachments from all syncs
claude-code-sync config --exclude-attachments true
# Enable Git LFS for large files
claude-code-sync config --enable-lfs true --lfs-patterns "*.jsonl,*.png"
# Use Mercurial instead of Git
claude-code-sync config --scm-backend mercurial
# Store projects in a custom subdirectory
claude-code-sync config --sync-subdirectory "claude-history"
# Show current config
claude-code-sync config --show
report
View conflict reports from previous syncs.
claude-code-sync report [--format <FORMAT>] [--output <FILE>]
Options:
--format, -f <FORMAT>: Output format:json,markdown, ortext(default: markdown)--output, -o <FILE>: Output file (default: print to stdout)
Examples:
# Print markdown report to console
claude-code-sync report
# Save JSON report to file
claude-code-sync report --format json --output conflicts.json
# View as markdown
claude-code-sync report --format markdown | less
remote
NEW! Manage git remote configuration.
claude-code-sync remote <COMMAND>
Commands:
show: Display current remote configuration and sync directoryset: Set or update remote URLremove: Remove a remote
Options for set:
--name, -n <NAME>: Remote name (default: origin)url: Remote URL (e.g., https://github.com/user/repo.git or [email protected]:user/repo.git)
Options for remove:
--name, -n <NAME>: Remote name (default: origin)
Examples:
# Show current remote and sync directory
claude-code-sync remote show
# Set/update remote URL (HTTPS)
claude-code-sync remote set origin https://github.com/user/claude-history.git
# Set/update remote URL (SSH)
claude-code-sync remote set origin [email protected]:user/claude-history.git
# Remove remote
claude-code-sync remote remove origin
Note: The remote URL must start with http://, https://, or git@ for SSH connections.
undo
NEW in v0.2.0! Undo the last sync operation by restoring from automatic snapshots.
claude-code-sync undo <OPERATION>
Operations:
pull: Undo the last pull operation (restores local files to pre-pull state)push: Undo the last push operation (resets git repository to previous commit)
Examples:
# Undo the last pull operation
claude-code-sync undo pull
# Undo the last push operation
claude-code-sync undo push
How it works:
- Every pull/push operation automatically creates a snapshot before making changes
- Snapshots are stored in
~/.claude-code-sync/snapshots/ - Undo operations restore files/git state from the snapshot
- After successful undo, the snapshot is automatically deleted
- Operation history is updated to reflect the undo
Note: You can only undo the most recent operation of each type. Once you run a new pull/push, the previous snapshot is replaced.
history
NEW in v0.2.0! View and manage operation history.
claude-code-sync history <COMMAND>
Commands:
list: List recent sync operationslast: Show detailed information about the last operationclear: Clear all operation history
Options for list:
--limit, -l <N>: Number of operations to show (default: 10)
Options for last:
--operation-type, -t <TYPE>: Filter by operation type (pullorpush)
Examples:
# List the last 10 operations
claude-code-sync history list
# List the last 20 operations
claude-code-sync history list --limit 20
# Show details of the last operation (pull or push)
claude-code-sync history last
# Show details of the last pull operation only
claude-code-sync history last -t pull
# Show details of the last push operation only
claude-code-sync history last -t push
# Clear all operation history
claude-code-sync history clear
History Information:
Each history entry shows:
- Operation type (PULL or PUSH)
- Timestamp
- Branch name
- Number of conversations affected
- Statistics (added, modified, conflicts, unchanged)
- Snapshot availability for undo
History Storage:
- Operation history is stored in
~/.claude-code-sync/operation-history.json - Up to 5 operations are kept (automatically rotated)
- Each operation includes details about affected conversations
Conflict Resolution
When the same conversation session is modified on different machines, claude-code-sync detects this as a conflict.
Smart Merge (NEW!)
Smart merge is now the default conflict resolution strategy! When conflicts are detected, claude-code-sync automatically attempts to intelligently merge both versions by:
- Analyzing message UUIDs and parent relationships: Builds a message tree to understand conversation structure
- Resolving edited messages by timestamp: If the same message was edited on both machines, keeps the newer version
- Preserving all conversation branches: When conversations diverge (same parent, different continuations), keeps all branches intact
- Handling entries without UUIDs: Falls back to timestamp-based merging for system events
Smart merge automatically handles:
- ✅ Non-overlapping changes (simple merge)
- ✅ Message additions to different parts of the conversation
- ✅ Conversation branches (multiple continuations from the same point)
- ✅ Edited messages (resolved by timestamp)
- ✅ Mixed UUID and non-UUID entries
If smart merge fails (e.g., due to corrupted data), the system falls back to interactive or "keep both" resolution.
Interactive Conflict Resolution (New!)
When running in an interactive terminal, claude-code-sync now provides a TUI (Text User Interface) for resolving conflicts:
# Pull with interactive conflict resolution
claude-code-sync pull
# Or sync (pull + push)
claude-code-sync sync
Interactive Features:
- 📋 List all conflicts with session IDs and project paths
- 🔍 Preview differences between local and remote versions
- 📊 View statistics: message counts, timestamps, file sizes
- 🎯 Choose resolution per conflict:
- Smart Merge (combine both versions - recommended) ✨ NEW
- Keep Local (discard remote changes)
- Keep Remote (overwrite local file)
- Keep Both (save remote with conflict suffix)
- View Details (show full comparison)
Example Interactive Flow:
Found 2 conflicts during pull:
! 2 conflicts detected
Attempting smart merge...
✓ Smart merged abc-123 (45 local + 52 remote = 90 total, 2 branches)
✓ Smart merged def-456 (30 local + 35 remote = 65 total, 0 branches)
✓ Successfully smart merged 2/2 conflicts
Pull complete!
Example: Smart Merge Failure with Interactive Fallback:
Found 1 conflicts during pull:
! 1 conflicts detected
Attempting smart merge...
⚠ Smart merge failed for xyz-789: circular reference detected
Falling back to manual resolution...
! 1 conflicts require manual resolution
→ Running in interactive mode for remaining conflicts
Conflict 1 of 1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Session ID: xyz-789
Project: my-project
Local: 45 messages, last modified 2 hours ago (15.2 KB)
Remote: 52 messages, last modified 1 hour ago (18.5 KB)
How do you want to resolve this conflict?
❯ Smart Merge (combine both versions - recommended)
Keep Local Version (discard remote)
Keep Remote Version (overwrite local)
Keep Both (save remote with conflict suffix)
View Detailed Comparison
Automatic Resolution (Non-Interactive)
When not in an interactive terminal (CI/CD, scripts), conflicts are automatically resolved:
Resolution Strategy:
- Local version: Kept as-is
- Remote version: Saved with suffix
-conflict-<timestamp>.jsonl - A detailed conflict report is generated
Example:
If session abc-123.jsonl conflicts:
- Local:
~/.claude/projects/my-project/abc-123.jsonl(unchanged) - Remote:
~/.claude/projects/my-project/abc-123-conflict-20250117-143022.jsonl(saved separately)
You can then manually review both versions and decide which to keep.
Configuration File
Configuration is stored in ~/.claude-code-sync.toml:
# Exclude projects older than N days
exclude_older_than_days = 30
# Include only these project path patterns
include_patterns = ["*my-project*", "*work*"]
# Exclude these project path patterns
exclude_patterns = ["*test*", "*temp*"]
# Maximum file size in bytes (10MB default)
max_file_size_bytes = 10485760
# Exclude file attachments (images, PDFs, etc.)
exclude_attachments = false
# Enable Git LFS for large files
enable_lfs = false
# File patterns to track with LFS
lfs_patterns = ["*.jsonl"]
# SCM backend: "git" or "mercurial"
scm_backend = "git"
# Subdirectory within sync repo for projects
sync_subdirectory = "projects"
Sync State
Sync state is stored in ~/.claude-code-sync/:
state.json: Current sync repository configurationoperation-history.json: History of sync operations (up to 5 entries)snapshots/: Directory containing snapshots for undo operationslatest-conflict-report.json: Most recent conflict report
Use Cases
Daily Backup Workflow
# At the end of each day
claude-code-sync push -m "Daily backup $(date +%Y-%m-%d)"
Multi-Machine Development
On Machine A:
claude-code-sync init --repo ~/claude-backup --remote [email protected]:user/claude-history.git
claude-code-sync push
On Machine B:
claude-code-sync init --repo ~/claude-backup --remote [email protected]:user/claude-history.git
claude-code-sync pull
# Work on Machine B
claude-code-sync push
Back on Machine A:
claude-code-sync pull # Merges Machine B's changes
Automated Backup (Cron)
Add to your crontab:
# Backup Claude Code history every night at 2 AM
0 2 * * * /usr/local/bin/claude-code-sync push --message "Automated backup" >> ~/claude-code-sync.log 2>&1
Architecture
Module Overview
- parser.rs: JSONL conversation file parser
- scm/: SCM abstraction layer supporting multiple backends
- mod.rs:
Scmtrait and factory functions - git.rs: Git backend via CLI commands
- hg.rs: Mercurial backend via CLI commands
- lfs.rs: Git LFS support
- mod.rs:
- sync/: Core sync engine with push/pull logic and snapshot integration
- conflict.rs: Conflict detection and resolution
- interactive_conflict.rs: Interactive TUI for conflict resolution
- filter.rs: Configuration and filtering system
- report.rs: Conflict reporting in JSON/Markdown formats
- history/: Operation history tracking and management
- undo/: Snapshot-based undo functionality for pull/push operations
- onboarding.rs: Interactive first-time setup wizard with config file support
- logger.rs: Enhanced logging system with file and console output
- main.rs: CLI interface (using
clap)
File Format
Claude Code stores conversations in JSONL format:
{"type":"user","uuid":"...","sessionId":"...","timestamp":"...","message":{...}}
{"type":"assistant","uuid":"...","sessionId":"...","timestamp":"...","message":{...}}
{"type":"file-history-snapshot","messageId":"...","snapshot":{...}}
Each line is a separate JSON object representing a conversation event.
Dependencies
clap: CLI argument parsingserde+serde_json: JSON parsingtoml: Configuration parsinganyhow: Error handlingchrono: Timestamp handlingwalkdir: Directory traversalcolored: Terminal colorsdirs: Cross-platform directory pathsuuid: Snapshot identificationbase64: Binary file encoding in snapshotsinquire: Interactive prompts and TUI menuslog: Logging facadeenv_logger: Console logging implementationatty: Terminal detection for interactive moderstest: Parameterized testing (dev dependency)
Note: Git/Mercurial operations are performed via CLI commands, not library bindings. This ensures compatibility with git hooks, LFS, and credential helpers.
Security Considerations
- Conversation history may contain sensitive information
- Use private git repositories for remote storage
- Consider encrypting the git repository for additional security
- SSH keys or access tokens are recommended for git authentication
Logging
claude-code-sync provides comprehensive logging to help you track operations and troubleshoot issues.
Console Logging
Control console output with the RUST_LOG environment variable:
# Show all debug messages
RUST_LOG=debug claude-code-sync sync
# Only show errors
RUST_LOG=error claude-code-sync push
# Only show warnings and errors
RUST_LOG=warn claude-code-sync pull
# Show info, warnings, and errors (default)
claude-code-sync sync
# Disable console output (file logging continues)
RUST_LOG=off claude-code-sync status
Log Levels:
trace- Everything (very verbose)debug- Debug information and aboveinfo- Informational messages, warnings, and errors (default)warn- Warnings and errors onlyerror- Errors onlyoff- No console output
File Logging
All operations are automatically logged to a file, regardless of console settings:
Log File Locations:
- Linux:
~/.config/claude-code-sync/claude-code-sync.logor$XDG_CONFIG_HOME/claude-code-sync/claude-code-sync.log - macOS:
~/Library/Application Support/claude-code-sync/claude-code-sync.log - Windows:
%APPDATA%\claude-code-sync\claude-code-sync.log
File Logging Features:
- ✅ Captures all log levels (trace to error)
- ✅ Persists across sessions
- ✅ Useful for debugging and audit trails
- ✅ Automatically rotated to prevent excessive disk usage
Example:
# Run sync silently, check logs later
RUST_LOG=off claude-code-sync sync
# View the log file
cat ~/.config/claude-code-sync/claude-code-sync.log
Troubleshooting
"Sync not initialized"
Run claude-code-sync init first to set up the sync repository, or let the interactive onboarding guide you.
"Failed to push to remote"
Check:
- Git remote URL is correct
- SSH keys or credentials are configured
- Network connectivity
- Remote repository permissions
Conflicts on every pull
This may indicate:
- Clock skew between machines
- Different filter configurations
- Same conversations being actively used on multiple machines
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi