Automatic version control for AI-assisted development. Every file change creates a checkpoint you can restore instantly.
Built on Jujutsu for Git compatibility.
# Install
./build.sh install
# Initialize in your project
cd /your/project
tl init
# That's it. Checkpoints are created automatically every 5 seconds.| Command | Description |
|---|---|
tl init |
Initialize timelapse in current directory |
tl init --skip-git |
Skip git initialization |
tl init --skip-jj |
Skip JJ initialization |
tl start |
Start background daemon |
tl start --foreground |
Run daemon in foreground (debugging) |
tl stop |
Stop background daemon |
tl status |
Show daemon and checkpoint status |
tl info |
Show detailed repository info |
| Command | Description |
|---|---|
tl log |
Show checkpoint history (default: 20) |
tl log --limit 50 |
Show more checkpoints |
tl flush |
Force immediate checkpoint |
tl restore <id> |
Restore to checkpoint (interactive) |
tl restore <id> -y |
Restore without confirmation |
tl diff <a> <b> |
File-level diff between checkpoints |
tl diff <a> <b> -p |
Line-level diff (unified format) |
tl diff <a> <b> -p -U 5 |
Diff with 5 context lines |
| Command | Description |
|---|---|
tl pin <id> <name> |
Name a checkpoint |
tl unpin <name> |
Remove a pin |
| Command | Description |
|---|---|
tl publish <id> |
Publish checkpoint to JJ |
tl publish <id> -b <name> |
Publish with bookmark name |
tl publish <id> --compact |
Squash into single commit |
tl publish <id> --no-pin |
Don't auto-pin published checkpoint |
tl push |
Push to Git remote |
tl push -b <name> |
Push specific bookmark |
tl push --all |
Push all bookmarks |
tl push --force |
Force push |
tl pull |
Pull from Git remote |
tl pull --fetch-only |
Fetch without merging |
tl pull --no-pin |
Don't pin pulled commits |
| Command | Description |
|---|---|
tl worktree list |
List all workspaces |
tl worktree add <name> |
Create new workspace |
tl worktree add <name> --path /custom/path |
Create at specific path |
tl worktree add <name> --from <checkpoint> |
Create from checkpoint |
tl worktree switch <name> |
Switch to workspace |
tl worktree remove <name> |
Remove workspace |
tl worktree remove <name> --delete-files |
Remove with files |
| Command | Description |
|---|---|
tl gc |
Garbage collection |
| Format | Example | Description |
|---|---|---|
| Full ULID | 01HN8XYZABC123... |
Complete identifier |
| Short prefix | 01HN8 |
4+ characters, must be unique |
| Pin name | my-feature |
Named checkpoint |
| Workspace pin | ws:feature-name |
Auto-created by workspace |
| HEAD | HEAD |
Latest checkpoint |
┌─────────────────────────────────────────────────────────────────────────────┐
│ TIMELAPSE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────────────────────────────────┐ │
│ │ CLI (tl) │ │ Background Daemon │ │
│ ├──────────────┤ ├──────────────────────────────────────────┤ │
│ │ init │ │ │ │
│ │ log │◄───────►│ ┌─────────────┐ ┌────────────────┐ │ │
│ │ restore │ IPC │ │ Watcher │ │ Checkpoint │ │ │
│ │ diff │ (Unix │ │ (FSEvents/ │───►│ Creator │ │ │
│ │ publish │ Socket) │ │ inotify) │ │ │ │ │
│ │ push/pull │ │ └─────────────┘ └───────┬────────┘ │ │
│ └──────────────┘ │ │ │ │ │
│ │ ▼ │ │ │
│ │ ┌─────────────┐ │ │ │
│ │ │ Debouncer │ │ │ │
│ │ │ (300ms) │ │ │ │
│ │ └─────────────┘ │ │ │
│ └─────────────────────────────┼────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────┼────────────────┐ │
│ │ Storage Layer │ │ │
│ ├──────────────────────────────────────────────────────┼────────────────┤ │
│ │ ▼ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Blobs │ │ Trees │ │ Journal │ │ │
│ │ │ (SHA-1, zstd) │ │ (Git format) │ │ (Sled DB) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ .tl/objects/ │ │ .tl/objects/ │ │ .tl/journal/ │ │ │
│ │ │ blobs/ │ │ trees/ │ │ │ │ │
│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ JJ Integration Layer │ │
│ ├──────────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ tl publish tl push/pull │ │
│ │ │ │ │ │
│ │ ▼ ▼ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │ │
│ │ │Checkpoint│───────────►│ JJ │───────────►│ Git Remote │ │ │
│ │ │ → JJ │ │ Commits │ │ (GitHub) │ │ │
│ │ └─────────┘ └─────────┘ └─────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
- File Watcher detects changes (FSEvents on macOS, inotify on Linux)
- Debouncer coalesces rapid changes (300ms window per file)
- Checkpoint Creator hashes only changed files (O(k) complexity)
- Storage Layer deduplicates via content-addressing (SHA-1)
- JJ Integration publishes checkpoints as Git-compatible commits
Timelapse uses Git's proven content-addressing model:
| Object | Format | Storage |
|---|---|---|
| Blobs | SHA-1 hash, zstd compressed | .tl/objects/blobs/ |
| Trees | Git tree format, sorted entries | .tl/objects/trees/ |
| Checkpoints | ULID + tree hash + parent ref | .tl/journal/ (Sled DB) |
Deduplication: Identical file content stored once. Identical directory states share the same tree hash.
| Operation | Target | Achieved |
|---|---|---|
| Checkpoint creation | <10ms | ~3ms |
| Restore | <100ms | ~60ms |
| Watcher throughput | >10k events/sec | 11k/sec |
| Memory (idle) | <10MB | ~8MB |
| Storage overhead | - | ~1.2x vs Git |
Timelapse uses Jujutsu (JJ) as the bridge to Git, providing:
- Git compatibility without implementing Git protocol
- Atomic operations via MVCC transactions
- Conflict-free merging inherited from JJ
- Standard workflows via
git push/pull
Timelapse Checkpoints (100s/day)
↓
tl publish
↓
JJ Commits (10s/day)
↓
tl push
↓
Git Commits → GitHub/GitLab
# Work normally - checkpoints created automatically
# ...make changes...
# Ready to push
tl publish HEAD # Publish latest checkpoint to JJ
tl push # Push to Git remote
# Or publish multiple checkpoints as one commit
tl publish HEAD~10 --compact -b feature-name
tl push -b feature-nameTimelapse automatically ignores:
- Editor temp files (
.swp,~,#*#) - IDE directories (
.vscode/,.idea/) - Build directories (
node_modules/,target/,__pycache__/) - System files (
.DS_Store,Thumbs.db) - VCS directories (
.tl/,.git/,.jj/)
Custom patterns via .tlignore (gitignore syntax):
/build/
/dist/
*.log
.tl/config (TOML):
[watcher]
debounce_ms = 300
[retention]
default_keep_count = 1000
default_keep_duration = "30d"
pinned_keep_forever = true
[storage]
compression_level = 3# Build
./build.sh check # Fast compile check
./build.sh debug # Debug build
./build.sh release # Release build
./build.sh install # Build + install to PATH
./build.sh info # Show current binary info
# Test
./test.sh test-quick # Fast tests (~10s)
./test.sh test-all # Full suite (~2min)
./test.sh test-jj # JJ integration tests
./test.sh ci # Full CI pipeline| Crate | Purpose |
|---|---|
core |
Content-addressed storage (blobs, trees) |
watcher |
File system monitoring |
journal |
Checkpoint management (Sled DB) |
jj |
Jujutsu integration |
cli |
Command-line interface |
- macOS (FSEvents) or Linux (inotify)
- Rust 1.75+
- Git (for JJ integration)
MIT or Apache-2.0