TL;DR – “git rm –cached ” means “Yo git, as far as you know, this file is gone”
In a git repo, there are three places for files to be:
1) In your working directory
2) In the staging area
3) In the most recent commit.
Getting rid of a file means moving it out of all 3 places.
1) by deleting it
rm
2) by removing it from the staging area:
git rm
3) by committing that removal.
git commit -m “die stupid file die”
When you want the file to remain on your filesystem but NOT in the repo, then tell git to ignore it. But that isn’t enough! You also have to get it out of the repo.
1) tell git to ignore it: add the file or directory name to .gitignore[1]
2) get it out of the staging area BUT NOT the working directory:
git rm –cached
3) If the file has been committed before, commit that removal, along with your .gitignore changes:
git add .gitignore
git commit -m “hide stupid file hide”
Git etiquette: package the .gitignore updates along with the removal of the newly-ignored files in one commit.
Warning: if you ever check out a commit that doesn’t have that file in .gitignore, whatever’s in the commit will overwrite your current one. No warnings. I hope this was some sort of build output that you can regenerate.
Sometimes the file has never been committed, but it was accidentally added to the staging area, and now you want git to leave you alone and ignore that file already!
Delete the file and remove it from the staging area in one easy step:
1) git rm -f pee
Or keep it, and tell git to leave it the freak alone:
1) tell git to ignore it: add the file or directory name to .gitignore
2) get it out of the staging area BUT NOT the working directory:
git rm –cached
Terminology: the “staging area” is also called the “index” and the “cache,” for historical reasons.
If this seems complicated… yeah, I agree. If you know that “git rm –cached ” means “Yo git, take this file out of you,” that’ll get you through most of the frustration.
—————
[1] For more ways to ignore files, and when to use each: http://jessitron.github.io/git-happens/ignore.html
