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'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 <commit></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 <commit></code>.</li>
<li>Run: <code>git history split <commit></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'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: