2615

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?

dreftymac
  • 27,818
  • 25
  • 108
  • 169
trobrock
  • 44,089
  • 11
  • 35
  • 44

21 Answers21

4342

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.

russt
  • 1,158
  • 1
  • 12
  • 15
trobrock
  • 44,089
  • 11
  • 35
  • 44
  • 278
    be aware to commit all your changes before, otherwise you will loose control on all the changed files – Hoang Pham Jan 13 '10 at 14:48
  • 2
    This doesn't seem to stay on a push or a clean clone. any ideas? – BenB May 21 '10 at 06:02
  • 8
    @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 – Jason S Dec 27 '11 at 20:41
  • Does this break any continuity for the files I do want to keep tracked? – Brady Moritz Jan 07 '12 at 17:47
  • 2
    @boomhauer It doesn't, just checked. – mgol Jan 14 '12 at 18:18
  • 2
    i did this and it said i had 100s of files changed afterwards. i did a revert and now, finally, my .gitignore is working properly and ignoring my *.user file. thanks! – jedmao Jun 18 '12 at 23:31
  • 9
    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 – Dean Hiller Aug 14 '12 at 20:07
  • Does git rm -r --cached actually remove everything from the *index*? By definition, the index is just the staging area, the place where files are before you commit. Or are there 2 definitions of "index"? (btw, it was successful for me) – dmonopoly Aug 15 '12 at 22:16
  • 1
    OMG I was so afraid that this deleted all of my previous commits bc for some reason it took some time for my previous commits to appear in Xcode x_x Thank goodness they are still there! – Ken M. Haggerty Nov 22 '12 at 06:23
  • 1
    this doesn't work for me. xcode 4.5 still tracks the user interface state file. grrr. what to do? – acecapades Jan 17 '13 at 08:03
  • This is the go to solution for properly .gitignoring files that you were previously tracking. Like... if you start a project by tracking everything (git add .) and then later figure out that you want to .gitignore application/config/database.php (without doing what @trobrock says to do in his answer above, git will just continue to track the contents of the application/config/database.php file). – John Erck Jan 31 '13 at 23:21
  • 3
    it didn't work for me either. Mine has subfolders. – liang Jun 02 '13 at 07:42
  • For future readers you may need these references about the command used on the answer. https://www.kernel.org/pub/software/scm/git/docs/git-rm.html https://www.kernel.org/pub/software/scm/git/docs/git-add.html – fiberOptics Jul 31 '13 at 03:08
  • 1
    I needed to do a push after the three commands to get this to work. I am using git on [http://tfs.visualstudio.com/](http://tfs.visualstudio.com/). I also did a sync, but the push should be sufficient. – JabberwockyDecompiler Aug 09 '13 at 16:56
  • 104
    Great answer but `git rm --cached filename` seems a little less drastic imho.. – Jim Morrison Oct 21 '13 at 20:37
  • 21
    @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. – longneck Nov 13 '13 at 13:52
  • 1
    This is an old question now and some people are saying it didn't/doesn't work for them. I have just tried it out and can confirm it works for me on `git version 1.8.2.1`. – crmpicco Jun 10 '14 at 16:45
  • I get this error fatal: pathspec '' did not match any files – pal4life Jul 28 '14 at 20:41
  • If you are unsure about running `git rm --cached filename`, you can do `git rm --cached --dry-run filename` to see what it is going to do. Also remember -r for directories. – ajh158 Aug 18 '14 at 14:52
  • 1
    For a not so brute forced method I use: `git rm -r --cached some-directory` This removes all files that are gitignored. After this call something like this: `git commit -m 'Remove the now ignored directory "some-directory"'` `git push origin master` – zzeroo Sep 23 '14 at 12:21
  • 1
    Hi @takeshin, where does `git push` fit into this flow? – ericn Jan 05 '15 at 11:04
  • 4
    Not a very helpful answer. I did remove all, un-tracked a file but it committed the deletion of file to live repository once it was set as ignored. Misguiding answer I would say. It SHOULD NOT HAVE git rm -r --cached . at the first place. It removes them all while one wouldn't want to. – Arvind K. Jan 08 '15 at 11:23
  • @ArvindK. Did you do a git add . after remove? this answer removes all files, then re-adds non-ignored ones perfectly for me (with a slightly complex .gitignore), there shouldn't be any auto-commit to a live repos... – Soylent Graham Apr 09 '15 at 09:24
  • be aware, when using this with "git ftp" it happily removes your file from the ftp server!!! – Unicornist Nov 11 '15 at 17:45
  • Worked as advertised :) however, there's no update to the git repo? All those "old" files are still checked in there.... is there way to update it? – Aaron Nov 15 '15 at 13:10
  • 1
    @takeshin This worked form me on my local repo, however when I pushed to remote (my staging environment) it removed files completely from staging. Is there a way to just have it just ignore files on remote as well. – Ross Apr 05 '16 at 14:48
  • 1
    Got scared at first seeing all of the 'rm' files! :) Then 'kept calm' and read on. It seems to have worked. – CodeFinity Jul 26 '16 at 14:01
  • 1
    Worked **perfectly** for me to remove a set of directories with multiple subfolders containing images that I did not wanted to be stored on GitHub. – davidkonrad Dec 17 '17 at 21:41
  • 1
    Make sure you use `git push` afterwards or else this won't work – pattyd Feb 07 '18 at 17:45
  • What will happen to other project members that already had the new gitignore, when they pull this new commit? Will the files be removed from their computers, or are they preserved "as is" because gitignore is making sure a git pull does not affect these files? – Micros Feb 12 '18 at 14:14
  • Don't miss the small dot at the end of the 2 first commands! (woops) – Thomas Mulder Apr 16 '18 at 07:24
  • In case you forgot to commit your changes before executing above command and lost all the changed file, use `git reset HEAD~1` to undo your last commit(recover your lost files). and use `git reset HEAD .` if you only run `git rm -r --cached .` – Tengku Fathullah Jun 22 '18 at 02:50
  • I lost track of all my submodules. Hadn't seen that mentioned here. – VaporwareWolf Oct 15 '18 at 19:07
  • I tried this process and it only ever works if i commit directly after step 1. Otherwise if I delete files from ignored directory, the changes still appear in git.... Is that what the edit at the end of the answer is saying? – Arthur Hylton Dec 07 '18 at 21:45
  • 1
    If this branch is pulled into master does it still work? – Philip Rego Dec 24 '18 at 17:42
  • I had to add "f" to force removal: `git rm -rf --cached .` – Ken Mar 20 '19 at 18:47
  • Best way I've found was add the ".idea" directory and after remove it with --cached . In the process, the "./idea/workspace.xml" appeared aparently from nothing! I've repeated the process with the file, and again with the ".idea" directory. Pretty annoying procedure! But works! – Andre Carneiro May 17 '20 at 13:39
  • I cannot count the amount of times I come back to this solution. – vikzilla Apr 23 '21 at 22:18
638

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) than what you want to do is:

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

If you wanna 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: Since people have been asking, here's a convenient (and updated since commented on below) 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:]]"
Community
  • 1
  • 1
dyodji
  • 6,616
  • 2
  • 14
  • 16
  • 16
    This is genius! Brilliantly useful. Do you know if there's a way to get a list of all the 'on hold' files? – artfulrobot Feb 05 '13 at 13:06
  • 14
    This'll work for you: `git ls-files -v` If the character printed is lower-case, the file is marked assume-unchanged. see: http://stackoverflow.com/a/2363495/677381 and: http://git-scm.com/docs/git-ls-files – dyodji Feb 06 '13 at 01:33
  • This only works as long as one of your remotes doesn't have a change to that file that conflicts with what you have. – Shauna May 03 '13 at 14:36
  • If you need to integrate a change, from outside your local, to files to which you've assume-unchanged you can always assume-changed, stash, pull/merge, stash pop and assume-unchanged again.... it's not uncommon to add a property, for example, that each local would want to retrieve this way.... but this is really for files where changes most likely WILL conflict... e.g. usernames or local paths... that's the point really. – dyodji May 04 '13 at 00:01
  • 2
    @dyodji Does this only affect myself? Or all users? – wisbucky Sep 26 '13 at 23:35
  • 1
    @wisbucky This only affects the locally checked out file(s) and does not affect origin or any other checked out copies of the repo. – dyodji Sep 27 '13 at 01:18
  • 3
    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 \nor track again with: git update-index --no-assume-unchanged '` The toplevel part of it makes sure it searches the entire repository. – Chris Feb 10 '15 at 06:22
  • This works well for modified files, but I cannot get it to work for files I have deleted on local machine but do not wish to delete from repo. Any idea how to get locally deleted files to stop showing up in commit window ? – jkb016 Jul 01 '15 at 02:24
  • 3
    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](http://stackoverflow.com/q/5962456/2747593). – Scott Weldon Apr 27 '16 at 17:39
  • 1
    This is a great way to see files that you've hidden with `assume-unchanged`, and thus I think you should call the alias 'hidden' not ignored. To me ignored files are ones that git doesn't look at because they match a pattern in .gitignore. You can find these files via `git status -s --ignored | grep '^!!'` – MERM Mar 11 '17 at 19:50
  • I'll just add to this that this command won't work on a file if it's staged. Make sure you unstage it if somehow it got in the staged state first. I mean this command will still work on it but it will remain in your list and won't drop off. So just make sure you unstage. – Uncle Iroh Jun 06 '17 at 22:36
  • 1
    @ScottWeldon maybe `skip-worktree` would be a good alternative. – Sebastianb Sep 12 '17 at 20:33
  • 6
    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:]]"'` – Crhistian Ramirez Mar 13 '18 at 16:14
  • The exclamation mark in your alias messes up with most shells. Maybe should you quote it, or add the simple command without any alias: `git ls-files -v | grep '^[[:lower:]]'` – Bilow Sep 20 '18 at 13:56
  • @CrhistianRamirez Thanks for your syntax, its worked great for the alias ! – Raphaël Roux Mar 09 '20 at 12:14
  • This is very useful. Thanks @dyodji – Parag Bangad Sep 24 '20 at 03:30
369

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

pagetribe
  • 14,073
  • 3
  • 22
  • 18
  • 8
    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. – Andrew Larned Apr 08 '11 at 16:17
  • 9
    Tip: for example if you add `*.config` to your `.gitignore`, you can do `git rm --cached *.config` to stop tracking all `*.config` files. – dav_i Mar 06 '13 at 13:30
  • 62
    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` – dav_i Mar 08 '13 at 10:15
  • 1
    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!" ;) – Olie Jul 17 '14 at 03:20
  • @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. – Sebastianb Sep 12 '17 at 20:37
89

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.

Paul van Leeuwen
  • 3,112
  • 1
  • 15
  • 30
Antony Stubbs
  • 11,897
  • 4
  • 32
  • 35
  • 12
    This isn't entirely true, it is possible to ignore changes in a tracked file... see my answer: http://stackoverflow.com/a/11366713/677381 – dyodji Jan 03 '13 at 22:08
  • git update-index --assume-unchanged and git rm --caheced was not actually working for me. I have done git rm and then created new file after that `` is successfully ignored. I am using git version 1.8.1 -- If that was the issue. – mujaffars Feb 24 '16 at 06:24
  • your syntax is wrong here. it's `git rm test.txt` and here's a link to a more comprehensive answer http://stackoverflow.com/questions/12661306/git-rm-cached-file-vs-git-reset-file – Linnea Huxford Dec 24 '16 at 20:13
  • 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. – devfaysal Feb 09 '20 at 03:39
54

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

MikeJansen
  • 3,043
  • 2
  • 22
  • 30
  • 4
    I had exactly the same problem, :P. I also got to this question because of that. Good thing you have this documented here. +1 – Hindol Jul 11 '12 at 05:08
  • 3
    If like me you use vi to quickly edit .gitignore use ':set list' to show whitespace. – Sam Giles Mar 12 '13 at 16:35
  • 1
    This happenened to me when I did a `echo node_modules >> .gitignore` (at least on windows) – Khôi May 03 '14 at 20:16
  • For weeks I was frustrated with this until I saw your whitespace post. Thanks, fixed my problem. – Blazes Oct 08 '15 at 22:01
45

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.

Orlando
  • 8,452
  • 2
  • 53
  • 48
42

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

przbadu
  • 5,093
  • 2
  • 37
  • 54
38

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!

Ahmad Awais
  • 23,458
  • 4
  • 66
  • 52
31

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                      
jasilva
  • 680
  • 18
  • 43
Mark Salvatore
  • 610
  • 1
  • 7
  • 12
30

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
Iman Mohamadi
  • 5,275
  • 2
  • 31
  • 33
25

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

Olga
  • 1,608
  • 1
  • 22
  • 29
25

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!

rrrr
  • 2,207
  • 23
  • 51
Hunter S
  • 1,163
  • 1
  • 14
  • 24
25

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.

Community
  • 1
  • 1
averydev
  • 5,587
  • 2
  • 32
  • 35
  • 3
    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. – IAmNaN May 16 '12 at 19:33
  • 3
    Be careful with the `--hard` flag. It *will* throw out any uncommitted changes without a warning! – Mikko Rantalainen Mar 01 '13 at 13:02
23

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

Aragorn
  • 843
  • 12
  • 25
  • 2
    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. – doublejosh Apr 17 '12 at 23:17
  • 2
    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. – AWrightIV Feb 21 '14 at 03:03
21

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/
kindahero
  • 5,584
  • 2
  • 22
  • 30
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.

dwlz
  • 9,793
  • 6
  • 46
  • 76
umop
  • 1,978
  • 2
  • 17
  • 21
  • 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? – Fake Name Aug 17 '16 at 17:27
10

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

Community
  • 1
  • 1
Matt Parkins
  • 22,276
  • 8
  • 43
  • 55
10

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!

Johannes Vetter
  • 101
  • 1
  • 2
  • 1
    If anyone has problems with .gitignore after creating the file in windows notepad, there is more information here: http://stackoverflow.com/questions/11451535/gitignore-not-working/13354744 – Matt Parkins Dec 04 '12 at 11:16
  • 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. – Mikko Rantalainen Mar 01 '13 at 13:05
8

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

Nakilon
  • 32,203
  • 13
  • 95
  • 132
ndemoreau
  • 3,749
  • 4
  • 40
  • 54
8

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

Etherealone
  • 3,239
  • 2
  • 28
  • 56
7

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.

Gabriel Perdue
  • 1,253
  • 2
  • 14
  • 20