<?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 ENKR's Blog | Jing Hui PANG</title><link>https://blog.enkr1.com/tags/git/</link><description>Recent content in Git on ENKR's Blog | Jing Hui PANG</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>ENKR</copyright><lastBuildDate>Sun, 20 Sep 2026 21:52:28 +0800</lastBuildDate><atom:link href="https://blog.enkr1.com/tags/git/index.xml" rel="self" type="application/rss+xml"/><item><title>Pick the Layer, Not the Tool: the Git TUI Comparison Everyone Runs Is One Level Too High</title><link>https://blog.enkr1.com/pick-the-layer-not-the-tool/</link><pubDate>Sat, 05 Sep 2026 13:48:20 +0800</pubDate><guid>https://blog.enkr1.com/pick-the-layer-not-the-tool/</guid><description>&lt;blockquote&gt;
&lt;p&gt;i asked my AI which terminal git client to download, got told lazygit, installed it, and then asked the question i should have asked first: what is the &lt;em&gt;best&lt;/em&gt;, actually. answering that one properly meant checking claims instead of repeating them, and two of the things i had just been told turned out to be wrong. i had it dig through the upstream docs, the published benchmarks and my own installed binary rather than trusting the summary. the personal note at the bottom is mine to write after.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="tldr"&gt;tl;dr
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;lazygit is still the right download. that part survived contact with the evidence.&lt;/li&gt;
&lt;li&gt;the speed benchmark everyone quotes is real, and irrelevant at my scale: it is worth about &lt;strong&gt;0.18 seconds&lt;/strong&gt; on my largest repo.&lt;/li&gt;
&lt;li&gt;lazygit and tig are not rivals. lazygit has no blame at all, and its own wiki tells you to call tig for it.&lt;/li&gt;
&lt;li&gt;the biggest single improvement was not a client. it was &lt;code&gt;delta&lt;/code&gt;, one layer down, in git config.&lt;/li&gt;
&lt;li&gt;and the delta-plus-lazygit config you will find online is &lt;strong&gt;stale&lt;/strong&gt;: the key was renamed. most posts still teach the dead one.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-question"&gt;the question
&lt;/h2&gt;&lt;p&gt;&amp;ldquo;which terminal git client should i download&amp;rdquo; is a shopping question, and shopping questions get you the popular answer. the popular answer here is lazygit, and it is not wrong. but &amp;ldquo;what is the best, actually&amp;rdquo; is a different question, and it is only answerable if you first say &lt;strong&gt;best at what&lt;/strong&gt;. that turned out to be the whole note.&lt;/p&gt;
&lt;p&gt;three tools get compared endlessly, so start there and attach real numbers to them, because the arguing is usually done without any.&lt;/p&gt;
&lt;h2 id="the-field-with-the-numbers-attached"&gt;the field, with the numbers attached
&lt;/h2&gt;&lt;p&gt;star counts pulled from the github api on 5 september 2026, so they are a snapshot, not a law.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;tool&lt;/th&gt;
&lt;th&gt;stars&lt;/th&gt;
&lt;th&gt;written in&lt;/th&gt;
&lt;th&gt;what it actually is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;lazygit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;81,999&lt;/td&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;full workflow manager: stage by hunk or line, interactive rebase, worktrees, custom commands&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;delta&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32,083&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;not a client at all. a diff renderer that sits under git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;jj&lt;/strong&gt; (jujutsu)&lt;/td&gt;
&lt;td&gt;31,403&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;not a client either. a different version-control model, git-compatible underneath&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;gitui&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;22,464&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;fast, low-memory TUI. still pre-1.0, interactive rebase is an open roadmap item&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tig&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;13,321&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;a reader: log, diff, blame. barely a writer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;magit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;7,217&lt;/td&gt;
&lt;td&gt;Emacs Lisp&lt;/td&gt;
&lt;td&gt;the most complete git interface anyone has built. costs Emacs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;neogit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5,609&lt;/td&gt;
&lt;td&gt;Lua&lt;/td&gt;
&lt;td&gt;magit&amp;rsquo;s ideas, ported to Neovim&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;gitu&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,906&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;magit&amp;rsquo;s ideas, standalone, young&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;the first thing worth noticing is that the second most-starred thing on that list is not a client. hold that.&lt;/p&gt;
&lt;h2 id="the-axis-everyone-argues-about-is-speed"&gt;the axis everyone argues about is speed
&lt;/h2&gt;&lt;p&gt;the benchmark that gets quoted in every comparison comes from gitui&amp;rsquo;s own README, off a RustBerlin talk, parsing the entire Linux kernel repository at over 900,000 commits:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;time&lt;/th&gt;
&lt;th&gt;memory&lt;/th&gt;
&lt;th&gt;binary&lt;/th&gt;
&lt;th&gt;freezes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gitui&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;24 s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.17 GB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10 MB&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lazygit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;57 s&lt;/td&gt;
&lt;td&gt;2.6 GB&lt;/td&gt;
&lt;td&gt;25 MB&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4 m 20 s&lt;/td&gt;
&lt;td&gt;1.3 GB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.6 MB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;sometimes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;two honest caveats before anyone leans on that table. it is published by the tool that wins it, and it is a single scale point. it is still useful, because the architecture underneath it is real and explains the shape: &lt;strong&gt;lazygit shells out to the &lt;code&gt;git&lt;/code&gt; binary for every operation, gitui talks to the repository through libgit2 bindings.&lt;/strong&gt; forking a process per operation is genuinely more expensive, and that cost scales with how many commits have to be parsed.&lt;/p&gt;
&lt;p&gt;so scale it. if the cost is roughly linear in commits parsed, which for a full log walk it should be, you can ask where that 33-second gap actually lands for a normal person. my own repositories are 882 commits (my coursework repo) and 5,028 for the busiest project i own.&lt;/p&gt;
&lt;figure style="margin:1.6rem 0"&gt;
&lt;svg viewBox="0 0 620 372" role="img" aria-label="Where the lazygit versus gitui speed gap actually appears, against repo size" style="width:100%;max-width:620px;height:auto;font-family:inherit;display:block;margin:0 auto"&gt;
&lt;text x="310" y="20" text-anchor="middle" font-size="14" font-weight="600" fill="currentColor"&gt;Where the speed gap actually appears&lt;/text&gt;
&lt;rect x="148.3" y="40" width="152.9" height="260" fill="currentColor" fill-opacity="0.05"/&gt;
&lt;text x="224.7" y="34" text-anchor="middle" font-size="10" fill="currentColor" fill-opacity="0.6"&gt;my repos&lt;/text&gt;
&lt;line x1="70" y1="300.0" x2="590" y2="300.0" stroke="currentColor" stroke-opacity="0.10"/&gt;
&lt;text x="62" y="304.0" text-anchor="end" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;.001s&lt;/text&gt;
&lt;line x1="70" y1="248.0" x2="590" y2="248.0" stroke="currentColor" stroke-opacity="0.10"/&gt;
&lt;text x="62" y="252.0" text-anchor="end" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;.01s&lt;/text&gt;
&lt;line x1="70" y1="196.0" x2="590" y2="196.0" stroke="currentColor" stroke-opacity="0.10"/&gt;
&lt;text x="62" y="200.0" text-anchor="end" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;.1s&lt;/text&gt;
&lt;line x1="70" y1="144.0" x2="590" y2="144.0" stroke="currentColor" stroke-opacity="0.10"/&gt;
&lt;text x="62" y="148.0" text-anchor="end" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;1s&lt;/text&gt;
&lt;line x1="70" y1="92.0" x2="590" y2="92.0" stroke="currentColor" stroke-opacity="0.10"/&gt;
&lt;text x="62" y="96.0" text-anchor="end" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;10s&lt;/text&gt;
&lt;line x1="70" y1="40.0" x2="590" y2="40.0" stroke="currentColor" stroke-opacity="0.10"/&gt;
&lt;text x="62" y="44.0" text-anchor="end" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;100s&lt;/text&gt;
&lt;line x1="70.0" y1="300" x2="70.0" y2="304" stroke="currentColor" stroke-opacity="0.45"/&gt;
&lt;text x="70.0" y="318" text-anchor="middle" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;100&lt;/text&gt;
&lt;line x1="200.0" y1="300" x2="200.0" y2="304" stroke="currentColor" stroke-opacity="0.45"/&gt;
&lt;text x="200.0" y="318" text-anchor="middle" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;1k&lt;/text&gt;
&lt;line x1="330.0" y1="300" x2="330.0" y2="304" stroke="currentColor" stroke-opacity="0.45"/&gt;
&lt;text x="330.0" y="318" text-anchor="middle" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;10k&lt;/text&gt;
&lt;line x1="460.0" y1="300" x2="460.0" y2="304" stroke="currentColor" stroke-opacity="0.45"/&gt;
&lt;text x="460.0" y="318" text-anchor="middle" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;100k&lt;/text&gt;
&lt;line x1="590.0" y1="300" x2="590.0" y2="304" stroke="currentColor" stroke-opacity="0.45"/&gt;
&lt;text x="590.0" y="318" text-anchor="middle" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;1M&lt;/text&gt;
&lt;text x="330.0" y="336" text-anchor="middle" font-size="11" fill="currentColor" fill-opacity="0.7"&gt;commits in the repo (log scale)&lt;/text&gt;
&lt;line x1="70" y1="300" x2="590" y2="300" stroke="currentColor" stroke-opacity="0.45"/&gt;
&lt;path d="M 70.0 258.3 L 590.0 50.3" fill="none" stroke="#f97316" stroke-width="2.5"/&gt;
&lt;path d="M 70.0 277.8 L 590.0 69.8" fill="none" stroke="#3b82f6" stroke-width="2.5"/&gt;
&lt;circle cx="584.1" cy="52.7" r="4" fill="#f97316" stroke="#f97316" stroke-width="2"/&gt;
&lt;circle cx="584.1" cy="72.2" r="4" fill="#3b82f6" stroke="#3b82f6" stroke-width="2"/&gt;
&lt;circle cx="291.2" cy="169.8" r="4" fill="var(--card-background, #fff)" stroke="#f97316" stroke-width="2"/&gt;
&lt;circle cx="291.2" cy="189.4" r="4" fill="var(--card-background, #fff)" stroke="#3b82f6" stroke-width="2"/&gt;
&lt;line x1="584.1" y1="52.7" x2="584.1" y2="72.2" stroke="currentColor" stroke-opacity="0.35" stroke-dasharray="3 3"/&gt;
&lt;text x="576.1" y="66.5" text-anchor="end" font-size="10" fill="currentColor" fill-opacity="0.75"&gt;33s apart (measured)&lt;/text&gt;
&lt;line x1="291.2" y1="169.8" x2="291.2" y2="189.4" stroke="currentColor" stroke-opacity="0.35" stroke-dasharray="3 3"/&gt;
&lt;text x="301.2" y="183.6" font-size="10" fill="currentColor" fill-opacity="0.75"&gt;0.18s apart&lt;/text&gt;
&lt;line x1="84" y1="46" x2="106" y2="46" stroke="#f97316" stroke-width="2.5"/&gt;
&lt;text x="113" y="50" font-size="11" fill="currentColor" fill-opacity="0.85"&gt;lazygit (shells out to git)&lt;/text&gt;
&lt;line x1="84" y1="63" x2="106" y2="63" stroke="#3b82f6" stroke-width="2.5"/&gt;
&lt;text x="113" y="67" font-size="11" fill="currentColor" fill-opacity="0.85"&gt;gitui (libgit2 bindings)&lt;/text&gt;
&lt;/svg&gt;
&lt;figcaption style="font-size:0.85rem;opacity:0.75;text-align:center;margin-top:0.5rem"&gt;Both lines are anchored on the single published measurement at 900k commits (gitui's own README) and scaled linearly in commit count, so treat everything left of that point as an extrapolation, not a measurement. The shaded band is where my own repositories actually sit.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;on my largest repository, the entire performance argument between the fastest client and the most popular one is worth &lt;strong&gt;0.18 seconds&lt;/strong&gt;. on my coursework repo it is 0.03 seconds. you would need something like 180 times my biggest repo before the difference cleared one second.&lt;/p&gt;
&lt;p&gt;this is the &lt;a class="link" href="https://blog.enkr1.com/build-vs-buy/" &gt;build versus buy crossover&lt;/a&gt; in a different costume: there is a real line where gitui wins, it is just nowhere near where i live. and it rhymes with the rule from my &lt;a class="link" href="https://blog.enkr1.com/curation-beats-collection/" &gt;curation note&lt;/a&gt;: the question is never &amp;ldquo;is this better&amp;rdquo;, it is &amp;ldquo;does it beat the thing it would replace, by enough to pay for the switch&amp;rdquo;. a fifth of a second, against losing interactive rebase, is not close.&lt;/p&gt;
&lt;h2 id="the-axis-that-actually-separates-them"&gt;the axis that actually separates them
&lt;/h2&gt;&lt;p&gt;drop speed and the tools separate cleanly along a different line: &lt;strong&gt;do you mutate the repository, or do you read it.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;lazygit cannot do blame.&lt;/strong&gt; i grepped its entire 343-line default config on the version i installed (0.64.1): zero occurrences of the word. this is not an oversight, it is a scope decision, and the project&amp;rsquo;s own wiki resolves it by suggesting you bind a custom command that launches &lt;strong&gt;tig&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;gitui cannot do interactive rebase.&lt;/strong&gt; that is not a jab from a competitor, it sits in gitui&amp;rsquo;s own README as an open pre-1.0 roadmap item.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;so the tool that mutates best cannot read, the tool that reads best barely writes, and the fast one cannot do the single most valuable mutation. &amp;ldquo;lazygit vs tig&amp;rdquo; was never a versus. upstream is telling you to install both, and both together are under 20 MB.&lt;/p&gt;
&lt;h2 id="the-layer-nobody-compares"&gt;the layer nobody compares
&lt;/h2&gt;&lt;p&gt;here is the part that actually changed my setup, and it is not a client.&lt;/p&gt;
&lt;p&gt;before any of this i had no &lt;code&gt;core.pager&lt;/code&gt; set and no diff renderer installed. every diff i read, in the terminal or inside any tool, was raw git green-and-red. swapping TUI changes one program. changing the renderer under git changes &lt;code&gt;git diff&lt;/code&gt;, &lt;code&gt;git show&lt;/code&gt;, &lt;code&gt;git log -p&lt;/code&gt;, &lt;code&gt;git add -p&lt;/code&gt;, and every tool downstream that pipes through git. that is why delta has more stars than every client in this note except lazygit itself: it is one level down, so it multiplies.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install git-delta tig
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;git config --global core.pager delta
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;git config --global interactive.diffFilter &lt;span class="s1"&gt;&amp;#39;delta --color-only&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;git config --global delta.navigate &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the shape of the mistake i made first time round is worth naming: i went shopping at the application layer for a problem that lived at the configuration layer. &lt;strong&gt;the tool comparison you are running may just be one level too high.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="a-real-one-the-config-that-works-today-not-in-2023"&gt;a real one: the config that works today, not in 2023
&lt;/h2&gt;&lt;p&gt;this is the bit that justified doing the reading, and it is a live trap.&lt;/p&gt;
&lt;p&gt;almost every guide online tells you to wire delta into lazygit like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;git&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;paging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;delta --dark --paging=never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;that key no longer exists.&lt;/strong&gt; lazygit renamed the whole feature: &lt;code&gt;docs/Custom_Pagers.md&lt;/code&gt; is gone from the repository and &lt;code&gt;docs/Custom_DiffRenderers.md&lt;/code&gt; replaced it, with upstream noting plainly that these &amp;ldquo;used to be called custom pagers in earlier lazygit versions&amp;rdquo;. i confirmed the current shape against my installed binary, whose default is an empty &lt;code&gt;git.diffRenderers: []&lt;/code&gt;. the config that works today:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;git&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;diffRenderers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;delta --dark --paging=never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;two things fall out of that which the stale guides cannot tell you. it is an &lt;strong&gt;array&lt;/strong&gt;, so you can list several renderers and cycle them in-app with &lt;code&gt;|&lt;/code&gt;, which is genuinely nice for switching to &lt;code&gt;--color-words&lt;/code&gt; on a prose diff. and &lt;code&gt;delta --navigate&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; work inside lazygit, by upstream&amp;rsquo;s own note, so that &lt;code&gt;delta.navigate true&lt;/code&gt; above earns its keep on the command line only.&lt;/p&gt;
&lt;p&gt;also worth correcting, because i said the opposite an hour earlier: lazygit does &lt;strong&gt;not&lt;/strong&gt; inherit your &lt;code&gt;core.pager&lt;/code&gt; by default. the default is empty, and you either write the renderer explicitly or opt in. setting &lt;code&gt;core.pager&lt;/code&gt; alone does nothing for it.&lt;/p&gt;
&lt;h2 id="where-people-get-this-wrong"&gt;where people get this wrong
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;quoting a vendor benchmark without scaling it to yourself.&lt;/strong&gt; the 900k-commit number is true and almost never relevant. run &lt;code&gt;git rev-list --count HEAD&lt;/code&gt; on your own repository before you let it decide anything.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;treating a reader and a writer as competitors&lt;/strong&gt; because both are TUIs and both are about git.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;reading tool docs through a search summary.&lt;/strong&gt; the renamed config key is exactly the failure mode: the summary confidently returned the old key, because the old key is what the internet is full of.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stopping at the application layer.&lt;/strong&gt; the pager, the diff renderer, the git config: all of it applies to every tool at once and none of it shows up in a &amp;ldquo;best git client&amp;rdquo; listicle.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="when-it-applies-and-when-it-doesnt"&gt;when it applies, and when it doesn&amp;rsquo;t
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;magit is genuinely the best git interface that exists.&lt;/strong&gt; everyone who has used it says so. it costs adopting Emacs, and i use VS Code. that price is real and i am not paying it, but &amp;ldquo;lazygit is best&amp;rdquo; is a claim about what is &lt;em&gt;adoptable&lt;/em&gt;, not what is &lt;em&gt;best&lt;/em&gt;, and it is worth being honest about the difference.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;gitui wins if you actually have the monorepo.&lt;/strong&gt; if &lt;code&gt;git rev-list --count HEAD&lt;/code&gt; comes back six figures, re-read that benchmark table, it is now about you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;jj is the interesting one.&lt;/strong&gt; it is not a nicer front end for git, it is a different model (no staging area, everything is a commit, undo anything) that happens to be git-compatible on disk. it is the only thing here that would change how i think rather than how i click. it is also the only one that would fight my setup, since most of my commits are made by agents driving the &lt;code&gt;git&lt;/code&gt; CLI directly. parked, not dismissed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="key-takeaways"&gt;key takeaways
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;ask &amp;ldquo;best at what&amp;rdquo; before &amp;ldquo;which one&amp;rdquo;. a shopping question returns the popular answer.&lt;/li&gt;
&lt;li&gt;scale every benchmark to your own numbers before letting it decide anything.&lt;/li&gt;
&lt;li&gt;tools that look like competitors are often a reader and a writer. check whether upstream tells you to install both.&lt;/li&gt;
&lt;li&gt;when comparing applications, check whether the problem lives a layer below them. config-layer changes multiply across every tool you own.&lt;/li&gt;
&lt;li&gt;verify tool config against the installed binary, not against a search result. renamed keys are invisible to consensus.&lt;/li&gt;
&lt;li&gt;the same move turned up a week later in a completely different corner of the stack, deciding a javascript dependency: https://blog.enkr1.com/should-i-use-ultrastorage/, where the useful thing again sat one layer below the thing being evaluated.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="a-personal-note"&gt;a personal note
&lt;/h2&gt;&lt;p&gt;wip &amp;hellip;&lt;/p&gt;
&lt;h2 id="sources-and-further-reading"&gt;sources and further reading
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/jesseduffield/lazygit" target="_blank" rel="noopener"
&gt;lazygit&lt;/a&gt; and its &lt;a class="link" href="https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_DiffRenderers.md" target="_blank" rel="noopener"
&gt;Custom Diff Renderers doc&lt;/a&gt;, which is the current, correct home of the delta config and explicitly records the rename away from &amp;ldquo;custom pagers&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/gitui-org/gitui" target="_blank" rel="noopener"
&gt;gitui&lt;/a&gt;: the benchmark table and the pre-1.0 roadmap both live in its README, which is the primary source for the 900k-commit numbers quoted above.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/jesseduffield/lazygit/discussions/1690" target="_blank" rel="noopener"
&gt;the &amp;ldquo;i cannot find git blame&amp;rdquo; discussion on lazygit&lt;/a&gt;, where the answer is to shell out to tig.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/dandavison/delta" target="_blank" rel="noopener"
&gt;delta&lt;/a&gt;: the three-line global config in its README is the whole setup.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/jonas/tig" target="_blank" rel="noopener"
&gt;tig&lt;/a&gt;, &lt;a class="link" href="https://github.com/magit/magit" target="_blank" rel="noopener"
&gt;magit&lt;/a&gt;, &lt;a class="link" href="https://github.com/martinvonz/jj" target="_blank" rel="noopener"
&gt;jujutsu&lt;/a&gt;, &lt;a class="link" href="https://github.com/altsem/gitu" target="_blank" rel="noopener"
&gt;gitu&lt;/a&gt; and &lt;a class="link" href="https://github.com/NeogitOrg/neogit" target="_blank" rel="noopener"
&gt;neogit&lt;/a&gt; for the rest of the field.&lt;/li&gt;
&lt;li&gt;my &lt;a class="link" href="https://blog.enkr1.com/build-vs-buy/" &gt;build versus buy note&lt;/a&gt;: the crossover maths behind &amp;ldquo;there is a scale where the other tool wins, and it is not mine&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;my &lt;a class="link" href="https://blog.enkr1.com/curation-beats-collection/" &gt;curation note&lt;/a&gt;: why &amp;ldquo;better&amp;rdquo; is not the bar, and &amp;ldquo;better by enough to pay for the switch&amp;rdquo; is.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>