Git – Amending multiple commit messages

Home_Alone_Boy1

There may come a time when you’ve really botched your commit messages and you need to amend a few of them all at once. You could amend all of them one at a time and then push them to a remote. Or you could just amend them in a large batch and save yourself some time and probably a bit of anxiety.

Remember, by amending commit messages, the metadata of the commits change so it will have a new SHA key – even if you didn’t change any code at all. Obviously, this will create conflicts with your remote, which has all of the old commit SHA keys. So once you’re done with your amendments, be sure to force push your changes to remote.


 Checking for commit errors

In class, we’re using Pivotal Tracker (PT) to keep track of ‘stories,’ or tasks, that required to complete for homework. It’s just one of many project management tools out there based on the Agile Way. In addition, we’re using a PT service on GitHub that requires us to add our PT story ID onto each commit message we write on a topic branch. Well guess what? Yours truly totally forgot about this requirement.

To check how badly I messed up, I went back to the branch I needed to amend, which happened to be one called 104389600_chapter_1_master, where 104389600 is the PT ID, chapter_1 is the topic branch name, and master is the branch I branched off of. Then, I ran git log to see how many amendments I needed to make.

$ git branch
  104389594_introduction_master
* 104389600_chapter_1_master
  104391102_chapter_0_master
  master
$ git log
commit d9f5b78f5e4701f0d5052827ea5ec8badc01a3cf
Author: Tim <timsjpark@gmail.com>
Date: Tue Sep 29 23:40:47 2015 -0600

 Add ex1.rb to run chapter exercises

commit d8ece159bc942fde9bf0b538c72b2c2df705acd4
Author: Tim <timsjpark@gmail.com>
Date: Tue Sep 29 23:40:00 2015 -0600

 Added Readme

commit 873e4bb55164372f2acec114f4d3fdc1a4dcf895
Author: Tim <timsjpark@gmail.com>
Date: Tue Sep 29 18:39:30 2015 -0600

 Create chapter_1 directory, and Readme and ex1.rb

 [#104389600]

commit 237eda11a586239ff8b67e06e406485f4b76acfd
Author: Tim <timsjpark@gmail.com>
Date: Tue Sep 29 18:58:27 2015 -0600

 Add file to have rubocop ignore Guardfile

commit e1a26f79b86ed9d5b27edf5e930289e4afdc2f78
Author: Tim <timsjpark@gmail.com>
Date: Mon Sep 28 20:20:08 2015 -0600

 Initial comment

As you can see, going back in time, I have two commit messages that need the PT ID added to the end of the message. The one before correctly shows the ID in brackets preceded by an octothorpe (#). You’ll also notice that the oldest two commit messages don’t have an ID. That’s because those commits were made in the master branch and the PT service aids in tracking topic branches, so it wouldn’t make sense for the master branch to have any ID in the commit message.


Preparing to make amendments

Now that we’ve spotted our problems, we need to start making amendments. To prepare to amend multiple messages, we first have to fetch from origin. Fetching looks for any new changes made in a remote repository. Then we use rebase to update our local repository. Luckily, our current branch is up to date and we don’t have to deal with any other obstacles other than amending our commits.

$ git fetch origin
$ git rebase origin/master
Current branch 104389600_chapter_1_master is up to date.

Now, let’s start amending our commits. We can accomplish this by typing in:

git rebase origin/master -i

If you read the documentation for git rebase --help , you would see that the -i option allows you to “make a list of the commits which are about to be rebased. Let the user edit that list before rebasing.”


Amending multiple commits

Once you type in git rebase origin/master -i you’ll be placed into vim. There, you want to look at the top, which lists your commits in chronological order.

NOTE: This is the opposite order of the git log output.

Since I wanted to amend the last two commits I made, I’ll replace the word pick with reword. Once you’re ready to amend those commits, get back into Normal mode by hitting ESC and then typing in :wq. If you’re new to vim, look for some extra help below the image.

reword

New to vim? Navigate to the line with the first commit you want to amend. Go to the first character, which should be ‘p’ in ‘pick.’ Then type cw on your keyboard – this keystroke tells vim that you want to changeword and place you in insert mode. See how ‘pick’ is now gone? Go ahead and type in reword and then hit ESC to return to normal mode.

Have multiple commits to amend? Navigate to the next commit you need to amend and return to the first character of the line. This time, hit the . key. Magic? The ‘dot’ key will create your last keystrokes in vim, which should have been cw, typing in reword, and then hitting ESC.

Finally, type :wq to ‘write’ your edits to the file and then ‘quit’ the vim editor.


Editing your commits

Now, all I have to do is add my Pivotal Tracker ID to each commit message. If you recall from before, I name my topic branches off of the PT ID for the story (task) I’m working on. One advantage of this is that when I go to edit commit messages, I know exactly which PT ID I’m using. I then add that ID to the bottom of the message preceded by a # and confined in square brackets. Finally, I go back to Normal mode and then :wq. Do this for each commit message.

edited message

Once you make your amendments, you’ll pop out of vim and back into your terminal. Notice that your have an output saying you successfully rebased.

$ git rebase origin/master -i
[detached HEAD 4da44d3] Added Readme
 Date: Tue Sep 29 23:40:00 2015 -0600
 1 file changed, 86 insertions(+)
[detached HEAD 58e1c94] Add ex1.rb to run chapter exercises
 Date: Tue Sep 29 23:40:47 2015 -0600
 1 file changed, 9 insertions(+)
Successfully rebased and updated refs/heads/104389600_chapter_1_master.

But wait…there’s more!

One last step. When I check git status , you’ll notice that my branch and origin “have 2 and 2 different commits each.” What the hell does that mean? Well remember that rebasing and then amending your commits changed their SHA keys. Since I amended two commits, my local branch has two new commits that origin doesn’t have and origin has the two old commits that my local branch doesn’t have.

Well I want my origin to reflect the changes I made with adding the Pivotal Tracker ID, which I know are correct. So I force push my changes onto origin with the -fu option. Run git status one more time and it looks like you’re all good…

$ git status
On branch 104389600_chapter_1_master
Your branch and 'origin/104389600_chapter_1_master' have diverged,
and have 2 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
nothing to commit, working directory clean
$ git push -fu origin 104389600_chapter_1_master
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 2.36 KiB | 0 bytes/s, done.
Total 8 (delta 2), reused 0 (delta 0)
To git@github.com:timsjpark/lrthw_exercises.git
 + d9f5b78...58e1c94 104389600_chapter_1_master -> 104389600_chapter_1_master (forced update)
Branch 104389600_chapter_1_master set up to track remote branch 104389600_chapter_1_master from origin.
$ git status
On branch 104389600_chapter_1_master
Your branch is up-to-date with 'origin/104389600_chapter_1_master'.
nothing to commit, working directory clean

Thanks to Jason Noble for showing me this nice Git feature.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s