Changing the author of commits using a rebase

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.

Getting ready

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'

How to do it...

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:

  1. Change the author of the 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(-)
    
  2. Verify that you have changed it with the Git log command:
    $ 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]
    
  3. We will list all the commits from 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
    
  4. As you can see, Git has opened the rebase's to-do list for you, and between every commit, you have the 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.
  5. As you will see, this process is not very good as the commit message editor opens every time and you have to close the editor to allow Git to continue with the rebase. To stop the rebase, clear the commit message editor and Git will return to the command line; then, you can use 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.
    
  6. Git provides an output indicating that the action was a success; however, to verify, you can execute the previous Git log command and you should see the e-mail address has changed on all the commits, as shown in the following command:
    $ 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]
    

How it works...

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset