-
-
Save MorikoHandford/ef1a6b113e882f861d3b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# WARNING | |
# This expects your repository to be in ~/git . If your repository is elsewhere you will need to alter the script. | |
# SYNOPSIS | |
# git_cleanup [repo name] [-xl] | |
# DESCRIPTION | |
# This script allows people to delete (-x) the history of a directory OR destroy (-l) the history of a directory and just | |
# retain the latest version (useful for cutting down on space consumption). | |
# OPTIONS | |
# -x, --expunge <directory> Deletes the directory and its history. | |
# -l, --keeplatest <directory> Deletes the history but keeps the latest version. | |
if [ ! -d ~/git/ ]; then | |
echo "This script currently requires your repository to be in ~/git . Either change your path or your script!" | |
exit | |
fi | |
if [ $# -lt 2 ]; then | |
echo "format: git_cleanup <repo name> [-x/--expunge <directory 1> -l/--keeplatest <directory 2> ...]" | |
exit | |
fi | |
PROJ="$1" | |
shift | |
if [ ! -d ~/git/${PROJ}.git ]; then | |
echo "Your repository directory must end with .git !" | |
exit | |
fi | |
export EXPUNGE=() | |
export KEEPLATEST=() | |
while [[ $# > 1 ]]; do | |
key="$1" | |
shift | |
case $key in | |
-x|--expunge) | |
folder="$1" | |
EXPUNGE+=("$folder") | |
echo "expunging: $folder" | |
shift | |
;; | |
-l|-k|--keeplatest) | |
folder="$1" | |
KEEPLATEST+=("$folder") | |
echo "keeping latest: $folder" | |
shift | |
;; | |
*) | |
echo "unknown option $key" | |
echo "format: git_cleanup <repo name> [-x/--expunge <directory 1> -l/--keeplatest <directory 2> ...]" | |
exit | |
;; | |
esac | |
done | |
echo ------------------------------------------------------------------- | |
echo setting up working repositories | |
cd ~/git | |
# folders used: | |
# X-shrinking: (non-bare) working repo where we rewrite git indexes to cut the unwanted folders | |
# X-stash: For retainlatest folders, keep a copy here during the expunging | |
# X-addback: a (non-bare) clone of the post-expunged shrinking repo, where we add back stashed folders | |
# X-shrink.git: The output | |
[ -d ${PROJ}-shrinking ] && rm -rf ${PROJ}-shrinking | |
[ -d ${PROJ}-stash ] && rm -rf ${PROJ}-stash | |
[ -d ${PROJ}-shrunk.git ] && rm -rf ${PROJ}-shrunk.git | |
mkdir ${PROJ}-stash | |
git clone --no-local ${PROJ}.git ${PROJ}-shrinking | |
cd ${PROJ}-shrinking | |
for folder in ${KEEPLATEST[@]}; do | |
echo "stashing the latest version of $folder" | |
rsync -az ~/git/${PROJ}-shrinking/$folder/ ~/git/${PROJ}-stash/$folder | |
done | |
echo ------------------------------------------------------------------- | |
echo filtering... | |
BADFOLDERS=("${EXPUNGE[@]}" "${KEEPLATEST[@]}") | |
FILTERPARTS=$(for folder in ${BADFOLDERS[@]}; do echo "git rm -rf --cached --ignore-unmatch $folder"; done) | |
export FILTERCMD=${FILTERPARTS[0]}$(printf " \&\& %s" "${FILTERPARTS[@]:1}") | |
git filter-branch -f --index-filter '$FILTERCMD' --prune-empty --tag-name-filter cat -- --all | |
rm -Rf refs/original | |
rm -Rf refs/logs | |
git gc | |
echo ------------------------------------------------------------------- | |
cd ~/git | |
git clone --no-local ${PROJ}-shrinking ${PROJ}-addback | |
cd ${PROJ}-addback | |
for folder in ${KEEPLATEST[@]}; do | |
echo "restoring from stashed copy of $folder" | |
rsync -az ~/git/${PROJ}-stash/$folder/ ~/git/${PROJ}-addback/$folder | |
git add . --all | |
git commit -a -m "re-adding latest version of $folder" | |
done | |
echo "Cloning to output repository" | |
cd ~/git | |
git clone --bare --no-local ${PROJ}-addback ${PROJ}-shrunk.git | |
read -p "delete working data (y/n)?" | |
echo | |
if [[ $REPLY =~ ^[Yy]$ ]]; then | |
rm -rf ${PROJ}-shrinking | |
rm -rf ${PROJ}-addback | |
rm -rf ${PROJ}-stash | |
fi | |
read -p "backup original and replace with shrunk repository (y/n)?" | |
echo | |
if [[ $REPLY =~ ^[Yy]$ ]]; then | |
mv ${PROJ}.git ${PROJ}-$(date -u +"%Y-%m-%dT%H:%M:%SZ").git | |
mv ${PROJ}-shrunk.git ${PROJ}.git | |
fi | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment