Apply git .gitignore rules to an existing repository [duplicate]

I started using git with an xcode project and have recently discovered that I can use .gitignore and .gitattributes files to ignore the noise from the compiler and system. Now that I have the .gitignore and .gitattributes files in place, how can I "apply" the new ignore rules and get rid of the crud from version control?

My .gitignore file is:

# xcode noise
*.modelv3
*.pbxuser
*.perspective
*.perspectivev3
*.pyc
*~.nib/
build/*

# Textmate - if you build your xcode projects with it
*.tm_build_errors

# old skool
.svn

# osx noise
.DS_Store
profile

And my .gitattributes file is:

*.pbxproj -crlf -diff -merge

Thanks!


Solution 1:

Here is one way to “untrack” any files that are would otherwise be ignored under the current set of exclude patterns:

(GIT_INDEX_FILE=some-non-existent-file \
 git ls-files --exclude-standard --others --directory --ignored -z) |
xargs -0 git rm --cached -r --ignore-unmatch --

This leaves the files in your working directory but removes them from the index.

The trick used here is to provide a non-existent index file to git ls-files so that it thinks there are no tracked files. The shell code above asks for all the files that would be ignored if the index were empty and then removes them from the actual index with git rm.

After the files have been “untracked”, use git status to verify that nothing important was removed (if so adjust your exclude patterns and use git reset -- path to restore the removed index entry). Then make a new commit that leaves out the “crud”.

The “crud” will still be in any old commits. You can use git filter-branch to produce clean versions of the old commits if you really need a clean history (n.b. using git filter-branch will “rewrite history”, so it should not be undertaken lightly if you have any collaborators that have pulled any of your historical commits after the “crud” was first introduced).

Solution 2:

use git rm --cached for files and git rm -r --cached for the build/ directory