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 also stumbled on this, and indedd JJ has workspaces which would be the equivalent of git worktrees.
Also this whole doc reads as AI slop, which probably explains its outdated nature.