[BUG] Desktop: staged worktree checkout runs before .gitattributes is in the index, so .claude/** and CLAUDE.md get CRLF on Windows (core.autocrlf=true)

Status Fixed / completed
Maintainer reply None cached
Activity 1 comment · opened Sep 2, 2026 · closed Sep 4, 2026

Summary

On Windows with core.autocrlf=true (the Git for Windows installer default, set in the system gitconfig), worktrees created by Claude Desktop for a spawned session end up with CRLF line endings in .claude/** and CLAUDE.md only, while the rest of the tree is LF as .gitattributes requires. Worktrees created by the CLI (EnterWorktree, Agent with isolation: "worktree") are LF throughout.

Symptom for the user: prettier --check . (with endOfLine: lf) fails on .claude/launch.json in a fresh worktree that nobody has touched, while git status reports the tree clean (autocrlf makes CRLF match the LF blob on read).

Root cause

Desktop's createWorktree uses a staged checkout so the CLI can spawn early:

  1. git worktree add --no-checkout … — the new worktree's index is empty.
  2. stageCheckout: git -c core.longpaths=true checkout HEAD -- <fixed path list> (this list includes .claude/** and CLAUDE.md; the later full checkout uses :(exclude).claude).
  3. Background full checkout: checkout HEAD -- . :(exclude).claude.

During step 2 the index is empty, so git cannot read .gitattributes for the checkout (it reads attributes from the index when checking out). With no attributes, core.autocrlf=true applies and those files are written with CRLF. Step 3 sees .gitattributes and writes LF for everything else, but does not rewrite files that are already checked out and up to date.

Desktop log line for reference: Created worktree "…" at … (prep=422ms fetch=1674ms/ok add=84ms stage1=116ms git_spawns=15).

Reproduction with plain git (no Claude involved)

Any repo with .gitattributes containing * text=auto eol=lf, on a Windows machine with core.autocrlf=true:

git worktree add --no-checkout -b repro ../repro main
git -C ../repro checkout HEAD -- .claude/launch.json CLAUDE.md
git -C ../repro ls-files --eol
#  i/lf    w/crlf  attr/                 .claude/launch.json
#  i/lf    w/crlf  attr/                 CLAUDE.md
git -C ../repro checkout HEAD -- .
git -C ../repro ls-files --eol | awk '$2=="w/crlf"'
#  still those two files; the other ~425 files are w/lf

Each of these makes step 2 come out LF:

  • git -c core.autocrlf=false checkout HEAD -- …
  • including .gitattributes in the same selective checkout: checkout HEAD -- .gitattributes .claude/launch.json CLAUDE.md
  • -c core.attributesFile=<file containing "* text=auto eol=lf">

Suggested fix

Add .gitattributes (and .gitattributes files in subdirectories, if any) to the stage-1 path list, so the selective checkout sees the repo's own line-ending rules. Alternatively run the selective checkout with -c core.autocrlf=false, which is what a plain git worktree add effectively honours once .gitattributes is present.

Environment

  • Claude Desktop 1.40609.1.0 (MSIX), Windows 11 Pro 10.0.26200
  • Claude Code CLI 2.1.255 (spawned by Desktop)
  • git 2.55.0 for Windows, system gitconfig core.autocrlf=true
  • Repo: .gitattributes = * text=auto eol=lf

Observed on two independent Desktop-spawned worktrees on 2026-08-31 and 2026-09-02. Workaround on the user side: .git/info/attributes with * text=auto eol=lf in the base repo (read for all worktrees regardless of index state) — verified to make step 2 produce LF.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗