Git History Command: The Safer Way to Split, Reword, and Fixup Commits
The git history command is an experimental addition to core Git for the work developers routinely do after the code is already written: split one messy commit, reword an old commit, or fix up a change without reaching immediately for a terrifying interactive rebase.
It is not a replacement for Git. It is a sharper set of scalpels for repairing Git history—and it is worth knowing about before you switch your entire workflow to Jujutsu (jj).
A Hacker News discussion pushed this command onto the front page today, with 372 points and 249 comments when checked. The timing is useful: the feature is new enough to be overlooked, but old enough to have landed across Git 2.54 and 2.55.
What is the git history command?
git history is an experimental command family documented by Git. The current subcommands are:
-
fixup— fold a commit's changes into another commit -
reword— change a commit message -
split— interactively divide a commit into multiple commits
The feature arrived incrementally. Git's 2.54 release notes added reword and split; Git 2.55 added fixup.
That matters because the command is not available in every Git installation. My current environment reports Git 2.39.5, so blindly copying these commands there will fail. Check first:
git --version
Use a recent Git build that includes the command, and remember the warning in the official documentation: this is experimental behavior, not a promise that the interface will never change.
Why git history beats a panic-driven interactive rebase
Interactive rebase is powerful. It is also a command where a small mistake can turn a straightforward cleanup into a recovery exercise involving reflogs, detached HEADs, and increasingly desperate searches through Stack Overflow.
The usual workflow looks like this:
git rebase -i <parent>
Then you edit a list of commits and hope the operation does exactly what you intended. That is fine when you are comfortable with rebase's state machine. It is less fine when you are fixing one specific commit in a branch with parallel work, merges, or references you do not want to disturb.
git history makes the intent explicit. You ask Git to split this commit, reword that commit, or fix up this commit. The command is still rewriting history—do not confuse a nicer interface with a risk-free operation—but the operation maps more directly to the job in your head.
How to use git history split
Suppose HEAD contains a commit that combines a refactor and a test update. You want two commits instead of one:
git history split HEAD
Git interactively lets you choose the hunks to move into the new split-out commit. The remaining changes stay in the original commit, whose parent is updated to the newly created commit.
You can limit the split to a pathspec when only one part of a large commit needs surgery:
git history split HEAD -- src/auth/
The important mental model is that you are not merely staging the current working tree. You are editing the shape of an existing commit. Treat the result as a history rewrite and inspect it immediately:
git log --oneline --decorate -5
git show --stat HEAD
git diff HEAD~2..HEAD
Do this before pushing. If the branch is already shared, coordinate with everyone who has based work on it.
How to use git history reword
Bad commit message? Fix it directly:
git history reword <commit>
This is the boring operation, which is exactly why it is useful. A clear commit message improves git log, release-note generation, blame investigations, and the next engineer's ability to understand why a change exists.
Use it to turn messages like this:
fix stuff
into something that carries actual information:
retry token refresh after a transient 401
Do not rewrite commits that are already part of a public branch merely to satisfy aesthetics. A clean private branch is a good target. A force-pushed shared branch is a team incident waiting to happen.
How to use git history fixup
To fold a commit into an earlier commit, run:
git history fixup <commit>
The command is conceptually similar to creating a fixup! commit and then running an interactive rebase with autosquash, but the intent is packaged as one history operation. The official documentation also exposes a --dry-run option for the history subcommands, so use it when you want to inspect the proposed operation before committing to it:
git history fixup <commit> --dry-run
The exact output and behavior can evolve while the command remains experimental. Read the version of the official documentation installed with your Git rather than assuming a blog post from another release is authoritative.
Git history vs. Jujutsu
The feature exists in the same problem space that makes Jujutsu attractive: developers want to manage a stream of changes without constantly wrestling with the index, temporary commits, and rebase choreography.
Jujutsu is still a distinct version-control system with a different model. git history is much less ambitious. It keeps you inside Git's object database, remotes, hosting integrations, and team conventions while improving a few high-friction history edits.
That is the pragmatic appeal:
- no repository migration
- no new hosting workflow
- no new mental model for everyday branching
- no need to teach the whole team a different VCS to get better commit surgery
If your pain is specifically “I need to split, rename, or fold this commit,” try the narrow tool first. Do not adopt a new version-control system to solve a problem a built-in command already addresses.
A safe workflow for rewriting history
History editing is still history editing. Use guardrails:
1. Create a recovery reference
Before experimenting, create a temporary branch or tag:
git branch before-history-edit
If the result is wrong, the original commit graph still has a name.
2. Run the operation on a private branch
Never start by rewriting main, a release branch, or a branch other people are actively using.
3. Prefer dry runs
Where supported, use --dry-run first. Then inspect the proposed commit graph and file changes.
4. Check the graph, not only the working tree
A clean working tree does not prove that the history is correct:
git log --graph --oneline --decorate --all -15
git diff before-history-edit..HEAD
5. Push rewritten history deliberately
If the branch is already remote, use the least dangerous force option available to your workflow:
git push --force-with-lease origin feature/my-change
--force-with-lease is not magic, but it refuses to overwrite a remote update you have not seen. That is a much better default than --force.
The sharp opinion
Git has spent years accumulating commands that expose its internals while leaving common history edits to a cryptic interactive todo list. git history is a welcome correction.
The feature does not make rewriting commits safe. It makes the requested operation legible. That is a meaningful improvement: fewer accidental rebases, fewer “what did I just do?” moments, and less pressure to migrate tools because Git's porcelain made a simple job feel like surgery with a chainsaw.
Try it on a disposable branch. Read the version-specific docs. Keep the reflog and a recovery reference. Then decide whether git history earns a place in your daily workflow.
Top comments (0)