Quantcast
Channel: Planet Ubuntu
Viewing all articles
Browse latest Browse all 17727

Scott James Remnant: git smash

$
0
0

A common thing I end up doing while working on code is to make a series of commits, and  then end up work changes in my working directory which I need to apply to an earlier revision in the history than the top-most one.

One common way to do this is to make a temporary commit with those changes, then use git rebase -i and move that commit below the one I want to amend and choose fixup to have it applied.

But that’s annoying manual work. There’s a more fun way. I have this script in my path as git-smash, it takes a revision as a single argument, e.g. git smash deadbeef:

git reset --keep "$1"
EDITOR=true git commit -a --amend
git checkout HEAD@{2}
git rebase --onto HEAD@{1} HEAD@{2}

This resets the revision history, keeping local changes, back to the given revision. Unfortunately git reset doesn’t have a mode which preserves the index so we then have to use commit -a to capture all of the local changes.

Now we use the reflog (history of revisions in the working tree) to manipulate the tree back to the previous state, first checking out the revision that was two back (before the amended commit and the reset, i.e. where we began). Then we rebase that onto the revision one back (before the checkout, i.e. the amended revision) using the revision that’s now two back (before the checkout and commit, i.e. the original revision we changed).

Mental gymnastics over, this is the same as what we were doing before, just in one handy command.

Git still sucks though.


Viewing all articles
Browse latest Browse all 17727

Trending Articles