Resync git repo with new .gitignore file

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.

Upvotes: 253

Views: 146898

Answers (4)

Rod Limao
Rod Limao

Reputation: 53

I found a more cautious but manual way to avoid losing your changes if you not have enough experience with GIT.

As same as the official answer, instead of removing everything with the period . you can remove just the new pattern you put in your .gitignore file.

Let's say you want to remove all .bak and .cache files, but you forgot to create or put these patterns in gitignore, here's what you should do after created the gitignore file:

git add .gitignore
git commit -m "Create/change gitignore message"
git push
git rm -r --cached .bak .cache
git add .
git commit -m "My regular commit message"

You can even verify if what you put in gitignore is working by checking every step with git status as follow:

git rm -r --cached .bak
git status
git rm -r --cached .cache
git status
...

If something wrong you could just use git restore {same_pattern_you_use_to_remove} and try again.

But if you have a lot of changes in your new gitignore file, I recommend you folow the official answer with jball037 comment:

git rm -r --cached .
git reset HEAD
# all files will be restored without what was included in the new gitignore
git add.
git commit -m "My regular commit message"
git push

Upvotes: 3

Jason
Jason

Reputation: 2671

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.

Upvotes: 1

VonC
VonC

Reputation: 1329692

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

Upvotes: 472

theor
theor

Reputation: 1595

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'

Upvotes: 10

Related Questions