Git Worktrees: Multiple working directories pointing to different branches of the same repo
Jujutsu (jj): Fundamentally different VCS with operation log, first-class conflicts, and automatic change tracking
They solve different problems and aren't direct alternatives.
repo/.git/ # Main git directory
repo/main/ # Worktree 1 (main branch)
repo/feature-a/ # Worktree 2 (feature-a branch)
repo/feature-b/ # Worktree 3 (feature-b branch)
Purpose: Work on multiple branches simultaneously without switching Limitation: Still Git underneath - conflicts block, no operation log, manual staging
repo/.jj/
├── repo/ # Commit storage
├── op_store/ # OPERATION LOG (every action recorded)
├── op_heads/ # Current operation state
└── working_copy/ # Working copy state
repo/.git/ # Git backend (for compatibility)
Purpose: Rethink version control with operation-first model Advantages: Operation log, first-class conflicts, auto-commit, time-travel
| Feature | Git Worktrees | Jujutsu (jj) |
|---|---|---|
| Multiple working directories | ✅ Yes | ❌ Not the focus |
| Operation log | ❌ No | ✅ Yes (every operation recorded) |
| First-class conflicts | ❌ No (blocks operations) | ✅ Yes (conflicts are commits) |
| Auto-commit working copy | ❌ No (manual staging) | ✅ Yes (working copy IS a commit) |
| Undo any operation | ❌ Limited (reflog) | ✅ Yes (full operation history) |
| Concurrent edits | ✅ Conflicts recorded, not blocking | |
| Branch model | ✅ Named branches | |
| Git compatibility | ✅ Native | ✅ Via Git backend |
| Learning curve | Low (standard Git) | Medium (new concepts) |
# Agent 1: Works on feature-a
git worktree add ../agent1-workspace feature-a
cd ../agent1-workspace
# ... agent makes changes ...
git add .
git commit -m "Agent 1: changes"
# Agent 2: Works on feature-b
git worktree add ../agent2-workspace feature-b
cd ../agent2-workspace
# ... agent makes changes ...
git add .
git commit -m "Agent 2: changes"
# Problem: Merging feature-a + feature-b
git checkout main
git merge feature-a # OK
git merge feature-b # CONFLICT! Everything stops!Issues:
- ❌ Conflicts still block operations
- ❌ No automatic tracking of what changed
- ❌ Requires manual coordination between agents
- ❌ Can't work on same files concurrently
- ❌ No operation log for learning
# Agent 1: Edits file.rs
jj edit file.rs
# Auto-committed, logged: "op_001: edit file.rs by agent-1"
# Agent 2: Edits SAME file.rs (concurrently!)
jj edit file.rs
# Auto-committed, logged: "op_002: edit file.rs by agent-2"
# Merge happens
jj rebase -s agent2-change -d agent1-change
# Conflict recorded IN the commit, doesn't block!
# Conflict resolution can happen later
jj resolve file.rs
# Logged: "op_003: resolve file.rs"Advantages:
- ✅ Conflicts don't block operations
- ✅ Every change auto-tracked with full context
- ✅ Agents work independently
- ✅ Can work on same files (conflicts recorded)
- ✅ Complete operation log for AgentDB learning
Git Worktrees: No operation log
git log # Shows commits only
git reflog # Shows branch pointer movements (limited)Jujutsu: Complete operation log
jj op log # Shows EVERY operation ever performedExample output:
@ qpvuntsm agent-1@example.com 2024-01-07 15:30:00 op_abc123
│ describe "Implement authentication"
◉ sqpuoqvx agent-2@example.com 2024-01-07 15:29:45 op_def456
│ edit src/auth.rs
◉ rqxostpw agent-1@example.com 2024-01-07 15:29:30 op_ghi789
new --after main
For AI Agents:
- ✅ Every edit is logged with agent ID, timestamp, context
- ✅ Can replay operations for learning
- ✅ AgentDB can analyze patterns: "Agent X always breaks tests after editing auth"
- ✅ Time-travel: Try 5 different approaches, compare results
Git Worktrees: Conflicts are errors
git merge feature-a
# CONFLICT in src/main.rs
# Everything stops until you resolve it
# Can't commit, can't switch branches, can't continueJujutsu: Conflicts are commits
jj rebase -s feature-a -d main
# Conflict recorded in commit
# You can:
jj new # Create new change on top of conflict
jj describe # Describe the conflicted change
jj log # See conflicted state in history
# Work continues!For AI Agents:
- ✅ Agent 1 can create a conflict, Agent 2 keeps working
- ✅ Conflict resolution can be delegated to specialist agent
- ✅ Can analyze conflict patterns for learning
- ✅ No blocking = true concurrent workflows
Git Worktrees: Manual staging
# Agent makes changes
vim file.rs
# Forgot to commit? Changes lost if you switch branches!
git add file.rs # Manual
git commit -m "" # ManualJujutsu: Working copy IS a commit
# Agent makes changes
vim file.rs
# AUTOMATICALLY a commit!
jj log # Shows working copy as "@" commit
jj describe -m "Auto: agent edits" # Optional: add message laterFor AI Agents:
- ✅ Never lose work
- ✅ Every keystroke trackable
- ✅ Automatic versioning
- ✅ Can undo individual file changes
Git Worktrees: Limited undo
git reflog # Only shows branch movements
git reset --hard # Dangerous, destructive
# Can't undo: merges, rebases, complex operationsJujutsu: Undo anything
jj op log # See all operations
jj undo # Undo last operation
jj op restore op_abc # Restore to specific operation
# Can undo: EVERYTHING (merges, rebases, edits, conflicts)For AI Agents:
- ✅ Safe experimentation
- ✅ Rollback failed approaches
- ✅ A/B test different solutions
- ✅ Learn from failures without consequences
# Setup (manual)
git worktree add ../agent1 feature-auth
git worktree add ../agent2 feature-db
git worktree add ../agent3 feature-tests
# Agent 1: Refactor auth (in ../agent1/)
cd ../agent1
vim src/auth.rs
git add src/auth.rs
git commit -m "Agent 1: refactor auth"
# Agent 2: Refactor DB (in ../agent2/)
cd ../agent2
vim src/db.rs
git add src/db.rs
git commit -m "Agent 2: refactor db"
# Agent 3: Update tests (in ../agent3/)
cd ../agent3
vim tests/test_auth.rs # Depends on Agent 1's changes!
# Problem: Can't see Agent 1's changes yet
git add tests/test_auth.rs
git commit -m "Agent 3: update tests"
# Merge (manual coordination required)
cd ../../repo
git checkout main
git merge feature-auth # OK
git merge feature-db # OK
git merge feature-tests # CONFLICT! (depends on feature-auth)
# Everything stops! Manual intervention required!Problems:
- ❌ Agents work in isolation (can't see each other's work)
- ❌ Manual worktree setup per agent
- ❌ Conflicts block the entire workflow
- ❌ No automatic tracking of dependencies
- ❌ Can't learn from the workflow (no operation log)
# No setup needed - all agents work in same repo
# Agent 1: Refactor auth
jj describe -m "Agent 1: refactor auth"
vim src/auth.rs
# Auto-committed as op_001
# Agent 2: Refactor DB (concurrent!)
jj new --after main # Create parallel change
jj describe -m "Agent 2: refactor db"
vim src/db.rs
# Auto-committed as op_002
# Agent 3: Update tests (sees Agent 1's work!)
jj new --after op_001 # Build on Agent 1's change
jj describe -m "Agent 3: update tests"
vim tests/test_auth.rs
# Auto-committed as op_003
# Merge (automatic conflict handling)
jj rebase -s op_002 -d op_001 # Rebase DB onto auth
# If conflict: recorded in commit, doesn't block!
jj rebase -s op_003 -d op_002 # Rebase tests onto DB
# If conflict: recorded, can be resolved later
# Operation log shows everything
jj op log
# op_001: Agent 1 refactor auth
# op_002: Agent 2 refactor db
# op_003: Agent 3 update tests
# op_004: rebase op_002 -> op_001
# op_005: rebase op_003 -> op_002
# AgentDB learns:
# - Agent 3 depends on Agent 1 (always tests after auth changes)
# - DB changes rarely conflict with auth
# - Test updates take 50% longer when conflicts occurAdvantages:
- ✅ Agents see each other's work in real-time
- ✅ No manual setup (single repo)
- ✅ Conflicts recorded, don't block
- ✅ Automatic dependency tracking via operation log
- ✅ Complete learning data for AgentDB
- ✅ You're a human developer
- ✅ You need to work on multiple branches at once
- ✅ You want standard Git semantics
- ✅ Your team is already using Git
- ✅ You don't need operation logging
- ✅ You have AI agents making code changes
- ✅ You need concurrent multi-agent editing
- ✅ You want to learn from code evolution patterns
- ✅ You need complete operation history
- ✅ Conflicts should be handled gracefully, not block
- ✅ You want time-travel debugging capabilities
- ✅ All of the above, PLUS:
- ✅ You need WASM (browser/Node.js/Deno)
- ✅ You want AgentDB integration for learning
- ✅ You need Rust performance with TypeScript ergonomics
- ✅ You're building multi-agent systems
.git/
├── worktrees/
│ ├── agent1/ # Worktree 1 metadata
│ │ ├── HEAD # Points to feature-a
│ │ ├── index # Staging area for this worktree
│ │ └── gitdir # Link back to main .git
│ └── agent2/ # Worktree 2 metadata
│ ├── HEAD # Points to feature-b
│ ├── index
│ └── gitdir
├── objects/ # Shared object store
├── refs/ # Shared refs
└── index # Main repo staging area
../agent1/ # Worktree 1 working directory
../agent2/ # Worktree 2 working directory
Key Points:
- Shares object store (efficient)
- Separate staging areas (isolated)
- Still uses Git's commit model (manual, staged)
.jj/
├── repo/
│ ├── store/ # Commit storage (like Git objects)
│ └── index/ # HNSW index for fast lookups
├── op_store/ # ⭐ OPERATION LOG (unique to jj)
│ ├── operations/ # Every operation ever performed
│ └── views/ # Repository state at each operation
├── op_heads/ # Current operation pointers
└── working_copy/
├── tree_state # Working copy as a commit
└── operation_id # Which operation created this state
.git/ # Git backend for compatibility
Key Points:
- Operation log is first-class (not reflog)
- Working copy is a commit (not separate state)
- Conflicts stored in commits (not blocking errors)
- Complete history of all operations (learning data!)
// ❌ Git Worktrees approach (limited)
class GitWorktreeAgent {
async work(taskId: string) {
// Create worktree for this agent
await exec(`git worktree add ../agent-${taskId} -b ${taskId}`);
process.chdir(`../agent-${taskId}`);
// Make changes
await this.editFiles();
// Manual staging and commit
await exec('git add .');
await exec(`git commit -m "Agent ${taskId}: completed"`);
// Return to main repo
process.chdir('../../repo');
// Merge (blocking on conflicts!)
try {
await exec(`git merge ${taskId}`);
} catch (error) {
// BLOCKED! Need human intervention
throw new Error('Merge conflict - manual resolution required');
}
// Cleanup
await exec(`git worktree remove ../agent-${taskId}`);
}
}
// Problem: Can't run agents in parallel due to merge conflicts
await agent1.work('task-1'); // Sequential
await agent2.work('task-2'); // Sequential
await agent3.work('task-3'); // Sequential// ✅ Jujutsu approach (concurrent, learning-enabled)
import { JJWrapper, JJHooksIntegration } from '@agentic-flow/jujutsu';
class JujutsuAgent {
private jj: JJWrapper;
private hooks: JJHooksIntegration;
async work(taskId: string) {
// Pre-task hook (logged)
await this.hooks.onPreTask({
agent_id: `agent-${taskId}`,
session_id: 'swarm-001',
task_description: `Task ${taskId}`,
timestamp: Date.now()
});
// Make changes (auto-committed!)
await this.editFiles();
// Post-edit hook (logged, synced to AgentDB)
const op = await this.hooks.onPostEdit('src/main.rs', context);
// Post-task hook (collect all operations)
const ops = await this.hooks.onPostTask(context);
// Conflicts? No problem - they're recorded, not blocking
const conflicts = await this.jj.getConflicts();
if (conflicts.length > 0) {
// Notify coordinator, continue working
await this.notifyConflicts(conflicts);
}
return ops; // Return operation log for learning
}
}
// ✅ Can run agents in parallel!
const [ops1, ops2, ops3] = await Promise.all([
agent1.work('task-1'), // Parallel
agent2.work('task-2'), // Parallel
agent3.work('task-3'), // Parallel
]);
// AgentDB learns from all operations
for (const ops of [ops1, ops2, ops3]) {
await agentDB.storeEpisodes(ops);
}
// Query learned patterns
const patterns = await agentDB.searchPatterns('refactoring conflicts');
// Result: "Agent type X tends to conflict with Agent type Y on auth files"- Purpose: Multiple working directories for human developers
- Strength: Familiar Git workflow, easy to understand
- Limitation: Still Git underneath - conflicts block, no learning data
- Purpose: Version control rethought for AI agent workflows
- Strength: Operation log, first-class conflicts, auto-tracking
- Advantage: Enables true concurrent multi-agent coding with learning
Git worktrees solve: "I want to work on multiple branches at once"
Jujutsu solves: "I want operation-first VCS with conflict-free workflows"
agentic-jujutsu adds: "I want AI agents to learn from code evolution"
- Git Worktrees: https://git-scm.com/docs/git-worktree
- Jujutsu: https://github.com/jj-vcs/jj
- agentic-jujutsu:
/workspaces/agentic-flow/packages/agentic-jujutsu/ - Operation Log Learning:
/docs/research/JJ_INTEGRATION_ANALYSIS.md
Bottom Line: Git worktrees are a feature of Git. Jujutsu is a different VCS philosophy. agentic-jujutsu makes Jujutsu accessible to AI agents with learning capabilities.
I'm more interested in a comparison of jujutsu's workspaces with git's worktrees.