Rob Jackson
Rob Jackson

Reputation: 138

How to reliably check whether a file is ignored by git?

I'm encountering a problem where git check-ignore is not respecting .gitignore's 'not' (!) rules. It's returning "Ignored" if a file matches any entry in the .gitignore file, regardless of whether that entry is telling it to not ignore the path (via the ! operator)

git check-ignore's documentation states the return codes map as follows:

EXIT STATUS

  • 0: One or more of the provided paths is ignored.
  • 1: None of the provided paths are ignored.
  • 128: A fatal error was encountered.

This doesn't match what I'm seeing when I add "Do not ignore" rules, i.e. sticking ! in front of an entry.

As an example, let's create a file structure as follows:

.gitignore
files/
    path-not-ignored
ignored-files/
    path-ignored
    path-not-ignored

and a .gitignore containing:

ignored-files/*
!ignored-files/path-not-ignored

According to the documentation, I'd expect the files in files/ and ignored-files/path-not-ignored to return exit status 1 (not ignored), and ignored-files/path-is-ignored to return 0 (ignored).

What I'm seeing instead of everything in ignored-files returning exit status 0 (ignored):

File                             | Expected exit status | Actual exit status | Summary
-------------------------------- | -------------------- | ------------------ | -------
`files/path-not-ignored`         | 1 (Not ignored)      | 1 (Not ignored)    | Expected
`ignored-files/path-ignored`     | 0 (Ignored)          | 0 (Ignored)        | Expected
`ignored-files/path-not-ignored` | 1 (Not ignored)      | 0 (Ignored)        | Unexpected

(Exit status codes are being checked with git check-ignore <file>;echo $?)

This doesn't match Git's internal behaviour, because I can git add add ignored-files/path-not-ignored just fine:

File                             | `git add`?                   | Matches `git check-ignore` output?
-------------------------------- | ---------------------------- | ----------------------------------
`files/path-not-ignored`         | Adds file (as expected)      | Yes
`ignored-files/path-ignored`     | Throws warning (as expected) | Yes
`ignored-files/path-not-ignored` | Adds file (as expected)      | No


git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   files/path-not-ignored
    new file:   ignored-files/path-not-ignored

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    .gitignore

As git check-ignore is unreliable in this case, are there any other commands I could use to check whether Git is ignoring / not ignoring a given file?

Something that returns exit codes would be ideal, as I'm using this in a bash script.

Upvotes: 4

Views: 1242

Answers (1)

VonC
VonC

Reputation: 1324347

Check if the issue persists since July 2017 with Git 2.18 (July 2018).

Commit d60771e might have helped remove false positive.

check-ignore: fix mix of directories and other file types

In check_ignore(), the first pathspec item determines the dtype for any subsequent ones.
That means that a pathspec matching a regular file can prevent following pathspecs from matching directories, which makes no sense.

Upvotes: 1

Related Questions