Hichigaya Hachiman
Hichigaya Hachiman

Reputation: 307

.gitignore not ignoring a file properly

I have a project and its structure is following:

build/
.git/
.gitignore
LICENSE
pics/
project.c
README.md
shared/
solutions/

My build/ folder is where I use CMake so there are various files like CMakeCache.txt, CMakeLists.txt etc. which I want git to ignore.

My .gitignore file has:

.gitignore
*.out
*.swp
/build/*

When I run git status there is modified: CMakeLists.txt which I don't understand. Why is CMakeLists.txt not ignored? And why is it the only file that's not ignored?

Upvotes: 0

Views: 4311

Answers (3)

Soham Krishna Paul
Soham Krishna Paul

Reputation: 1243

Add directory into .gitignore:

echo 'node_modules/' >> .gitignore

Add file into .gitignore:

echo 'config/constants.js' >> .gitignore

then:

git rm -r --cached node_modules/   

or:

git rm -r --cached config/constants.js

Add your other files:

git add .

or:

git add --all

Commit it:

git commit -m ".gitignore is now working"

Finally push your code into the repo.

Upvotes: -1

Mark Adelsberger
Mark Adelsberger

Reputation: 45649

Ignore rules (like those in .gitignore) only apply to untracked files. Changes to tracked files cannot be ignored. There are mechanisms people like to suggest for this use case, but they all cause more trouble than the solve.

(And we know that the file in question is tracked, because git tells you it's modified. That means there's a version of the file already in the index.)

If you remove the file from the index then ignore rules can apply. That means that from this commit forward, the repo contains no version of the file. If you want ignore to successfully cover the entire build directory, you could say

git rm -r --cached build

Of course if the file still exists in other "current" commits (i.e. on other branches), then it will still be there (and could sneak back into your current branch by way of merges).

If you never meant the file to be there and can abide a history rewrite, you might consider using BFG Repo Cleaner to fully get rid of it; but it is an extreme solution that will change commit ID's and require any collaborators to replace their repos.

As an aside, there is basically no reason to ever put .gitignore itself in the .gitignore file. Normally you want ignore rules shared as part of the repo, but if you don't you can use .git/info/exclude instead of .gitignore.

You also don't need separate entries for path-based exclusion and extension-based exclusion, unless files with the given extension exist outside the given path.

Upvotes: 1

skovorodkin
skovorodkin

Reputation: 10274

As git ls-files --error-unmatch build/CMakeLists.txt does not show you any error, it means that build/CMakeLists.txt file is already tracked in your repo, so .gitignore file does not affect it anymore. You need to run git rm --cached build/CMakeLists.txt to delete it from git.

Upvotes: 4

Related Questions