Search code examples
gitcommitrebasesquash

git - Easier way to do a simple one-commit squash?


The project I'm working on requires that all feature contributions be single commits, but I still like to commit my progress along the way, so I usually squash my commits as I make them.

Let's say I'm making my first new commit on the branch:

git commit -am "Added new feature"

From then on, until I submit my changes, I will do:

git commit -am "asdfasdasd"
git rebase -i HEAD~2

...and then squash my commits in interactive rebase.

I do this 10-20 times a day, and it just seems like a disproportionately high number of keypresses for the seemingly-simple effect I'm trying to get. Is there a better/faster/easier way to get the same results? If there's no single magic command to do this, then I guess what I'm looking for is the most efficient way. to pop off the most recent commit from the history (without discarding the changes it contains!), and just commit again, which would include the changes from the popped-off commit, as well as the working changes.


Solution

  • Use git commit --amend -am "message goes here" (or --amend -a—usually the previous commit message is a good starting point—or even just --amend after manually adding, etc). The --amend takes this git commit history:

    ...-o-X-Y   <-- branch
    

    and in effect does a "soft reset" to make the label branch point to X so that the new commit's parent is again X, resulting in this commit history:

            Y   [no label, but still in reflog as branch@{1}]
           /
    ...-o-X-Z   <-- branch
    

    When you do your commit-and-rebase you get, first:

    ...-o-X-Y-Z   <-- branch
    

    (the new commit), then:

            Y-Z   [no label, but still in reflog as usual]
           /
    ...-o-X-Z'    <-- branch
    

    where Z' is the squash-commit of Y and Z. So these are different, but for your purposes, probably equally useful.