gitgit-commitgit-rewrite-history

How do I change the git author/committer name/email for multiple commits while keeping the commit timestamp as they are?


I have used a wrong email for a project and need to change it all over the commits, and the solution from a post I found works great, but it resets the timestamp to the current time.

I ran this command, git rebase -r --root --exec "git commit --amend --no-edit --reset-author", and the timestamps show like the screenshot below:

enter image description here

How do I keep the commit timestamp the same as they are while resetting the author info? Any help would be greatly appreciated!

Link to the original post: How do I change the author and committer name/email for multiple commits?


Solution

  • The last time I had to do this, I tried the --committer-date-is-author-date option:

    git rebase --root --committer-date-is-author-date \
    -x "git commit --allow-empty --amend --author 'me <me@mail.com>' --no-edit -CHEAD"
    

    With --committer-date-is-author-date:

    Instead of using the current time as the committer date, use the author date of the commit being rebased as the committer date. This option implies --force-rebase.

    But, as noted in the comments by Phillip Wood, -C@ (-C HEAD) would only reuse authorship information: message and author date.
    That would not alter committer date.


    Setting the committer date explicitly using the configuration rebase.instructionFormat (to be used for the todo list during an interactive rebase) is the right approach, as the OP found out.

    Since rebase.instructionFormat uses git log format placeholders, it does include newline indeed: %n

    That means a rebase.instructionFormat starting with %nexec ... will execute a command on each rebased commit from the todo list.

    I have tested on Windows CMD:

    git -c rebase.instructionFormat="%nexec GIT_COMMITTER_DATE='%cD' GIT_AUTHOR_DATE='%aD' GIT_COMMITTER_NAME='me' GIT_COMMITTER_EMAIL='me@mail.com' git commit --allow-empty --amend --author 'me <me@mail.com>' --no-edit -CHEAD" rebase --root --committer-date-is-author-date

    And with a Linux shell:

    git -c rebase.instructionFormat='%nexec GIT_COMMITTER_DATE="%cD" GIT_AUTHOR_DATE="%aD" GIT_COMMITTER_NAME="me" GIT_COMMITTER_EMAIL="me@mail.com" git commit --allow-empty --amend --author "me <me@mail.com>" --no-edit -CHEAD' rebase --root --committer-date-is-author-date

    Note that, in the rebase.instructionFormat, I had to set GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL: the rebase --author 'me <me@mail.com>' only reset the author name/email, not the committer's.


    Test it out yourself: initialize a repository with a commit from… 2012/2013!

    git init test
    cd test
    git config user.name wrongName
    git config user.email wrong@email.com
    
    # Windows CMD
    
    cmd /v /c "set GIT_AUTHOR_DATE=12/12/12 4:40p +0000&&set "GIT_COMMITTER_DATE=!GIT_AUTHOR_DATE!"&& git commit --allow-empty -m "Initial empty commit""
    cmd /v /c "set GIT_AUTHOR_DATE=12/12/13 5:40p +0000&&set "GIT_COMMITTER_DATE=!GIT_AUTHOR_DATE!"&& git commit --allow-empty -m "Second empty commit""
    
    #Linux shell
    
    GIT_AUTHOR_DATE="12/12/12 4:40p +0000" GIT_COMMITTER_DATE=${GIT_AUTHOR_DATE} git commit --allow-empty -m "Initial empty commit"
    GIT_AUTHOR_DATE="12/12/13 5:40p +0000" GIT_COMMITTER_DATE=${GIT_AUTHOR_DATE} git commit --allow-empty -m "Second empty commit"
    

    You now have commits from 2012 and 2013, with the "wrongName" and "wrong@email.com":

    git log --pretty=fuller
    commit e450da16554dbb5810c387d8b74130aa7ace6e30 (HEAD -> main)
    Author:     wrongName <wrong@email.com>
    AuthorDate: Thu Dec 12 05:40:00 2013 +0000
    Commit:     wrongName <wrong@email.com>
    CommitDate: Thu Dec 12 05:40:00 2013 +0000
    
        Second empty commit
    
    commit e8587f2df3d61c92817c45b42c9f10f1d4adfc9e
    Author:     wrongName <wrong@email.com>
    AuthorDate: Wed Dec 12 04:40:00 2012 +0000
    Commit:     wrongName <wrong@email.com>
    CommitDate: Wed Dec 12 04:40:00 2012 +0000
    
        Initial empty commit
    

    Now change the author/committer name and email, while preserving both author and committer date:

    # Windows CMD
    git -c rebase.instructionFormat="%nexec GIT_COMMITTER_DATE='%cD' GIT_AUTHOR_DATE='%aD' GIT_COMMITTER_NAME='me' GIT_COMMITTER_EMAIL='me@mail.com' git commit --allow-empty --amend --author 'me <me@mail.com>' --no-edit -CHEAD" rebase --root --committer-date-is-author-date
    
    # Linux shell
    
    git -c rebase.instructionFormat='%nexec GIT_COMMITTER_DATE="%cD" GIT_AUTHOR_DATE="%aD" GIT_COMMITTER_NAME="me" GIT_COMMITTER_EMAIL="me@mail.com" git commit --allow-empty --amend --author "me <me@mail.com>" --no-edit -CHEAD' rebase --root --committer-date-is-author-date
    

    Check the resulting log, making sure your commits are still from 2012/2013, but both author and committer names are now correct.

    git log --pretty=fuller
    commit f7f2ee6cea4ec80a3699f6c6cac6553002556727 (HEAD -> main)
    Author:     me <me@mail.com>
    AuthorDate: Thu Dec 12 05:40:00 2013 +0000
    Commit:     me <me@mail.com>
    CommitDate: Thu Dec 12 05:40:00 2013 +0000
    
        Second empty commit
    
    commit d5a1e9518406a5fc0dfa8706454718bb6ceb281e
    Author:     me <me@mail.com>
    AuthorDate: Wed Dec 12 04:40:00 2012 +0000
    Commit:     me <me@mail.com>
    CommitDate: Wed Dec 12 04:40:00 2012 +0000
    
        Initial empty commit