Applying .gitignore to committed files
Asked Answered
D

11

608

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.

Decretive answered 23/9, 2011 at 11:2 Comment(3)
possible duplicate of .gitignore file not ignoringSweeper
@Sweeper The answer may be similar, but this question exactly describes the problem I was faced with and needed to solve.Pridemore
This is the answer that directly addresses the title question with minimal changes to your git repo: https://mcmap.net/q/64166/-applying-gitignore-to-committed-filesMclellan
L
633
  1. Edit .gitignore to match the file you want to ignore
  2. git rm --cached /path/to/file

See also:

Lester answered 23/9, 2011 at 11:5 Comment(7)
There's a lot of files though. I don't want to have do this for every single oneDecretive
Are the files in any common directories? If not, the problem reduces to a shell usage question, not a git one.Lester
There does need to be a 'I forgot to add my .gitignore until after my initial commit' mode.Testy
'I forgot to add my .gitignore until after my initial commit' and the answer is the post below this one. It works!Mallorie
It asked me to add flag -r to be able to do so.Hemiplegia
Another way to fix it: #45608837Yorktown
Does this need to be done by every developer or just once?Sundin
A
719

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!

Aerobiosis answered 23/9, 2011 at 16:30 Comment(16)
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!Hyacinthe
On Windows for /F "tokens=*" %a in ('git ls-files -ci --exclude-standard') do @git rm --cached "%a"Testy
This just removed my .gitignore files, not the files I wanted to ignore that were listed in the .gitignore files - was that the point?Distant
@Distant 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.Aerobiosis
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?Farrago
Worked flawlessly. Much appreciated!Encomiast
I got an error xargs: git : Bad file number using git 1.9.2. Using SourceTree's embedded git works fine, not sure why.Grosberg
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!Mallorie
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.Poll
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)Ingredient
@Zero3 This is what happens when you have to dive into the plumbing instead of just using porcelain commandsAerobiosis
For mac users, -r is default and is not accepted by BSD versions. So remove -r.Brebner
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.Debrahdebrecen
I have done both steps but removed files to be ignored from commits all of them ended in a "staged files" area in the SourceTreeRoast
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?Burdette
Is it possible to remove such files from all previous commits?Grane
L
633
  1. Edit .gitignore to match the file you want to ignore
  2. git rm --cached /path/to/file

See also:

Lester answered 23/9, 2011 at 11:5 Comment(7)
There's a lot of files though. I don't want to have do this for every single oneDecretive
Are the files in any common directories? If not, the problem reduces to a shell usage question, not a git one.Lester
There does need to be a 'I forgot to add my .gitignore until after my initial commit' mode.Testy
'I forgot to add my .gitignore until after my initial commit' and the answer is the post below this one. It works!Mallorie
It asked me to add flag -r to be able to do so.Hemiplegia
Another way to fix it: #45608837Yorktown
Does this need to be done by every developer or just once?Sundin
S
211

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/

Susann answered 7/10, 2014 at 21:55 Comment(5)
Chronial has a great answer for doing this recursively for a directory: https://mcmap.net/q/12404/-recursive-git-update-index-assume-unchangedMagistrate
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.Quarterly
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.Mclellan
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.Kimi
The last command, on windows, replace grep with findstr for the same result. git ls-files -v|findstr '^h'Continuity
D
206

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

Danielson answered 31/3, 2017 at 14:18 Comment(4)
This should be the accepted answer as the question specifically said there were a lot of files to remove.Styria
Note that step 2 this can take a while if you have a big repository.Mignonmignonette
This just led to removal of all files from the index! This saved me: git reset HEAD (Remember to stash any changes)Nebraska
Step 2 removes everything, yes, but step 3 should readd them all, except for the ones that fail due to .gitignore.Impertinence
F
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 $_ }
Fontanel answered 11/2, 2015 at 15:46 Comment(0)
L
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.

Leapfrog answered 23/8, 2021 at 13:49 Comment(0)
H
1

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)
Hitt answered 26/11, 2021 at 17:5 Comment(0)
B
1

After editing .gitignore file.

git rm -r --cached ./ &&  git add ./ && git commit -a -m "Removing ignored files" && git push
Blood answered 3/8, 2022 at 18:1 Comment(0)
T
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.

Teetotum answered 17/12, 2021 at 12:4 Comment(0)
A
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.

Adulterant answered 4/6, 2023 at 4:59 Comment(0)
K
-3

Follow these steps:

  1. Add path to gitignore file

  2. Run this command

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

Kellen answered 20/4, 2017 at 7:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.