Mastering Targeted History Rewrites with Git 2.54's New `git history` Command

By ● min read
<h2>Introduction</h2> <p>Git 2.54, released with contributions from over 137 developers, introduces an experimental command designed for simpler history rewriting tasks: <code>git history</code>. Unlike the full power (and complexity) of <code>git rebase -i</code>, this new command focuses on two specific operations: <strong>reword</strong> and <strong>split</strong>. Whether you need to fix a typo in an old commit message or carve a large commit into two logical pieces, <code>git history</code> offers a targeted, non-interactive approach that doesn't touch your working tree or index. This guide walks you through everything you need to get started.</p><figure style="margin:20px 0"><img src="https://github.blog/wp-content/uploads/2026/04/git254.png" alt="Mastering Targeted History Rewrites with Git 2.54&#039;s New `git history` Command" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px">Source: github.blog</figcaption></figure> <h2 id="what-you-need">What You Need</h2> <ul> <li><strong>Git 2.54 or later</strong> – The <code>git history</code> command is only available in this version. Check with <code>git --version</code>.</li> <li><strong>A Git repository</strong> – Preferably one where you have permission to rewrite history (avoid shared branches unless you know what you're doing).</li> <li><strong>Basic command-line familiarity</strong> – You should be comfortable running Git commands and using a text editor.</li> <li><strong>Understanding of commit structure</strong> – Know what a commit hash is and how parent-child relationships work.</li> </ul> <h2>Step-by-Step Guide</h2> <h3 id="step1">Step 1: Upgrade to Git 2.54</h3> <p>If you haven't already, install or compile Git 2.54. On macOS, use Homebrew: <code>brew upgrade git</code>. On Ubuntu/Debian, add the official Git PPA or build from source. Verify the version:</p> <pre><code>git --version # Should output something like: git version 2.54.0</code></pre> <h3 id="step2">Step 2: Understand the Limitations</h3> <p>Before diving in, note that <code>git history</code> is experimental and intentionally limited. It <strong>does not</strong> support merge commits. It will refuse any operation that would cause a merge conflict. It's built on top of <code>git replay</code>'s machinery, making it safe for linear histories. Always test on a backup or a separate clone first.</p> <h3 id="step3">Step 3: Reword a Commit Message</h3> <p>To change the message of a specific commit (without interactive rebase), use <code>git history reword</code>. This opens your editor with the existing message, lets you edit it, and then rewrites history from that point forward. It does <strong>not</strong> modify your working tree or index, and it works even in bare repositories.</p> <ol> <li>Identify the commit hash (e.g., <code>abc123</code>) using <code>git log --oneline</code>.</li> <li>Run: <code>git history reword abc123</code>.</li> <li>Your default editor opens with the current message. Edit as needed, save, and close.</li> <li>Git automatically updates all descendant branches to point to the rewritten commit.</li> </ol> <p><strong>Example:</strong> Suppose commit <code>a1b2c3</code> has the message “Fix typo” but you want “Fix critical typo in login flow”. Running the reword command lets you change it instantly.</p> <h3 id="step4">Step 4: Split a Commit into Two</h3> <p>Use <code>git history split &lt;commit&gt;</code> to interactively carve out hunks into a new parent commit. The interface is similar to <code>git add -p</code>. After selecting which hunks belong to the new commit, Git creates a new parent commit with those changes, and the original commit retains the remaining hunks. All descendant branches are rewritten.</p> <ol> <li>Check the commit you want to split with <code>git show &lt;commit&gt;</code>.</li> <li>Run: <code>git history split &lt;commit&gt;</code> (e.g., <code>git history split HEAD</code>).</li> <li>For each hunk, you'll see a prompt like: <code>(1/1) Stage addition [y,n,q,a,d,p,?]?</code>. Press <strong>y</strong> to include that hunk in the new parent commit, or <strong>n</strong> to leave it in the original commit.</li> <li>After making your choices, Git creates the new commit and rewrites history. The original commit now has the new commit as its first parent.</li> </ol> <p><strong>Practical tip:</strong> Use this when you accidentally bundled two unrelated changes into a single commit. For example, a commit that both adds a feature and fixes a typo can be split into two clean commits.</p><figure style="margin:20px 0"><img src="https://github.blog/wp-content/uploads/2024/06/AI-DarkMode-4.png?resize=800%2C425" alt="Mastering Targeted History Rewrites with Git 2.54&#039;s New `git history` Command" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px">Source: github.blog</figcaption></figure> <h3 id="step5">Step 5: Verify the Rewritten History</h3> <p>After using either operation, inspect the new commit graph with <code>git log --oneline --graph</code>. Check that branch pointers have moved correctly. If something goes wrong, you can reset to the original state using <code>git reflog</code> – but note that <code>git history</code> does not create any backup references automatically.</p> <h2>Tips for Success</h2> <ul> <li><strong>Remember it's experimental.</strong> The <code>git history</code> command may change in future releases. Use it with caution on non-critical repositories.</li> <li><strong>Avoid merge commits.</strong> The command refuses to operate on histories containing merges. Stick to linear histories.</li> <li><strong>No conflicts allowed.</strong> If a rewrite would cause a merge conflict, Git aborts. This is by design – it's meant for safe, targeted changes.</li> <li><strong>Back up first.</strong> Create a clone or a branch (<code>git branch backup</code>) before rewriting any shared history.</li> <li><strong>Combine with other tools.</strong> For complex rewrites (reordering, squashing, dropping commits), stick with <code>git rebase -i</code>. Use <code>git history</code> only for quick rewords and splits.</li> <li><strong>Use in bare repos.</strong> Unlike most history-rewriting commands, <code>git history reword</code> works perfectly in bare repositories – great for server-side hook scripts.</li> </ul> <h2>Conclusion</h2> <p>Git 2.54's <code>git history</code> command fills a niche gap: straightforward commit message editing and commit splitting without the overhead of interactive rebase. By leveraging the robust <code>git replay</code> machinery under the hood, it provides a safe, focused tool for these two operations. While it won't replace <code>git rebase -i</code> for complex scenarios, it's a welcome addition for everyday quick fixes. Upgrade to Git 2.54, give it a try on a test repository, and see how it simplifies your history maintenance tasks.</p>
Tags: