When I start working on a new project, I often forget to set my author name and author e-mail address for the specified project; therefore, I often have commits in my local branch that have been committed with the wrong username and/or e-mail ID. Unfortunately, I can't use the same account everywhere as some work with regards to my cooperate account still needs to be done; however, for most other parts, I can use my private account.
Before we begin this exercise, we need a branch, as always with Git. Name the branch resetAuthorRebase
and make it track origin/master
. Use the following command to achieve this:
$ git checkout -b resetAuthorRebase -t origin/master Branch resetAuthorRebase set up to track remote branch master from origin. Switched to a new branch 'resetAuthorRebase'
Now, we want to change the author of all the commits from origin/stable-3.2
to our HEAD
, which is master
. This is just an example; you will rarely have to change the author of commits that have already been published to a remote repository.
You can change the author of the HEAD
commit by using git commit --amend --reset-author
; however, this will only change the author of HEAD
and leave the rest of the commits as they were. We will start by changing the author of the HEAD
commit and then verifying why that is wrong by performing the following steps:
HEAD
commit as follows:$ git commit --amend --reset-author [resetAuthorRebase b0b2836] Update Kepler target platform to use Kepler SR2 orbi t R-build 1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --format='format:%h %an <%ae>' origin/stable-3.2..HEAD b0b2836 Rasmus Voss <[email protected]> b9a0621 Matthias Sohn <[email protected]> ba15d82 Matthias Sohn [email protected]
origin/stable-3.2
to HEAD
and we will define a format with %h
as the abbreviated commit hash, %an
for the author's name, and %ae
for the author's e-mail address. From the output, you can see that I am now the author of the HEAD
commit, but what we really wanted was to change the author of all the commits. To do this, we will rebase onto the origin/stable-3.2
branch; then, for each commit, we will stop to amend and reset the author. Git can do most of that work with --exec option
for the git
rebase, as follows:git rebase --interactive --exec "git commit --amend --reset-author" origin/stable-3.2 pick b14a939 Prepare 3.3.0-SNAPSHOT builds exec git commit --amend --reset-author pick f2abbd0 archive: Prepend a specified prefix to all entry filenames exec git commit --amend --reset-author
exec
keyword and the command we specified on the command line. You can have more exec
lines between commits if you have a use case for them. Closing the editor will start the rebase.git rebase --abort
as follows:Executing: git commit --amend --reset-author Aborting commit due to empty commit message. Execution failed: git commit --amend --reset-author You can fix the problem, and then run git rebase --continue $ git rebase --abort
To achieve what we really want, you can add the --reuse-message
option for git commit
; this will reuse the commit message for the commit you will specify. We want to use the message of HEAD
as we are going to amend it to the HEAD
commit. So, try again as shown in the following command:
git rebase --interactive --exec "git commit --amend --reset-author --reuse-message=HEAD" origin/stable-3.2 Executing: git commit --amend --reset-author --reuse-message=HEAD [detached HEAD 0cd3e87] Prepare 3.3.0-SNAPSHOT builds 51 files changed, 291 insertions(+), 291 deletions(-) rewrite org.eclipse.jgit.java7.test/META-INF/MANIFEST.MF (62%) rewrite org.eclipse.jgit.junit/META-INF/MANIFEST.MF (73%) rewrite org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF (61%) rewrite org.eclipse.jgit.test/META-INF/MANIFEST.MF (76%) rewrite org.eclipse.jgit.ui/META-INF/MANIFEST.MF (67%) Executing: git commit --amend --reset-author --reuse-message=HEAD [detached HEAD faaf25e] archive: Prepend a specified prefix to all entry filenames 5 files changed, 115 insertions(+), 1 deletion(-) Executing: git commit --amend --reset-author --reuse-message=HEAD [detached HEAD cfd743e] [CLI] Add option --millis / -m to debug-show-dir-cache cOmmand Successfully rebased and updated refs/heads/resetAuthorRebase.
$ git log --format='format:%h %an <%ae>' origin/stable-3.2..HEAD 9b10ff9 Rasmus Voss <[email protected]> d8f0ada Rasmus Voss <[email protected]> 53df2b7 Rasmus Voss [email protected]
It works as you would expect! There is one thing to remember: when using the exec
option, Git will check the work area for unstaged and staged changes. Consider the following command line:
exec echo rainy_day > weather_main.txtexec echo sunny_day > weather_california.txt
If you have a line as illustrated in the preceding command, the first exec
would be executed and you will then have an unstaged change in your work area. Git would complain and you have to solve that before continuing with the next exec. So, if you want to do something like this, you must create a single exec line that executes all the things you want. Besides this, the rebase functionality is fairly simple, as it just tries to apply the changes in the order that is specified in the rebase's to-do list. Git will only apply the changes specified in the list, so if you remove some of them, they will not be applied. This is a way to clean up a feature branch for unwanted commits, for instance, commits that enable you to debug.