50

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!

bzeaman
  • 1,128
  • 11
  • 28
Smarl Teeksoe
  • 523
  • 1
  • 4
  • 4
  • 2
    +1 The link at Chris's comment here worked better for me than anything on this page. – Jorin May 10 '12 at 21:02
  • **No no no,** [this is the right way](http://stackoverflow.com/a/7532131/288906). Most suggested answers re-commit ALL the files. – fregante Oct 18 '16 at 09:34

6 Answers6

64

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).

Chris Johnsen
  • 214,407
  • 26
  • 209
  • 186
  • 1
    This solution made more sense for me: http://stackoverflow.com/questions/1139762/gitignore-file-not-ignoring – wfbarksdale Jul 13 '12 at 17:25
  • How is this command executed? Pasting it into a terminal gives the error `-bash: git: command not found`, yet I can execute git commands in that directory. – memmons Feb 20 '13 at 17:18
  • @Answerbot: What does `type git` say? It sounds like it is an alias (or shell function?). The fact that `git` is not just an normal, external command for you is causing the shell to fail when combined with the temporary environment variable assignment (e.g. `FOO=bar git …` does not expand your `git` alias, and your PATH has no `git`). Either one would also fail with *xargs* since *xargs* is execing your commands itself, not using the shell to do it. You either need to “expand” your *git* uses to match your alias/function, or use an external wrapper script that bundles the same effects. – Chris Johnsen Feb 20 '13 at 19:59
  • Thanks for the detailed response @ChrisJohnsen . `type git` returns `git is hashed (/usr/local/bin/git)`. Any good references on expanding git to match or using an external wrapper? – memmons Feb 20 '13 at 21:12
  • @Answerbot: Since your `git` does seem to be an external command my guess was wrong; the expansion or wrapping is not applicable since your `git` is not an alias or shell function. I wrote the command to be pasted into a (Bourne compatible) shell, and it does work for me in *ksh*, *bash*, and *zsh*. Right now, I have no other guesses as to why your shell produced those symptoms. – Chris Johnsen Feb 20 '13 at 22:19
41

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

Christian Stewart
  • 15,217
  • 20
  • 82
  • 139
Neal L
  • 4,329
  • 8
  • 34
  • 39
  • 25
    While that's *accurate*, I arrived from Google and found that an *unhelpful* answer because that is how to do it one file at a time. Far more helpful and efficient would be an answer like Chris Johnsen's that tells you how to kill all of the should-be-ignored files in one step. – Brighid McDonnell Jun 13 '11 at 16:53
  • 4
    This is a better answer: http://stackoverflow.com/a/1139797/743957 – James Billingham Feb 18 '14 at 15:14
  • This doesn't have to be one file at a time. Run `git rm -r --cached *` to purge everything. – cbartondock Jul 20 '16 at 17:58
  • Even [better answer, it just re-applies gitignore](http://stackoverflow.com/a/7532131/288906) correctly – fregante Oct 18 '16 at 09:35
12

If you are already tracking files you want to ignore, you have to remove them with

git rm --cached <file>

Git won't ignore files which are already tracked (i.e. you added them with git add ).

Sven Koschnicke
  • 6,523
  • 2
  • 34
  • 49
2

mv the_file_i_want_to_ignore the_file_i_want_to_ignore.back

git rm the_file_i_want_to_ignore

mv the_file_i_want_to_ignore.back the_file_i_want_to_ignore

git status

git commit -m 'ignore a bunch of stuff i should have ignored before'

this a bit of a manual workflow but its how i've done this in the past.

Jed Schneider
  • 14,085
  • 4
  • 35
  • 46
2

If you want to remove the files completely, then here's a handy reference from Github.

Be warned that:

  1. This will rewrite your history, so it's probably only worth doing before you publish your repo.
  2. Remember that the old shas will still be in the object database, but the guide I've linked to will show you how to deal with those as well.
Abizern
  • 146,289
  • 39
  • 203
  • 257
-1

You shouldn't have to 'apply' the changes. simply put the .gitignore file in your home directory (if you want it to be global) or in your project root (if you want it to be unique only to that project).

Edit: It occurs to me that you might be having this problem because you've added the files you don't want to track already. Here's what the gitignore man page has to say about that:

Note that all the gitignore files really concern only files that are not already tracked by git; in order to ignore uncommitted changes in already tracked files, please refer to the git update-index --assume-unchanged documentation.

Alex Bliskovsky
  • 5,973
  • 7
  • 32
  • 41
  • The the people that dislike this answer... please offer feedback as to why you don't like it. It's not helpful to just downvote it without a reason. – Nick Res Dec 02 '15 at 07:40