Reputation: 1341
So I read a lot about how to change previous commit's email address but for some reason mine is not updating.
I did like 40 commits to my private repo with my local email ([email protected]) which is bad since this email is not associated(and it can't be) with Github.
I then remembered that I needed to set the git.config before and so I did:
git config user.email "[email protected]"
and did a test commit and it worked perfectly.
Is there a way I can revert all my previous commits to this new email?
I read this question on SO How do I change the author and committer name/email for multiple commits? and used this
git filter-branch -f --env-filter "
GIT_AUTHOR_EMAIL='[email protected]';
GIT_COMMITTER_EMAIL='[email protected]';
"
HEAD
But it DID NOT work... I can still see the email of my previous commits with the .patch extension as the .local email address
Upvotes: 47
Views: 31201
Reputation: 369
Here's a version based on Chris Maes' answer that only applies the change to commits with a matching email address, and uses rebase --root
(since git 1.7) to write from the beginning of your history.
If you want to choose the a specific base commit, you'll want to remove --root
, and use the refspec you want.
function reauthor_all {
if [[ "$#" -eq 0 ]]; then
echo "Incorrect usage, no email given, usage is: $FUNCNAME <email>" 1>&2
return 1
fi
local old_email="$1"
# Based on
# SO: https://stackoverflow.com/a/34863275/9238801
local new_email="$(git config --get user.email)"
local new_name="$(git config --get user.name)"
# get each commit's email address ( https://stackoverflow.com/a/58635589/9238801 )
# I've broken this up into two statements and concatenated
# because I want to delay evaluation
local command='[[ "$(git log -1 --pretty=format:'%ae')" =='
command+=" '$old_email' ]] && git commit --amend --author '$new_name <$new_email>' --no-edit || true"
git rebase -i --root -x "$command"
}
Use on my own repo:
reauthor_all "[email protected]"
hint: Waiting for your editor to close the file...
Press ENTER or type command to continue
Executing: [[ "$(git log -1 --pretty=format:%ae)" == '[email protected]' ]] && git commit --amend --author 'Matthew Strasiotto <[email protected]>' --no-edit || true
Executing: [[ "$(git log -1 --pretty=format:%ae)" == '[email protected]' ]] && git commit --amend --author 'Matthew Strasiotto <[email protected]>' --no-edit || true
[detached HEAD 1e281b5] First Message
...etc
You'll need to force push when it looks right eventually, and this WILL change commit shas, so that's going to cause a whole host of other problems.
Upvotes: 3
Reputation: 37722
You can indeed do his for many commits at once like this:
git rebase -i HEAD~40 -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"
I worked this out better in this answer.
Upvotes: 88
Reputation: 142004
As you mentioned in your question (the link to the answer you found), this is the script indeed.
filter-branch
is doing a rebase (will rewrite the history of the branch) which means that everyone who had a copy of the branch will have to delete and checkout it again.
The script origin is from here - Git-Tools-Rewriting-History:
# Loop over all the commits and use the --commit-filter
# to change only the email addresses
git filter-branch --commit-filter '
# check to see if the committer (email is the desired one)
if [ "$GIT_COMMITTER_EMAIL" = "<Old Email>" ];
then
# Set the new desired name
GIT_COMMITTER_NAME="<New Name>";
GIT_AUTHOR_NAME="<New Name>";
# Set the new desired email
GIT_COMMITTER_EMAIL="<New Email>";
GIT_AUTHOR_EMAIL="<New Email>";
# (re) commit with the updated information
git commit-tree "$@";
else
# No need to update so commit as is
git commit-tree "$@";
fi'
HEAD
Its looping over all your commits and once you find match its replacing the name and email of the committer.
Upvotes: 15