Last active
December 15, 2023 14:25
-
-
Save EtherZa/5be6dee35219525cc9b305e86143ea69 to your computer and use it in GitHub Desktop.
git filter to smudge/clean secrets stored in .ini
This file contains hidden or 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 | |
# README | |
# Swap secrets for placeholders on commit/restore | |
# | |
# Copy this file to ~/scipts/git-redact-filter.sh | |
# chmod +x ~/scripts/git-redact-filter.sh | |
# | |
# Create ~/scripts/secret.ini | |
# populate with key=value | |
# ensure last key/value pair has a line break. | |
# empty lines, section headings and lines starting with # or ; are excluded | |
# | |
# Add fiters to git (drop --global for a single repo) | |
# git config --global filter.redact.smudge "~/scripts/git-redact-filter.sh smudge ~/scripts/secrets.ini" | |
# git config --global filter.redact.clean "~/scripts/git-redact-filter.sh clean ~/scripts/secrets.ini" | |
# | |
# Add files to process to .gitattributes | |
# *.json filter=redact | |
# *.env filter=redact | |
# *.yml filter=redact | |
# | |
# To remove filters | |
# git config --global --unset filter.redact.smudge | |
# git config --global --unset filter.redact.clean | |
# Check if the correct number of arguments is provided | |
if [ "$#" -ne 2 ]; then | |
echo "Usage: $0 <clean/smudge> <config_file>" | |
exit 1 | |
fi | |
config_file="$2" | |
# Exist if the file does not exist | |
if [ ! -e "$config_file" ]; then | |
echo "$config_file not found" | |
exit 2 | |
fi | |
sedcmd="sed" | |
# mac - use gsed instead of sed | |
# if [[ "$(uname)" == "Darwin" ]]; then | |
# sedcmd="gsed" | |
# fi | |
declare -A mapArr | |
# Use process substitution to avoid subshell | |
while read -r bash_code; do | |
eval "$bash_code" | |
done < <( | |
awk -F '=' '/^[[:space:]]*[^#\[;[:space:]].*[[:space:]]*=[[:space:]]*[^[:space:]]+[[:space:]]*/ { | |
key = $1 | |
value = $2 | |
# Trim leading and trailing whitespace | |
gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) | |
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value) | |
# Escape quote for print | |
gsub(/"/, "\\\"", key) | |
gsub(/"/, "\\\"", value) | |
# Escaoe / for sed replacement | |
gsub(/\//, "\\/", key) | |
gsub(/\//, "\\/", value) | |
# Use print to generate Bash code for populating mapArr | |
print "mapArr[\"" key "\"]=" "\"" value "\"" | |
}' "$config_file" | |
) | |
if [[ "$1" == "smudge" ]]; then | |
# For smudge, sort by descending value length to avoid clashes | |
# Create an mapArray of keys | |
keys=("${!mapArr[@]}") | |
# Sort the keys based on the corresponding values' lengths | |
IFS=$'\n' sorted_keys=($( | |
for key in "${keys[@]}"; do | |
echo "${#mapArr[$key]} $key" | |
done | sort -k1,1nr | cut -d ' ' -f 2- | |
)) | |
for key in "${sorted_keys[@]}"; do | |
value=${mapArr[${key}]} | |
sedcmd+=" -e \"s/\[${key}\]/${value}/g\"" | |
done | |
elif [[ "$1" == "clean" ]]; then | |
for key in "${!mapArr[@]}"; do | |
value=${key} | |
key=${mapArr[${key}]} | |
sedcmd+=" -e \"s/${key}/\[${value}\]/g\"" | |
done | |
else | |
echo "Usage: $0 <clean/smudge> <config_file>" | |
exit 1 | |
fi | |
eval "$sedcmd" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Clean/smudge configurations can also be applied to a collection of repositories separated by folder.
~/.gitconfig - apply config per parent path
c:/git - common redact script
git-redact-filter.sh
c:/git/aa
.gitattributes - which files to apply redact to
.gitconfig - override global .gitattributes location and add filter
.redact.ini - secrets to smudge/clean