How the Superpowers skill detects an existing Git worktree

The Superpowers using-git-worktrees skill checks for an existing linked worktree before asking Claude Code to create another checkout. Otherwise, edits could land outside the checkout where the session started.

The check compares Git’s checkout-specific and shared metadata directories. It also checks whether a parent repository tracks the current path as a submodule. A checkout can satisfy both tests, and the submodule check takes precedence. Superpowers v7.0.2, Step 0

How Claude Code gets the instructions

With the Superpowers plugin enabled, Claude Code discovers the skill at skills/using-git-worktrees/SKILL.md under the plugin root. The YAML frontmatter at the top has two fields. The name is using-git-worktrees. The description points Claude toward feature work that needs isolation and toward executing implementation plans. Claude Code makes the description available before loading the body. To load the instructions directly, start a message with /superpowers:using-git-worktrees. Skill frontmatter, Claude Code skill locations, skill invocation

Superpowers also registers a SessionStart hook. Its wrapper launches a script that reads the separate using-superpowers skill and returns it as extra session context. That introduction directs Claude to use its skill tool for other Superpowers skills. The worktree probe is an ordinary code block in the worktree skill’s body. Once the body is loaded, Claude has to choose to run those Git commands through its shell tool. Hook registration, startup script, Step 0 commands

What the Git commands tell the agent

A linked worktree is an extra checkout of the same repository. Its HEAD and index live in a private directory under the repository’s .git/worktrees/, while objects and most refs are shared. git rev-parse --git-dir gives the agent the private directory and git rev-parse --git-common-dir gives it the shared one. The skill resolves both to physical paths before comparing them. In a main checkout the two paths usually resolve to the same .git directory. Git worktree internals, git rev-parse options

A submodule is a separate repository tracked at a path inside a parent repository, called the superproject. A typical submodule checkout has a .git file pointing into the superproject’s .git/modules/. A linked worktree also has a .git file. The skill checks for a submodule with git rev-parse --show-superproject-working-tree, which prints the parent path when Git recognizes the checkout as a submodule. Git submodule layout, git rev-parse options

Git’s output in four checkouts

This Bash example uses Git to create two temporary repositories and a local submodule clone. The final case replaces the usual submodule checkout with a linked worktree of the same source repository at the same commit.

(
  set -eu
  demo=$(mktemp -d)
  trap 'rm -rf -- "$demo"' EXIT
  cd "$demo"

  git init -q -b main library
  git -C library -c user.name=Demo -c user.email=[email protected] \
    commit -qm initial --allow-empty

  git init -q -b main app
  git -C app -c protocol.file.allow=always submodule add -q ../library vendor/library
  git -C app -c user.name=Demo -c user.email=[email protected] \
    commit -qm 'Track the library'
  git -C app worktree add -qb feature ../app-feature

  probe() (
    cd "$1"
    private_dir=$(cd "$(git rev-parse --git-dir)" && pwd -P)
    common_dir=$(cd "$(git rev-parse --git-common-dir)" && pwd -P)
    superproject=$(git rev-parse --show-superproject-working-tree)

    directories=same
    if [ "$private_dir" != "$common_dir" ]; then
      directories=different
    fi
    printf '%s | %s | %s\n' "$2" "$directories" "${superproject:+app}"
  )

  probe app 'Main checkout'
  probe app-feature 'Linked worktree'
  probe app/vendor/library 'Submodule'

  git -C app submodule deinit -q -- vendor/library
  git -C library worktree add -q --detach ../app/vendor/library
  probe app/vendor/library 'Linked worktree at submodule path'
)

With Git 2.50.1 (Apple Git-155), this printed the following. The probe abbreviates the superproject’s absolute path to app.

Main checkout | same |
Linked worktree | different |
Submodule | same | app
Linked worktree at submodule path | different | app

In the ordinary submodule, both directories resolve to the same .git/modules/vendor/library directory under app. In the final case, they resolve to two different locations under library/.git. Git still reports app as the superproject because app’s index records vendor/library as a submodule. Git 2.50.1 checks the parent repository’s index for an entry with mode 160000, the mode Git uses for submodule entries. Git 2.50.1 implementation

What the skill does with the result

Superpowers skips worktree creation when the paths differ and Git prints no superproject path. In the ordinary linked worktree above, the skill tells Claude to stay put and proceed to project setup and baseline tests. In the fourth case, Git sees both a linked worktree and a submodule. The skill’s submodule rule takes precedence, so its instructions send Claude through the same worktree-preference decision it uses for the main checkout. These are outcomes from reading the skill’s instructions against the Git output. The experiment runs Git in Bash. Step 0 and baseline instructions, setup and tests

If the user wants a new worktree, the skill prefers the host’s native tool when available. In Claude Code, EnterWorktree can create a checkout and move the session into it. If the tool is unavailable, the skill supplies a git worktree add fallback and tells the agent to report a sandbox denial and work in place if Git cannot create it. Claude Code controls tool availability and permissions. For example, the permissions.blockWritesOutsideWorkingDirectories setting can remove EnterWorktree or cause the host to refuse a call. Superpowers creation and fallback instructions, Claude Code tool reference

A read-only check makes sense before a skill changes the session directory. The fourth case is useful as a test fixture because it exercises the submodule rule when the Git directories differ.

To check the contents of a proposed commit, see How to test staged Git changes without stashing.