247

Is it possible to "refresh" a git repository after updating the gitignore file?

I just added more ignorations(?) to my gitignore and would like to remove stuff already in the repo matching the new file.

Pavan Nagadiya
  • 652
  • 4
  • 10
Christian Wattengård
  • 5,543
  • 5
  • 30
  • 43

3 Answers3

458

The solution mentioned in ".gitignore file not ignoring" is a bit extreme, but should work:

# rm all files
git rm -r --cached .
# add all files as per new .gitignore
git add .
# now, commit for new .gitignore to apply
git commit -m ".gitignore is now working"

(make sure to commit first your changes you want to keep, to avoid any incident as jball037 comments below.
The --cached option will keep your files untouched on your disk though.)

You also have other more fine-grained solution in the blog post "Making Git ignore already-tracked files":

git rm --cached `git ls-files -i --exclude-standard`

Bassim suggests in his edit:

Files with space in their paths

In case you get an error message like fatal: path spec '...' did not match any files, there might be files with spaces in their path.

You can remove all other files with option --ignore-unmatch:

git rm --cached --ignore-unmatch `git ls-files -i --exclude-standard`

but unmatched files will remain in your repository and will have to be removed explicitly by enclosing their path with double quotes:

git rm --cached "<path.to.remaining.file>"
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I have found that the git add step is unnecessary, when I run git status after git rm --cached , the removed files are already in the staging area and you can just go ahead and commit them. – chap May 07 '15 at 05:33
  • 9
    I just ran this, lost all of my uncommitted changes, and nearly announced my resignation from my job. The accepted answer on this thread saved my life: http://stackoverflow.com/questions/2125710/how-to-revert-a-git-rm-r – jball037 Jul 07 '15 at 15:12
  • @jbal I am sorry for this bad experience, but also confused: did you keep the --cached option? This option ensures the files remain (untouched) on your disk, meaning your changes should have still been there. – VonC Jul 07 '15 at 15:56
  • 2
    @VonC sorry, that wasn't meant to be a rant or a stick :) But yes, I used --cached and all of my uncommitted changes were lost when I checked my files. Panicked for a moment but "git reset HEAD" restored my files (but this time without the files I specified in .gitignore, so your solution still worked!) – jball037 Jul 07 '15 at 17:03
  • @jball037 Great! Is there anything I can add/edit to my answer in order for your kind of experience to *not* happen again? – VonC Jul 07 '15 at 17:06
  • @VonC sure, maybe mention that the user should first commit the changes he wishes to keep, then do your solution. It *seems* like the second link you posted might have a workaround for that, but frankly it wasn't completely clear to me. Regardless, I still appreciate you posting this answer! – jball037 Jul 07 '15 at 17:13
  • 3
    @jball037 Good. I have added the warning and edited the answer accordingly. – VonC Jul 07 '15 at 17:21
  • 1
    if only i read one line further before doing this "(make sure to commit first your changes you want to keep, to avoid any incident as jball037" #fml – Aiden Strydom Sep 15 '16 at 06:50
  • @AidenStrydom Hopefully, jball037's solution helps: http://stackoverflow.com/a/2125738/6309 – VonC Sep 15 '16 at 06:53
10

I might misunderstand, but are you trying to delete files newly ignored or do you want to ignore new modifications to these files ? In this case, the thing is working.

If you want to delete ignored files previously commited, then use

git rm –cached `git ls-files -i –exclude-standard`
git commit -m 'clean up'
theor
  • 1,545
  • 1
  • 9
  • 16
1

I know this is an old question, but gracchus's solution doesn't work if file names contain spaces. VonC's solution to file names with spaces is to not remove them utilizing --ignore-unmatch, then remove them manually, but this will not work well if there are a lot.

Here is a solution that utilizes bash arrays to capture all files.

# Build bash array of the file names
while read -r file; do 
    rmlist+=( "$file" )
done < <(git ls-files -ic --exclude-standard)

git rm --cached "${rmlist[@]}"

git commit -m 'ignore update'

Edit: As of version ~2.41.0, git ls-files -i also requires -c.

Jason
  • 2,493
  • 2
  • 27
  • 27