cow create [OPTIONS] [NAME]

Create a new cow pasture (copy-on-write workspace) from a repository using APFS. Names are automatically scoped by source repository: feature-x becomes brightblur/feature-x. Omit the name and cow auto-generates brightblur/agent-1, brightblur/agent-2, and so on. Supply an explicit scope/name to override the default scope.

OptionDescription
--source <PATH>Source repository to clone (default: current directory)
--branch <BRANCH>Override the branch name (default: same as pasture name)
--no-branchDo not switch or create a branch after cloning
--change <CHANGE>jj change ID to edit in the new pasture (jj repos only)
--from <REV>jj revision to branch from — creates a new change on top rather than editing directly (jj repos only)
-m, --message <MSG>Set the initial jj change description immediately after creation (jj repos only)
--dir <PATH>Parent directory for pastures (default: ~/.cow/pastures/)
--worktreeCreate a git linked worktree instead of an APFS clone. All worktree pastures share the same .git/objects/ pack store — cross-pasture rebase works without any remote (git only)
--no-symlinkSkip large-directory detection and always perform a full clone
--no-cleanSkip post-clone cleanup of runtime artefacts (.pid, .sock, etc.)
--print-pathPrint only the pasture path on stdout after creation, suppressing all other output — useful for scripting and automation
Uses clonefile(2) directly — the same kernel syscall Time Machine uses. A 2 GB repository clones in around 130 ms wall time, with near-zero extra disk until files are modified.

cow list [OPTIONS]

List all active pastures managed by cow. Names are shown in source/pasture form. The branch column is omitted when the branch matches the pasture name. Status shows dirty (N) with a file count.

OptionDescription
--source <PATH>Filter to pastures created from this source repository
--jsonMachine-readable JSON output for scripting and MCP tools

cow status [NAME]

Show detailed status of a pasture, including its path, source repository, branch, dirty/clean state, and a short diff summary. Defaults to the current directory if it is a cow pasture.

cow diff [NAME]

Show uncommitted changes in a pasture relative to its last commit. Passes through to git diff or jj diff as appropriate. Defaults to the current directory if inside a pasture.

cow extract [OPTIONS] <NAME>

Extract committed changes from a pasture back into the source repository. Use --patch to produce a patch file for review, or --branch to land the branch directly in the source repo so you can push a PR normally.

OptionDescription
--patch <FILE>Write a unified diff patch to this file
--branch <NAME>Create (or update) this branch in the source repo at pasture HEAD
Direction: cow extract goes from pasture to source. cow sync goes the other way.

cow remove [OPTIONS] <NAME...>

Remove one or more pastures. Warns before removing pastures with uncommitted changes, and offers to push unpushed commits first. Pass multiple names to remove several pastures at once.

OptionDescription
--forceSkip dirty-state warnings and remove without prompting
-y, --yesSkip confirmation prompts without implying a safety override — dirty warnings are still shown
--allRemove all pastures (can be scoped with --source)
--source <PATH>Scope --all to pastures from this source repository

cow sync [SOURCE_BRANCH]

Fetch the latest commits from the source repository and rebase (or merge) the pasture onto them. Defaults to syncing with the pasture's own branch; pass a branch name to sync against a different one (e.g. cow sync main).

OptionDescription
--mergeMerge instead of rebase
--name <NAME>Target a named pasture instead of auto-detecting from the current directory
Not yet supported for jj pastures.

cow migrate [OPTIONS]

Discover existing git linked worktrees, jj secondary workspaces, and orphaned cow directories for a source repository and migrate each one into a proper cow-managed APFS clone pasture. Without --all, lists candidates and exits — nothing is modified.

OptionDescription
--source <PATH>Source repository to scan (default: current directory)
--allMigrate all discovered candidates without prompting
--forceMigrate dirty candidates (those with uncommitted changes)
--dry-runPrint what would happen without making any changes

cow run <NAME> <CMD> [ARGS...]

Run a command inside a pasture's working directory. Automatically detects the package manager from lockfiles (pnpm-lock.yaml, yarn.lock, bun.lockb/bun.lock, package-lock.json) and injects shims so install subcommands write to the pasture-local node_modules rather than the shared source. All other subcommands pass through unchanged.

Three environment variables are always set for the subprocess:
COW_PASTURE — pasture name
COW_SOURCE — absolute path to the source repository
COW_PASTURE_PATH — absolute path to the pasture directory

cow materialise <NAME>

Replace symlinked dependency directories in a pasture with real APFS clonefiles. After materialisation the pasture is fully independent — packages can be added, removed, or upgraded without affecting the source or any other pasture.

Large dep dirs (node_modules, vendor, .venv, Pods, etc.) are symlinked per-package at create time to keep clone overhead near zero. Run cow materialise when you need full isolation for package management.

cow fetch-from <FROM> [OPTIONS]

Fetch all refs from another pasture into this one, enabling cross-pasture rebase without touching any remote. Useful for rebasing one agent's work on top of another's.

OptionDescription
--name <NAME>Pasture to fetch into (default: current directory)
--forceAllow fetching from a pasture with a different source repository

cow recreate <NAME> [OPTIONS]

Remove a pasture and immediately re-create it from the same source. Useful for getting a clean slate without having to remember the original source path.

OptionDescription
--branch <BRANCH>Override the branch checked out in the fresh clone
--no-branchDo not switch or create a branch (stay on source's current branch)

cow cd <NAME>

Print the absolute path of a named pasture. Designed for shell integration rather than direct use.

Run cow install to set up shell integration automatically (zsh and bash supported). This adds cowcd and tab completion to your shell config.

Then use cowcd brightblur/feature-x to jump straight into a pasture. Tab completion requires jq.

A shell function is required because a subprocess cannot change the working directory of its parent shell — this is a fundamental Unix constraint, and the same reason tools like z and fzf also require shell functions for directory jumping.

cow path <NAME>

Print the absolute path of a named pasture. Identical to cow cd — provided as an alias for scripting contexts where the intent is clearer as "print path" rather than "cd".

cow install

Install the cowcd shell function and tab completion into your shell config (~/.zshrc for zsh, ~/.bashrc for bash). Idempotent — safe to run multiple times. Detects your shell from $SHELL.

cow mcp

Run cow as a Model Context Protocol stdio server, exposing all cow commands as MCP tools so agents can manage pastures without any human intervention: cow_create, cow_list, cow_remove, cow_status, cow_sync, cow_extract, cow_migrate, cow_materialise, cow_fetch_from, and cow_run.

Configure in ~/.claude.json (global) or a project-local .mcp.json. See the MCP section on the homepage for the config snippet.

cow gc [OPTIONS]

Remove pastures whose branches have been pushed or merged to origin. Checks cached remote-tracking refs by default — no network call needed. Use --merged for a stricter check (only removes branches that are fully merged into the default branch).

OptionDescription
--mergedOnly remove pastures whose branch is merged into the default branch on origin
--fetchFetch from origin first (updates remote-tracking refs before checking)
--dry-runShow what would be removed without removing anything
-y, --yesSkip confirmation prompts
--forceSkip dirty-state warnings and remove immediately

cow stats

Show estimated disk savings across all pastures. Groups pastures by source repository and compares the total disk usage of each source against the incremental delta of its pastures — the difference is what cow saves versus a traditional clone. Estimates are shown for both npm-style and pnpm-style node_modules layouts.

.cow.json — project config

Add a .cow.json to the root of your repository to define project-specific post-clone behaviour. Runs automatically after every cow create.

{ "post_clone": { // Paths to remove (glob patterns ok) "remove": [".next/server", "*.pid", "*.sock"], // Commands to run inside the new pasture "run": ["npm run codegen"] } }

Herd — menubar companion

Herd is a native macOS menubar app that gives you a live view of all your pastures without opening a terminal. Pastures are grouped by project, with hover actions to open in Finder, open in Terminal, sync from source, or remove. A stats strip at the bottom shows real-time disk savings.

ActionWhat it does
Open in FinderReveals the pasture directory in Finder
Open in TerminalOpens a Terminal window at the pasture path
SyncRuns cow sync for that pasture in the background
RemoveConfirms then runs cow remove, deleting the pasture
Install
brew install joeinnes/tap/cow-herd

Then copy the app to your Applications folder:
cp -r $(brew --prefix)/opt/cow-herd/Herd.app /Applications/

Herd is unsigned. On first launch, right-click Herd.app and choose Open, then click Open in the Gatekeeper prompt. Subsequent launches work normally.

Herd requires the cow CLI to be installed and on your PATH.