Last Updated: February 25, 2016
·
729
· arichiardi

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 -"

3 Responses
Add your response

Why not just SHA=$(git rev-parse HEAD)?

over 1 year ago ·

Right! I will try it out (but it should work) and then correct my tip. Thank you!

over 1 year ago ·

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.

over 1 year ago ·