Skip to content

Instantly share code, notes, and snippets.

@dataday
Created August 1, 2018 09:52
Show Gist options
  • Save dataday/2138c330a2f640cf16ee0cc9a84d6161 to your computer and use it in GitHub Desktop.
Save dataday/2138c330a2f640cf16ee0cc9a84d6161 to your computer and use it in GitHub Desktop.
Provides the ability to remove the top 5 heavy references from projects (to be tested)
#!/usr/bin/env bash
# description: This script provides the ability to remove the top 5 heavy references from projects
# author: dataday
# version: 0.1.0
# defaults
EXEC=$(realpath -L "${0#./}")
EXEC_BASE="${EXEC%/*}"
EXEC_NAME=$(basename "$EXEC")
# enable extended pattern matching features
# https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
shopt -s extglob
function remove_file_reference() {
local reference="$1"
printf '%s\n' "Removing $reference"
# remove the reference from all branches
git filter-branch --index-filter $(git rm --cached --ignore-unmatch "$reference")
# remove the local git backup
rm -rf "$EXEC_BASE/.git/refs/original/"
# set loose object expiry
git reflog expire --all --expire='now'
# check for remaining loose objects
git fsck --full --unreachable
# repack the git 'pack'
git repack -A -d
# remove reference from project
git prune
}
#
# determines user action from prompt
function prompt() {
local revision="$1"
local reference="$2"
# failed to determine file reference (not set or empty value)
if [ -z ${reference+v} ]; then
printf '%s\n' "Could not determine file reference: '$reference'"
exit 1
# determined file reference
else
# read user input to confirm reference removal
read -p "Remove $reference ($revision)? (y|Y/n|N) " SELECTION </dev/tty;
# pattern match user input from selection
case "$SELECTION" in
# remove reference
@(y|Y) ) remove_file_reference "$reference" ;;
# ignore reference
@(n|N) ) printf '%s\n' "Ignoring $reference ($revision)" ;;
esac
fi
}
#
# inspect pack for top 5 heavy file references
git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | while IFS= read -r line; do
# assign asset revision hash
revision=$(echo "$line" | cut -d' ' -f1)
# assign file reference from revision hash
reference=$(git rev-list --objects --all | grep "$revision")
file_reference=$(echo "$reference" | cut -d' ' -f2)
# call prompt to confirm file reference removal
prompt "$revision" "$file_reference"
done
exit $?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment