Search code examples
gitsquashfixup

Non-interactive fixup until specified hash


Let’s say I have hour commits

* 7bd4815 (HEAD) four
* afe9410 third
* db064dd second
* 46ab932 first

There are no uncommitted changes. What I want to do is non-interactively squash everything after first, into it. I want the equivalent of

pick 46ab932 first
fixup db064dd second
fixup afe9410 third
fixup 7bd4815 four

Here I’m using four commits as an example, but the actual number of commits will vary. I’ll know the commit’s hash, though, so that’s what I’d like to use.

Searching for this has been fruitless (I’m likely not searching for the correct terms), as I find a lot of solutions, but never to this exact situation.


Solution

  • This solution is similar to my solution to Combine or rebase an arbitrarily large number of commits. You basically want to use a soft reset to achieve the same affect as a squash/fixup, followed by a commit.

    For the following solutions, I will use the term "first" to mean the commit sha of the first commit (as shown in the original poster's example), and "fourth" to mean the last commit sha, the one where HEAD is.

    Solution 1: Soft Reset with Amend

    git reset --soft first
    git commit --amend --no-edit
    
    # Verify results
    git diff fourth
    

    Solution 2: Soft Reset without Amend

    This requires you to reset to the parent of the first commit, to avoid having to amend:

    git reset --soft first^
    git commit -C first
    
    # Verify results
    git diff fourth
    

    The -C option of git commit reuses the commit message of first.

    Documentation