7 releases
| new 0.2.4 | Apr 15, 2026 |
|---|---|
| 0.2.3 | Apr 15, 2026 |
| 0.1.1 | Apr 14, 2026 |
#1754 in Command line utilities
3MB
4K
SLoC
git-parsec
Git worktree lifecycle manager for parallel AI agent workflows
parsec manages isolated git worktrees tied to tickets (Jira, GitHub Issues), enabling multiple AI agents or developers to work on the same repository in parallel without lock conflicts.

What is parsec?
parsec is a command-line tool (CLI) that automates the full lifecycle of git worktrees: create an isolated workspace from a ticket ID, work in parallel without lock conflicts, then push + create PR + clean up in one command. It integrates with Jira, GitHub Issues, and GitLab Issues for automatic ticket title lookup, and supports GitHub and GitLab for PR/MR creation.
Unlike plain git worktree, parsec tracks workspace state, detects file conflicts across worktrees, provides operation history with undo, supports stacked PRs, and offers CI status monitoring — all from a single CLI.
Key use cases:
- Run multiple AI coding agents on the same repo simultaneously (no
index.lockconflicts) - Work on several tickets in parallel as a developer without stashing or switching branches
- Ship complete features (push + PR + cleanup) with one command
- Monitor CI, merge PRs, and manage stacked dependencies from the terminal
The Problem
Git uses a single working directory with a single index.lock. When multiple AI agents (or developers) try to work on the same repo simultaneously:
git add/commitoperations collide on.git/index.lock- Context switching between tasks requires stashing or committing WIP
- Worktrees exist but have poor lifecycle management
- No connection between tickets and working directories
The Solution
# Create isolated workspaces for two tickets
$ parsec start PROJ-1234 --title "Add user authentication"
Created workspace for PROJ-1234 at /home/user/myapp.PROJ-1234
Add user authentication
$ parsec start PROJ-5678 --title "Fix payment timeout"
Created workspace for PROJ-5678 at /home/user/myapp.PROJ-5678
Fix payment timeout
# See all active workspaces
$ parsec list
╭───────────┬──────────────────────┬────────┬──────────────────┬──────────────────────────────╮
│ Ticket │ Branch │ Status │ Created │ Path │
├───────────┼──────────────────────┼────────┼──────────────────┼──────────────────────────────┤
│ PROJ-1234 │ feature/PROJ-1234 │ active │ 2026-04-15 09:00 │ /home/user/myapp.PROJ-1234 │
│ PROJ-5678 │ feature/PROJ-5678 │ active │ 2026-04-15 09:01 │ /home/user/myapp.PROJ-5678 │
╰───────────┴──────────────────────┴────────┴──────────────────┴──────────────────────────────╯
# Check if any workspaces touch the same files
$ parsec conflicts
No conflicts detected.
# Complete: push, create PR, and clean up in one step
$ parsec ship PROJ-1234
Shipped PROJ-1234!
PR: https://github.com/org/repo/pull/42
Workspace cleaned up.
# Remove all remaining workspaces
$ parsec clean --all
Removed 1 worktree(s):
- PROJ-5678
Features
- Ticket-driven workspaces -- Create worktrees named after Jira/GitHub Issues tickets
- Zero-conflict parallelism -- Each workspace has its own index, no lock contention
- Conflict detection -- Warns when multiple workspaces modify the same files
- One-step shipping --
parsec shippushes, creates a GitHub PR or GitLab MR, and cleans up - Adopt existing branches -- Import branches already in progress with
parsec adopt - Attach to existing branches -- Start a workspace from an existing local or remote branch with
--branch - Operation history and undo --
parsec logshows what happened,parsec undoreverts it - Keep branches fresh --
parsec syncrebases or merges the latest base branch into any worktree - Agent-friendly output --
--jsonflag on every command for machine consumption - Status dashboard -- See all parallel work at a glance
- Auto-cleanup -- Remove worktrees for merged branches automatically
- GitHub and GitLab -- PR and MR creation for both platforms
- Stacked PRs -- Create dependent PR chains with
--onand sync the entire stack
Installation
cargo install git-parsec
Or build from source:
git clone https://github.com/erishforG/git-parsec.git
cd git-parsec
cargo build --release
# Binary at ./target/release/parsec
Quick Start
# 1. (Optional) Run interactive setup
$ parsec config init
# 2. Start work on a ticket
$ parsec start PROJ-1234 --title "Add rate limiting"
Created workspace for PROJ-1234 at /home/user/myapp.PROJ-1234
Add rate limiting
Tip: cd $(parsec switch PROJ-1234)
# 3. Switch into the workspace
$ cd $(parsec switch PROJ-1234)
# 4. Work, commit as normal...
$ git add . && git commit -m "Implement rate limiter"
# 5. Start a second ticket in parallel
$ parsec start PROJ-5678 --title "Fix auth bug"
# 6. Check for file conflicts across workspaces
$ parsec conflicts
# 7. Ship when done
$ parsec ship PROJ-1234
Shipped PROJ-1234!
PR: https://github.com/org/repo/pull/42
Workspace cleaned up.
# 8. See what happened
$ parsec log
Commands
parsec start <ticket>
Create an isolated worktree for a ticket. Fetches the ticket title from your configured tracker (Jira, GitHub Issues) or accepts a manual title.
parsec start <ticket> [--base <branch>] [--title "text"] [--on <parent-ticket>] [--branch <name>]
| Option | Description |
|---|---|
-b, --base <branch> |
Base branch to create from (default: main/master) |
--title "text" |
Set ticket title manually, skip tracker lookup |
--on <ticket> |
Stack on another ticket's branch (for dependent PRs) |
--branch <name> |
Use an existing branch instead of creating a new one |
# With Jira integration (title auto-fetched)
$ parsec start CL-2283
Created workspace for CL-2283 at /home/user/myapp.CL-2283
Implement rate limiting for API endpoints
Tip: cd $(parsec switch CL-2283)
# With manual title
$ parsec start 42 --title "Fix login redirect"
Created workspace for 42 at /home/user/myapp.42
Fix login redirect
Tip: cd $(parsec switch 42)
# From a specific base branch
$ parsec start PROJ-99 --base release/2.0
# Attach to an existing branch (local or remote)
$ parsec start CL-2208 --branch feature/CL-2208
# Attach to a remote-only branch (auto-fetches and tracks)
$ parsec start CL-2208 --branch origin/feature/CL-2208
parsec adopt <ticket>
Import an existing branch into parsec management. Useful when you started work before using parsec, or when taking over someone else's branch.
parsec adopt <ticket> [--branch <name>] [--title "text"]
| Option | Description |
|---|---|
-b, --branch <name> |
Branch to adopt (default: <prefix><ticket>) |
--title "text" |
Set ticket title manually |
# Adopt a branch matching the default prefix
$ parsec adopt PROJ-1234
Adopted branch 'feature/PROJ-1234' as PROJ-1234 at /home/user/myapp.PROJ-1234
# Adopt a branch with a different name
$ parsec adopt PROJ-99 --branch fix/payment-timeout
Adopted branch 'fix/payment-timeout' as PROJ-99 at /home/user/myapp.PROJ-99
parsec list
List all active parsec-managed worktrees.
parsec list
$ parsec list
╭────────┬────────────────┬────────┬──────────────────┬────────────────────────────╮
│ Ticket │ Branch │ Status │ Created │ Path │
├────────┼────────────────┼────────┼──────────────────┼────────────────────────────┤
│ TEST-1 │ feature/TEST-1 │ active │ 2026-04-15 09:00 │ /home/user/myapp.TEST-1 │
│ TEST-2 │ feature/TEST-2 │ active │ 2026-04-15 09:05 │ /home/user/myapp.TEST-2 │
╰────────┴────────────────┴────────┴──────────────────┴────────────────────────────╯
$ parsec list --json
[{"ticket":"TEST-1","path":"/home/user/myapp.TEST-1","branch":"feature/TEST-1","base_branch":"main","created_at":"2026-04-15T09:00:00Z","ticket_title":"Add auth","status":"active"}]
parsec status [ticket]
Show detailed status of a workspace. Shows all workspaces if no ticket is specified.
parsec status [ticket]
$ parsec status PROJ-1234
──────────────────────────────────────────────────
Ticket: PROJ-1234
Title: Add user authentication
Branch: feature/PROJ-1234
Base: main
Status: active
Created: 2026-04-15 09:00 UTC
Path: /home/user/myapp.PROJ-1234
──────────────────────────────────────────────────
parsec ship <ticket>
Push the branch, create a PR (GitHub) or MR (GitLab), and clean up the worktree. The forge is auto-detected from the remote URL.
parsec ship <ticket> [--draft] [--no-pr]
| Option | Description |
|---|---|
--draft |
Create the PR/MR as a draft |
--no-pr |
Push only, skip PR/MR creation |
# Push + PR + cleanup
$ parsec ship PROJ-1234
Shipped PROJ-1234!
PR: https://github.com/org/repo/pull/42
Workspace cleaned up.
# Draft PR
$ parsec ship PROJ-5678 --draft
# Push only, no PR
$ parsec ship PROJ-9000 --no-pr
Token required: set PARSEC_GITHUB_TOKEN (or GITHUB_TOKEN, GH_TOKEN) for GitHub, or PARSEC_GITLAB_TOKEN (or GITLAB_TOKEN) for GitLab.
parsec clean
Remove worktrees whose branches have been merged. Use --all to remove everything.
parsec clean [--all] [--dry-run]
| Option | Description |
|---|---|
--all |
Remove all worktrees, including unmerged |
--dry-run |
Preview what would be removed |
# Preview first
$ parsec clean --dry-run
Would remove 1 worktree(s):
- PROJ-1234
# Remove merged worktrees
$ parsec clean
Removed 1 worktree(s):
- PROJ-1234
# Remove everything
$ parsec clean --all
Removed 3 worktree(s):
- PROJ-1234
- PROJ-5678
- PROJ-9000
parsec conflicts
Detect files modified in more than one active worktree. Workspaces with no changes are skipped.
parsec conflicts
# No conflicts
$ parsec conflicts
No conflicts detected.
# Conflicts found
$ parsec conflicts
╭──────────────────┬──────────────────────╮
│ File │ Worktrees │
├──────────────────┼──────────────────────┤
│ src/api/router.rs│ PROJ-1234, PROJ-5678 │
╰──────────────────┴──────────────────────╯
parsec switch [ticket]
Print the absolute path to a ticket's worktree. When called without a ticket, shows an interactive picker. Designed for cd $(parsec switch ...).
parsec switch [ticket]
# Direct switch
$ parsec switch PROJ-1234
/home/user/myapp.PROJ-1234
# Interactive picker (no argument)
$ parsec switch
? Switch to workspace ›
❯ PROJ-1234 — Add user authentication
PROJ-5678 — Fix payment timeout
# Use with cd
$ cd $(parsec switch PROJ-1234)
parsec log [ticket]
Show the history of parsec operations. Each mutating command (start, adopt, ship, clean, undo) is recorded with a timestamp.
parsec log [ticket] [-n, --last N]
| Option | Description |
|---|---|
[ticket] |
Filter to a specific ticket |
-n, --last N |
Show last N entries (default: 20) |
$ parsec log
╭───┬───────┬───────────┬───────────────────────────────────────────────┬──────────────────╮
│ # │ Op │ Ticket │ Detail │ Time │
├───┼───────┼───────────┼───────────────────────────────────────────────┼──────────────────┤
│ 4 │ clean │ PROJ-5678 │ Cleaned workspace for branch 'feature/5678' │ 2026-04-15 14:30 │
│ 3 │ ship │ PROJ-1234 │ Shipped branch 'feature/PROJ-1234' │ 2026-04-15 14:02 │
│ 2 │ start │ PROJ-5678 │ Created workspace at /home/user/myapp.5678 │ 2026-04-15 13:55 │
│ 1 │ start │ PROJ-1234 │ Created workspace at /home/user/myapp.1234 │ 2026-04-15 09:14 │
╰───┴───────┴───────────┴───────────────────────────────────────────────┴──────────────────╯
# Filter by ticket
$ parsec log PROJ-1234
# Last 3 entries only
$ parsec log --last 3
parsec undo
Undo the last parsec operation.
- Undo
startoradopt: removes the worktree and deletes the branch - Undo
shiporclean: re-creates the worktree from the branch (if still available locally or on remote)
parsec undo [--dry-run]
| Option | Description |
|---|---|
--dry-run |
Preview what would be undone |
# Preview
$ parsec undo --dry-run
Would undo: start PROJ-5678
Would remove worktree at /home/user/myapp.PROJ-5678
Would delete branch 'feature/PROJ-5678'
# Execute
$ parsec undo
Undid start for PROJ-5678
Worktree removed.
# Nothing to undo
$ parsec undo
Error: nothing to undo. Run `parsec log` to see operation history.
parsec sync [ticket]
Fetch the latest base branch and rebase (or merge) the worktree on top. Detects the current worktree automatically when no ticket is given.
parsec sync [ticket] [--all] [--strategy rebase|merge]
| Option | Description |
|---|---|
--all |
Sync all active worktrees |
--strategy |
rebase (default) or merge |
# Sync current worktree
$ parsec sync
✓ rebase 1 worktree(s):
- PROJ-1234
# Sync a specific worktree
$ parsec sync PROJ-5678
# Sync all worktrees at once
$ parsec sync --all
# Use merge instead of rebase
$ parsec sync --strategy merge
parsec open <ticket>
Open the associated PR/MR or ticket tracker page in your default browser. If the ticket has been shipped, opens the PR by default; otherwise opens the tracker page.
parsec open <ticket> [--pr] [--ticket-page]
| Option | Description |
|---|---|
--pr |
Force open the PR/MR page |
--ticket-page |
Force open the ticket tracker page |
# Open PR if shipped, otherwise ticket page
$ parsec open PROJ-1234
Opening https://github.com/org/repo/pull/42
# Force open the Jira ticket
$ parsec open PROJ-1234 --ticket-page
Opening https://yourcompany.atlassian.net/browse/PROJ-1234
# Force open the PR
$ parsec open PROJ-1234 --pr
Opening https://github.com/org/repo/pull/42
parsec pr-status [ticket]
Check the CI and review status of shipped PRs. Shows CI check results, review approvals, and merge state in a color-coded table.
parsec pr-status [ticket]
# Check a specific ticket's PR
$ parsec pr-status PROJ-1234
┌───────────┬─────┬────────┬──────────┬──────────────┐
│ Ticket │ PR │ State │ CI │ Reviews │
├───────────┼─────┼────────┼──────────┼──────────────┤
│ PROJ-1234 │ #42 │ open │ ✓ passed │ ✓ approved │
└───────────┴─────┴────────┴──────────┴──────────────┘
# Check all shipped PRs
$ parsec pr-status
# JSON output
$ parsec pr-status PROJ-1234 --json
Requires: PARSEC_GITHUB_TOKEN (or GITHUB_TOKEN, GH_TOKEN)
parsec ci [ticket] [--watch] [--all]
Check CI/CD pipeline status for a ticket's PR. Shows individual check runs with status, duration, and an overall summary.
parsec ci [ticket] [--watch] [--all]
| Option | Description |
|---|---|
ticket |
Ticket identifier (auto-detects current worktree if omitted) |
--watch |
Poll CI every 5s until all checks complete |
--all |
Show CI for all shipped PRs |
# Auto-detect from current worktree
$ parsec ci
CI for PROJ-1234 (PR #42, a1b2c3d)
┌────────────┬───────────┬──────────┐
│ Check │ Status │ Duration │
├────────────┼───────────┼──────────┤
│ Tests │ ✓ passed │ 2m 15s │
│ Build │ ✓ passed │ 1m 42s │
│ Lint │ ● running │ running… │
└────────────┴───────────┴──────────┘
✓ CI: 2/3 — 2 passed, 1 running
# Check a specific ticket
$ parsec ci PROJ-1234
# Watch mode — refreshes every 5s until done
$ parsec ci PROJ-1234 --watch
# All shipped PRs
$ parsec ci --all
# JSON output
$ parsec ci PROJ-1234 --json
Requires: PARSEC_GITHUB_TOKEN (or GITHUB_TOKEN, GH_TOKEN)
parsec merge [ticket] [--rebase] [--no-wait] [--no-delete-branch]
Merge a ticket's PR directly from the terminal. Waits for CI to pass before merging, then cleans up the local worktree.
parsec merge [ticket] [--rebase] [--no-wait] [--no-delete-branch]
| Option | Description |
|---|---|
ticket |
Ticket identifier (auto-detects current worktree if omitted) |
--rebase |
Use rebase merge instead of squash (default: squash) |
--no-wait |
Skip CI check before merging |
--no-delete-branch |
Keep remote branch after merge |
# Squash merge (default)
$ parsec merge PROJ-1234
Waiting for CI to pass... ✓
Merged PR #42 for PROJ-1234!
Method: squash
SHA: a1b2c3d
# Rebase merge
$ parsec merge PROJ-1234 --rebase
# Skip CI wait
$ parsec merge PROJ-1234 --no-wait
# JSON output
$ parsec merge PROJ-1234 --json
Requires: PARSEC_GITHUB_TOKEN (or GITHUB_TOKEN, GH_TOKEN)
parsec diff [ticket] [--stat] [--name-only]
View changes in a worktree compared to its base branch. Uses merge-base for accurate comparison.
parsec diff [ticket] [--stat] [--name-only]
| Option | Description |
|---|---|
ticket |
Ticket identifier (auto-detects current worktree if omitted) |
--stat |
Show file-level summary only |
--name-only |
List changed file names only |
# Full diff for current worktree
$ parsec diff
# File summary
$ parsec diff PROJ-1234 --stat
# Just file names
$ parsec diff --name-only
# JSON output (changed files list)
$ parsec diff PROJ-1234 --json
parsec stack [--sync]
View and manage stacked PR dependencies. Worktrees created with --on form a dependency chain.
parsec stack [--sync]
| Option | Description |
|---|---|
--sync |
Rebase the entire stack chain |
# Create a stack
$ parsec start PROJ-1 --title "Add models"
$ parsec start PROJ-2 --on PROJ-1 --title "Add API endpoints"
$ parsec start PROJ-3 --on PROJ-2 --title "Add frontend"
# View the dependency graph
$ parsec stack
Stack dependency graph:
└── PROJ-1 Add models
└── PROJ-2 Add API endpoints
└── PROJ-3 Add frontend
# Sync the entire stack
$ parsec stack --sync
# Ship creates PRs with correct base branches
$ parsec ship PROJ-1 # PR to main
$ parsec ship PROJ-2 # PR to feature/PROJ-1
$ parsec ship PROJ-3 # PR to feature/PROJ-2
parsec config
# Interactive setup wizard
$ parsec config init
# Show current configuration
$ parsec config show
[workspace]
layout = sibling
base_dir = .parsec/workspaces
branch_prefix = feature/
[tracker]
provider = jira
jira.base_url = https://yourcompany.atlassian.net
[ship]
auto_pr = true
auto_cleanup = true
draft = false
# Output shell integration script
$ parsec config shell zsh
# Generate shell completions
$ parsec config completions zsh
# Install man page
$ sudo parsec config man
Global Flags
These flags work on every command:
| Flag | Description |
|---|---|
--json |
Machine-readable JSON output |
-q, --quiet |
Suppress non-essential output |
--repo <path> |
Target a different repository |
$ parsec list --json
$ parsec ship PROJ-1234 --quiet
$ parsec status --repo /path/to/other-repo
Shell Integration
parsec switch prints a path but cannot cd for you. The shell integration wraps parsec switch so it changes your directory automatically:
# Add to ~/.zshrc
eval "$(parsec config shell zsh)"
# Or for bash, add to ~/.bashrc
eval "$(parsec config shell bash)"
After sourcing, parsec switch <ticket> will cd into the worktree directly:
$ parsec switch PROJ-1234
# Now you're in /home/user/myapp.PROJ-1234
Shell Completions
Generate tab-completion scripts for your shell:
# Zsh — add to ~/.zshrc
eval "$(parsec config completions zsh)"
# Bash — add to ~/.bashrc
eval "$(parsec config completions bash)"
# Fish — add to ~/.config/fish/config.fish
parsec config completions fish | source
# Other shells
parsec config completions elvish
parsec config completions powershell
Man Page
Install the man page so man parsec works:
sudo parsec config man
# Man page installed to /usr/local/share/man/man1/parsec.1
# Custom directory
parsec config man --dir ~/.local/share/man
Configuration
Config file: ~/.config/parsec/config.toml
[workspace]
# "sibling" (default) creates worktrees next to repo: ../repo.ticket/
# "internal" creates inside repo: .parsec/workspaces/ticket/
layout = "sibling"
base_dir = ".parsec/workspaces"
branch_prefix = "feature/"
[tracker]
# "jira" | "github" | "gitlab" | "none"
provider = "jira"
[tracker.jira]
base_url = "https://yourcompany.atlassian.net"
# Auth: PARSEC_JIRA_TOKEN or JIRA_PAT env var
[tracker.gitlab]
base_url = "https://gitlab.com"
# Auth: PARSEC_GITLAB_TOKEN env var
[ship]
auto_pr = true # Create PR/MR on ship
auto_cleanup = true # Remove worktree after ship
draft = false # Create PRs as drafts
[hooks]
# Commands to run in new worktrees after creation
post_create = ["npm install"]
Environment Variables
| Variable | Description |
|---|---|
PARSEC_JIRA_TOKEN |
Jira API token (or personal access token) |
JIRA_PAT |
Alternative Jira token variable |
JIRA_BASE_URL |
Jira URL (overrides config) |
PARSEC_GITHUB_TOKEN |
GitHub token for PR creation |
GITHUB_TOKEN |
Fallback GitHub token |
GH_TOKEN |
Fallback GitHub token |
PARSEC_GITLAB_TOKEN |
GitLab token for MR creation |
GITLAB_TOKEN |
Fallback GitLab token |
Token priority: PARSEC_*_TOKEN > platform-specific variables.
Comparison with Alternatives
| Feature | parsec | GitButler | worktrunk | git worktree | git-town |
|---|---|---|---|---|---|
| Ticket tracker integration | Jira + GitHub Issues | No | No | No | No |
| Physical isolation | Yes (worktrees) | No (virtual branches) | Yes | Yes | No |
| Conflict detection | Cross-worktree | N/A | No | No | No |
| One-step ship (push+PR+clean) | Yes | No | No | No | Yes |
| GitHub + GitLab | Both | Both | No | No | No |
| Operation history + undo | Yes | Yes | No | No | No |
| JSON output | Yes | Yes | Yes | No | No |
| Auto-cleanup merged | Yes | No | Yes | Manual | No |
| GUI | CLI only | Desktop + TUI | CLI | CLI | CLI |
| Zero config start | Yes | No | Yes | No | No |
License
MIT
Dependencies
~13–30MB
~382K SLoC