I have some files in my repository that should be ignored, i added them to the .gitignore but, of course, they are not removed from my repository.
So my question is, is there a magic command or script using filter-branch that can rewrite my history and remove all these files easily? Or simply a command that will create a commit that will remove them ?
I did a very straightforward solution by manipulating the output of the .gitignore statement with sed:
cat .gitignore | sed '/^#.*/ d' | sed '/^\s*$/ d' | sed 's/^/git rm -r /' | bash
Explanation:
If you really want to prune your history of .gitignore
d files, first save .gitignore
outside the repo, e.g. as /tmp/.gitignore
, then run
git filter-branch --force --index-filter \
"git ls-files -i -X /tmp/.gitignore | xargs -r git rm --cached --ignore-unmatch -rf" \
--prune-empty --tag-name-filter cat -- --all
Notes:
git filter-branch --index-filter
runs in the .git
directory I think, i.e. if you want to use a relative path you have to prepend one more ../
first. And apparently you cannot use ../.gitignore
, the actual .gitignore
file, that yields a "fatal: cannot use ../.gitignore as an exclude file" for some reason (maybe during a git filter-branch --index-filter
the working directory is (considered) empty?)git ls-files -iX <(git show $(git hash-object -w .gitignore))
instead to avoid copying .gitignore
somewhere else, but that alone already returns an empty string (whereas cat <(git show $(git hash-object -w .gitignore))
indeed prints .gitignore
's contents as expected), so I cannot use <(git show $GITIGNORE_HASH)
in git filter-branch
....gitignore
-clean a specific branch, replace --all
in the last line with its name. The --tag-name-filter cat
might not work properly then, i.e. you'll probably not be able to directly transfer a single branch's tags properlyIn linux you can use this commande :
for exemple i want to delete "*.py~" so my command should be ==>
find . -name "*.py~" -exec rm -f {} \;
The git will ignore the files matched .gitignore pattern after you add it to .gitignore.
But the files already existed in repository will be still in.
use git rm files_ignored; git commit -m 'rm no use files'
to delete ignored files.
An easier way that works regardless of the OS is to do
git rm -r --cached .
git add .
git commit -m "Drop files from .gitignore"
You basically remove and re-add all files, but git add
will ignore the ones in .gitignore
.
Using the --cached
option will keep files in your filesystem, so you won't be removing files from your disk.
Note:
Some pointed out in the comments that you will lose the history of all your files. I tested this with git 2.27.0 on MacOS and it is not the case. If you want to check what is happening, check your git diff HEAD~1
before you push your commit.
I can't say it's an appropriate solution but you can try this.
Steps
This is just a hack solution if you want to maintain the history and don't to create mass in it.
If you don't want to use this solution please kindly ignore and try to avoid devote it. Because I am really trying to increase my score on this side
As the files in .gitignore are not being tracked, you can use the git clean command to recursively remove files that are not under version control.
Use git clean -xdn
to perform a dry run and see what will be removed.
Then use git clean -xdf
to execute it.
Basically, git clean -h
or man git-clean
(in unix) will give you help.
Be aware that this command will also remove new files that are not in the staging area.
Hope it helps.
Source: Stackoverflow.com