Skip to content

worktree: the info/exclude line for a WORKTREE_SYMLINKS entry is unanchored and hides nested directories of the same name #4925

Closed

Description

@bmethod

Outcome: a WORKTREE_SYMLINKS entry's info/exclude line ignores only the link at the repository root, so a tracked nested directory of the same name keeps showing new files in git status and git add -A stages them.

Location: skills/worktree/scripts/lib/links.sh (exclude_from_worktree_index, the one writer of the entry and its negation), skills/worktree/scripts/lib/help.sh (fix-links --help section "info/exclude entries"), skills/worktree/tests/, changelog.d/worktree/. One subsystem: the worktree skill.

Done when

  • Each entry line is anchored to the repository root (/NAME, and the negation !/NAME/); a test shows a new file under a tracked nested x/NAME/ is not ignored while the root link still is.
  • worktree fix-links --help names the anchored form.

Scope cut (overseer ruling on ask 1791906275, PR #4976): migrating bare lines an earlier version wrote moved to KEN-4001; this item anchors every line it writes.

Defect

For each WORKTREE_SYMLINKS entry, worktree setup writes an ignore line into the common git directory's info/exclude (worktree fix-links --help, section "info/exclude entries"). The line is the bare entry name, with no leading slash. A gitignore pattern with no slash matches at every depth, so the line also ignores every nested directory of the same name.

Reproduction

A repository that sets WORKTREE_SYMLINKS = ".env.local .agents .claude" and tracks a nested directory agents/.agents/ (a GNU stow package whose payload is .agents).

After one worktree create, info/exclude holds:

.agents
.claude
.claude/agents
.claude/hooks
.claude/settings.json
.claude/settings.local.json
.claude/skills
!.claude/

Then:

$ git check-ignore -v --no-index agents/.agents/skills/new-skill/SKILL.md
.git/info/exclude:21:.agents	agents/.agents/skills/new-skill/SKILL.md

Effect

A new file under the tracked directory agents/.agents/ does not show in git status, and git add -A skips it. The commit and push land without the file. Edits to files that are already tracked are not affected.

The .claude entry does not hide nested paths in this repository, because !.claude/ follows it: git check-ignore reports no match from info/exclude for new paths under claude/.claude/ or agents/.claude/. The child lines such as .claude/hooks have a middle slash, so git anchors them to the repository root.

Expected

The entry line is anchored to the repository root: /.agents, /.claude. A WORKTREE_SYMLINKS entry is a path relative to the worktree root, so the anchored form matches the same link and no nested directory.

Workaround in the consumer

!/agents/.agents/ in the tracked root .gitignore. A tracked .gitignore outranks info/exclude.

Activity

  1. added
    skillsskills/, agents/, skill-templates/, and base agent instructions
    on Oct 13, 2026
  2. linear-code commented on Oct 13, 2026

    @linear-code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:runtimeskillsskills/, agents/, skill-templates/, and base agent instructions

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions