Git autosquash goodies
Interactive rebase is a powerful tool, but more so is the --autosquash feature of git 1.7.
After having added your changes to index with git add
, the following aliases will allow you to specify a short SHA of a commit to fixup/squash to, rebasing interactively the intermediate commits:
fixup = !sh -c 'REV=$(git rev-parse $1) && git commit --fixup $@ && git rebase -i --autosquash $REV^' -
squash = !sh -c 'REV=$(git rev-parse $1) && git commit --squash $@ && git rebase -i --autosquash $REV^' -
These first two aliases can be freely found in the wild, I cannot find the source where I got them and therefore give proper credits.
If the goal is to fixup/squash some work to the last commit instead, you can use:
fixprev = "!f() { SHA=$(git rev-parse HEAD) && REV=$(git rev-parse $SHA) && git commit --fixup $SHA && git rebase -i --autosquash $REV^; }; f -"
sqprev = "!f() { SHA=$(git rev-parse HEAD) && REV=$(git rev-parse $SHA) && git commit --squash $SHA && git rebase -i --autosquash $REV^; }; f -"
Written by Andrea Richiardi
Related protips
3 Responses
Why not just SHA=$(git rev-parse HEAD)
?
Right! I will try it out (but it should work) and then correct my tip. Thank you!
I don't see the point of fixprev and sqprev since they are equivalent to git commit --amend [--no-edit]
I wrote an alias leveraging those --fixup
and --autosquash
options: https://gist.github.com/jcarsique/24f8dd46d176bb67253e
I use it every day combined with git add -p
to separate the fommatting and cleanup changes from the important code changes, or to distribute the changes on the relevant commits.
Worth to mention that this command changes the Git history: to be used on a local or "feature" branch.
fix = "!_() { c=$(git rev-parse $1) && git commit --fixup $c && git diff-index --quiet HEAD; s=$?; [ $s != 0 ] && git stash; git -c core.editor=cat rebase -i --autosquash --keep-empty $c~ && [ $s != 0 ] && git stash pop; }; _"
Simplified since Git 1.8.4 with --autostash
:
fix = "!_() { c=$(git rev-parse $1) && git commit --fixup $c && git -c core.editor=cat rebase -i --autosquash --keep-empty --autostash $c~; }; _"
Usage:
git add ... # stage changes to fix up
git fix <rev>
That will temporarily stash the current changes if any and fixup the given revision with the staged changes.