Skip to content
Tech News
← Back to articles

The git history command

read original more articles

Working with lots of changes in parallel on git can be painful. You end up juggling branches and commits, and running scary rebase -i commands that can leave your tree in a half-broken state if you so much as sneeze.

jj , an alternative to git , gets discussed a lot these days (1, 2, 3, 4) and is often pitched as a solution. While I’m very sold on the problems jj is trying to solve, the way it solves them hasn’t quite hit home with me. Every 3 months, for the last 1.5 years, I try it out for a few days, really trying to make it part of my workflow but eventually I give up and go back to git.

That’s where git history comes in. It’s an experimental command that arrived across two releases, 2.54 (April, reword and split subcommands) and 2.55 (June, fixup subcommand). It got a flurry of attention on each release day, and then, as far as I can tell, not much community discussion since. Which is a shame, because IMO it already delivers several of the benefits people tout for jj without needing to switch your whole workflow. And the cool thing is that it’s part of the core git distribution, so you can try it without installing anything.

There are three subcommands: fixup , reword and split .

fixup

git history fixup fixes an old commit that has something wrong in it, then autorebases all your branches to match.

You stage the fix as usual with git add , then run git history fixup <commit> to fold those staged changes into the target commit. It’s like a git commit --fixup plus an autosquash rebase but with the extra magic that it also updates any other branch which contained that commit.

That last part goes further than git rebase --update-refs , which only moves refs sitting inside the range you’re actively rebasing. git history instead finds and rewrites every local branch descended from the commit (while also having an option to limit it to only the current branch). On the other hand it does not work in the presence of merge commits which, for some usages of git, is going to be a dealbreaker.

Here’s how it works in practice:

Before, with a fix staged for B :

... continue reading