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:

#/bin/sh
[ $# -lt 3 ] && echo "Usage:\n$0 ./super-cool-git-repo 'bob.smith@gmail.com' 'pseudonym <pseud@name.lol>'" && exit 1
oldRepo="$1" # Path to the git repository you want to fix
newRepo="${oldRepo}_renamed"
[ -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 <bob@smith.com>'
mkdir "$newRepo"
cd "$newRepo"
user="$(echo "$newFrom" | grep -Po '.*(?= <)')"
email="$(echo "$newFrom" | grep -Po '<\K[^>]*')"
git init
git config user.name "$user"
git config user.email "$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:

./git_rename.sh ./coolrepo 'bob.smith@gmail.com' 'cool pseudonym <pseud@name.lol>'

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!