My notes about performing a “git squash” — squashing many commits in a pull request into a single commit (with git rebase)

[toc]

I’m putting these “git squash” notes here as a reminder for myself. They’re a little cryptic, but hopefully they can also be helpful for others. But if not, I also included some good links at the end that helped me through this process. (They were all good, but none of them were complete by themselves.)

Introduction

When I was working on porting my Hello, Scala book to the docs.scala-lang.org website, the last thing I was asked to do was to “squash” all of the commits on my pull request so it would appear as a single commit. As I would learn, there were 55 commits over a period of two months, and here’s a little story of how that “git squash” process worked.

In the following examples, please note that by branch was named hello-scala-2.

Figuring out my commit history

The first thing I learned to do was a git cherry -v master command in my hello-scala-2 branch. When I did that, these are the first five commits I saw:

+ b9a717ce 5208544e6e3dedb6cc819ce9f23429c2 updated version of the “Hello, Scala” book contents.
+ e0be005a 8ca1b584196aefc17078712a827a0a59 Update _overviews/hello-scala/prelude-taste-of-scala.md
+ 4a8b0dd9 a9d8a64b82d4dad0d894d34302cce6d9 Update _overviews/hello-scala/prelude-taste-of-scala.md
+ 3b29c820 6ddf0f82e259a0ee1515c220698b6e56 Update _overviews/hello-scala/prelude-taste-of-scala.md
+ 28f204b5 a011b9ea96e21596d9dc0c834c4de8d9 Update _overviews/hello-scala/where-next.md
...
...

My notes also show this output with git cherry -v master, and as I type this I have the flu, so frankly, I don’t remember which one is right:

> git cherry -v master
# this show 55 lines/commits, including the first commit
+ b9a717ce5208544e6e3dedb6cc819ce9f23429c2 updated version of the “Hello, Scala” book contents.
+ c601ba26d4eef3769ec09127803255c6eae969ab Added “Hello, Scala” book contents and renamed it to “Scala Book.”

Depending on which approach you take with the git rebase command you’ll use in the next section, the two important things to know are:

  • The first commit is the one that begins with b9a717ce
  • There were 55 total commits

Because of the rebase command I decided to use, the second piece of information ended up being the most important thing to know.

The “git rebase” (squash) command

At this point the solution is to issue the correct git rebase command. Because I had 55 commits, and I wanted to squash them into one commit, I issued this command:

git rebase -i HEAD~55

This brought up the vim editor with a list of my 55 commits, and what I did is:

  • I changed the first line to begin with “reword”
  • I changed all other lines to begin with “squash”

After that I saved the file and exited the editor. Then another vim editor came up and I added one commit message that summarized the previous 55 commits. In this case I initially added my Hello, Scala book contents to the pull request, then I made a bunch of changes, and finally I/we renamed the book to Scala Book, so I wrote something to that effect.

After I saved that, another editor came up with a summary of all previous commits, and I just saved that file as-is so we’d still have all of those old messages.

After that I was returned to the command line, and I ran the git cherry -v master command again, and saw only one commit:

+ 9cfa04c99a891b05e8cc395b3d29ec238d933df1 Added the “Scala Book” contents.

I confirmed that this was a new commit, so now I just needed to push my changes back to Github.

Push the changes back to Github

I used this command to push my changes back to Github:

git push origin hello-scala-2 --force

I didn’t look into whether the --force part of that command was required. I read something about it in one of the following resources, so I just went with it, and fortunately it worked as desired. (Please remember that I have the flu as I write this, and I’m not really into details at the moment.)

Actual commands I ran

If you’re interested in the details, my bash history shows these are the commands I actually ran:

2587  git clone git@github.com:alvinj/docs.scala-lang.git
2589  git branch
2590  git checkout hello-scala-2
2591  git cherry -v master
2592  git branch
2593  git rebase -i HEAD~55
2594  git cherry -v master
2596  git push origin hello-scala-2 --force

Note that I restarted everything with command #2587. This is because I previously tried other git rebase commands that didn’t work as desired, so I decided to restart the process by checking out a clean copy of my pull request.

Resources

For much more information, these are the resources I read that helped me through this git squash process:

I don’t remember which article was the best, but I made a note that the last article was important because it included the git push origin branch-name --force command.