<html>
<head>
<title>Simple Git Branch Squashing</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/static/app.css">
<link rel="alternate" type="application/atom+xml" href="/atom.xml">
</head>
<body>
<header class="site-header">
<div class="wrapper">
<a class="site-title" href="/">Adam Neumann's blog</a>
<nav class="site-nav">
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger">
<span class="menu-icon">
<svg viewBox="0 0 18 15" width="18px" height="15px">
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
</svg>
</span>
</label>
<div class="trigger">
<a class="page-link" href="/pages/about.html">About</a>
<a class="page-link" href="/pages/resources.html">Resources</a>
</div>
</nav>
</div>
</header>
<main class="page-content">
<div class="wrapper">
<article class="post">
<header class="post-header">
<h1 class="post-title">Simple Git Branch Squashing</h1>
<p class="post-meta">
<span>Oct 22, 2019</span>
</p>
</header>
<div class="post-content">
<h2>The old way</h2>
<p>When developing features, I'll often use temporary WIP branches to store WIP commits before squashing them into a single feature commit.
To squash the WIP commits, I have always run <code>git rebase -i HEAD~x</code>, where <code>x</code> is the number of commits to squash.
To calculate <code>x</code>, I run <code>git log</code> and manually count each commit.
This week I found a simpler way write that command.</p>
<h2>A simpler way</h2>
<p>It turns out that <code>HEAD~x</code> is a commit-ish, which refers to the commit <code>x-1</code> before <code>HEAD</code>.
For trunk based development, <code>HEAD~1</code> is actually the head of the trunk branch!
Conveniently, this commit can also be referred to by the trunk branch's name.</p>
<p>Put more concisely:</p>
<blockquote>
<p>When squashing <code>x</code> commits atop a branch named <code>develop</code>, then <code>HEAD~x</code> and <code>develop</code> are equivalent commit-ishes.</p>
</blockquote>
<p>That means the command <code>git rebase -i develop</code> can be used instead of <code>git rebase -i HEAD~x</code>.
Same outcome, less cognitive overhead!</p>
<h2>Example</h2>
<p>For this blog, the trunk branch is <code>develop</code>.
When implementing the Atom Feed feature, the <code>atom-feed</code> branch was used to track work in progress.</p>
<p><img src="/assets/squashing-wip-branches/unsquashed-branch.png" alt="Unsquashed WIP branch" /></p>
<p>The <code>atom-feed</code> branch contains 4 WIP commits that together comprise the feature.
The goal is to squash these 4 commits into a single commit on develop.</p>
<p>First, to perform the squash I ran <code>git rebase -i develop</code> to start an interactive rebase:</p>
<p><img src="/assets/squashing-wip-branches/interactive-rebase.png" alt="Interactive rebase" /></p>
<p>Here I <code>reword</code> the first commit (to describe the overall feature) and then <code>fixup</code> to squash the final 3 commits into the first.
The resulting commit (<code>a55bf81</code>) is our feature commit.
Also, this results in the <code>atom-feed</code> branch being 1 commit ahead of <code>develop</code>:</p>
<p><img src="/assets/squashing-wip-branches/squashed-branch.png" alt="Squashed WIP branch" /></p>
<p>Finally, after merging the <code>atom-feed</code> branch into <code>develop</code>, the history looks like this:</p>
<p><img src="/assets/squashing-wip-branches/merged-into-develop.png" alt="Merged into develop" /></p>
</div>
</article>
</div>
</main>
<footer class="site-footer">
<div class="wrapper">
<div class="footer-col-wrapper">
<div class="footer-col one-half">
<h2 class="footer-heading">Adam Neumann's blog</h2>
<ul class="contact-list">
<li class="p-name">Adam Neumann</li>
<li><a class="u-email" href="mailto:blog@noizwaves.com">blog@noizwaves.com</a></li>
</ul>
</div>
<div class="footer-col one-half">
<p>Technical blog of Adam Neumann. Engineer at Gusto in Boulder, CO.
</p>
</div>
</div>
<div class="footer-col-wrapper">
<div class="social-links">
<ul class="social-media-list">
<li>
<a href="https://github.com/noizwaves">
<span class="username">Github</span>
</a>
</li>
<li>
<a href="https://www.twitter.com/noizwaves">
<span class="username">Twitter</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</footer>
</body>
</html>