I just read amending a single file in a past commit in git but unfortunately the accepted solution \'reorders\' the commits, which is not what I want. So here\'s my question
I wrote a little shell function called gcf
to perform the fixup commit and the rebase automatically:
$ git add -p
... select hunks for the patch with y/n ...
$ gcf
That commits the fixup and does the rebase. Done! You can get back to coding.
For example, you can patch the second commit before the latest with: gcf HEAD~~
Here is the function. You can paste it into your ~/.bashrc
git_commit_immediate_fixup() {
local commit_to_amend="$1"
if [ -z "$commit_to_amend" ]; then
echo "You must provide a commit to fixup!"; return 1
fi
# Get a static commit ref in case the commit is something relative like HEAD~
commit_to_amend="$(git rev-parse "${commit_to_amend}")" || return 2
#echo ">> Committing"
git commit --no-verify --fixup "${commit_to_amend}" || return 3
#echo ">> Performing rebase"
EDITOR=true git rebase --interactive --autosquash --autostash \
--rebase-merges --no-fork-point "${commit_to_amend}~"
}
alias gcf='git_commit_immediate_fixup'
It uses --autostash
to stash and pop any uncommitted changes if necessary.
--autosquash
requires an --interactive
rebase, but we avoid the interaction by using a dummy EDITOR
.
--no-fork-point
protects commits from being silently dropped in rare situations (when you have forked off a new branch, and someone has already rebased past commits).