fix(#2206): strip trailing slashes in isGitIgnored to avoid CRLF check-ignore quirk (#2235)

* fix(#2206): strip trailing slashes in isGitIgnored to avoid CRLF check-ignore quirk

isGitIgnored was called with a trailing slash (`.planning/`) in config-loader.
git check-ignore has a longstanding quirk: a CRLF .gitignore with blank lines
falsely reports any path WITH a trailing slash as ignored. This silently set
commit_docs=false on Windows repos (where CRLF .gitignore is the norm), skipping
all planning-doc commits. Normalize trailing slashes inside isGitIgnored so every
call site is protected.

Closes #2206

* docs(#2206): add changeset fragment

* docs(#2206): backfill PR number
This commit is contained in:
Tom Boucher
2026-07-13 13:04:16 -04:00
committed by GitHub
parent 8d63667121
commit 880fbd963a
2 changed files with 11 additions and 2 deletions

View File

@@ -0,0 +1,5 @@
---
type: Fixed
pr: 2235
---
**`commit_docs` no longer silently disables on CRLF `.gitignore` repos** — git check-ignore falsely reports a trailing-slash path (e.g. `.planning/`) as ignored when the .gitignore has CRLF line endings with blank lines. isGitIgnored now strips trailing slashes before querying, so the false positive cannot occur. (#2206)

View File

@@ -175,10 +175,14 @@ interface ParsedConfig {
const _gitIgnoredCache = new Map<string, boolean>();
function isGitIgnored(cwd: string, targetPath: string): boolean {
const key = cwd + '::' + targetPath;
// #2206: strip trailing slashes — `git check-ignore` has a quirk where a
// CRLF .gitignore with blank lines falsely reports a trailing-slash path
// (e.g. `.planning/`) as ignored. Normalizing here protects every call site.
const normalized = targetPath.replace(/\/+$/, '');
const key = cwd + '::' + normalized;
if (_gitIgnoredCache.has(key)) return _gitIgnoredCache.get(key)!;
// --no-index checks .gitignore rules regardless of whether the file is tracked.
const result = execGit(['check-ignore', '-q', '--no-index', '--', targetPath], { cwd });
const result = execGit(['check-ignore', '-q', '--no-index', '--', normalized], { cwd });
const ignored = result.exitCode === 0;
_gitIgnoredCache.set(key, ignored);
return ignored;