A TypeScript-based CLI for managing Git worktrees with automation-first design
Pando makes it effortless to work on multiple branches simultaneously using Git worktrees. Built for modern developer workflows, it provides both human-friendly commands and machine-readable output for CI/CD automation.
- 🌳 Worktree Management: Create, list, and remove git worktrees with ease
- 🤖 Automation-First: Every command supports
--jsonflag for scripting and AI agents - 🎯 Developer-Friendly: Interactive prompts when flags aren't provided
- ⚡ Fast: Built with TypeScript for type safety and performance
- 🔧 Extensible: Clean architecture makes adding new commands simple
Not yet available. The Homebrew tap (
zpyoung/homebrew-pando) has not been published; until it exists, install via pnpm/npm below. Tracked in ROADMAP.md.
# Coming soon
brew tap zpyoung/pando
brew install pandopnpm install -g @zyoung-ff/pandonpm install -g @zyoung-ff/pandogit clone https://github.com/zpyoung/pando.git
cd pando
pnpm install
pnpm build
pnpm link --global# Initialize configuration (optional but recommended)
pando config init
# Create a new worktree for a feature branch
pando add --path ../feature-x --branch feature-x
# List all worktrees
pando list
# Remove a worktree (interactive selection or direct with --path)
pando remove
pando remove --path ../feature-x
# View current configuration and sources
pando config showCreate a new git worktree (supports both creating new branches and checking out existing branches)
Flags:
-p, --path: Path for the new worktree (optional ifworktree.defaultPathis configured)-b, --branch: Branch to checkout or create (also accepted as a positional argument, e.g.pando add feature-x)-c, --commit: Commit hash to base the new branch on-f, --force: Force create branch even if it exists (uses git worktree add -B)--no-rebase: Skip automatic rebase of existing branch onto source branch--ephemeral: Mark the worktree as ephemeral (mutually exclusive with--long-lived)--long-lived: Mark the worktree as long-lived (mutually exclusive with--ephemeral)--ttl <duration>: Set a per-worktree TTL override (for example,30mor2d)--owner <id>: Record an owner or agent session id--ports: Force-enable configured port and database-name allocation for this run--skip-rsync: Skip the rsync copy step (ignores rsync config)--rsync-flags: Override rsync flags (comma-separated; repeatable)--rsync-exclude: Additional rsync exclude patterns (comma-separated; repeatable)--skip-symlink: Skip symlink creation (ignores symlink config)--symlink: Additional symlink patterns, overriding config (comma-separated; repeatable)--absolute-symlinks: Use absolute paths for symlinks instead of relative--details: Show detailed setup information after the worktree is created-j, --json: Output in JSON format
When
--skip-rsyncis combined with--rsync-flagsor--rsync-exclude, the rsync flags are ignored and a warning is shown.
Lifecycle metadata: pando add stores the worktree kind, creation time, source branch, and optional owner/TTL in Git's per-worktree config. Flags override worktree.defaultKind; auto treats Claude worktree paths, active agent-session environments, and boolean PANDO_EPHEMERAL=true|1|yes signals as ephemeral, and other worktrees as long-lived. Worktrees created during an active CLAUDE_SESSION_ID or PANDO_SESSION are automatically Git-locked when worktree.autoLockActive is enabled; passing --owner alone does not trigger auto-locking. When [ports].enabled or --ports is set, requested service ports and a database name derived from each worktree's own branch are also stored. Exhausted ports produce a warning without failing worktree creation.
Automatic Rebase: When checking out an existing branch, pando automatically rebases it onto the current branch. This keeps your feature branches up-to-date. If the rebase fails (e.g., conflicts), a warning is shown but the worktree is still created. Use --no-rebase to skip this behavior, or set worktree.rebaseOnAdd = false in config.
Rsync Behavior: By default (rsync.onlyUntracked = true), rsync carries over only files that git ignores in the source worktree — build artifacts like .venv/, node_modules/, and caches. Tracked files always come from the new worktree's own checkout, so rsync can never dirty the tree, and artifact syncing works even when the new worktree is on a different branch or commit. Non-ignored untracked files (work in progress) are deliberately not copied. With rsync.onlyUntracked = false, pando mirrors the full source tree instead, but only when the source and new worktree are on the same commit — otherwise rsync is skipped with a warning so tracked files from the source branch do not dirty the new checkout. Use --skip-rsync to disable rsync explicitly.
Clean-tree check: After setup, pando runs git status in the new worktree. If anything unexpected shows up (beyond the symlinks pando itself created), a warning lists the offending paths, and JSON output reports setup.cleanTree: false so automation can detect it.
Symlinking tracked paths: When a symlink pattern matches a git-tracked path (package.json, a lockfile), replacing the checked-out file with a symlink would make git status report deletions/modifications — so pando hides those entries via git update-index --skip-worktree. Untracked/gitignored patterns need no hiding and are filtered from the skip-worktree step automatically. Skip-worktree is local, per-clone state that git can silently drop; the clean-tree check surfaces any drift. Set symlink.allowTracked = false for strict mode: tracked patterns are then skipped with a warning, and only gitignored paths get symlinked.
Examples:
# Create new branch in worktree
pando add --path ../feature-x --branch feature-x
# Checkout existing branch into worktree
pando add --path ../existing --branch existing-branch
# Using config default path (if worktree.defaultPath is set in .pando.toml)
pando add --branch feature-x
# OR using shorthand (positional argument)
pando add feature-x
# From specific commit
pando add --path ../hotfix --branch hotfix --commit abc123
# Force reset existing branch to commit
pando add --path ../feature --branch feature-x --commit abc123 --force
# Show detailed setup output, including rsync totals and sample symlink paths
pando add --path ../feature-x --branch feature-x --detailsWhen --details is used with --json, the response includes a stable details object with rsync totals and symlink counts/sample paths. Without --details, default human and JSON output are unchanged.
List all git worktrees
Flags:
-v, --verbose: Show detailed information-j, --json: Output in JSON format
Examples:
pando list
pando list --verbose
pando list --jsonVerbose human output includes compact kind, owner, age, and lock details. JSON output always includes kind, createdAt, owner, ttl, ageMs, and locked for every worktree (nullable metadata fields are null).
Show health status of all worktrees
Flags:
-j, --json: Output in JSON format
Health Status Types:
clean: No issues detecteduncommitted: Has modified files (shows count)behind: Branch is N commits behind upstreamgone: Remote tracking branch was deleteddetached: Worktree is in detached-HEAD state (no branch)error: Cannot check status (directory missing, git error, or remote check failed)
Each human report entry also shows lifecycle kind and lock state. JSON worktree entries include kind, ageMs, ttl, locked, and owner alongside the health fields.
Examples:
# Show human-readable health report
pando health
# Output in JSON format
pando health --jsonHuman Output Example:
Worktree Health Report
==================================================
🚨 Uncommitted changes:
/worktree/feature-auth
Branch: feature/auth
2 files modified
⚠️ Behind upstream:
/worktree/feature-fix
Branch: feature/fix
3 commits behind
Remote: origin/feature/fix
👻 Remote branch gone:
/worktree/old-feature
Branch: feature/old
remote branch deleted
✅ All good:
/worktree/main
Branch: main
/worktree/develop
Branch: develop
Total: 5 worktrees
Remove a git worktree
Flags:
-p, --path: Path to the worktree to remove (optional - will prompt interactively if omitted)-f, --force: Force removal even with uncommitted changes-k, --keep-branch: Keep the local branch (do not delete it)-d, --delete-branch: Override branch deletion behavior (none|local|remote); when omitted, uses the configured default (localunless overridden byworktree.deleteBranchOnRemove)none: Don't delete any brancheslocal: Delete local branch only (default)remote: Delete both local and remote branches
-j, --json: Output in JSON format (requires --path)
Branch Deletion:
- By default, the local branch is deleted when removing a worktree
- Use
--keep-branchto preserve the branch - Before deleting, checks if branch is merged (use
--forceto skip this check) - Remote branch deletion requires confirmation unless
--forceis used - Use
worktree.deleteBranchOnRemovein config to change default behavior - JSON results include the worktree's captured lifecycle
metadata, including assigned ports and database name
Examples:
# Interactive selection (select from list)
pando remove
# Direct removal with path (deletes local branch by default)
pando remove --path ../feature-x
pando remove --path ../feature-x --force
# Keep the branch when removing worktree
pando remove --path ../feature-x --keep-branch
# Remove worktree and delete both local and remote branches
pando remove --path ../feature-x --delete-branch remote --force
# Interactive multi-select with force flag
pando remove --forceClean stale git worktrees (merged branches, gone upstream, prunable)
Detection Categories:
- Merged: Branch fully merged into main/master (or specified target branch)
- Gone: Remote tracking branch was deleted upstream
- Prunable: Worktree directory was already deleted
Flags:
--fetch: Rungit fetch --prunebefore detection to update remote tracking branch state (configurable:clean.fetch)-f, --force: Skip confirmation prompts and clean all stale worktrees-k, --keep-branch: Keep local branch after worktree removal (configurable:worktree.deleteBranchOnRemove = "none")--dry-run: Show what would be removed without acting-t, --target-branch: Branch to check merges against (default: main or master) (configurable:worktree.targetBranch)-j, --json: Output in JSON format
Examples:
# Interactive selection of stale worktrees
pando clean
# Fetch latest and detect stale worktrees
pando clean --fetch
# See what would be cleaned without acting
pando clean --dry-run
# Clean all stale worktrees without prompts
pando clean --force
# Check merges against develop branch
pando clean --target-branch develop
# Keep branches after removing worktrees
pando clean --keep-branch
# JSON output for scripting
pando clean --jsonReclaim expired ephemeral worktrees without touching long-lived, locked, or dirty worktrees. A worktree is eligible after its metadata TTL (or worktree.ephemeralTtl, default 4h) expires. By default its branch must also be merged into worktree.targetBranch; set reap.requireMerged = false to retain unmerged branches while removing clean worktrees.
Flags:
--dry-run: Show eligible and safety-skipped worktrees without removing anything--owner <session>: Only consider worktrees owned by the specified session-f, --force: Skip the confirmation prompt; safety checks still apply-j, --json: Run non-interactively and emit structured results
pando reap --dry-run
pando reap --owner session-123 --force
pando reap --jsonLock a worktree so Git and pando reap leave it alone, or remove that lock. Targets may be an absolute/relative worktree path or an exact branch name; --path is available as an alternative to the positional target.
Flags:
-p, --path <target>: Worktree path or branch name--reason <text>: Record a lock reason (pando lockonly)-j, --json: Output in JSON format
pando lock ../feature-x --reason "active work"
pando lock feature/x --json
pando unlock ../feature-x
pando unlock --path feature/x --jsonMove a file from the current worktree to the main worktree and replace it with a symlink. Useful for keeping configuration files, dependencies, or other shared files in sync across all worktrees.
Arguments:
FILE: File to symlink (required)
Flags:
-f, --force: Overwrite file in main worktree if it exists--dry-run: Simulate the operation without making changes-j, --json: Output in JSON format
Examples:
# Move .env file to main worktree and symlink it
pando symlink .env
# Preview what would happen
pando symlink package.json --dry-run
# Overwrite existing file in main worktree
pando symlink config.json --force
# Use with JSON output
pando symlink .env --jsonUse Cases:
- Environment files (
.env,.env.local): Share environment configuration across worktrees - Lock files (
package-lock.json,pnpm-lock.yaml): Ensure consistent dependency resolution - IDE settings (
.vscode/settings.json): Share editor configuration - Build cache directories: Avoid duplicate downloads/compilation
Create a timestamped backup of a branch. Backup branches are named backup/<sourceBranch>/<timestamp> where timestamp is UTC YYYYMMDD-HHmmss format.
Flags:
-b, --branch: Source branch to backup (default: current branch)-m, --message: Optional message to store with the backup-j, --json: Output in JSON format
Examples:
# Backup the current branch
pando branch backup
# Backup with a descriptive message
pando branch backup -m "Before risky refactor"
# Backup a specific branch
pando branch backup --branch main
# Backup with JSON output for scripts
pando branch backup --branch feature/auth -m "Pre-merge backup" --jsonUse Cases:
- Before rebasing: Create a safety net before interactive rebase
- Before merging: Snapshot a feature branch before merging to main
- Experimenting: Save current state before trying something risky
- Checkpointing: Regular backups during long-running work
Restore a branch to a previous backup state. Resets the target branch to match the commit of a selected backup branch.
Flags:
-b, --branch: Target branch to restore (default: current branch)--backup: Backup branch to restore from (interactive selection if omitted)-f, --force: Skip confirmation prompt-d, --delete-backup: Delete the backup branch after successful restore-j, --json: Output in JSON format (requires--backup)
Safety Features:
- Checks for uncommitted changes before restoring current branch
- Prevents restoring branches checked out in other worktrees
- Shows commits that will become unreachable before confirmation
- Requires explicit
--backupflag with--json(no interactive mode)
Examples:
# Interactive restore - select from available backups
pando branch restore
# Restore from a specific backup
pando branch restore --backup backup/main/20250117-153045
# Restore a specific branch with force (no confirmation)
pando branch restore --branch main --backup backup/main/20250117-153045 --force
# Restore and delete the backup afterward
pando branch restore --backup backup/feature/20250117-100000 -f -d
# JSON output for automation (requires explicit backup)
pando branch restore --backup backup/feature/20250117-100000 --force --jsonUse Cases:
- Undo a rebase: Restore to pre-rebase state if conflicts are too complex
- Recover from mistakes: Quickly get back to a known good state
- A/B testing approaches: Restore and try a different implementation
Pando supports flexible configuration through multiple sources with a clear priority hierarchy.
Generate a configuration file with defaults and helpful comments.
Flags:
-g, --global: Create user-level config at~/.config/pando/config.toml--git-root: Create config at git repository root-f, --force: Overwrite existing config file-m, --merge: Merge missing defaults into existing config (default behavior)--no-merge: Error if config already exists-j, --json: Output in JSON format
Examples:
# Create project config in current directory
pando config init
# Create user-level (global) config
pando config init --global
# Create config at git repository root
pando config init --git-root
# Overwrite existing config
pando config init --force
# Add missing defaults to existing config
pando config init --mergeDisplay the current effective configuration with source information.
Flags:
-j, --json: Output in JSON format
Examples:
# Show current config with sources
pando config show
# JSON output for scripts
pando config show --jsonPando discovers configuration from multiple locations:
| Location | File | Use Case |
|---|---|---|
| Current directory | .pando.toml |
Project-specific settings |
| Git root | .pando.toml |
Repository-wide defaults |
| Project files | pyproject.toml, package.json, etc. |
Embedded in existing config |
| User home | ~/.config/pando/config.toml |
User-level defaults |
Settings are merged with the following priority (highest to lowest):
- CLI flags - Always win (e.g.,
--path,--no-rebase) - Environment variables -
PANDO_*prefixed variables - Project
.pando.toml- In current directory or parent directories - Project files -
pyproject.toml[tool.pando],package.json"pando", etc. - Global config -
~/.config/pando/config.toml - Built-in defaults - Sensible defaults for all options
Project config (.pando.toml in repo):
- Shared with team via version control
- Project-specific worktree paths and patterns
- Checked into git
User config (~/.config/pando/config.toml):
- Personal preferences across all projects
- Default behaviors you always want
- Not shared with team
# Create user-level config
pando config init --globalPando uses TOML format for configuration:
# Rsync Configuration
[rsync]
enabled = true
flags = ["--archive"] # .git is always excluded automatically (do not add it here)
exclude = ["dist/", "node_modules/"]
onlyUntracked = true # Sync only gitignored artifacts (default). false = mirror the
# full tree, but only when source/target share the same commit.
# Symlink Configuration
[symlink]
patterns = ["package.json", ".env*"]
relative = true
beforeRsync = true
allowTracked = true # Symlink git-tracked paths, hidden via skip-worktree (default).
# false = strict mode: skip tracked patterns with a warning.
# Worktree Configuration
[worktree]
defaultPath = "../worktrees" # Default parent directory for worktrees
rebaseOnAdd = true # Rebase existing branches when adding worktree
deleteBranchOnRemove = "local" # Delete branch on worktree remove: "none", "local", "remote" (default: "local")
useProjectSubfolder = false # Nest worktrees as defaultPath/projectName/branchName (default: false)
targetBranch = "main" # Target branch for merge checks (used by clean command)
defaultKind = "auto" # auto, ephemeral, or long-lived
ephemeralTtl = "4h" # Default TTL exposed to ephemeral setup hooks
autoLockActive = true # Git-lock worktrees owned by active sessions
# Optional per-worktree resources
[ports]
enabled = false # Or opt in for one add with --ports
range = "3100-3199"
names = ["web"]
dbStrategy = "named"
dbBaseName = "dev" # Prefix for a name derived from each worktree's own branch
# Clean Configuration
[clean]
fetch = false # Run git fetch --prune before detection
# Post-command scripts
# Runs after a command succeeds. For pando add, scripts run from the created worktree.
[postCommands]
add = ["pnpm install"] # Optional setup commands after pando add succeedspostCommands lets you configure shell commands to run after Pando completes a command successfully. The first supported hook is add:
[postCommands]
add = ["pnpm install", "pnpm run prepare"]Scripts configured for add run after the worktree has been created and rsync/symlink setup has finished. They execute from the created worktree directory and receive useful context through environment variables:
PANDO_COMMAND— command id, such asaddPANDO_WORKTREE_PATH— absolute path to the created worktreePANDO_BRANCH— branch name, or empty in detached HEAD modePANDO_COMMIT— created worktree commitPANDO_KIND— resolved lifecycle kind (ephemeralorlong-lived)PANDO_TTL— effective TTL when defined (explicit--ttl, otherwise the ephemeral default)PANDO_PORT_<NAME>— each assigned port; service names are uppercased and hyphens become underscores (for example,web-apibecomesPANDO_PORT_WEB_API)PANDO_DB_NAME— the derived database name when port allocation is enabled
Human-readable output shows each script, its working directory, exit status, stdout, and stderr. JSON output includes a stable postCommands array with name, command, cwd, exitCode, signal, stdout, stderr, success, and duration fields. A non-zero exit code stops later scripts and returns the existing JSON error shape with success: false, error, postCommands, and failedPostCommand.
Post-commands defined in a config file run with a shell, so a .pando.toml
committed in a repository you just cloned could otherwise execute arbitrary
commands the first time you run pando add. To prevent that, Pando uses a
direnv-style trust gate: the post-commands in a config file only run once you
have explicitly trusted that exact file.
How it works:
- One-time prompt. The first time a config file would run post-commands, Pando lists them and asks whether to trust the file. If you decline, the scripts are skipped.
- Content-hash pinning. Trust is recorded against the file's SHA-256 content
hash and stored at
$XDG_CONFIG_HOME/pando/trusted-configs.json(falling back to~/.config/pando/trusted-configs.json). The store is written with0o600permissions. - Re-prompt on change. Editing the config file changes its hash and invalidates the trust, so you are prompted again.
- Non-interactive /
--jsonruns skip. When there is no interactive TTY, or when--jsonoutput is requested, untrusted post-commands are not run; a warning explains how to trust them. - CI escape hatch. Set
PANDO_TRUST_CONFIG=1(ortrue) to run post-commands without prompting — intended for CI and automation. - Environment-only post-commands (configured purely via
PANDO_*variables, with no file on disk) are implicitly trusted and always run.
Instead of a separate .pando.toml, you can embed configuration in existing project files:
pyproject.toml (Python projects):
[tool.pando]
[tool.pando.worktree]
defaultPath = "../worktrees"package.json (Node.js projects):
{
"pando": {
"worktree": {
"defaultPath": "../worktrees"
}
}
}Cargo.toml (Rust projects):
[package.metadata.pando]
[package.metadata.pando.worktree]
defaultPath = "../worktrees"The worktree.defaultPath setting allows you to specify a default parent directory for worktrees:
- Relative paths are resolved from the git repository root
- Absolute paths are used as-is
- When creating a worktree with
--branchbut no--path, the branch name is appended to the default path - Branch name sanitization: Forward slashes (
/) in branch names are automatically converted to underscores (_) for filesystem safety
Example:
[worktree]
defaultPath = "../worktrees"# Creates worktree at ../worktrees/feature-x (relative to git root)
pando add --branch feature-x
# Branch names with slashes are sanitized
pando add --branch feature/auth
# Creates: ../worktrees/feature_authAll configuration options can be set via environment variables using the PANDO_ prefix:
# Set default worktree path
export PANDO_WORKTREE_DEFAULT_PATH="../worktrees"
# Disable automatic rebase on existing branches
export PANDO_WORKTREE_REBASE_ON_ADD=false
# Delete local branch when removing worktree
export PANDO_WORKTREE_DELETE_BRANCH_ON_REMOVE=local
# Set target branch for merge checks (clean command)
export PANDO_WORKTREE_TARGET_BRANCH=main
# Always fetch before detecting stale worktrees
export PANDO_CLEAN_FETCH=true
# Now you can omit --path
pando add --branch feature-xEnvironment variable format:
- Prefix:
PANDO_ - Pattern:
PANDO_SECTION_KEY - Example:
PANDO_WORKTREE_DEFAULT_PATH→worktree.defaultPath
Environment variables override file-based configuration but are overridden by explicit command-line flags.
Supported variables:
| Variable | Config path | Type |
|---|---|---|
PANDO_RSYNC_ENABLED |
rsync.enabled |
boolean |
PANDO_RSYNC_FLAGS |
rsync.flags |
array |
PANDO_RSYNC_EXCLUDE |
rsync.exclude |
array |
PANDO_RSYNC_ONLY_UNTRACKED |
rsync.onlyUntracked |
boolean |
PANDO_SYMLINK_PATTERNS |
symlink.patterns |
array |
PANDO_SYMLINK_RELATIVE |
symlink.relative |
boolean |
PANDO_SYMLINK_BEFORE_RSYNC |
symlink.beforeRsync |
boolean |
PANDO_SYMLINK_ALLOW_TRACKED |
symlink.allowTracked |
boolean |
PANDO_WORKTREE_DEFAULT_PATH |
worktree.defaultPath |
string |
PANDO_WORKTREE_REBASE_ON_ADD |
worktree.rebaseOnAdd |
boolean |
PANDO_WORKTREE_DELETE_BRANCH_ON_REMOVE |
worktree.deleteBranchOnRemove |
string |
PANDO_WORKTREE_USE_PROJECT_SUBFOLDER |
worktree.useProjectSubfolder |
boolean |
PANDO_WORKTREE_TARGET_BRANCH |
worktree.targetBranch |
string |
PANDO_CLEAN_FETCH |
clean.fetch |
boolean |
- Booleans accept
true/false,1/0, oryes/no(case-insensitive). - Arrays are comma-separated, e.g.
PANDO_RSYNC_EXCLUDE=*.log,tmp/.
PANDO_TRUST_CONFIG is a separate, non-config escape hatch for the
post-command trust gate — set it to 1 or true to run
post-commands from config files non-interactively (e.g. in CI). It is not part
of the merged configuration.
All commands support the --json flag for machine-readable output:
# Use in scripts
worktrees=$(pando list --json)
# Parse with jq
pando list --json | jq '.[] | select(.branch == "feature-x")'pnpm install # Install dependencies
pnpm dev list # Run the CLI from source (no rebuild)
pnpm validate # Format check, lint, typecheck, and testsSee CONTRIBUTING.md for the full development workflow.
pando/
├── src/
│ ├── commands/ # Command implementations
│ ├── utils/ # Shared utilities
│ └── index.ts # Main entry point
├── test/ # Tests
├── bin/ # Executable scripts
└── dist/ # Compiled output
- Node.js >= 20.0.0 (development targets Node 20, pinned in
.node-version) - Git >= 2.5.0 (for worktree support)
Pando uses clean error messages for expected errors (like "file already exists" or "not a git repository"). You should not see stack traces for these errors.
If you see a stack trace for a validation error, this indicates a bug - please report it!
Common error types:
- Validation Errors: Clean error messages without stack traces (use
--force, missing files, invalid arguments) - Operation Errors: Runtime failures with context (network errors, permission issues, git command failures)
- Internal Errors: Stack traces indicating bugs that should be reported
All commands support --json flag for machine-readable output:
# Merge missing defaults into existing config
pando config init --json
# Output: {"status":"success","action":"merged","added":[...],"addedCount":2}
# Check exit codes in scripts
pando add --path ../feature --branch feature --json
if [ $? -ne 0 ]; then
echo "Command failed"
fiFor detailed debugging, run commands with Node.js debug environment:
# Enable debug output
NODE_DEBUG=pando pnpm dev list
# Or with node inspector
node --inspect bin/dev.js list"Not a git repository"
- Make sure you're running pando from within a git repository
- Check
git statusworks in your current directory
"Worktree path already exists"
- The target path already has a directory/file
- Use a different path or remove the existing path first
"Worktree has uncommitted changes"
- The worktree you're trying to remove has uncommitted changes
- Commit or stash changes first, or use
--forceto remove anyway (WARNING: will lose changes)
"rsync is not installed"
- Install rsync for file syncing features
- macOS:
brew install rsync - Ubuntu/Debian:
apt install rsync - Or use
--skip-rsyncto disable file syncing
Contributions are welcome! See CONTRIBUTING.md for setup, the development loop, quality gates, and PR expectations. For the project structure and design rationale, read ARCHITECTURE.md and DESIGN.md.
MIT © zpyoung
Pando is a clonal colony of aspen trees that shares a single root system - much like how git worktrees share a single repository!