How to make Git “forget” about a file that was tracked but is now in .gitignore?
The series of commands below will remove all of the items from the Git Index (not from the working directory or local repo), and then updates the Git Index, while respecting git ignores. PS. Index = Cache
git rm -r --cached . git add .
git commit -am "Remove ignored files"
There is a file that was being tracked by
git, but now the file is on the
However, that file keeps showing up in
git status after it's edited. How do you force
git to completely forget about it?
If you cannot
git rm a tracked file because other people might need it (warning, even if you
git rm --cached, when someone else gets this change, their files will be deleted in their filesystem) please look at https://gist.github.com/1423106 for ways people have worked around the problem.
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached git commit -am "Remove ignored files"
This takes the list of the ignored files and removes them from the index, then commits the changes.
Use this when:
1. You want to untrack a lot of files, or
2. You updated your gitignore file
Let’s say you have already added/committed some files to your git repository and you then add them to your .gitignore; these files will still be present in your repository index. This article we will see how to get rid of them.
Step 1: Commit all your changes
Before proceeding, make sure all your changes are committed, including your .gitignore file.
Step 2: Remove everything from the repository
To clear your repo, use:
git rm -r --cached .
- rm is the remove command
- -r will allow recursive removal
- –cached will only remove files from the index. Your files will still be there.
rm command can be unforgiving. If you wish to try what it does beforehand, add the
--dry-run flag to test things out.
Step 3: Re add everything
git add .
Step 4: Commit
git commit -m ".gitignore fix"
Your repository is clean :)
Push the changes to your remote to see the changes effective there as well.
.gitignorefile – for instance, add a folder you don't want to track to
git rm -r --cached .– Remove all tracked files, including wanted and unwanted. Your code will be safe as long as you have saved locally.
git add .– All files will be added back in, except those in
Hat tip to @AkiraYamamoto for pointing us in the right direction.
What didn't work for me
(Under Linux), I wanted to use the posts here suggesting the
ls-files --ignored --exclude-standard | xargs git rm -r --cached approach. However, (some of) the files to be removed had an embedded newline/LF/
\n in their names. Neither of the solutions:
git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
cope with this situation (get errors about files not found).
So I offer
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
This uses the
-z argument to ls-files, and the
-0 argument to xargs to cater safely/correctly for "nasty" characters in filenames.
In the manual page git-ls-files(1), it states:
When -z option is not used, TAB, LF, and backslash characters in pathnames are represented as \t, \n, and \\, respectively.
so I think my solution is needed if filenames have any of these characters in them.
EDIT: I have been asked to add that --- like any
git rm command --- this must be followed by a commit to make the removals permanent, e.g.
git commit -am "Remove ignored files".
The BFG is specifically designed for removing unwanted data like big files or passwords from Git repos, so it has a simple flag that will remove any large historical (not-in-your-current-commit) files: '--strip-blobs-bigger-than'
$ java -jar bfg.jar --strip-blobs-bigger-than 100M
If you'd like to specify files by name, you can do that too:
$ java -jar bfg.jar --delete-files *.mp4
Move or copy the file to a safe location, so you don't lose it. Then git rm the file and commit. The file will still show up if you revert to one of those earlier commits, or another branch where it has not been removed. However, in all future commits, you will not see the file again. If the file is in the git ignore, then you can move it back into the folder, and git won't see it.