Hacker News new | ask | show | jobs
by exDM69 4031 days ago
This can be easily solved without aliases by adding a new commit on top, then using `git rebase -i` to re-order and squash the commit on top of another one.

It wasn't immediately obvious to me that you can also re-order patches using `rebase -i`. I've used for squashing and dropping temporary code before but realizing it can also reorder commits was really useful.

3 comments

git rebase is just a mechanized cherry picker. (Agricultural implement, really, when you think about it.)

In fact, you can add arbitrary commits to the list, not only re-order the existing ones!

I sometimes do this:

    $ git log --reverse --oneline here..there > arbitrary-picks
Then we edit the arbitrary-picks file so that it has the interactive rebase syntax: i.e. putting the word "pick" in front of every line. Then:

    $ git rebase -i HEAD   # noop!
In the editor, we delete the "noop" line and read in the arbitrary-picks:

    :r arbitrary-picks
Wee, now we are picking all those commits into this branch, with the interactive rebase workflow.
Even cooler is the "exec" directive. I converted a darcs repo to git and then used rebase to separate the huge mass of commits in the dev repo into their own branches. It went something like this:

    exec git branch new_master
    exec git checkout -b branch-a
    pick a
    pick b
    pick c
    exec git checkout new_master
    pick d
    exec git checkout -b branch-b
    pick e
    exec git checkout new_master
    exec git checkout -b branch-c
    pick f
    ...
    exec git checkout new_master
The only trick was that you're doing stuff behind rebase's back, so whatever branch you end the script on gets `git reset` to the last pick. So you have to remember to switch back to master or end on a dummy branch that you can delete. Also, since the branch you are rebasing is not changed until the end, you can't rely on its name (since at the start it's pointing to the current state of things, not the new state), so you have to create your own branch if you want to keep popping back and forth.

It was a neat trick and when it was done all the commits were nicely sorted into feature branches, as if we'd been doing that all along.

There's also a feature called autosquash that lets you use 'git commit --fixup sha' to write a commit preformatted to be recognized by interactive rebase. You have to turn it on in your config, but it's very handy for this sort of thing.
Yep, git inject uses this feature :)
The point of the alias is to make it more user-friendly and less error-prone.