git - How to remove committed files no longer in working directory -
i have repo lots of files no longer in working directory- files have been added , removed on months/years of repository.
i make file list of these files stored in commit histories no longer required, including locations.. i.e.
/web/scripts/index.php /sql/tables.sql ...
then command runs through file , removes files referenced in commit history completely, git rm --cached
list of files.
short answer
alias david underhill's script, run (with caution):
$ git delete `git log --all --pretty=format: --name-only --diff-filter=d`
explanation
david underhill's command uses filter-branch
modify history of repository, removing history of given file path.
the script, in entirety (source):
#!/bin/bash set -o errexit # author: david underhill # script permanently delete files/folders git repository. use # it, cd repository's root , run script list of paths # want delete, e.g., git-delete-history path1 path2 if [ $# -eq 0 ]; exit 0 fi # make sure we're @ root of git repo if [ ! -d .git ]; echo "error: must run script root of git repository" exit 1 fi # remove paths passed arguments history of repo files=$@ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" head # remove temporary history git-filter-branch otherwise leaves behind long time rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune
save script location on hard drive (e.g. /path/to/deletion_script.sh
), , make sure it's executable (chmod +x /path/to/deletion_script.sh
).
then alias command:
$ git config --global alias.delete '!/path/to/deletion_script.sh'
to sorted list of deleted files:
$ git log --all --pretty=format: --name-only --diff-filter=d | sort -u
bringing together
with list of deleted files, it's matter of hooking git delete
process each file in list:
$ git delete `git log --all --pretty=format: --name-only --diff-filter=d`
testing/example usage
make dummy repository additions, renamings, , deletions:
mkdir test_repo cd test_repo/ git init echo "dummy content" >> stays.txt git add stays.txt && git commit -m "first file, stay" echo "rename content" >> will_rename.txt git add will_rename.txt && git commit -m "going rename" echo "delete file" >> will_delete.txt git add will_delete.txt && git commit -m "delete file" git mv will_rename.txt renamed.txt && git commit -m "file renamed" git rm will_delete.txt && git commit -m "file deleted"
inspect history:
$ git whatchanged --oneline d768c58 file deleted :100644 000000 7a4187c... 0000000... d will_delete.txt 96aadf0 file renamed :000000 100644 0000000... 94a12c7... renamed.txt :100644 000000 94a12c7... 0000000... d will_rename.txt 3ba05fa delete file :000000 100644 0000000... 7a4187c... will_delete.txt c88850a going rename :000000 100644 0000000... 94a12c7... will_rename.txt 6db6015 first file, stay :000000 100644 0000000... f3ae800... stays.txt
delete old files:
$ git delete `git log --all --pretty=format: --name-only --diff-filter=d` rewrite 8c2009db5ac05b27cd065482da94dec717f5ef4a (8/9)rm 'will_delete.txt' rewrite e1348d588597f2f6dd63cade081e0fbdf8692c74 (9/9) ref 'refs/heads/master' rewritten counting objects: 27, done. delta compression using 4 threads. compressing objects: 100% (22/22), done. writing objects: 100% (27/27), done. total 27 (delta 12), reused 10 (delta 0)
inspect repository now. notice deletions have been removed history, , renamings appear if file added way.
c800020 file renamed :000000 100644 0000000... 94a12c7... renamed.txt 0a729d7 first file, stay :000000 100644 0000000... f3ae800... stays.txt
Comments
Post a Comment