<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Git on Jhooq</title><link>https://jhooq.com/tags/git/</link><description>Recent content in Git on Jhooq</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Jhooq</copyright><lastBuildDate>Mon, 26 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jhooq.com/tags/git/index.xml" rel="self" type="application/rss+xml"/><item><title>git rebase --exec Explained - Run Your Tests on Every Commit Before You Push, with Real Output, the Failure Path, and the Three Things That Bit Me</title><link>https://jhooq.com/git-rebase-exec/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://jhooq.com/git-rebase-exec/</guid><description>
&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;git rebase --exec &amp;quot;&amp;lt;cmd&amp;gt;&amp;quot; &amp;lt;upstream&amp;gt;&lt;/code&gt;&lt;/strong&gt; (short form &lt;code&gt;-x&lt;/code&gt;) appends an &lt;code&gt;exec &amp;lt;cmd&amp;gt;&lt;/code&gt; line after every &lt;code&gt;pick&lt;/code&gt; in the rebase instruction list, so the command runs in the working tree of each replayed commit. A non-zero exit stops the rebase on that commit with exit code 1.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;When it stops, fix the commit in place:&lt;/strong&gt; edit, &lt;code&gt;git commit --amend --no-edit -a&lt;/code&gt;, then &lt;code&gt;git rebase --continue&lt;/code&gt;. Every commit from the fixed one onward gets a new hash; commits that passed unchanged keep theirs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fixing a commit can conflict with the next one.&lt;/strong&gt; In my run the amended line was the context the following commit appended to, so &lt;code&gt;--continue&lt;/code&gt; hit a merge conflict I had to resolve before the exec ran again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--reschedule-failed-exec&lt;/code&gt;&lt;/strong&gt; re-runs the failed command on every &lt;code&gt;--continue&lt;/code&gt; until it passes, instead of moving on. Set it permanently with &lt;code&gt;git config rebase.rescheduleFailedExec true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An empty range runs nothing&lt;/strong&gt; and still prints &lt;code&gt;Successfully rebased&lt;/code&gt;. Check &lt;code&gt;git log --oneline &amp;lt;upstream&amp;gt;..HEAD&lt;/code&gt; first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not your exact case?&lt;/strong&gt; If you want to find which commit introduced a bug rather than test all of them, that is &lt;code&gt;git bisect run&lt;/code&gt;; and if you are new to rebasing, start with my free &lt;a href="https://jhooq.com/git-github-blueprint-course/"&gt;Git and GitHub course&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="video"&gt;
&lt;iframe src="https://www.youtube.com/embed/O84IxYEo2cg?controls=1&amp;rel=0" loading="lazy"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2 id="table-of-content"&gt;Table of Content&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-what-exec-does-inside-a-rebase"&gt;What exec does inside a rebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-the-lab-repository"&gt;The lab repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-a-clean-run-over-every-commit"&gt;A clean run over every commit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-a-run-that-stops-on-a-bad-commit-and-the-fix"&gt;A run that stops on a bad commit, and the fix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-reschedule-failed-exec-retry-instead-of-skipping"&gt;reschedule-failed-exec: retry instead of skipping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-more-than-one-command-and-seeing-which-commit-is-running"&gt;More than one command, and seeing which commit is running&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-exec-versus-bisect-run-versus-ci"&gt;exec versus bisect run versus CI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-what-broke-when-i-ran-this"&gt;What broke when I ran this&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br/&gt;
&lt;h2 id="1-what-exec-does-inside-a-rebase"&gt;1. What exec does inside a rebase&lt;/h2&gt;
&lt;p&gt;Most people meet &lt;code&gt;exec&lt;/code&gt; as one of the commands in the interactive rebase instruction list, next to &lt;code&gt;pick&lt;/code&gt;, &lt;code&gt;squash&lt;/code&gt; and &lt;code&gt;drop&lt;/code&gt;. The &lt;a href="https://git-scm.com/docs/git-rebase"&gt;git rebase reference&lt;/a&gt; describes the &lt;code&gt;--exec &amp;lt;cmd&amp;gt;&lt;/code&gt; option as appending &lt;code&gt;exec &amp;lt;cmd&amp;gt;&lt;/code&gt; after each line that creates a commit in the final history, and says that any command that fails will interrupt the rebase with exit code 1. It also says it uses the interactive machinery internally but can be run without &lt;code&gt;--interactive&lt;/code&gt;, which is the form I use most: no editor opens, the commands just run.&lt;/p&gt;</description></item></channel></rss>