How to change the author and committer name and e-mail of multiple commits in Git?

1,000,657

Solution 1

This answer uses git-filter-branch, for which the docs now give this warning:

git filter-branch has a plethora of pitfalls that can produce non-obvious manglings of the intended history rewrite (and can leave you with little time to investigate such problems since it has such abysmal performance). These safety and performance issues cannot be backward compatibly fixed and as such, its use is not recommended. Please use an alternative history filtering tool such as git filter-repo. If you still need to use git filter-branch, please carefully read SAFETY (and PERFORMANCE) to learn about the land mines of filter-branch, and then vigilantly avoid as many of the hazards listed there as reasonably possible.

Changing the author (or committer) would require rewriting all of the history. If you're okay with that and think it's worth it then you should check out git filter-branch. The manual page includes several examples to get you started. Also note that you can use environment variables to change the name of the author, committer, dates, etc. -- see the "Environment Variables" section of the git manual page.

Specifically, you can fix all the wrong author names and emails for all branches and tags with this command (source: GitHub help):

#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

For using alternative history filtering tool git filter-repo, you can first install it and construct a git-mailmap according to the format of gitmailmap.

Proper Name <[email protected]> Commit Name <[email protected]>

And then run filter-repo with the created mailmap:

git filter-repo --mailmap git-mailmap

Solution 2

NOTE: This answer changes SHA1s, so take care when using it on a branch that has already been pushed. If you only want to fix the spelling of a name or update an old email, Git lets you do this without rewriting history using .mailmap. See my other answer.

Using Rebase

First, if you haven't already done so, you will likely want to fix your name in git-config:

git config --global user.name "New Author Name"
git config --global user.email "<[email protected]>"

This is optional, but it will also make sure to reset the committer name, too, assuming that's what you need.

To rewrite metadata for a range of commits using a rebase, do

git rebase -r <some commit before all of your bad commits> \
    --exec 'git commit --amend --no-edit --reset-author'

--exec will run the git commit step after each commit is rewritten (as if you ran git commit && git rebase --continue repeatedly).

If you also want to change your first commit (also called the 'root' commit), you will have to add --root to the rebase call.

This will change both the committer and the author to your user.name/user.email configuration. If you did not want to change that config, you can use --author "New Author Name <[email protected]>" instead of --reset-author. Note that doing so will not update the committer -- just the author.

Single Commit

If you just want to change the most recent commit, a rebase is not necessary. Just amend the commit:

 git commit --amend --no-edit --reset-author

For older Git clients (pre-July 2020)

-r,--rebase-merges may not exist for you. As a replacement, you can use -p. Note that -p has serious issues and is now deprecated.

Solution 3

One liner, but be careful if you have a multi-user repository - this will change all commits to have the same (new) author and committer.

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

With linebreaks in the string (which is possible in bash):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD

Solution 4

You can also do:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

Note, if you are using this command in the Windows command prompt, then you need to use " instead of ':

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD

Solution 5

It happens when you do not have a $HOME/.gitconfig initialized. You may fix this as:

git config --global user.name "you name"
git config --global user.email [email protected]
git commit --amend --reset-author

Tested with Git version 1.7.5.4.

Note that this fixes only the last commit.

Share:
1,000,657
Dugan
Author by

Dugan

Just someone trying to learn something...

Updated on July 28, 2022

Comments

  • Dugan
    Dugan over 1 year

    I was writing a simple script on the school computer, and committing the changes to Git (in a repo that was in my pen drive, cloned from my computer at home). After several commits, I realized I was committing stuff as the root user.

    Is there any way to change the author of these commits to my name?

    • AndyL
      AndyL over 13 years
      Question: does using git filter-branch preserve the SHA1's for previous tags, versions and objects? Or will changing the author name force change the associated SHA1's as well?
    • Anonigan
      Anonigan over 13 years
      Or you can try to use refs/replace/ mechanism.
    • Anonigan
      Anonigan over 13 years
      After rewrite, if they didn't base their work on history pre-rewrite, just git reset --hard origin/master or just git pull origin (which should fast-forward). If they based their change, they have to rebase using git rebase origin/master or just git pull --rebase origin (the commands are only examples).
    • Not Available
      Not Available about 13 years
      Hashes will change yes
    • tripleee
      tripleee over 9 years
      Tangentially, I created a small script which finally fixed the root cause for me. gist.github.com/tripleee/16767aa4137706fd896c
    • Claudia
      Claudia about 9 years
      @tripleee I really enjoy your link/response, but this question is about 5 years old at this point. This could become a great Q&A post to make here for other users (answer your own question). It would be more useful, descriptive, and visible than a mere comment here.
    • tripleee
      tripleee about 9 years
      @impinball The age of the question is hardly relevant. Creating a new duplicate question is out of the question. I suppose I could create a question which begs this particular answer but I'm not altogether convinced it would get all that much visibility. It's not like there is a shortage of Git questions here... Glad I could help, anyway.
    • brauliobo
      brauliobo over 5 years
      this answer is much simpler @Flávio Amieiro stackoverflow.com/a/11768870/670229
    • Kaiwen Sun
      Kaiwen Sun about 3 years
      The github script that @TimurBernikovich mentioned is great and works for me. But that github url has changed: docs.github.com/en/enterprise/2.17/user/github/using-git/…
    • paradocslover
      paradocslover over 2 years
      The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • mloughran
    mloughran about 14 years
    Great for the odd commit though - useful if you're pairing and forget to change the author
  • Alec the Geek
    Alec the Geek almost 14 years
    Minor point, the export is actually superfluous although it does no harm. e.g. git-filter-branch --env-filter "GIT_AUTHOR_NAME='New name';GIT_AUTHOR_EMAIL='New email'" HEAD.
  • Nathan Kidd
    Nathan Kidd over 13 years
    +1 for mentioning the usecase for the typical one-mistake fix: git commit --amend --author=username
  • manumoomoo
    manumoomoo over 13 years
    So, there is no safe way to rewrite the user.email. Without blowing up everyone else. I knew that rewriting history was a bad idea, I just thought that there might be a clean way to do it safely. Thanks.
  • Anonigan
    Anonigan over 13 years
    @mediaslave: Try refs/replace/ mechanism.
  • Zitrax
    Zitrax about 13 years
    This is perfect, my most common usecase is that I sit down at another computer and forget to set up author and thus usually have < 5 commits or so to fix.
  • Alan Plum
    Alan Plum almost 13 years
    Worked perfectly. Just had to git reset --hard HEAD^ a couple of times on the other local repositories to get them to an earlier version, git pull-ed the amended version, and here I am without any lines containing unknown <[email protected]> (got to love git's defaulting).
  • stigkj
    stigkj almost 12 years
    Isn't using env-filter the easier solution? Not sure why this is getting more votes, then.
  • Richard
    Richard almost 12 years
    but that's only if it's the most recent commit
  • Daniel Hershcovich
    Daniel Hershcovich over 11 years
    Thanks, I wonder why this is not core git (or git-svn) functionality. This can be done with a flag for git svn clone, but not in git filter-branch...
  • Russell
    Russell over 11 years
    Then link is broken. How do we push these changes to another repository?
  • asmeurer
    asmeurer over 11 years
    @Mike, I totally agree. git filter-branch is a very dangerous command. This should only be used imho in the rare case where you need to delete information from the history permanently (e.g., accidentally committed password or something).
  • asmeurer
    asmeurer over 11 years
    So even if you want to streamline it for multiple commits, it would be better to script git rebase and git commit --amend than to use git filter-branch.
  • user208769
    user208769 over 11 years
    env-filter will change all the commits. This solution allows a conditional.
  • Rory O'Kane
    Rory O'Kane over 11 years
    According to git help commit, git commit --amend changes the commit at the “tip of the current branch” (which is HEAD). This is normally the most recent commit, but you can make it any commit you want by first checking out that commit with git checkout <branch-name> or git checkout <commit-SHA>.
  • hhh
    hhh over 11 years
    "A previous backup already exists in refs/original/ Force overwriting the backup with -f" sorry but where the -f -flag is going to be whene executing this script two times. Actually that is in Brian's answer, sorry about disturbance just after the filter-branch is the solution.
  • Ben
    Ben over 11 years
    That works really well on the last commit. Nice and simple. Doesn't have to be a global change, using --local works too
  • dhara tcrails
    dhara tcrails over 11 years
    But if you do that, all of the commits that already have that commit as a parent will be pointing to the wrong commit. Better to use filter-branch at that point.
  • Fish Monitor
    Fish Monitor over 11 years
    I cannot push after this. Do I have to use "-f"?
  • Fish Monitor
    Fish Monitor over 11 years
    I did git push -f. Also, local repos have to be recloned after this.
  • therobyouknow
    therobyouknow over 11 years
    +1 to this answer, works perfectly for me out-of-the-box. On my local GIT setup in my work I had used my GitHub email for commits. I wanted my corporate email to be present in my work GIT repo commits because my GitHub and work Git were entirely separate projects altogether. This script worked great for this purpose.
  • falstaff
    falstaff almost 11 years
    I needed to use git push -f in order to push this to my repository host (git push -f -u origin master)
  • asmeurer
    asmeurer almost 11 years
    Yes, this rewrites history! See my other response if you want to avoid that.
  • Mike
    Mike almost 11 years
    There is a problem with this solution. It duplicates previous commits. So, if you had 200 commits after running this command you will get 400 commits.
  • Mike
    Mike almost 11 years
    To those who find themselves having duplicates in their commit history, please read refer to this post: stackoverflow.com/questions/1983101/git-duplicate-commit-iss‌​ue
  • Andrew
    Andrew almost 11 years
    Definitely awesome. Can you shorten it by setting user.name and user.email in the repo's local config, and then each line is onlyexec git commit --amend --reset-author -C HEAD ?
  • stigkj
    stigkj over 10 years
    It's not duplicates, it's backup from running the filter-branch command. Nice to have if you did something wrong.
  • stigkj
    stigkj over 10 years
    @user208769 env-filter also allows a conditional; look at my answer :-)
  • Robert Kajic
    Robert Kajic over 10 years
    If you need to run the shell script on a specific branch you can change the last line into: "' master..your-branch-name" (assuming you branched of master).
  • Exectron
    Exectron over 10 years
    If you've got tags, you probably want to use --tag-name-filter cat switch.
  • halfer
    halfer over 10 years
    The problem with this is that other commit metadata (e.g. date and time) is also amended. I just found that out the hard way ;-).
  • D.R.
    D.R. about 10 years
    After executing the script you may remove the backup branch by executing "git update-ref -d refs/original/refs/heads/master".
  • Thanatos
    Thanatos about 10 years
    @JohnGietzen: You can rebase the commits back onto the one that's changed to fix that. However, if you're doing >1 commit, then as mentioned, filter-branch is probably going to be a lot easier.
  • Pete
    Pete almost 10 years
    Instead of specifying an explicit author name and email, you could just use the option --reset-author when amending (assuming you want to use the values from your git configuration), i.e. 'git commit --amend --rebase-author'
  • Antony Stubbs
    Antony Stubbs almost 10 years
    Use ref..head to only run the rewrite on a certain collection of commits. You rarely want to rewrite the entire history.
  • laplasz
    laplasz almost 10 years
    these modifications can be pushed with the -f --force swith
  • Avinash R
    Avinash R almost 10 years
    you can do more automation in this by reusing the commit message in the file .git/rebase-merge/message. this would prevent opening the editor altogether using -f .git/rebase-merge/message :-)
  • user1236048
    user1236048 over 9 years
    I get stackoverflow.com/questions/19864934/… . How do I push the edited commit to replace the already pushed one?
  • asmeurer
    asmeurer over 9 years
    You have to use -f when pushing if you do this, because it changes history. Note that this will screw up anyone who has pulled your code. See my other answer if you want a way to do this without changing history.
  • ThanksForAllTheFish
    ThanksForAllTheFish over 9 years
    +1, although the command in Additional Note must be run for every commit whose author need to change (kind of boring). Also, cannot change author of the first commit with your solution (a problem when you are as dumb as me and do not notice you have global author set to a wrong email from the beginning)
  • Brice
    Brice over 9 years
    That would be even simpler if using the --no-edit option, it'll keep the message of the amended commit.
  • Roman Starkov
    Roman Starkov over 9 years
    Do note that this will leave any tags pointing at the old commits. --tag-name-filter cat is the "make it work" option.
  • jeberle
    jeberle over 9 years
    It's very important to use --tag-name-filter cat. Otherwise your tags will remain on the original chain of commits. The other answers fail to mention this.
  • Rafael Barros
    Rafael Barros over 9 years
    @rodowi, it duplicates all my commits.
  • jmtd
    jmtd over 9 years
    The canonical answer, to use filter-branch, just deleted refs/heads/master for me. So +1 to your controllable, editable solution. Thanks!
  • pts
    pts over 9 years
    git commit --amend --reset-author also works once user.name and user.email are configured correctly.
  • thepeer
    thepeer over 9 years
    Just FYI, I got "malformed --author parameter" when I first tried this. Tried again without my email address and it worked (and inserted my email address into the actual commit).
  • ruffin
    ruffin about 9 years
    Note that the old value is still in a few places in path\to\repo\.git. I'm not sure yet what you'd need to do to expunge it totally. Amends unfortunately (?) don't seem to erase.
  • ruffin
    ruffin about 9 years
    meta.stackexchange.com/a/8259/184684 -- aka, sum links to make them into answers.
  • ntc2
    ntc2 over 8 years
    Rewrite author info on all commits after <commit> using user.name and user.email from ~/.gitconfig: run git rebase -i <commit> --exec 'git commit --amend --reset-author --no-edit', save, quit. No need to edit!
  • asmeurer
    asmeurer over 8 years
    But the typical use-case here is to set the author as something other than the author in .gitconfig.
  • fredoverflow
    fredoverflow over 8 years
    Why do you start with Someone else's commit instead of my bad commit 1? I just tried HEAD^^ to amend the last 2 commits, and it worked perfectly fine.
  • Johnny Utahh
    Johnny Utahh over 8 years
    Kudos for supplying a procedure that changes commits on all refs/branches.
  • spankmaster79
    spankmaster79 over 8 years
    you should not that this of course changes the author on all commits since the commit you're rebasing from. Not just your own
  • Jarosław Bielawski
    Jarosław Bielawski over 8 years
    In place of git rebase -i HEAD^^^^^^ you can also write git rebase -i HEAD~6
  • johannes
    johannes over 8 years
    @RafaelBarros the author info (just like anything else in the history) is part of the commit's sha key. Any change to the history is a rewrite leading to new id's for all commits. So don't rewrite on a shared repo or make sure all users are aware of it ...
  • Nick Volynkin
    Nick Volynkin over 8 years
    Why does it rewrite all commits if you specify HEAD in the end of the command?
  • Nick Volynkin
    Nick Volynkin over 8 years
    @romkyns any idea on how to change tags as well?
  • Nick Volynkin
    Nick Volynkin over 8 years
    Note that this changes only commit author and not the committer
  • Roman Starkov
    Roman Starkov over 8 years
    @NickVolynkin Yes, you specify --tag-name-filter cat. This really should have been the default behaviour.
  • Shumoapp
    Shumoapp about 8 years
    Make sure to checkout a bare repository before running the github script (--bare option). Otherwise it'll flatten your branches.
  • Govind
    Govind about 8 years
    when i run your command, it says "fatal: cannot exec 'git-changemail': Permission denied"
  • Tariq
    Tariq about 8 years
    I'm working in a multi-user repository but I see that my commits were never hooked to my account. Will this safely amend only my commits which are currently submitted as "Unknown author"(but it does have a name) to my Github account?
  • sashoalm
    sashoalm almost 8 years
    Is it possible to adapt this to rename multiple emails in a single pass? I asked a new question about this at stackoverflow.com/questions/33866185/…
  • haxpor
    haxpor over 7 years
    Is there any way to fix the duplicated commits to have only ones from fixed author's email?
  • oligofren
    oligofren over 7 years
    You can use stackoverflow.com/a/11768870/200987 to just affect say the last ten commits
  • Pedro Benevides
    Pedro Benevides over 7 years
    For a single commit, and if you wanna put your username, this is most easy way.
  • Debajit
    Debajit over 7 years
    You can add --no-edit to make this even easier, as generally most people will want to update only the email address and not the commit message
  • Adil
    Adil over 7 years
    Can you guys please share the git command for just to update last commit's email/username with the new one
  • Ryanmt
    Ryanmt over 7 years
    Did you try this? That should be a side effect of this, if not stackoverflow.com/a/2717477/654245 looks like a good path.
  • Olorin
    Olorin about 7 years
    This does not work for my bitbucket repository, any idea ? I do a git push --force --tags origin 'refs/heads/*' after the advised command
  • Matrosov Oleksandr
    Matrosov Oleksandr about 7 years
    For the first time it works perfect. But second time I got this error: Cannot create a new backup. A previous backup already exists in refs/original/ Force overwriting the backup with -f
  • mcont
    mcont almost 7 years
    This works, locally. But what if I want to push the changes to a remote? The command git push --force --tags origin 'refs/heads/*' mentioned in the GitHub docs gives me Everything up-to-date
  • mcont
    mcont almost 7 years
    Solved using git push --force --tags origin HEAD:master
  • daka
    daka almost 7 years
    @rodowi Why have they recommended the use of git push --force --tags origin 'refs/heads/*' over git push -f origin master? I've tried both, the results seem to be the same.
  • Daniel Serodio
    Daniel Serodio almost 7 years
    Beware, I used this script on a very simple branch that I used to create a PR and it completely messed up the history
  • Alessandro Resta
    Alessandro Resta almost 7 years
    To include the first commit you can use git rebase -i --root
  • gw0
    gw0 almost 7 years
    IMPORTANT!!! Before executing the script, set your user.name and user.email git config parameter properly! And after executing the script you'll have some duplicate backup history called "original"! Delete it via git update-ref -d refs/original/refs/heads/master and then check if .git/refs/original folder structure is empty and then just remove it with rm -rf .git/refs/original. Lastly, you can verify the new rewritten log via: git log --pretty=format:"[%h] %cd - Committer: %cn (%ce), Author: %an (%ae)" ! One more thing: .git/logs has some log files that still have your old name!
  • gw0
    gw0 almost 7 years
    By the way: .git/logs is your reflog. It is important and cannot be hand-edited. The only way to get rid of your own name from there is to make a brand new empty repository, set your existing one as a remote, pull in your old repo to a branch, then rebase that branch onto your new repo. I just did that for a sensitive project but it's way too much work for most people (I used a variation of the two answers here: stackoverflow.com/questions/5340790/…). I also did git gc --aggressive afterwards to clean it all up. Good luck.
  • nandilugio
    nandilugio over 6 years
    Both solutions create new commits, but github's one (see accepted answer) keeps the rest of the metadata (e.g. commit date) intact.
  • Native_Mobile_Arch_Dev
    Native_Mobile_Arch_Dev over 6 years
    "git: 'change-commits' is not a git command. See 'git --help'."
  • Aleks
    Aleks over 6 years
    Very nice answer. I like that the changes are wrapped up from the very update to even cleaning up the git commits
  • Toma Radu-Petrescu
    Toma Radu-Petrescu over 6 years
    What if there is no e-mail set? I have been committing and pushing to a repo and now, on GitHub the account which says that committed, doesn't have any avatar or mail. Could you help me, please?
  • asmeurer
    asmeurer over 6 years
    @TomaRadu-Petrescu you will have better luck getting an answer if you ask a new question. There's not enough space in the comments to give a full answer to your question.
  • Yaron U.
    Yaron U. over 6 years
    I've created an interactive script based on this answer - to avoid reediting the script if you have multiple authors to modify gist.github.com/yaronuliel/8157d7318de988f4399f561d466e12f3
  • Samveen
    Samveen about 6 years
    Please note that this changes the timestamp of the commits. See stackoverflow.com/a/11179245/1353267 for reverting to the correct timestamps
  • gxpr
    gxpr over 5 years
    Click on the link <nice solution> as the script has been updated
  • Jorjon
    Jorjon over 5 years
    Note that this resets the commit date
  • bitsmack
    bitsmack over 5 years
    To re-iterate what nandilugio and Jorjon said: This overwrites all of the commit's timestamps. Use the filter-branch script from the accepted answer if you don't want to clobber the metadata.
  • Dan Friedman
    Dan Friedman over 5 years
    I spent hours looking for a solution that worked in PowerShell and this finally solved it for me. I would +1, but apparently, I already did. :)
  • HARSH NILESH PATHAK
    HARSH NILESH PATHAK over 5 years
    The push command for this is : $git push --force --tags origin 'refs/heads/master'
  • vhs
    vhs over 5 years
    Got me 90% of the way there but didn't rewrite my tags with new commit SHAs. I found this example which, when I followed it, updated the commit SHA on my tag.
  • Peter Chaula
    Peter Chaula about 5 years
    I think we can also make our lives easier if we defined an alias for the exec command
  • ecbrodie
    ecbrodie over 4 years
    This one was the big winner for me! The git commit --amend --reset-author --no-edit command is especially useful if you created commits with the wrong author information, then set the correct author after-the-fact via git config. Saved my a$$ just now when I had to update my email.
  • Vladimir
    Vladimir over 4 years
    After this command & sync with master all commits in the history are duplicated! Even of other users :(
  • brauliobo
    brauliobo over 4 years
    @Vladimir that is expected, please study about changing history in git
  • FedFranz
    FedFranz over 4 years
    I also wrote a convenient script to replace author/committer name/email. It can be found here: github.com/frz-dev/utilities/blob/master/git/…
  • Alex
    Alex about 4 years
    I tried many other solutions but this one was the one that worked the best for me :)
  • Soren Bjornstad
    Soren Bjornstad almost 4 years
    This needs to be higher. filter-branch is usually overkill for changing authors -- in my experience it's typically only a few commits that got messed up. And exec is way less confusing and error-prone than manually running the command on every commit you need to change.
  • Soren Bjornstad
    Soren Bjornstad almost 4 years
    Also, by default rebase doesn't show which commits have which authors, so if wrong authors are mixed with right authors this might be a little annoying to get right. In that case, you can use git -c rebase.instructionFormat="[%an <%ae>] %s" rebase -i COMMITISH to add the author details to your rebase plan.
  • danielrvt
    danielrvt almost 4 years
    This will change commits SHA1s. So you keep it in mind
  • asmeurer
    asmeurer almost 4 years
    @danielrvt yes, I've added a note at the top and a link to my other answer which shows how to just fix name spellings or alternate emails without rewriting history (using .mailmap).
  • lepe
    lepe almost 4 years
    To prevent duplications and be safe, I added an answer based in this one (with minor modifications and other explanations replacing the master branch with a clean one).
  • Ashutosh Jindal
    Ashutosh Jindal almost 4 years
    Just a comment to say that once you have used one of the answers below, before updating remote, use the following command to see the updated info: git log -i --date=short --pretty="format:'%C(auto) (%ae, $an, $ce, %cn, %cr, %cd) %h --%s--'" which shows the author's and committer's email and name.
  • Dave
    Dave almost 4 years
    This (i.e. the GitHub solution) does not work on a mac or debian. In both cases, I am unable to subsequently push the changes. I always get the following: remote: error: denying non-fast-forward refs/heads/master (you should pull first) To myserver:/path/to/repo.git ! [remote rejected] HEAD -> master (non-fast-forward) error: failed to push some refs to 'myserver:/path/to/repo.git' Is this solution for GitHub only?
  • Dave
    Dave almost 4 years
    For anyone getting the error in my previous comment, this was the issue for me: How to force push a reset to remote repository?
  • Bryan Bryce
    Bryan Bryce almost 4 years
    I used HEAD~8 and it shows way more than the last 8 commits.
  • Chris Maes
    Chris Maes almost 4 years
    @BryanBryce if there are merge commits involved, things get complicated :)
  • Bryan Bryce
    Bryan Bryce almost 4 years
    @ChrisMaes Ah, I see what's going on. I don't want to mess with those, just on the branch I'm on.
  • Chris Maes
    Chris Maes almost 4 years
    In that case, supposed you branched from master, you could: git rebase -i master -x ...
  • LEVEL
    LEVEL over 3 years
    after all do "git push -f"
  • DharmaTurtle
    DharmaTurtle over 3 years
    Neat; this keeps the old timestamps too.
  • Gabriel Staples
    Gabriel Staples over 3 years
    Even after running this script, some of the metadata sitting around in your project's .git folder may still contain the old email address, which can be confusing when grepping the folder. To find and replace the old email address in that metadata with the new email address, use this command: grep -rl "[email protected]" | xargs sed -i 's/[email protected]/[email protected]/g'. Source: unix.stackexchange.com/questions/472476/….
  • Mayur
    Mayur over 3 years
    This script saves my day.
  • Alexey Sh.
    Alexey Sh. over 3 years
    please pay attention that OLD_EMAIL is case sensitive
  • Steffen Schwigon
    Steffen Schwigon over 3 years
    For me it seems to run in /bin/sh, so I had to replace the bash-specific test [[ ]] with sh-compatible test [ ] (single brackets). Besides that it works very well, thanks!
  • DylanYoung
    DylanYoung over 3 years
    Use --rebase-merges (-p is deprecated)
  • Òscar Raya
    Òscar Raya about 3 years
    Actually this is a very interesting answer. In my case I made some commits from home and it may be confusing an extra author so this is all I needed.
  • Òscar Raya
    Òscar Raya about 3 years
    Also, notice this does not works for web side on Gitea.
  • planetmaker
    planetmaker about 3 years
    This indeed did the trick for me nicely and quickly when I only have a few commits done with a wrong identity.
  • PHP Avenger
    PHP Avenger about 3 years
    I guess push is missing
  • notacorn
    notacorn almost 3 years
    for some reason the old gh help article you linked was removed. script still works but its odd.
  • DJMcMayhem
    DJMcMayhem almost 3 years
    For anyone else struggling with the same problem as me, if you are trying to include the initial commit and you get fatal: Needed a single revision, try git rebase -i --root instead
  • Edward Millen
    Edward Millen almost 3 years
    I think I've found a (seemingly safe) way to delete the old entries in the reflog and the original (now orphaned) commits which still contain the old author details. First run the script as described in this answer, then run git update-ref -d refs/original/refs/heads/master followed by git -c gc.reflogExpireUnreachable=now gc --prune=now. This removes the reference to the old chain of commits, making them orphans, which the second command will then clear all references to from the reflog and delete (prune) the actual commit blobs (check with git show <one of the old commit hashes>)
  • Mauricio Chirino
    Mauricio Chirino almost 3 years
    Dude! You're a lifesaver, I just used your instructions step by step and they saved me a whole bunch of time (I had accidentally pushed several commits with my job key into a public personal library I have and had seriously contemplated copying and pasting again all that work). THANKS!
  • Theodore R. Smith
    Theodore R. Smith almost 3 years
    One line: git rebase -i --rebase-merges --root; while true; do git commit --amend --no-edit --author "Theodore R. Smith <[email protected]>"; git rebase --continue; done
  • Luke Usherwood
    Luke Usherwood almost 3 years
    And to correct the top 10 commits: git rebase --exec 'git commit --amend --author="Author Name <[email protected]>"' HEAD~10 (note the commit-time will be modified)
  • bit
    bit almost 3 years
    @TheodoreR.Smith does this execute without the need for user interaction? I assumed that's what the -i option for the rebase command was for.
  • asmeurer
    asmeurer almost 3 years
    @iuliu.net I'm not sure. This question stackoverflow.com/questions/53629125/… seems to suggest it does, but I haven't confirmed it. Certainly if they don't then they ought to, because it's a standard part of git.
  • Alex Gisi
    Alex Gisi almost 3 years
    @HARSHNILESHPATHAK Note that for recently created repositories the branch master has been renamed main, so the command becomes $git push --force --tags origin 'refs/heads/main'
  • Allan Deamon
    Allan Deamon over 2 years
    You use --root instead of HEAD~N to edit the entire history (including initial commit), and use --reset-author to take the current committer instead of --author ...
  • user2692263
    user2692263 over 2 years
    This seems to be the new kid on the block and I cherish this answer like gold. remember the fields have to be binary and then remove the == lines, and You can unconditionally change everything before pushing. Did I say I like this answer? It should be the accepted one.
  • Wim Deblauwe
    Wim Deblauwe over 2 years
    You can replace -p with --root to change all commits in the history (The -p option is deprecated). And note that this only works after you have corrected the username and email via git config user.name <yourname> and git config user.email <youremail>.
  • H Aßdøµ
    H Aßdøµ over 2 years
    All you have to do is to pass if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
  • H Aßdøµ
    H Aßdøµ over 2 years
    @Govind You need to set the execute permission for the script chmod +x git-changemail
  • PlasmaBinturong
    PlasmaBinturong over 2 years
    The "filter-branch" manpage simply uses the --all flag, it would be interesting to know the reason for the choice of options in your answer. From the "rev-list" manual, I understand that --all affects the remotes refs in addition to the heads (--branches) and tags. But I am unsure if I want to change the remote refs as well...
  • Amir Hajiha
    Amir Hajiha over 2 years
    @Native_Mobile_Arch_Dev You need this: git config --global 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"
  • paradocslover
    paradocslover over 2 years
    The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • paradocslover
    paradocslover over 2 years
    The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • paradocslover
    paradocslover over 2 years
    The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • paradocslover
    paradocslover over 2 years
    The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • paradocslover
    paradocslover over 2 years
    The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • paradocslover
    paradocslover over 2 years
    The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • paradocslover
    paradocslover over 2 years
    The answers might be overkill. First check whether this satisfies your usecase - stackoverflow.com/a/67363253/8293309
  • Alex Brown
    Alex Brown over 2 years
    @paradocslover your referenced question and answer only apply to github, the website. The OPs question is clearly not about github, so your comment is not appropriate on this question.
  • paradocslover
    paradocslover over 2 years
    It's just that Github has the most number of users. And it is highly probable that anyone who lands on this page is a GitHub user (Like me). That's why I mentioned, "whether this satisfies your use-case".
  • John King
    John King over 2 years
    I had many existing branches, so "git update-ref -d refs/original/refs/heads/master" alone was not sufficient to clean up the backup refs (under .git/refs/original). What did work was: "ls .git/refs/original/refs/heads/ | xargs -I {} git update-ref -d refs/original/refs/heads/{}"
  • Ajay Pillay
    Ajay Pillay over 2 years
    My use case was that I had to change all past commits in some private repositories because my pushes were under a different username with no email attached. The first bit allowed me to change the author and email for the first N commits but it did not preserve the commit timestamps, those got updated along with it. I solved this by using this script. It is nice and clean and allows me to change the entire commit history to a single username and email while preserving the commit timestamps.
  • Pedro Henrique
    Pedro Henrique about 2 years
    For some reason this just edited my 5 last commits email (from 142), got different results on multiple repositories
  • Chris Maes
    Chris Maes about 2 years
    @PedroHenrique: you need to replace HEAD~4 with the reference until where you want to rewrite your commits... I'll try to make this a little clearer in my answer. As I mentioned before: beware for merge commits where you will get into complicated stuff
  • CervEd
    CervEd almost 2 years
    This is useful for me when I clone a new repo and forget to specify my work email. To run it only on a branch, replace --branches --tags with main..HEAD or similar
  • Chris Maes
    Chris Maes almost 2 years
    this will work only for the current branch.
  • Nicolai Weitkemper
    Nicolai Weitkemper over 1 year
    The link is broken and not in the web archive. :/
  • David G
    David G over 1 year
    I'm getting unknown switch -r. If I remove that it works fine.
  • transang
    transang over 1 year
    note that --author does not change commit date, while --reset-author does.
  • Joy
    Joy over 1 year
    @asmeurer How to amend including the very first commit, not just the commits after it. Also if possible, how to preserve timestamps while doing it?