[BUG] check-ignore matches trailing-slash paths against CRLF blank lines

flat view

From: Mike Beaton <hidden>
Date: 2026-10-28 12:49:28

## Summary

With a .gitignore containing a single blank CRLF line, `git check-ignore -v`
reports paths ending in `/` as ignored by an empty pattern. Replacing that
blank line with an LF-only blank line removes the match.

This occurs with both ordinary names and dot-prefixed names. In the tests
below, real files inside those directories remain visible to `git status`
and eligible for `git add`. The observed issue is therefore an incorrect
ignore result for the trailing-slash path spelling, rather than demonstrated
loss of files from normal status or staging operations.

## Versions and environment

Reproduced on Linux using Git 2.56.0 built from the official source tarball,
and also using Git 2.51.1.

The 2.56.0 build used:
make -j8 NO_RUST=YesPlease NO_GETTEXT=YesPlease NO_TCLTK=YesPlease \
    NO_CURL=YesPlease NO_EXPAT=YesPlease git
The 2.56.0 tests disabled system and global Git configuration using
`GIT_CONFIG_NOSYSTEM=1` and `GIT_CONFIG_GLOBAL=/dev/null`.

Originally observed independently in a WSL working tree under /mnt/c.

## Minimal reproduction

Run in a shell with the Git executable to be tested on PATH:
repro_dir=$(mktemp -d)
cd "$repro_dir" || exit 1
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null

git --version
git init -q --template=

# Exactly one blank CRLF line; no ignore patterns.
printf '\r\n' > .gitignore

git check-ignore -v foo/ .foo/
printf 'exit status: %s\n' "$?"

# Same paths without trailing slashes.
git check-ignore -v foo .foo
printf 'exit status: %s\n' "$?"

# Replace CRLF with LF and repeat the first check.
printf '\n' > .gitignore
git check-ignore -v foo/ .foo/
printf 'exit status: %s\n' "$?"
## Actual result

With CRLF, the trailing-slash check reports the following (there is a tab
between the final colon and each pathname):
.gitignore:1:    foo/
.gitignore:1:    .foo/
exit status: 0
Without trailing slashes, it prints no matching patterns and returns 1.
After changing the blank line to LF, the trailing-slash check also prints no
matching patterns and returns 1.

The behaviour also reproduces when `foo` and `.foo` are existing directories
containing files.

## Expected result

Neither path should match a blank line, regardless of the line-ending style
or whether the pathname has a trailing slash. Both checks should print no
matches and return 1.

The gitignore documentation states: "A blank line matches no files, so it
can serve as a separator for readability."

https://git-scm.com/docs/gitignore

## Checks with actual files

In the same temporary repository:
printf '\r\n' > .gitignore
mkdir foo .foo
printf 'hello\n' > foo/test.txt
printf 'hello\n' > .foo/test.txt

git check-ignore -v foo/ .foo/ foo .foo foo/test.txt .foo/test.txt
git status --porcelain --untracked-files=all
git add --dry-run -- foo/test.txt .foo/test.txt
Only `foo/` and `.foo/` receive the unexpected ignore matches.
`git status` lists both test files as untracked, and `git add --dry-run`
reports that both would be added.

## Reporting references

Git's reporting instructions direct bug reports to git@vger.kernel.org:

https://git-scm.com/community

This report concerns upstream Git, as it reproduces on Linux with an
upstream source build; it is not specific to Git for Windows.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help