Fixups
In a PR review, some feedback about Commit Two requires making some changes. After the changes have been made, we can fixup Commit Two to avoid extra commits. First we need to grab the reference.
git log
commit fa11fa11fa11fa11fa11fa11fa11fa11fa11fa11
Author: Robert Masen <r.f.masen@gmail.com>
Date: Mon Jan 29 15:09:29 2024 -0600
Commit Three
# copy this commit has (or first 7)
commit facefacefacefacefacefacefacefacefaceface
Author: Robert Masen <r.f.masen@gmail.com>
Date: Mon Jan 29 09:44:37 2024 -0600
Commit Two
commit cafecafecafecafecafecafecafecafecafecafe
Author: Robert Masen <r.f.masen@gmail.com>
Date: Fri Jan 26 15:09:01 2024 -0600
Commit One
Now we can use the --fixup flag to update an existing commit
git commit --fixup a9d3dea #updating Commit Two
Just to confirm here is the new log
git log
# the commit message is prefixed with fixup! which is how git figures
# out where to merge this in the next step
commit beeffeedbeeffeedbeeffeedbeeffeedbeeffeed
Author: Robert Masen <r.f.masen@gmail.com>
Date: Mon Jan 29 15:09:29 2024 -0600
fixup! Commit Two
commit fa11fa11fa11fa11fa11fa11fa11fa11fa11fa11
Author: Robert Masen <r.f.masen@gmail.com>
Date: Mon Jan 29 15:09:29 2024 -0600
Commit Three
commit facefacefacefacefacefacefacefacefaceface
Author: Robert Masen <r.f.masen@gmail.com>
Date: Mon Jan 29 09:44:37 2024 -0600
Commit Two
commit cafecafecafecafecafecafecafecafecafecafe
Author: Robert Masen <r.f.masen@gmail.com>
Date: Fri Jan 26 15:09:01 2024 -0600
Commit One
Now, we can perform a rebase to combine our fixup commit with Commit Two
# we can use ~1 to mean the commit before this commit
git rebase -i --autosquash a9d3dea~1
This will open the text editor you have configured with the key core.editor
pick cafecafec Commit One
pick facefacef Commit Two
fixup beeffeedb fixup! Commit Two
pick facefacef Commit Three
# Rebase baseba119..beeffeed6 onto baseba119 (2 commands)
#
# Commands
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom
#
# If you remove a line here THAT COMMIT WILL BE LOST
#
# However, if you remove everything, the rebase will be aborted
Now, we have rewritten our git history as if our fixup changes were part of the original set of change.
git log
commit fa11fa11fa11fa11fa11fa11fa11fa11fa11fa11
Author: Robert Masen <r.f.masen@gmail.com>
Date: Mon Jan 29 15:09:29 2024 -0600
Commit Three
# note: this commit hash has changed
commit ba11ba11ba11ba11ba11ba11ba11ba11ba11ba11
Author: Robert Masen <r.f.masen@gmail.com>
Date: Mon Jan 29 09:44:37 2024 -0600
Commit Two
commit cafecafecafecafecafecafecafecafecafecafe
Author: Robert Masen <r.f.masen@gmail.com>
Date: Fri Jan 26 15:09:01 2024 -0600
Commit One
I personally have this script in my path named git-fixup
# ! /bin/bash
# ~/.local/bin/git-fixup
# this can be used via `git fixup <commit-hash>`
git commit --fixup $1 && git rebase -i --autosquash $1~1