Skip to content

Instantly share code, notes, and snippets.

@maxpeterson
Last active December 16, 2020 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxpeterson/ffc196f739404066997b7b9d002114a3 to your computer and use it in GitHub Desktop.
Save maxpeterson/ffc196f739404066997b7b9d002114a3 to your computer and use it in GitHub Desktop.
Rewrite all commits to anonymise author and committer's name and email
#!/bin/sh
# Each author and committer's name and email will be replaced by an anonymous value
# Create a git alias
# git change-commits GIT_AUTHOR_NAME "old name" "new name"
git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "
# Git valriables to replace with git log formats to generate a list of values toi change
declare -a formats=("GIT_AUTHOR_NAME::%aN" "GIT_AUTHOR_EMAIL::%aE" "GIT_COMMITTER_NAME::%cN" "GIT_COMMITTER_EMAIL::%cE");
formatslength=${#formats[@]};
filename="git-anonymise-$(date '+%Y-%m-%d-%H-%M-%S').csv";
echo 'Branch\tName\tOld Value\tNew Value\tReverse' > $filename;
ls .git/refs/heads | while read -r branch ; do
echo "Processing branch $branch";
for index in "${formats[@]}" ; do
gitName="${index%%::*}";
format="${index##*::}";
newValueFmt=$([[ $gitName == *_EMAIL ]] && echo 'echo anon$counter@example.com' || echo 'echo Anonymous $counter');
echo "Processing $gitName";
counter=0;
git log --all --format="$format" | sort -u | while read -r oldValue ; do
counter=$[counter + 1];
newValue=$(eval $newValueFmt);
echo "$branch"'\t'"$gitName"'\t'"$oldValue"'\t'"$newValue"'\t'"git change-commits '$gitName' '$newValue' '$oldValue' '$branch'" >> $filename;
git change-commits "$gitName" "$oldValue" "$newValue" "$branch";
# Delete the old commits
rm -rf .git/refs/original/
done
done
done
echo "Anonymisation mapping in $filename"
# Delete remotes, which might point to the old commits
git remote | while read -r name ; do git remote rm $name; done
# Your old commits will now no longer show up in GitK, `git log` or `git
# reflog`, but can still be found using `git show $commit-id`.
@maxpeterson
Copy link
Author

Use filter-repo

Create a mapping based on the git shortlog email summary 

git shortlog —email --summary > mailmap-author.txt

Ensue all committer are included (not just authors), using ... 

git shortlog —email --summary --committer

Update mailmap-author.txt to include the mapping using any of the following formats:

Name For User <email@addre.ss>
<new@ema.il> <old1@ema.il>
New Name And <new@ema.il> <old2@ema.il>
New Name And <new@ema.il> Old Name And <old3@ema.il>

Run the mapping (this will rewrite git history so ensure you have a backup of the repo)

git filter-repo --mailmap mailmap-author.txt --replace-refs delete-no-add —force

The filter-repo  command will remove the original remote … 

Add the new remote.

git remote add origin ssh://git-codecommit.eu-west-1.amazonaws.com/v1/repos/<project_name>

Push to the remote

git push --set-upstream origin master

Also see https://tanimislamblog.wordpress.com/2019/11/05/how-to-use-git-filter-repo-to-change-inconvenient-emails/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment