Base on AD7six, with renamed files history preserved. (you can skip the preliminary optional section) ref.: https://stackoverflow.com/a/33873223
remove all remotes
git remote | while read -r line; do (git remote rm "$line"); done
remove all tags
git tag | xargs git tag -d
remove all other branches
git branch | grep -v \* | xargs git branch -D
remove all stashes
git stash clear
remove all submodules configuration and cache
git config --local -l | grep submodule | sed -e 's/^\(submodule\.[^.]*\)\(.*\)/\1/g' | while read -r line; do (git config --local --remove-section "$line"); done
rm -rf .git/modules/
Pruning untracked files history, keeping tracked files history & renames
git ls-files | sed -e 's/^/"/g' -e 's/$/"/g' > keep-these.txt
git ls-files | while read -r line; do (git log --follow --raw --diff-filter=R --pretty=format:%H "$line" | while true; do if ! read hash; then break; fi; IFS=$'\t' read mode_etc oldname newname; read blankline; echo $oldname; done); done | sed -e 's/^/"/g' -e 's/$/"/g' >> keep-these.txt
git filter-branch --force --index-filter "git rm --ignore-unmatch --cached -qr .; cat \"$PWD/keep-these.txt\" | xargs git reset -q \$GIT_COMMIT --" --prune-empty --tag-name-filter cat -- --all
rm keep-these.txt
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
First two commands are to list tracked files and tracked files old names, using quotes to preserve paths with spaces. Third command is to rewrite the commits for those files only. Subsequent commands are to clean the history.
repack (from the-woes-of-git-gc-aggressive)
git repack -a -d --depth=250 --window=250