@j4k-oss/worktree-add (2.2.0)

Published 2026-10-23 08:46:45 +00:00 by oss-publisher in j4k-oss/worktree-add

Installation

@j4k-oss:registry=
npm config set @j4k-oss:registry=
npm install @j4k-oss/worktree-add@2.2.0
"@j4k-oss/worktree-add": "2.2.0"

About this package

worktree-add

Source: https://code.j4k.dev/j4k-oss/worktree-add. github.com/Jercik/worktree-add is a read-only mirror; open issues and pull requests on the Forge.

Create a Git worktree next to your current repo for a branch, copy useful local files, install deps, and open it in your apps.

What it does

Running worktree-add <branch> from inside a repo:

  1. Normalizes <branch> (supports origin/foo, refs/heads/foo, etc.).
  2. Refuses if that branch is already checked out in any worktree.
  3. Picks a destination next to your current repo: ../<repo>-<safe-branch>.
    • If the current checkout is a submodule inside a parent repo, it places the new worktree outside the parent repo so it does not show up as an untracked directory there.
  4. If the destination exists, pass --interactive to be prompted for confirmation, or --yes to move it to the system trash without prompting. Without either flag, the command exits.
  5. Fetches origin/<branch> and refreshes your local branch when safe:
    • fast-forwards the local branch if it’s strictly behind origin/<branch>
    • warns and keeps the local branch as-is if it’s ahead
    • exits with recovery steps if local and remote have diverged
  6. Creates a git worktree:
    • reuses an existing local branch
    • or creates a tracking branch from origin/<branch>
    • or creates a new branch from the current HEAD (only when the branch does not exist on origin/, or when you pass --offline and origin/ can’t be reached)
    • before creating a new branch from HEAD, it checks the branch you are on against origin/ and exits if that branch is behind, so new work doesn't start from outdated code. Update the branch and retry, or pass --allow-stale to create the branch anyway. A detached HEAD and a branch that doesn't exist on origin/ are not checked. The check runs before an existing destination is moved to the trash, so a refusal leaves that directory in place.
  7. Copies untracked / ignored files into the new worktree, skipping heavy stuff (node_modules, dist, .next, caches, virtualenvs, etc.).
    • It also skips any directory that has its own .git (a nested clone or linked worktree, such as third-party sources under an ignored directory), so a worktree doesn't carry full copies of other repositories. Each skipped directory is named on stderr, for example Skipping sources/codex (nested git repository).
  8. Detects your package manager and installs dependencies with lockfile‑safe flags (npm ci, pnpm install --frozen-lockfile, yarn install --immutable, etc.).
  9. If the project uses Next.js and supports it, runs next typegen.
  10. Opens the new worktree if you passed --app or --open.

Pass --no-setup to skip dependency installation and Next.js type generation, including their detection. Branch creation, local file copying and app opening still run; ordinary Git hooks still apply. Run any needed setup yourself afterward.

Your original checkout is left untouched.

If a later step fails or you interrupt the run, the tool removes the new worktree. Once the worktree is removed, it also deletes the branch if this run created it (from HEAD or from origin/<branch>) and the branch still points at the commit it was created at. Its branch.<branch>.* config goes back to what it was before the run: the tracking settings the run added are removed, and any values you had set are kept. A branch that existed before the run, gained commits, or is checked out in another worktree is kept.

Requirements

  • Node.js ≥ 24.15.0
  • Git with git worktree support
  • Git 2.42 or newer to create a worktree in a repository with no commits yet. Older versions exit with an error that names the requirement.
  • A package manager when package.json is present, unless you pass --no-setup
  • Git credentials configured for origin/ (the tool is non-interactive and won’t prompt for authentication)

Install / run

Releases publish only as @j4k-oss/worktree-add on the code.j4k.dev registry, which reads anonymously. The unscoped worktree-add package on npmjs.org is deprecated and gets no updates.

A command that doesn't map the scope to code.j4k.dev looks on npmjs.org, finds nothing, and fails with a 404. Map it once in ~/.npmrc:

@j4k-oss:registry=https://code.j4k.dev/api/packages/j4k-oss/npm/

You usually don’t need a global install. The inline registry flag is enough for a single npx run. Keep the ~/.npmrc line for global installs: without it, npm update -g and npm outdated -g look the scoped name up on npmjs.org.

If you installed the unscoped package globally, remove it first (npm uninstall -g worktree-add or pnpm remove -g worktree-add). Both packages provide the worktree-add command: npm stops with EEXIST, and pnpm keeps running the old copy.

# inside /my/path/my-app
# one‑off
npx -y --@j4k-oss:registry=https://code.j4k.dev/api/packages/j4k-oss/npm/ @j4k-oss/worktree-add@latest feature/my-branch

# or install globally
npm install -g --@j4k-oss:registry=https://code.j4k.dev/api/packages/j4k-oss/npm/ @j4k-oss/worktree-add
worktree-add feature/my-branch

pnpm rejects the inline flag, so a global pnpm install relies on the ~/.npmrc line above:

pnpm add -g @j4k-oss/worktree-add

To add it to a pnpm project instead, map the scope and exempt it from minimumReleaseAge in pnpm-workspace.yaml, then add the package:

registries:
  "@j4k-oss": https://code.j4k.dev/api/packages/j4k-oss/npm/
minimumReleaseAgeExclude:
  - "@j4k-oss/*"
pnpm add -D @j4k-oss/worktree-add

After a project-local install, run the examples with pnpm exec worktree-add in place of worktree-add. Global installs expose worktree-add directly.

Run it from anywhere inside an existing worktree of the repo.

Usage

# inside /my/path/my-app
worktree-add <branch> [options]

Run this inside an existing worktree of your project—the tool discovers the repo root from your current directory and creates the sibling worktree next to it. If that checkout is a submodule inside a parent repo, the new worktree is created outside the parent repo instead.

Example:

# inside /my/path/my-app
# reuses a local branch, tracks origin/<branch> if it exists, otherwise creates a new branch from current HEAD
worktree-add feature/login-form

Common options:

  -a, --app <name>   Open the worktree in an app (repeatable)
  -o, --open         Open the worktree after creating it
  --offline          Create from HEAD when origin can't be reached
  --allow-stale      Create from HEAD even when the current branch is behind origin
  --no-setup         Skip dependency installation and Next.js type generation
  -y, --yes          Skip confirmation and replace existing destination
  --interactive      Allow confirmation prompts (requires a TTY)
  --dry-run          Show what would happen without making changes
  --verbose          Show progress messages on stderr

A new branch from the current HEAD is created only when the branch does not already exist locally or on origin/. If origin/ can’t be reached and the branch doesn’t exist locally, the tool aborts unless you pass --offline.

Destination directory (assuming repo named my-app):

/my/path/my-app                     # current checkout
/my/path/my-app-feature-login-form  # new worktree for branch "feature/login-form"

Pipeline examples

# create a worktree for the newest local branch
git for-each-ref --sort=-committerdate --format="%(refname:short)" refs/heads \
  | head -n1 \
  | xargs worktree-add

# create a worktree for the first feature branch
git branch --format="%(refname:short)" \
  | grep '^feature/' \
  | head -n1 \
  | xargs worktree-add

App control

After creating the worktree, the tool can open it in one or more apps. Nothing is opened by default. App names are executed on your machine, so only use values you trust. Validation is a UX guardrail (not a security boundary): it only blocks control characters to prevent common mistakes, while other punctuation is allowed because open uses platform launchers (macOS open, Windows PowerShell) and makes no security guarantees. Arguments are not parsed: values like code -w are treated as part of the app name and will likely fail.

  1. --app <name> flag (repeatable): worktree-add feature/foo --app ghostty --app code
  2. -o, --open: worktree-add feature/foo --open
  3. WORKTREE_ADD_APP env var (comma-separated): the app list used by --open

--app takes priority over --open / WORKTREE_ADD_APP. WORKTREE_ADD_APP does not open anything on its own; pass --open to use it. If --open is set and no apps are configured, the destination is opened with the OS default handler. To explicitly open nothing even when --open is set, pass --app "". Whitespace-only values like --app " " are treated as absent and do not override WORKTREE_ADD_APP.

If launching an app fails to start, the worktree remains created.

Platform note: on macOS the app value is passed to open -a, so use an application name like Visual Studio Code (or an .app path). On Linux/Windows it’s typically treated as an executable name/path.

Terminal-based editors (vim/nvim/nano) are not supported via --app — apps are launched detached from the current terminal.

Tip: set default apps for --open in your shell profile, then pass -o when you want them. In bash or zsh:

worktree-add() { WORKTREE_ADD_APP=ghostty,code command worktree-add "$@"; }
# worktree-add feature/foo     # create only
# worktree-add feature/foo -o  # create and open in Ghostty + VS Code

Add it to your shell profile:

  • zsh: ~/.zshrc or ~/.zprofile
  • bash: ~/.bashrc or ~/.bash_profile

In fish, that syntax is a parse error. Add this function to ~/.config/fish/config.fish instead:

function worktree-add
    env WORKTREE_ADD_APP=ghostty,code worktree-add $argv
end

Agent rule

If you are an automated agent, read and follow AGENTS.md (and CLAUDE.md if present) at the repo root before making changes.

License

MIT

Dependencies

Dependencies

ID Version
@commander-js/extra-typings ^15.0.0
commander ^15.0.0
open ^11.0.0
package-manager-detector ^1.6.0
trash ^10.1.1

Development dependencies

ID Version
@j4k-oss/fta-check ^1.5.11
@j4k/oxlint-config ^2.14.2
@j4k/semantic-release-forgejo ^1.2.4
@total-typescript/ts-reset ^0.6.1
@types/node ^24.0.0
@vitest/coverage-v8 ^4.1.8
conventional-changelog-conventionalcommits ^9.3.1
fta-cli ^3.0.0
knip ^6.16.1
oxfmt ^0.57.0
oxlint ^1.86.0
oxlint-tsgolint ^7.0.2003
semantic-release ^25.0.5
typescript ^7.0.2
vitest ^4.1.8

Keywords

cli development git git-worktree workflow worktree
Details
npm
2026-10-23 08:46:45 +00:00
7
2026-11-04 16:21:48 +00:00
Łukasz Jerciński
MIT
41 KiB
Assets (1)
Versions (5) View all
2.3.2 2026-11-03
2.3.1 2026-10-28
2.3.0 2026-10-24
2.2.0 2026-10-23
2.1.1 2026-10-21