Ignore files that have already been committed to a Git repository [duplicate]

Asked 2023-09-20 20:24:15 View 716,435

I have an already initialized Git repository that I added a .gitignore file to. How can I refresh the file index so the files I want ignored get ignored?

Answers

To untrack a single file that has already been added/initialized to your repository, i.e., stop tracking the file but not delete it from your system use: git rm --cached filename

To untrack every file that is now in your .gitignore:

First commit any outstanding code changes, and then, run this command:

git rm -r --cached .

This removes any changed files from the index(staging area), then just run:

git add .

Commit it:

git commit -m ".gitignore is now working"

To undo git rm --cached filename, use git add filename.

Make sure to commit all your important changes before running git add . Otherwise, you will lose any changes to other files.

Please be careful, when you push this to a repository and pull from somewhere else into a state where those files are still tracked, the files will be DELETED

Answered   2023-09-20 20:24:15

  • be aware to commit all your changes before, otherwise you will loose control on all the changed files - anyone
  • @TravisWebb You would have to make sure you set up .gitignore first. Also I tend not to remove all files from the index, only the ones I need to by using Fileglobs such as *.o - anyone
  • git rm -r --cached . removed way more files than was in the git ignore for me :( :(. It removed files in directories that I don't even have listed - anyone
  • Great answer but git rm --cached filename seems a little less drastic imho.. - anyone
  • @JimMorrison you miss the point. if you have a large project with a complicated .gitignore (such as a C# project in Visual Studio) figuring out each individual file to remove is tedious. these three simple commands fixes everything painlessly. - anyone

If you are trying to ignore changes to a file that's already tracked in the repository (e.g., a dev.properties file that you would need to change for your local environment but you would never want to check in these changes), then what you want to do is:

git update-index --assume-unchanged <file>

If you want to start tracking changes again:

git update-index --no-assume-unchanged <file>

See git-update-index(1) Manual Page.

Also have a look at the skip-worktree and no-skip-worktree options for update-index if you need this to persist past a git-reset (via)


Update: Here's a convenient alias for seeing which files are currently "ignored" (--assume-unchanged) in your local workspace

git config --global alias.ignored = !git ls-files -v | grep "^[[:lower:]]"

Answered   2023-09-20 20:24:15

  • This is genius! Brilliantly useful. Do you know if there's a way to get a list of all the 'on hold' files? - anyone
  • This'll work for you: git ls-files -v If the character printed is lower-case, the file is marked assume-unchanged. see: stackoverflow.com/a/2363495/677381 and: git-scm.com/docs/git-ls-files - anyone
  • Here's my slightly more verbose version of the ignored alias, as it appears in my ~/.gitconfig file: ignored = !git ls-files -v $(git rev-parse --show-toplevel) | (grep '^[[:lower:]]' || echo 'None ignored.') && echo '\nIgnore changes with: git update-index --assume-unchanged <file> \nor track again with: git update-index --no-assume-unchanged <file>' The toplevel part of it makes sure it searches the entire repository. - anyone
  • Unfortunately --assume-unchanged doesn't work with git stash: the changes are reverted during git stash and not reapplied during git stash pop. See this question. - anyone
  • Not sure if the syntax is different on mac but I had to modify the alias slightly git config --global alias.hidden '!git ls-files -v | grep "^[[:lower:]]"' - anyone

To untrack a file that has already been added/initialized to your repository, ie stop tracking the file but not delete it from your system use: git rm --cached filename

Answered   2023-09-20 20:24:15

  • This was the perfect way to remove the couple of files I'd added, committed, but later realized didn't need to be tracked. After adding those files to .gitignore, I was able to do this and untrack them perfectly. - anyone
  • Tip: for example if you add *.config to your .gitignore, you can do git rm --cached *.config to stop tracking all *.config files. - anyone
  • Also note doing this will delete the files from other repos you push to, even though it stays on your system. If you're just ignoring changes to files and don't want to delete them from other user's repos try using git update-index --assume-unchanged file.name - anyone
  • IMO, this is the correct answer. Wiki answer works-kinda, but is awfully heavy-handed, especially given the question. (I'd fix the wiki, but I'm not sure how. "Soon!" ;) - anyone
  • @Olie be extremely careful with this "solution". This will remove the file in the repo, and anyone who pulls this change will have the file removed too. The best solution would be to assume-unchanged, as @dav_i said, or --skip-worktree as an alternative. - anyone

Yes - .gitignore system only ignores files not currently under version control from git.

I.e. if you've already added a file called test.txt using git-add, then adding test.txt to .gitignore will still cause changes to test.txt to be tracked.

You would have to git rm test.txt first and commit that change. Only then will changes to test.txt be ignored.

Answered   2023-09-20 20:24:15

  • This isn't entirely true, it is possible to ignore changes in a tracked file... see my answer: stackoverflow.com/a/11366713/677381 - anyone
  • git update-index --assume-unchanged <file> and git rm --caheced <file> was not actually working for me. I have done git rm <file> and then created new file after that <file> is successfully ignored. I am using git version 1.8.1 -- If that was the issue. - anyone
  • your syntax is wrong here. it's git rm test.txt and here's a link to a more comprehensive answer stackoverflow.com/questions/12661306/… - anyone
  • This is the correct answer if your .gitignore is not working for some specific files. The accepted answer will cause a commit for all of your files. - anyone

Remove trailing whitespace in .gitignore

Also, make sure you have no trailing whitespace in your .gitignore. I got to this question because I was searching for an answer, then I had a funny feeling I should open the editor instead of just cat'ing .gitignore. Removed a single extra space from the end and poof it works now :)

Answered   2023-09-20 20:24:15

  • I had exactly the same problem, :P. I also got to this question because of that. Good thing you have this documented here. +1 - anyone
  • If like me you use vi to quickly edit .gitignore use ':set list' to show whitespace. - anyone
  • This happenened to me when I did a echo node_modules >> .gitignore (at least on windows) - anyone
  • For weeks I was frustrated with this until I saw your whitespace post. Thanks, fixed my problem. - anyone

i followed these steps

git rm -r --cached .
git add .
git reset HEAD

after that, git delete all files (*.swp in my case) that should be ignoring.

Answered   2023-09-20 20:24:15

  • be careful with that one, as it assumes you want to add all files except what's ignored, and usually that's not the case - anyone
  • Awesomeness! +1 - anyone

Complex answers everywhere!

Just use the following

git rm -r --cached .

It will remove the files you are trying to ignore from the origin and not from the master on your computer!

After that just commit and push!

Answered   2023-09-20 20:24:15

If you want to stop tracking file without deleting the file from your local system, which I prefer for ignoring config/database.yml file. Simply try:

git rm --cached config/database.yml
# this will delete your file from git history but not from your local system.

now, add this file to .gitignore file and commit the changes. And from now on, any changes made to config/database.yml will not get tracked by git.

$ echo config/database.yml >> .gitignore

Thanks

Answered   2023-09-20 20:24:15

To remove just a few specific files from being tracked:

git update-index --assume-unchanged path/to/file

If ever you want to start tracking it again:

git update-index --no-assume-unchanged path/to/file                      

Answered   2023-09-20 20:24:15

As dav_i says, in order to keep the file in repo and yet removing it from changes without creating an extra commit you can use:

git update-index --assume-unchanged filename

Answered   2023-09-20 20:24:15

  • Undo : git update-index --no-assume-unchanged filename - anyone
  • what if you want to do that for all files in a folder in one go? - anyone

None of the answers worked for me.

Instead:

  1. Move the file out of the git-controlled directory
  2. Check the removal into git
  3. Move the file back into the git-controlled directory

After moving the file back, git will ignore it.

Works with directories too!

Answered   2023-09-20 20:24:15

  • the only sane solution it seems :) - anyone

Not knowing quite what the 'answer' command did, I ran it, much to my dismay. It recursively removes every file from your git repo.

Stackoverflow to the rescue... How to revert a "git rm -r ."?

git reset HEAD

Did the trick, since I had uncommitted local files that I didn't want to overwrite.

Answered   2023-09-20 20:24:15

  • The git rm -r --cached . didn't work for me. Git was still claiming an my textmate project file was not being tracked even though .tmproj is in my global ignore file. Resetting my local repro like this worked, though. Actually I added the 'hard' option as in git reset --hard HEAD. That should have nearly the same effect in this case. - anyone
  • Be careful with the --hard flag. It will throw out any uncommitted changes without a warning! - anyone

There is another suggestion maybe for the slow guys like me =) Put the .gitignore file into your repository root not in .git folder. Cheers!

Answered   2023-09-20 20:24:15

If the files are already in version control you need to remove them manually.

Answered   2023-09-20 20:24:15

  • I tried git rm --cached and git reset HEAD both tools I'm fairly familiar with and just could get it from the repo. Success came from first rm --cached, then actually manually deleting it, committing the delete, then recreating it manually. And it's gone. - anyone
  • This worked for me like so: rm foo/bar && git add -u && git commit -m "removed foo/bar" && git push. Then running touch foo/bar && git status will show the file is now properly ignored. - anyone

another problem I had was I placed an inline comment.

tmp/*   # ignore my tmp folder (this doesn't work)

this works

# ignore my tmp folder
tmp/

Answered   2023-09-20 20:24:15

Thanks to your answer, I was able to write this little one-liner to improve it. I ran it on my .gitignore and repo, and had no issues, but if anybody sees any glaring problems, please comment. This should git rm -r --cached from .gitignore:

cat $(git rev-parse --show-toplevel)/.gitIgnore | sed "s/\/$//" | grep -v "^#" | xargs -L 1 -I {} find $(git rev-parse --show-toplevel) -name "{}" | xargs -L 1 git rm -r --cached

Note that you'll get a lot of fatal: pathspec '<pathspec>' did not match any files. That's just for the files which haven't been modified.

Answered   2023-09-20 20:24:15

  • Is the sed s//$// supposed to be s/$//? Also, what's the point of the sed and grep commands? I'm guessing it's comment filtering from the gitignore? - anyone

I have found a weird problem with .gitignore. Everything was in place and seemed correct. The only reason why my .gitignore was "ignored" was, that the line-ending was in Mac-Format (\r). So after saving the file with the correct line-ending (in vi using :set ff=unix) everything worked like a charm!

Answered   2023-09-20 20:24:15

  • If anyone has problems with .gitignore after creating the file in windows notepad, there is more information here: stackoverflow.com/questions/11451535/gitignore-not-working/… - anyone
  • The .gitignore format is each line is either a comment (starting with a #) or the whole line (including any whitespace) is full filename pattern. If you have \r mixed into the line, git will ignore only files that end up with \r (you can create those if you want!). See man gitignore for details, it's worth reading. - anyone

One other problem not mentioned here is if you've created your .gitignore in Windows notepad it can look like gibberish on other platforms as I found out. The key is to make sure you the encoding is set to ANSI in notepad, (or make the file on linux as I did).

From my answer here: https://stackoverflow.com/a/11451916/406592

Answered   2023-09-20 20:24:15

If you need to stop tracking a lot of ignored files, you can combine some commands:

git ls-files -i --exclude-standard | xargs -L1 git rm --cached

This would stop tracking the ignored files. If you want to actually remove files from filesystem, do not use the --cached option. You can also specify a folder to limit the search, such as:

git ls-files -i --exclude-standard -- ${FOLDER} | xargs -L1 git rm

Answered   2023-09-20 20:24:15

  • This should be the accepted answer. git rm -r --cached . removes lot of other things! - anyone

On my server linux server (not true on my local dev mac), directories are ignored as long as I don't add an asterisk:

www/archives/*

I don't know why but it made me loose a couple of hours, so I wanted to share...

Answered   2023-09-20 20:24:15

One thing to also keep in mind if .gitignore does not seem to be ignoring untracked files is that you should not have comments on the same line as the ignores. So this is okay

# ignore all foo.txt, foo.markdown, foo.dat, etc.
foo*

But this will not work:

foo*   # ignore all foo.txt, foo.markdown, foo.dat, etc.

.gitignore interprets the latter case as "ignore files named "foo* # ignore all foo.txt, foo.markdown, foo.dat, etc.", which, of course, you don't have.

Answered   2023-09-20 20:24:15