593

I have committed loads of files that I now want to ignore. How can I tell git to now ignore these files from future commits?

EDIT: I do want to remove them from the repository too. They are files created after ever build or for user-specific tooling support.

user880954
  • 7,317
  • 6
  • 22
  • 20
  • 2
    possible duplicate of [.gitignore file not ignoring](http://stackoverflow.com/questions/1139762/gitignore-file-not-ignoring) – Wooble Sep 23 '11 at 11:10
  • 8
    @Wooble The answer may be similar, but this question exactly describes the problem I was faced with and needed to solve. – rjmunro Jan 03 '13 at 12:15
  • 1
    This is the answer that directly addresses the title question with minimal changes to your git repo: https://stackoverflow.com/a/26245961/3543437 – kayleeFrye_onDeck Jun 06 '17 at 22:35

11 Answers11

707

After editing .gitignore to match the ignored files, you can do git ls-files -ci --exclude-standard to see the files that are included in the exclude lists; you can then do

  • Linux/MacOS: git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached
  • Windows (PowerShell): git ls-files -ci --exclude-standard | % { git rm --cached "$_" }
  • Windows (cmd.exe): for /F "tokens=*" %a in ('git ls-files -ci --exclude-standard') do @git rm --cached "%a"

to remove them from the repository (without deleting them from disk).

Edit: You can also add this as an alias in your .gitconfig file so you can run it anytime you like. Just add the following line under the [alias] section (modify as needed for Windows or Mac):

apply-gitignore = !git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached

(The -r flag in xargs prevents git rm from running on an empty result and printing out its usage message, but may only be supported by GNU findutils. Other versions of xargs may or may not have a similar option.)

Now you can just type git apply-gitignore in your repo, and it'll do the work for you!

Jonathan Callen
  • 11,301
  • 2
  • 23
  • 44
  • 10
    I think xargs for mac has no -r... or mine is buggy/old, I don't know... and why the `!` before git? well... mine one worked as `alias apply-gitignore="git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached"`. tks! – Felipe Sabino Dec 06 '12 at 21:09
  • 20
    On Windows `for /F "tokens=*" %a in ('git ls-files -ci --exclude-standard') do @git rm --cached "%a"` – Luke Puplett Jul 03 '13 at 16:07
  • This just removed my .gitignore files, not the files I wanted to ignore that were listed in the .gitignore files - was that the point? – Hippyjim Mar 21 '14 at 07:38
  • @Hippyjim if the files are already committed (even though they were listed in .gitignore), and .gitignore is *not* yet committed, then that would be the expected result, otherwise, I'm not sure what is going on in your case. – Jonathan Callen Mar 21 '14 at 23:35
  • But isn't this a bad idea as git rm will remove the files from other places on pull, even if you use --cached to avoid that locally? – user2451227 Apr 23 '14 at 09:28
  • 1
    Worked flawlessly. Much appreciated! – Rixhers Ajazi Jun 06 '14 at 19:11
  • I got an error `xargs: git : Bad file number` using git 1.9.2. Using SourceTree's embedded git works fine, not sure why. – Chin Jun 17 '14 at 17:01
  • THIS is the answer. I also added a "git add .gitignore" to have that file in there so others don't add stuff. Nice one! – unom Oct 22 '14 at 20:18
  • You usually do not get to re-elect an "Accepted" answer on SO. Unfortunately I've seen this a lot here. The best thing to do is to scroll to the bottom and read all the answers before going with just one of them (upvotes dont always make for the best answer btw, ive found gems with NEGATIVE votes as well, however in this instance, that is clearly not the case) but anyway, excellent answer this is, I'll accept this is the real answer. – osirisgothra May 19 '15 at 11:58
  • The one that worked for me is to change ~/.gitconfig ```apply-gitignore= !git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached ``` This is based on @Felipe-sabino response but without the quotes and using a ```!git``` hint. I'm using git version 1.8.5.2 (Apple Git-48) – D.Deriso Aug 10 '15 at 21:04
  • @Zero3 This is what happens when you have to dive into the plumbing instead of just using porcelain commands – Jonathan Callen Dec 29 '15 at 01:52
  • 1
    For mac users, `-r` is default and is not accepted by BSD versions. So remove `-r`. – Weishi Z Apr 09 '16 at 04:56
  • NOTE: that this will add "remove those files" into your git. You will keep your local files due to "--cached" argument, however if you have to go back into your history before the deletion and return again, git will look into the "remove those files" and delete it from your local folder. So you should be careful with it. – Jav Nov 26 '16 at 13:45
  • I have done both steps but removed files to be ignored from commits all of them ended in a "staged files" area in the SourceTree – JackTheKnife Jul 19 '17 at 13:08
  • Hi, the `git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached` command results in `xargs: cannot fork` at me (on Windows). What can I do with this? – mma Sep 11 '18 at 13:19
  • Is it possible to remove such files from all previous commits? – Ian Warburton Sep 26 '18 at 11:53
624
  1. Edit .gitignore to match the file you want to ignore
  2. git rm --cached /path/to/file

See also:

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
203

to leave the file in the repo but ignore future changes to it:

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

and to undo this:

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

to find out which files have been set this way:

git ls-files -v|grep '^h'

credit for the original answer to http://blog.pagebakers.nl/2009/01/29/git-ignoring-changes-in-tracked-files/

ben.tiberius.avery
  • 2,194
  • 1
  • 13
  • 8
  • 1
    Chronial has a great answer for doing this recursively for a directory: http://stackoverflow.com/a/16346756/1101076 – alana314 Feb 26 '16 at 20:46
  • 1
    I wanted to commit an IDE config but not track unnecessary changes to it. This works, though I'm not sure if it'll work for others who check out the repository. It can be combined with `git ls-files -ci --exclude-standard -z | xargs -0 git update-index --assume-unchanged` if that helps. – dlamblin May 10 '17 at 07:17
  • 18
    This is the _only_ answer that does precisely what the title question asks for. PERFECT! Most of these other answers were messing with files needlessly. – kayleeFrye_onDeck Jun 06 '17 at 22:34
  • 1
    This is the exactly right answer for the question. Using commands like `git rm --cached` will remove the file in repository, which doesn't meet the need of quizzer. Thank you. I really appreciate it. Your answer helps me a lot. – ramwin Apr 14 '20 at 05:15
  • The last command, on windows, replace grep with findstr for the same result. git ls-files -v|findstr '^h' – MattyMatt Dec 10 '21 at 16:31
199

Be sure that your actual repo is the latest version and without ongoing changes

  1. Edit .gitignore as you wish
  2. git rm -r --cached . (remove all files)
  3. git add . (re-add all files according to gitignore)

then commit as usual

Théo Attali
  • 2,200
  • 1
  • 9
  • 10
  • 34
    This should be the accepted answer as the question specifically said there were a lot of files to remove. – nbeuchat Feb 01 '18 at 12:30
  • 4
    Note that step 2 this can take a while if you have a big repository. – brainbag Jun 04 '18 at 14:16
  • 3
    This just led to removal of *all* files from the index! [This](https://stackoverflow.com/questions/2125710/how-to-revert-a-git-rm-r) saved me: `git reset HEAD` (Remember to stash any changes) – aksh1618 Nov 14 '18 at 19:54
  • 4
    Step 2 removes everything, yes, but step 3 should readd them all, except for the ones that fail due to .gitignore. – ojchase Jan 15 '19 at 18:19
  • This works perfectly. – Blues Clues Jun 07 '23 at 09:03
12

Old question, but some of us are in git-posh (powershell). This is the solution for that:

git ls-files -ci --exclude-standard | foreach { git rm --cached $_ }
Chris Pfohl
  • 18,220
  • 9
  • 68
  • 111
2
  1. Add your filename/file-path into the .gitignore file.
  2. Now run command in git bash git rm --cached file/path/from/root/folder
  3. Now commit your code using git commit.

Now the file should not get tracked in the git status command.

Jay
  • 329
  • 2
  • 12
0

I tend to forget / am too lazy to read what these git commands do. So I do it like this:

  • I move all files, which I want to ignore, temporarily outside the repository
  • I commit these "deleted files" in my git GUI (they are now untracked)
  • I update the .gitignore file
  • I move the files back into the repository (or delete them, if that was my intention)
Nils Lindemann
  • 1,146
  • 1
  • 16
  • 26
0

İf you already committed, you can use this:

  1. Add folder path to .gitignore file.
  2. Run this command for removing exe (for another file extensions, just write "*extension") files. git rm --cached *exe
  3. Commit changes.

You should do this for every extension that you wanted to remove.

umutcx
  • 1
0

After editing .gitignore file.

git rm -r --cached ./ &&  git add ./ && git commit -a -m "Removing ignored files" && git push
Greggory Wiley
  • 660
  • 6
  • 16
0

If you are git rm'ing a lot of files (say, 100k), answers in this thread could be improved by processing the list of files (produced by git ls-files -ci --exclude-standard) in batches. (AFAIK, parallel processing will not work with git due to its index-locking mechanism.)

Example of batching in Powershell:

$files = git ls-files -ci --exclude-standard
$batchSize = 100

for ($i = 0; $i -lt $files.Count; $i += $batchSize) {
    $batch = $files[$i..($i + $batchSize - 1)]
    git rm -f --cached $batch
}

On Windows, the upper bound on $batchSize is the limit of the command line length. For short paths, you might get away with larger a $batchSize.

em_kay
  • 1
  • 1
-3

Follow these steps:

  1. Add path to gitignore file

  2. Run this command

    git rm -r --cached foldername
    
  3. commit changes as usually.

Martin
  • 2,411
  • 11
  • 28
  • 30