Redo – recreate the latest commit with new changes

As with undo, redo can mean a lot of things. In this context, redoing a commit will mean creating almost the same commit again with the same parent(s) as the previous commit, but with different content and/or different commit messages. This is quite useful if you've just created a commit but perhaps have forgotten to add a necessary file to the staging area before you committed, or if you need to reword the commit message.

Getting ready

Again, we'll use the hello world repository. Make a fresh clone of the repository, or reset the master branch if you have already cloned.

We can create a fresh clone as follows:

$ git clone https://github.com/dvaske/hello_world_cookbook.git
$ cd hello_world_cookbook

We can reset an existing clone as follows:

$ cd hello_world_cookbook
$ git checkout master
$ git reset --hard origin master
HEAD is now at 3061dc6 Adds Java version of 'hello world'

How to do it...

Let's pretend we need to redo the latest commit because we need to reword the commit message to include a reference to the issue tracker.

  1. Let's first take a look at the latest commit and make sure the working directory is clean:
    $ git log -1
    commit 3061dc6cf7aeb2f8cb3dee651290bfea85cb4392
    Author: Aske Olsson <[email protected]>
    Date:   Sun Mar 9 14:12:45 2014 +0100
    
        Adds Java version of 'hello world'
    
        Also includes a makefile
    $ git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
    
    nothing to commit, working directory clean
    
  2. Now, we can redo the commit and update the commit message with the git commit --amend command. This will bring up the default editor, and we can add a reference to the issue tracker in the commit message (Fixes: RD-31415):
    $ git commit --amend
    Adds Java version of 'hello world'
    
    Also includes a makefile
    
    Fixes: RD-31415
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # Author:    Aske Olsson <[email protected]>
    #
    # On branch master
    # Your branch is up-to-date with 'origin/master'.
    #
    # Changes to be committed:
    #       new file:   HelloWorld.java
    #       new file:   Makefile
    #
    ~
    ~
    [master 75a41a2] Adds Java version of 'hello world'
     Author: Aske Olsson <[email protected]>
     2 files changed, 19 insertions(+)
     create mode 100644 HelloWorld.java
     create mode 100644 Makefile
    
  3. Now let's check the log again to see whether everything worked:
    $ git log -1
    commit 75a41a2f550325234a2f5f3ba41d35867910c09c
    Author: Aske Olsson <[email protected]>
    Date:   Sun Mar 9 14:12:45 2014 +0100
    
        Adds Java version of 'hello world'
    
        Also includes a makefile
    
        Fixes: RD-31415
    
  4. We can see that the commit message has changed, but we can't verify from the log output that the parent of the commit is the same as in the original commit, and so on, as we saw in the first commit we did. To check this, we can use the git cat-file command we learned about in Chapter 1, Navigating Git. First, let's see how the original commit looked:
    $ git cat-file -p 3061dc6
    tree d3abe70c50450a4d6d70f391fcbda1a4609d151f
    parent 9c7532f5e788b8805ffd419fcf2a071c78493b23
    author Aske Olsson <[email protected]> 1394370765 +0100
    committer Aske Olsson <[email protected]> 1394569447 +0100
    Adds Java version of 'hello world'
    
    Also includes a makefile
    

    The parent commit is b8c39bb35c4c0b00b6cfb4e0f27354279fb28866 and the root tree is d3abe70c50450a4d6d70f391fcbda1a4609d151f.

  5. Let's check the data from the new commit:
    $ git cat-file -p HEAD
    tree d3abe70c50450a4d6d70f391fcbda1a4609d151f
    parent 9c7532f5e788b8805ffd419fcf2a071c78493b23
    author Aske Olsson <[email protected]> 1394370765 +0100
    committer Aske Olsson <[email protected]> 1394655225 +0100
    
    Adds Java version of 'hello world'
    
    Also includes a makefile
    
    Fixes: RD-31415
    

    The parent is the same, that is, 9c7532f5e788b8805ffd419fcf2a071c78493b23 and the root tree is also the same, that is, d3abe70c50450a4d6d70f391fcbda1a4609d151f. This is what we expected as we only changed the commit message. If we had added some changes to the staging area and executed git commit--amend, we would have included those changes in the commit and the root-tree SHA1 ID would have been different, but the parent commit ID still the same.

How it works...

The --amend option to git commit is roughly equivalent to performing git reset –soft HEAD^, followed by fixing the files needed and adding those to the staging area. Then, we will run git commit reusing the commit message from the previous commit (git commit –c ORIG_HEAD).

There is more…

We can also use the --amend method to add missing files to our latest commit. Let's say you needed to add the README.md file to your latest commit in order to get the documentation up to date, but you have already created the commit though you have not pushed it yet.

You then add the file to the index as you would while starting to craft a new commit. You can check with git status that only the README.md file is added:

$ git add README.md
$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commit each, respectively.
  (use "git pull" to merge the remote branch into yours)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   README.md

Now you can amend the latest commit with git commit --amend. The command will include files in the index in the new commit and you can, as with the last example, reword the commit message if needed. It is not needed in this example, so we'll pass the --no-edit option to the command:

$ git commit --amend --no-edit
[master f09457e] Adds Java version of 'hello world'
 Author: Aske Olsson <[email protected]>
 3 files changed, 20 insertions(+)
 create mode 100644 HelloWorld.java
 create mode 100644 Makefile
 create mode 100644 README.md

You can see from the output of the commit command that three files were changed and README.md was one of them.

Tip

You can also reset the author information (name, e-mail, and timestamp) with the commit --amend command. Just pass along the --reset-author option and Git will create a new timestamp and read author information from the configuration or environment, instead of the using the information from the old commit object.

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

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