Modify name and email of past git commits in repository

If you work under multiple names and aliases, such as a work and a hobby name/email, it can be annoying if you started working on a project under one name but want to publish it under another. It would be nice to be able to change this retrospectively.

All the resources I could find on the internet about this didn't fully do what I wanted because all of them either

So I came up with an—admittedly very hacky—script to do this:

[ $# -lt 3 ] && echo "Usage:
$0 ./super-cool-git-repo '' 'pseudonym <>'" && exit 1
oldRepo="$1" # Path to the git repository you want to fix
[ -e "$newRepo" ] && echo "$PWD/$newRepo already exists" && exit 1
oldFrom="$2" # A regex that matches the name/email you want to replace
newFrom="$(echo "$3")" # The new name and email in the format 'bob@smith <>'
mkdir "$newRepo"
cd "$newRepo"
user="$(echo "$newFrom" | grep -Po '.*(?= <)')"
email="$(echo "$newFrom" | grep -Po '<\K[^>]*')"
git init
git config "$user"
git config "$email"
	initial=$(git -C "../$oldRepo" rev-list --max-parents=0 HEAD)
	git -C "../$oldRepo" format-patch -k --stdout -1 $initial
	git -C "../$oldRepo" format-patch -k --stdout $initial..HEAD
} | sed "/From:.*$oldFrom.*/c From: $newFrom" | git am --committer-date-is-author-date
cd - > /dev/null
echo "Done! The modified repository is at $PWD/$newRepo"

Use like so:

./ ./coolrepo '' 'cool pseudonym <>'

The script will create a coolrepo_renamed directory with all commits by bob smith changed to being by cool pseudonym!

WARNING: This script hasn't been thoroughly tested and I don't know whether it might not mess things up in certain edge cases. Make a backup before using it on unpushed work!