Question

I want to change the author of one specific commit in the history. It's not the last commit.

I know about this question - How do I change the author of a commit in git?

But I am thinking about something, where I identify the commit by hash or short-hash.

Was it helpful?

Solution

Interactive rebase off of a point earlier in the history than the commit you need to modify (git rebase -i <earliercommit>). In the list of commits being rebased, change the text from pick to edit next to the hash of the one you want to modify. Then when git prompts you to change the commit, use this:

git commit --amend --author="Author Name <email@address.com>"

For example, if your commit history is A-B-C-D-E-F with F as HEAD, and you want to change the author of C and D, then you would...

  1. Specify git rebase -i B (here is an example of what you will see after executing the git rebase -i B command)
    • if you need to edit A, use git rebase -i --root
  2. change the lines for both C and D from pick to edit
  3. Once the rebase started, it would first pause at C
  4. You would git commit --amend --author="Author Name <email@address.com>"
  5. Then git rebase --continue
  6. It would pause again at D
  7. Then you would git commit --amend --author="Author Name <email@address.com>" again
  8. git rebase --continue
  9. The rebase would complete.
  10. Use git push -f to update your origin with the updated commits.

OTHER TIPS

The accepted answer to this question is a wonderfully clever use of interactive rebase, but it unfortunately exhibits conflicts if the commit we are trying to change the author of used to be on a branch which was subsequently merged in. More generally, it does not work when handling messy histories.

Since I am apprehensive about running scripts which depend on setting and unsetting environment variables to rewrite git history, I am writing a new answer based on this post which is similar to this answer but is more complete.

The following is tested and working, unlike the linked answer. Assume for clarity of exposition that 03f482d6 is the commit whose author we are trying to replace, and 42627abe is the commit with the new author.

  1. Checkout the commit we are trying to modify.

    git checkout 03f482d6
    
  2. Make the author change.

    git commit --amend --author "New Author Name <New Author Email>"
    

    Now we have a new commit with hash assumed to be 42627abe.

  3. Checkout the original branch.

  4. Replace the old commit with the new one locally.

    git replace 03f482d6 42627abe
    
  5. Rewrite all future commits based on the replacement.

    git filter-branch -- --all
    
  6. Remove the replacement for cleanliness.

    git replace -d 03f482d6
    
  7. Push the new history (only use --force if the below fails, and only after sanity checking with git log and/or git diff).

    git push --force-with-lease
    

Instead of 4-6 you can just rebase onto new commit:

git rebase -i 42627abe

Github documentation contains a script that replaces the committer info for all commits in a branch.

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"

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
  • Reset your email to the config globally:

    git config --global user.email example@email.com

  • Now reset the author of your commit without edit required:

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

You can change author of last commit using the command below.

git commit --amend --author="Author Name <email@address.com>"

However, if you want to change more than one commits author name, it's a bit tricky. You need to start an interactive rebase then mark commits as edit then ammend them one by one and finish.

Start rebasing with git rebase -i. It will show you something like this.

https://monosnap.com/file/G7sdn66k7JWpT91uiOUAQWMhPrMQVT.png

Change the pick keyword to edit for the commits you want to change the author name.

https://monosnap.com/file/dsq0AfopQMVskBNknz6GZZwlWGVwWU.png

Then close the editor. For the beginners, hit Escape then type :wq and hit Enter.

Then you will see your terminal like nothing happened. Actually you are in the middle of an interactive rebase. Now it's time to amend your commit's author name using the command above. It will open the editor again. Quit and continue rebase with git rebase --continue. Repeat the same for the commit count you want to edit. You can make sure that interactive rebase finished when you get the No rebase in progress? message.

The answers in the question to which you linked are good answers and cover your situation (the other question is more general since it involves rewriting multiple commits).

As an excuse to try out git filter-branch, I wrote a script to rewrite the Author Name and/or Author Email for a given commit:

#!/bin/sh

#
# Change the author name and/or email of a single commit.
#
# change-author [-f] commit-to-change [branch-to-rewrite [new-name [new-email]]]
#
#     If -f is supplied it is passed to "git filter-branch".
#
#     If <branch-to-rewrite> is not provided or is empty HEAD will be used.
#     Use "--all" or a space separated list (e.g. "master next") to rewrite
#     multiple branches.
#
#     If <new-name> (or <new-email>) is not provided or is empty, the normal
#     user.name (user.email) Git configuration value will be used.
#

force=''
if test "x$1" = "x-f"; then
    force='-f'
    shift
fi

die() {
    printf '%s\n' "$@"
    exit 128
}
targ="$(git rev-parse --verify "$1" 2>/dev/null)" || die "$1 is not a commit"
br="${2:-HEAD}"

TARG_COMMIT="$targ"
TARG_NAME="${3-}"
TARG_EMAIL="${4-}"
export TARG_COMMIT TARG_NAME TARG_EMAIL

filt='

    if test "$GIT_COMMIT" = "$TARG_COMMIT"; then
        if test -n "$TARG_EMAIL"; then
            GIT_AUTHOR_EMAIL="$TARG_EMAIL"
            export GIT_AUTHOR_EMAIL
        else
            unset GIT_AUTHOR_EMAIL
        fi
        if test -n "$TARG_NAME"; then
            GIT_AUTHOR_NAME="$TARG_NAME"
            export GIT_AUTHOR_NAME
        else
            unset GIT_AUTHOR_NAME
        fi
    fi

'

git filter-branch $force --env-filter "$filt" -- $br

Commit before:

enter image description here

To fix author for all commits you can apply command from @Amber's answer:

git commit --amend --author="Author Name <email@address.com>"

Or to reuse your name and email you can just write:

git commit --amend --author=Eugen

Commit after the command:

enter image description here

For example to change all starting from 4025621:

enter image description here

You must run:

git rebase --onto 4025621 --exec "git commit --amend --author=Eugen" 4025621

Note: To include an author containing spaces such as a name and email address, the author must be surrounded by escaped quotes. For example:

git rebase --onto 4025621 --exec "git commit --amend --author=\"Foo Bar <foo@bar.com>\"" 4025621

or add this alias into ~/.gitconfig:

[alias]
    reauthor = !bash -c 'git rebase --onto $1 --exec \"git commit --amend --author=$2\" $1' --

And then run:

git reauthor 4025621 Eugen

There is one additional step to Amber's answer if you're using a centralized repository:

git push -f to force the update of the central repository.

Be careful that there are not a lot of people working on the same branch because it can ruin consistency.

When doing git rebase -i there is this interesting bit in the doc:

If you want to fold two or more commits into one, replace the command "pick" for the second and subsequent commits with "squash" or "fixup". If the commits had different authors, the folded commit will be attributed to the author of the first commit. The suggested commit message for the folded commit is the concatenation of the commit messages of the first commit and of those with the "squash" command, but omits the commit messages of commits with the "fixup" command.

  • If you have an history of A-B-C-D-E-F,
  • and you want to change commits B and D (= 2 commits),

then you can do:

  • git config user.name "Correct new name"
  • git config user.email "correct@new.email"
  • create empty commits (one for each commit):
    • you need a message for rebase purpose
    • git commit --allow-empty -m "empty"
  • start the rebase operation
    • git rebase -i B^
    • B^ selects the parent of B.
  • you will want to put one empty commit before each commit to modify
  • you will want to change pick to squash for those.

Example of what git rebase -i B^ will give you:

pick sha-commit-B some message
pick sha-commit-C some message
pick sha-commit-D some message
pick sha-commit-E some message
pick sha-commit-F some message
# pick sha-commit-empty1 empty
# pick sha-commit-empty2 empty

change that to:

# change commit B's author
pick sha-commit-empty1 empty
squash sha-commit-B some message
# leave commit C alone
pick sha-commit-C some message
# change commit D's author
pick sha-commit-empty2 empty
squash sha-commit-D some message
# leave commit E-F alone
pick sha-commit-E some message
pick sha-commit-F some message

It will prompt you to edit the messages:

# This is a combination of 2 commits.
# The first commit's message is:

empty

# This is the 2nd commit message:

...some useful commit message there...

and you can just remove the first few lines.

In furtherance to Eugen Konkov response, to start from the root commit, use --root flag. The --no-edit flag is helpful too

git rebase --root --exec "git commit --amend --author='name <email>' --no-edit"

If what you need to change is the AUTHOR OF THE LAST commit and no other is using your repository, you may undo your last commit with:

git push -f origin last_commit_hash:branch_name 

change the author name of your commit with:

git commit --amend --author "type new author here"

Exit the editor that opens and push again your code:

git push

There is also a lazy approach to this problem, especially if you have more than one commit that you want to change. In my case, I had a new branch with several commits with a wrong author, so what helped me:

Go to your original branch:

git checkout develop

Create new branch from it:

git checkout -b myFeature develop 

Merge it without commit info as one commit:

git merge --no-commit --squash branchWrongAuthor

You might also want to stage changes:

git stage .

Change the name of the author and commit changes:

git commit --amend --author "New Author Name <New Author Email>" -m "new feature added"

And that's it, you can push the changes.

git push

You can delete the branch with a wrong author after that.

If the commit that you want to change is not the last commit, then follow the below steps. If your commit is in different branch then first switch to that branch.

git checkout branch_name

Find commit before the commit that you want to change and find its hash. Then issue rebase command.

git rebase -i -p hash of commit

Then an editor will open and enter 'edit' for the commits that you want to change. Leave others with default 'pick' option. Once changed enter 'esc' key and wq! to exit.

Then issue git commit command with amendment option.

git commit --amend --author="Username email" --no-edit

Then issue the following command.

git rebase --continue

Once commit author is updated in the local repository, push the changes to the remote repository.

Steps to rename author name after commit pushed

  1. First type "git log" to get the commit id and more details
  2. git rebase i HEAD~10 (10 is the total commit to display on rebase)

    If you Get anything like below

    fatal: It seems that there is already a rebase-merge directory, and I wonder if you are in the middle of another rebase. If that is the case, please try

    git rebase (--continue | --abort | --skip) If that is not the case, please rm -fr ".git/rebase-merge" and run me again. I am stopping in case you still have something valuable there.

  3. Then type "git rebase --continue" or "git rebase --abort" as per your need

    • now your will rebase window opened, click "i" key from keyboard
    • then you will get list of commits to 10 [because we have passed 10 commit above] Like below

    pick 897fe9e simplify code a little

    pick abb60f9 add new feature

    pick dc18f70 bugfix

  4. Now you need to add below command just below of the commit you want to edit, like below

    pick 897fe9e simplify code a little exec git commit --amend --author 'Author Name <author.name@mail.com>' pick abb60f9 add new feature exec git commit --amend --author 'Author Name <author.name@mail.com>' pick dc18f70 bugfix exec git commit --amend --author 'Author Name <author.name@mail.com>'

    1. That's it, now just press ESC, :wq and you are all set

    2. Then git push origin HEAD:BRANCH NAME -f [please take care of -f Force push]

    like git push -f or git push origin HEAD: dev -f

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top