<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>point.free</title>
      <link>https://point.free</link>
      <description>Notes from Christina Sørensen — software engineer, NixOS Steering Committee, author of eza.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://point.free/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Mon, 15 Jun 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>I restarted a 10 year old Xeon 174 times to delete twelve flags and gain four tokens a second</title>
          <pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/delete-12-flags/</link>
          <guid>https://point.free/blog/delete-12-flags/</guid>
          <description xml:base="https://point.free/blog/delete-12-flags/">&lt;p&gt;&lt;em&gt;A follow-up to running Gemma 4 on a 2016 Xeon. I took that 25-flag config apart one flag at a time, to find which ones actually do the work, which are harmful, and which are just pitfalls. Most of my tuned config will do nothing for the typical user.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A couple of weeks ago I got Gemma 4, a 26-billion-parameter model, running at
reading speed on a &lt;a href=&quot;..&#x2F;gemma-4-on-a-2016-xeon&#x2F;&quot;&gt;2016 Xeon with no GPU and 128 GB of
DDR3&lt;&#x2F;a&gt;. That post spent about eight hours on the
front page of Hacker News, which means a lot of people now have a 25-flag
command sitting in a terminal somewhere, copied from a blog, with no real idea
which of those flags is doing the work.&lt;&#x2F;p&gt;
&lt;p&gt;I have some bad news about that command. You’re likely holding it wrong.&lt;&#x2F;p&gt;
&lt;p&gt;What I said in that post in passing, is that half of those flags would not take
just by being present. Some need the right hardware. Some need the right host
setup. Some only help on the right workload. The engine accepts all of them and
tells you almost nothing about which ones actually fired. So this post is me
going back and finding out what will actually work for YOU.&lt;&#x2F;p&gt;
&lt;p&gt;The way you find out is an ablation. You take the working config, switch off
exactly one flag, measure what changes, put it back, and do the same for every
flag in turn. The word is borrowed from neuroscience by way of machine learning,
where it normally means knocking out a piece of the model itself, an attention
head or a layer, to see what it was for. I am using it a little improperly here,
for inference flags rather than model internals, but the idea carries over: turn
one thing off, measure, repeat, and the differences tell you what each piece was
worth.&lt;&#x2F;p&gt;
&lt;p&gt;It was a lot of work. Like a lot. One hundred and seventy-four runs, each one a
fresh server reloading twenty-five gigabytes of weights off a spinning disk
before it can answer a single token. Three prompts per launch, several
repetitions each, and one entire overnight run I had to throw in the bin over a
deadlock I will get to. I am telling you the count because the count is the
point. The reason nobody knows which of these flags matter is that finding out
is slow and tedious, so almost nobody does it. I did, so here is the answer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-setup&quot;&gt;The setup&lt;&#x2F;h2&gt;
&lt;p&gt;The box is the same one from the Xeon post. A Xeon E5-2620 v4, eight physical
cores, sixteen threads, 128 GB of DDR3, no GPU, no swap. The engine is
&lt;code&gt;ik_llama.cpp&lt;&#x2F;code&gt; on the &lt;code&gt;feat&#x2F;gemma-4-mtp&lt;&#x2F;code&gt; branch. The verifier is
&lt;code&gt;gemma-4-26B-A4B-it&lt;&#x2F;code&gt; at Q8_0, paired with its MTP drafter at Q8_0.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll use 3  test prompts:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a short chat turn&lt;&#x2F;li&gt;
&lt;li&gt;a roughly five-thousand-token document to summarize&lt;&#x2F;li&gt;
&lt;li&gt;a code generation request.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Greedy decoding, fixed seed, 256 new tokens, three repetitions, median reported.&lt;&#x2F;p&gt;
&lt;p&gt;Two things to clear out of the way before the numbers.&lt;&#x2F;p&gt;
&lt;p&gt;I ran the benchmark under &lt;code&gt;llama-server&lt;&#x2F;code&gt; rather than the &lt;code&gt;llama-cli&lt;&#x2F;code&gt; from the
original command. The server is where the per-request speculative-decoding
telemetry lives, which is the only clean way to check whether the drafter
actually fired on a given request, and it is what the upstream pull request
drives its own benchmarks through. Nothing about the config changes, just the
harness around it.&lt;&#x2F;p&gt;
&lt;p&gt;And every number below is the full config with one flag changed, so each delta
is that flag’s contribution given everything else is still on, not its effect in
a vacuum. Flags interact. Speculation changes how much the thread count matters.
Repacking changes what flash attention has to read. The deltas do not add up to
the gap between this config and a naive one, and I will not pretend they do.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-whole-board&quot;&gt;The whole board&lt;&#x2F;h2&gt;
&lt;p&gt;Here is every lever that moves the needle, in one place, before I walk through
them. Decode speed, tokens per second, median of the repetitions, each row the
full config with exactly one thing changed. The percentage is against the
published config, so a flag that helps shows up as a &lt;em&gt;loss&lt;&#x2F;em&gt; when you remove it.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;lever changed&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;chat&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;long doc&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;code&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;published config&lt;&#x2F;strong&gt; (autotune drafter)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;12.3&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;6.8&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;15.6&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;drafter, fixed draft 1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;15.6 (+27%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;9.8 (+44%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;15.9 (+2%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;drafter, fixed draft 2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;16.1 (+31%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;7.4 (+8%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;17.8 (+14%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;drafter, fixed draft 3, autotune off&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;13.9 (+13%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;7.1 (+4%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;18.3 (+17%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;drafter off entirely&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;12.2 (wash)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;10.5 (+54%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;12.2 (−22%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;flash attention off&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;6.7 (−46%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;4.3 (−37%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;7.5 (−52%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;threads &lt;code&gt;-t 4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;7.9 (−35%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;5.0 (−28%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;9.5 (−39%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;threads &lt;code&gt;-t 16&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;10.8 (−12%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;7.1 (+3%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;16.2 (+4%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;run-time-repack off&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;11.8 (−4%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;9.2 (+35%)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;13.7 (−12%)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Everything else I tried, &lt;code&gt;--mla-use&lt;&#x2F;code&gt;, &lt;code&gt;--cpu-moe&lt;&#x2F;code&gt;, &lt;code&gt;--merge-up-gate-experts&lt;&#x2F;code&gt;,
&lt;code&gt;--no-kv-offload&lt;&#x2F;code&gt;, the &lt;code&gt;-sm graph&lt;&#x2F;code&gt; cluster, lands within a few percent of the
published config on chat and code, which is to say inside the noise. The
long-document column is messier than the other two and I will come back to why
in the repack section. Read the negatives as the interesting part. Most of these
levers do nothing or cost you, and the work is concentrated in flash attention,
the physical-core thread count, and the drafter once it is configured the right
way.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-drafter-is-workload-dependent-and-one-setting-was-wrong&quot;&gt;The drafter is workload-dependent, and one setting was wrong&lt;&#x2F;h2&gt;
&lt;p&gt;Speculative decoding is the most tuned part of the config, and it is where I found the most.&lt;&#x2F;p&gt;
&lt;p&gt;The first finding is that the drafter is not a free win across the board. Measured against turning it off entirely:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;On chat it is roughly a wash at the default setting.&lt;&#x2F;li&gt;
&lt;li&gt;On code it is worth about &lt;strong&gt;twenty-eight percent&lt;&#x2F;strong&gt;. A real win.&lt;&#x2F;li&gt;
&lt;li&gt;On the long document it makes things slower. Turning the drafter off is fifty-four percent faster. Summarization is hard to predict, the drafter’s acceptance rate sits down around 0.15. A draft that gets rejected most of the time is mostly overhead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So the drafter wants to be gated by workload. On for code, off for long-context
work. The config has it on globally, which quietly costs you about a third of
your throughput every time you summarize something. This was not something I had
clocked when I wrote the original post, and it is the single most useful thing
in this one.&lt;&#x2F;p&gt;
&lt;p&gt;The same flag being a win, a wash, and a loss depending on the prompt is worth sitting with, because it is a tiny hand-measured example of a routing gap. The model already routes internally: a mixture-of-experts gate sends every token to the experts it judges most useful, learned and conditional, per token. But that gate optimizes for the next token, not for which inference machinery pays off on a given kind of work. The choice I am making by hand here, speculate on code, do not speculate on the summary, is a second and coarser routing decision sitting one level up, per request instead of per token, and the config hardcodes one answer to it and applies that everywhere. You could imagine a cheap classifier in front of the engine that picks the decoding policy the way the expert gate picks experts, and &lt;code&gt;--spec-autotune&lt;&#x2F;code&gt; is a clumsy first stab at that idea, aimed at a single knob and, on this workload, aimed badly. I am not saying the expert routing is broken. I am saying there is a routing decision above it that my numbers say is worth making, and I made this one with a shell script and a stopwatch… metaphorically. The stopwatch is a metaphor to be clear.&lt;&#x2F;p&gt;
&lt;p&gt;The second finding is a setting I had wrong. In the Xeon post I described
&lt;code&gt;--spec-autotune&lt;&#x2F;code&gt; as the way to squeeze the most speed out of speculation. Over
these generations it is the worst speculation setting I tested. Every fixed
&lt;code&gt;--draft-max&lt;&#x2F;code&gt; beats it.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;chat: autotune 12.3 tokens per second, a fixed draft of 2 gets 16.1. Twenty-five flags, and the biggest single win in the file was deleting one of them and typing a number.&lt;&#x2F;li&gt;
&lt;li&gt;code: autotune 15.6, a fixed draft of 3 with autotune off gets 18.3.&lt;&#x2F;li&gt;
&lt;li&gt;long document: autotune 6.9, a fixed draft of 1 gets 9.8.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The mechanism is acceptance rate. A shorter, fixed draft gets accepted by the
verifier more often. A draft of 1 on chat sits at 0.74 acceptance against
autotune’s 0.37, and acceptance is the entire currency speculation trades in.
The autotuner spends the generation hunting for a draft length, and over a
couple of hundred tokens it never settles, so the average gets dragged below the
steady state.&lt;&#x2F;p&gt;
&lt;p&gt;The honest caveat, because it matters: 256 tokens is a short generation. It is
entirely possible that over a long session, a couple of thousand tokens, the
autotuner converges up to the fixed rate and my numbers are simply
under-reporting it. I have a test designed to settle that and I have not run it
yet. So the careful claim is narrow: at short generation lengths, on this
workload, a fixed draft beats autotune. Whether that survives at length is the
next experiment. Either way it is a free win today, because picking a number
puts the interactive prompts up around sixteen to eighteen tokens per second.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;flash-attention-is-the-one-doing-the-heavy-lifting&quot;&gt;Flash attention is the one doing the heavy lifting&lt;&#x2F;h2&gt;
&lt;p&gt;If you keep one flag from the whole spell, keep this one. Flash attention is
worth roughly two times. Turn it off and chat falls from 12.3 tokens per second
to 6.7, code from 15.6 to 7.5, the long document from 6.8 to 4.3. Forty-six,
fifty-two, and thirty-seven percent gone, from a single flag.&lt;&#x2F;p&gt;
&lt;p&gt;It also turns out to be holding up the drafter, which I did not expect. With
flash attention off, speculative acceptance collapses to near zero. So the flag
doing the most obvious work is also quietly propping up the flag I just spent a
whole section on. That is the kind of dependency you only see when you turn
things off one at a time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;threads-want-physical-cores-and-there-is-a-wall-behind-them&quot;&gt;Threads want physical cores, and there is a wall behind them&lt;&#x2F;h2&gt;
&lt;p&gt;This one I got right in the original, and now I have the number to back it. &lt;code&gt;-t 8&lt;&#x2F;code&gt;, one thread per physical core, is the sweet spot, holding chat at 12.3 tokens per second. &lt;code&gt;-t 16&lt;&#x2F;code&gt;, using all sixteen hyperthreads, slips to 10.8, slightly worse, because the work is waiting on memory and extra threads add scheduling overhead without adding bandwidth. The cores are stalled on DDR3, not on each other. &lt;code&gt;-t 4&lt;&#x2F;code&gt; is about thirty-five percent slower on decode and closer to forty-five percent slower on prefill, which is the memory wall poking through.&lt;&#x2F;p&gt;
&lt;p&gt;While we are here, that wall is worth making concrete, because it tells you when
to stop fiddling with flags. Gemma 4 26B-A4B activates about four billion
parameters per token, which at Q8_0 is roughly 4.25 gigabytes read for every
token generated. Divide that into the memory bandwidth this box can sustain and
you get a ceiling around ten to eleven tokens per second for the verifier on its
own. That is almost exactly where the thread sweep flattens out, which is how
you know it is a real physical wall and not a tuning problem. Past that point,
no flag saves you. The only move left is to read fewer bytes per token, which is
the entire subject of the next post.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;repacking-earns-its-keep-on-prefill&quot;&gt;Repacking earns its keep on prefill&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;--run-time-repack&lt;&#x2F;code&gt; mostly helps prefill, about nineteen percent on the chat and
code prompts, with a small and noisy effect on decode for those two. It spends a
few seconds at startup physically rearranging the weight matrices to match how
the CPU wants to read them. On a Q8_0 model that is a modest, real win, and
worth the startup cost.&lt;&#x2F;p&gt;
&lt;p&gt;There is one honest oddity the board above will have flagged. On the long
document, turning repack &lt;em&gt;off&lt;&#x2F;em&gt; reads about thirty-five percent faster on decode,
which is the opposite of what a prefill optimization should do. It is not a
prefill effect. It is the drafter’s long-document acceptance jumping, from
around 0.15 to around 0.41, when the weights are not repacked. I do not yet know
why repacking the tensors should move acceptance at all, so I am flagging it as
a loose thread rather than dressing it up as a result. It is also most of why
the long-document column on the board is noisier than the other two.&lt;&#x2F;p&gt;
&lt;p&gt;It also has a much more interesting and much worse behavior on a different
quant, which is a cliffhanger for the next post.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-flags-that-do-not-take-for-free&quot;&gt;The flags that do not take for free&lt;&#x2F;h2&gt;
&lt;p&gt;This is the half I warned you about. None of it is dramatic, and most of it is
not “useless flag,” it is “flag that needs something you might not have”. I ran
each one as its own measurement specifically to pin down which is which, with
the engine log as evidence rather than a hunch.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;--mlock&lt;&#x2F;code&gt; needs a persistent memory-lock limit, and it worked last time.&lt;&#x2F;strong&gt; I have to be careful with this one, because it is easy to tell the wrong story about it. mlock pins the weights in RAM so the kernel cannot page twenty-five gigabytes of model out to disk and drop your speed to zero. In the Xeon post it worked, because I had raised the memlock ulimit on that box. For this round of measurements the box had been rebooted, the ulimit had quietly reverted to its tiny default, and mlock fell back to running unpinned behind a one-line warning. That is not the flag doing nothing. That is my host setup not surviving a reboot. The fix is to raise the limit &lt;em&gt;persistently&lt;&#x2F;em&gt;, in the systemd unit or &lt;code&gt;limits.conf&lt;&#x2F;code&gt;, not in a shell that dies when you log out. On a box with no swap, like this one, pinning is belt-and-suspenders anyway, but on anything with a swap device it is the difference between steady output and a sudden cliff.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;-sm graph&lt;&#x2F;code&gt; and its friends want more than one device.&lt;&#x2F;strong&gt; The &lt;code&gt;-sm graph -smgs -sas -mea --split-mode-f32&lt;&#x2F;code&gt; cluster is about splitting the work across multiple processors or sockets. This box is one CPU with no GPU, so there is nothing to split across, the engine says exactly that, and it falls back to a sequential layer split. I keep these in as a forward bet, because the moment you put this on a two-socket board they start mattering, and &lt;code&gt;-sas&lt;&#x2F;code&gt; is there for precisely that. On one socket they are inert, and that is expected, not broken.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;--cpu-moe&lt;&#x2F;code&gt; and &lt;code&gt;--merge-up-gate-experts&lt;&#x2F;code&gt; fire but do not move the needle here.&lt;&#x2F;strong&gt; These two do engage. The log confirms the fused expert path is active. But switching them off lands inside the run-to-run noise on this hardware and workload. So the honest verdict is narrower than the rest: they take, they just do not measurably change decode speed on this box. They may well earn their place on a different CPU. Engaged and useful are not the same property, and the only way to tell them apart is to measure.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;--mla-use&lt;&#x2F;code&gt; is the one that is genuinely not wired.&lt;&#x2F;strong&gt; Here is the second thing I had wrong in the original. I presented &lt;code&gt;--mla-use 3&lt;&#x2F;code&gt; as active. It is not. MLA is a DeepSeek architecture feature, it is not implemented for Gemma 4, and the flag is accepted and silently ignored with no log line at all. I swept it from 0 to 3 to be sure. No difference. This is the one in the section you can actually just delete.&lt;&#x2F;p&gt;
&lt;p&gt;A general warning against reading any of this too hard. “No measurable
difference on my box, on my workload, at these context lengths” is not “useless
everywhere”. Several of these earn their keep on other hardware. The claim is
deliberately narrow, and the only reason I can sort them at all is that I
checked each one against the log instead of trusting the command.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-pitfalls&quot;&gt;The pitfalls&lt;&#x2F;h2&gt;
&lt;p&gt;Not everything worth knowing is a tokens-per-second number. Three of these cost
me real time, and they are the kind of thing you only hit by running the engine
into the ground on purpose.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;mlock fails silently.&lt;&#x2F;strong&gt; I covered the cause above, but the failure mode earns
its own line, because it is nasty. mlock does not error out. It prints one
warning and runs unpinned. A config that pinned your model perfectly last week
can quietly stop pinning after a reboot, your speed gets unpredictable, and
nothing in the output points at the cause. Set the limit in the unit file, and
check the startup log actually says it took. Every boot.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;-sm graph&lt;&#x2F;code&gt; is a landmine that another flag is defusing.&lt;&#x2F;strong&gt; With the drafter
on, the engine sees that graph split is unsupported under MTP and quietly
downgrades it to a layer split. That downgrade is the only reason the flag is
survivable at all. Turn the drafter off, run the same config, and the model
refuses to load:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;error loading model: It is not possible to use split mode &amp;#39;graph&amp;#39;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;with less than 2 devices
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So a flag that does nothing useful on this box is also fatal on its own, and it
only avoids exploding because a neighbor steps in front of it. You find that out
by turning the neighbor off.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The slot-zero deadlock that ate an overnight run.&lt;&#x2F;strong&gt; The first full benchmark
looked nondeterministic in a way that smelled like a memory death spiral. The
chat prompt always finished, but the long document and the code prompt usually
hit the timeout, including a 106-character code prompt that should take fifteen
seconds. It was not memory. Under &lt;code&gt;--parallel 8&lt;&#x2F;code&gt; the server has eight slots, but
the drafter only works on slot zero on this build. Any request that lands on
another slot deadlocks the instant it clears the cache, generates nothing, and
never lets go:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;kv cache rm [p0, end) ... id_slot=1 id_task=82 p0=0    &amp;lt;- then nothing, ever
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The server assigns slots by prompt similarity, so which prompt drew the dead
slot changed from run to run, which is where the fake randomness came from.
Aggregated up, it looked like a resource problem. The per-request log showed a
plain control-flow deadlock. Read the log, do not theorize about RAM. The fix is
to pin every request to slot zero, which is also exactly what a single
interactive user does anyway.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Setting a parameter to its own default breaks it.&lt;&#x2F;strong&gt; My favorite. The config passes no &lt;code&gt;-c&lt;&#x2F;code&gt;, so it runs at the model default context of 262144. Under &lt;code&gt;llama-server&lt;&#x2F;code&gt; that default path fails to initialize the drafter and wedges the server: it stays up, holds the port, and never reports healthy, so a naive wait-for-health loop hangs forever:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;llama_init_from_model: n_batch and n_ubatch cannot both be zero
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;MTP context creation failed
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pass &lt;code&gt;-c&lt;&#x2F;code&gt; explicitly at any size, including &lt;code&gt;262144&lt;&#x2F;code&gt;, the exact value the
default would have resolved to, and it works. The bug is in the path that
handles the missing flag, not in the number. I nearly shipped a wrong
explanation for this, a theory about per-slot sizes built on two data points,
and only dodged it because the benchmark actually ran the 262144 case instead of
assuming it would fail. Run the experiment you think you can predict.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;so-which-flags-actually-mattered&quot;&gt;So which flags actually mattered&lt;&#x2F;h2&gt;
&lt;p&gt;After all of it, the honest shape of the config.&lt;&#x2F;p&gt;
&lt;p&gt;The flags doing real, measurable work on this box are flash attention by a mile,
the physical-core thread count, run-time repack for prefill, and the drafter for
code with a fixed draft length. mlock belongs in that list too, as long as you
set the limit so it survives a reboot. The rest is either waiting on hardware I
do not have, firing without moving the needle, genuinely not wired, or a
landmine held in check by a neighbor. Decode runs from about seven tokens per
second on the long document up to sixteen on code, which is reading speed, and
gating the drafter and fixing the draft length lift both ends from there.&lt;&#x2F;p&gt;
&lt;p&gt;I knew the rough shape of this before I started. I said half the flags would not
take. What I did not have, and now do, is the sorted version: which half, the
two settings I had wrong, the few that carry the whole thing, and the exact cost
of each. Twelve of the twenty-five come out entirely, and the honest part is
that deleting them changed nothing, because they were deadweight, and removing
deadweight is free. The few tokens a second I picked up did not come from the
cull. They came from fixing two flags I kept: trading the autotuner for a fixed
draft length, which on its own takes chat from 12.3 to 16.1, and gating the
drafter by workload. The config I keep is a good deal shorter than the one that
went up on Hacker News, but the shortening and the speedup are two different
stories, and only one of them is about deletion.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-check-your-own&quot;&gt;How to check your own&lt;&#x2F;h2&gt;
&lt;p&gt;The transferable part of this is not my flag list, which is specific to this box
and will go stale the next time the fork moves. It is the procedure, and there
are four steps.&lt;&#x2F;p&gt;
&lt;p&gt;Check that the flag fired. For everything you are relying on, find the line in
the engine log that proves it engaged: the init message, the &lt;code&gt;= 1&lt;&#x2F;code&gt;, the
loaded-drafter block. There are three outcomes, not two. It engaged, it was
declined with a warning, or it was silently ignored with no line at all. That
last one, like &lt;code&gt;--mla-use&lt;&#x2F;code&gt; here, is the easiest thing in the world to
cargo-cult, because it costs nothing, does nothing, and looks exactly like
success.&lt;&#x2F;p&gt;
&lt;p&gt;Turn off one thing at a time. The whole approach only works if you change a
single flag per run, off a config that already works. The marginal contribution
given everything else is the number that is actually true. Change five flags at
once and you learn nothing.&lt;&#x2F;p&gt;
&lt;p&gt;Gate by workload. The same drafter was a win for code and a loss for
summarization. If your config hardcodes a choice that depends on what you are
generating, you are leaving throughput on the floor for half of what you do.&lt;&#x2F;p&gt;
&lt;p&gt;Know your ceiling. Active parameters times bytes per weight divided by memory
bandwidth gives you the verifier’s solo speed limit. On this box that is around
ten to eleven at Q8_0. Once you are there, you are not adding flags anymore, you
are reading bytes, and the only way down is fewer of them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-next&quot;&gt;What is next&lt;&#x2F;h2&gt;
&lt;p&gt;Every flag in this whole exercise either does nothing about the memory wall or
chips at it sideways. The one lever that hits it head on is the one I never
touched. Everything here ran at Q8_0.&lt;&#x2F;p&gt;
&lt;p&gt;Dropping the verifier to a smaller quant reads fewer bytes per token directly,
which is the most honest way to buy speed on a memory-bound box, and it should
be a clean win. It mostly is. But it also handed me the best benchmark trap I
have ever walked into, where the single fastest config I measured was emitting
pure garbage, and was fast precisely because it was garbage. That is the next
post.&lt;&#x2F;p&gt;
&lt;p&gt;And yes. The next post is where we confirm my suspicion that this can run past
20 TPS.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for reading. If you want, you can stop reading here. I’ll add some meta
commentary to the end, so those that don’t care can skip it. To those, see you
all next time! o&#x2F;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;meta-comments-on-this-series&quot;&gt;Meta Comments on this series&lt;&#x2F;h2&gt;
&lt;p&gt;I didn’t plan to get lost in these weeds… but here we are.&lt;&#x2F;p&gt;
&lt;p&gt;Since last time, I’ve made sure to address the comments about link colors to
make this WCAG compliant. Another big outstanding comment was that there was a
clear lack of numbers.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve tried to benchmark things here, but as it turns out, the combinatorial
explosion of benchmarking everything is beyond my current compute and time
constraints.&lt;&#x2F;p&gt;
&lt;p&gt;I’m glad about all the positive feedback I’m getting about this, and I keep
ending up writing more. My plan was to “just” write a follow up with numbers,
but then that turned into it’s own rabbit hole. And just before I shipped it, I
thought “what if I looked into the difference between difference
quantizations”… and of course, that gave enough content for an entirely
separate post (that I think will likely be the one with the strongest numbers so
far, I can’t wait to show it once I’ve done the final polish).&lt;&#x2F;p&gt;
&lt;p&gt;It’s important to remember that I am NOT an ML engineer. I’m here in the weeds
with you, dear reader, and I may be saying things that aren’t correct. So I
really encourage anyone with the interest to actually try and replicate some of
this.&lt;&#x2F;p&gt;
&lt;p&gt;Point is. If something is wrong, I can probalby fix it. If you think I’m saying
something stupid, tell me, that would be a great post. And by all means, apply
this. Till next time.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A 10 year old Xeon is all you need</title>
          <pubDate>Mon, 01 Jun 2026 00:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/gemma-4-on-a-2016-xeon/</link>
          <guid>https://point.free/blog/gemma-4-on-a-2016-xeon/</guid>
          <description xml:base="https://point.free/blog/gemma-4-on-a-2016-xeon/">&lt;p&gt;The &lt;a href=&quot;&#x2F;blog&#x2F;gemma-4-mtp&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt; covered getting Gemma 4’s MTP
drafters quantized and paired with a verifier. This one is about
running the result on a machine that has no business running it.&lt;&#x2F;p&gt;
&lt;p&gt;I have a recycled server. To its credit, it has a whopping 128 GB RAM, but it’s
DDR3… That RAM is 5-6 times slower than the current best laptop ram. It also
has a single Intel Xeon E5-2620 v4 from 2016, which is about 5 times slower than my laptops CPU…&lt;&#x2F;p&gt;
&lt;p&gt;Oh, and as I did mention, we have &lt;strong&gt;no GPU&lt;&#x2F;strong&gt;. And no, the Xeon does not have an
integrated GPU.&lt;&#x2F;p&gt;
&lt;p&gt;But, just hear me out…&lt;&#x2F;p&gt;
&lt;p&gt;If we were to just break out ollama here, well… as explained in earlier blog
posts, we can’t. And we’d be lucky if we could in 6 months when they add support
for the model we need, if they ever do. Might be they never do. And even still,
ollama simply doesn’t expose enough knobs for us to ever make this run well,
neither does even the standard &lt;code&gt;llama-cpp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But. Why would that stop us?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
	&lt;p&gt;I’ve recieved feedback that some of the previous posts were too high level, I’ll
try to make things as clear as reasonably possible here. If you’re a tech
worker, or a Linux enthusiast that has built a computer and used something like
ChatGPT, most of this should be approachable.&lt;&#x2F;p&gt;

&lt;&#x2F;blockquote&gt;
&lt;p&gt;So, just to really set the stage fully. The hardware, per &lt;code&gt;lscpu&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CPU:&lt;&#x2F;strong&gt; Intel Xeon E5-2620 v4 @ 2.10 GHz&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Cores:&lt;&#x2F;strong&gt; 8 physical, 16 threads&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Instruction sets:&lt;&#x2F;strong&gt; AVX2 (no AVX-512, no AVX-VNNI, no BF16)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Cache:&lt;&#x2F;strong&gt; 20 MiB L3, 2 MiB L2 total&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Memory:&lt;&#x2F;strong&gt; 128 GB DDR3&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;GPU:&lt;&#x2F;strong&gt; none&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For LLM inference, memory bandwidth is the limiting resource. Every token
generated requires hauling gigabytes of weights from RAM into the CPU cache.&lt;&#x2F;p&gt;
&lt;p&gt;When you use a tool like ChatGPT and watch the text stream onto your screen word
by word, you are watching the “decoder pass”. During this phase, the model
generates the output one piece (or “token”) at a time.&lt;&#x2F;p&gt;
&lt;p&gt;In this step, the system’s raw processing power is rarely the bottleneck.
Instead, the limitation is memory bandwidth. To calculate that next word, the
processor has to constantly pull massive amounts of data. That data is the “weights” that
contain the model’s learned knowledge. It moves this from memory into the compute cores.&lt;&#x2F;p&gt;
&lt;p&gt;The processor executes the required matrix calculations so quickly that it is
left sitting idle, waiting for the hardware to physically move the next chunk of
weights across the memory bus. In traditional software terms, decoding is
heavily memory-bound, not compute-bound.&lt;&#x2F;p&gt;
&lt;p&gt;This is the so called “memory wall”, one of the single biggest performance
hurdles now, whether you’re on a Xeon or an H100.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Naively running &lt;code&gt;llama-cli&lt;&#x2F;code&gt; on a DDR3 machine without a GPU is
horrendously slow, even if it can run it, because it’s optimized for a generic
GPU usecase, and often leaves a lot of improvements on the table. Further, it
simply doesn’t have most of the actual optimizations that the state of the art
currently uses to run these at scale.&lt;&#x2F;p&gt;
&lt;p&gt;The remedy is to pull every optimization lever &lt;code&gt;ik_llama.cpp&lt;&#x2F;code&gt; exposes.
Most of them are slightly obscure.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the magic spell that makes this actually run.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;llama-cli&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  --&lt;&#x2F;span&gt;model&lt;&#x2F;span&gt; gemma-4-26B-A4B-it-Q8_0.gguf &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  --&lt;&#x2F;span&gt;model-draft&lt;&#x2F;span&gt; gemma-4-26B-A4B-it-assistant-GGUF&#x2F;&lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;wikitext-2-raw_ik-llama-mtp_drafter-conservative&#x2F;&lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;gemma-4-26B-A4B-it-assistant-Q8_0.gguf &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  --&lt;&#x2F;span&gt;spec-type&lt;&#x2F;span&gt; mtp&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;draft-max&lt;&#x2F;span&gt; 3&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;draft-p-min&lt;&#x2F;span&gt; 0.0&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;spec-autotune&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  -&lt;&#x2F;span&gt;cnv&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;color&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;jinja&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;special&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  -&lt;&#x2F;span&gt;sm&lt;&#x2F;span&gt; graph&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;smgs&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;sas&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;mea&lt;&#x2F;span&gt; 256&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;split-mode-f32&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  --&lt;&#x2F;span&gt;temp&lt;&#x2F;span&gt; 0.7&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; 8&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;parallel&lt;&#x2F;span&gt; 8 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  --&lt;&#x2F;span&gt;cpu-moe&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;merge-up-gate-experts&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  --&lt;&#x2F;span&gt;flash-attn&lt;&#x2F;span&gt; on&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;mla-use&lt;&#x2F;span&gt; 3 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  --&lt;&#x2F;span&gt;mlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;run-time-repack&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;no-kv-offload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Under a blackbox tool like &lt;code&gt;ollama&lt;&#x2F;code&gt; you never see this line. On aging hardware
you have to understand what each flag does, because half of them won’t
take, and the engine will tell you so in passing.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Speculative decoding.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;--spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This pairs the 26B verifier with the small drafter from the previous
post. Up to three tokens per draft (&lt;code&gt;--draft-max 3&lt;&#x2F;code&gt;), all probabilities accepted (&lt;code&gt;--draft-p-min 0.0&lt;&#x2F;code&gt;),
&lt;code&gt;--spec-autotune&lt;&#x2F;code&gt; adjusting the chain length per workload.&lt;&#x2F;p&gt;
&lt;p&gt;This ties directly back to our previous discussion about the memory-bound decoder pass.&lt;&#x2F;p&gt;
&lt;p&gt;When a model uses a long reasoning chain, it is generating those “thinking”
tokens one by one. Even if the internal reasoning is hidden from the user and
all you see is a short final answer, the hardware still has to perform a full
decoder pass for every single token in that hidden chain.&lt;&#x2F;p&gt;
&lt;p&gt;In fact, speculative decoding is currently one of the most brilliant software workarounds the AI industry has invented to bypass the “memory wall,” and spec autotune is how you squeeze the maximum speed out of it.&lt;&#x2F;p&gt;
&lt;p&gt;The argument for speculative decoding is stronger on CPU than on GPU. CPU
compute is cheap relative to the cost of streaming the verifier’s weights
through cache, so spending extra cycles on a tiny drafter whose active layers
easily fit in L3 buys tokens at very little marginal cost. The drafter’s working
set fits in L3. The verifier however spills out of everything.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;CPU and MoE routing.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;--cpu-moe --merge-up-gate-experts -t 8 --parallel 8
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Gemma 4 26B-A4B has 128 experts with 8 active per token, giving about 3.8B
active parameters out of ~25.2B total. &lt;code&gt;--cpu-moe&lt;&#x2F;code&gt; tunes the routing for CPU
cache hierarchies.&lt;&#x2F;p&gt;
&lt;p&gt;CPUs handle memory very differently than GPUs. While a GPU has a massive pool of
ultra-fast High-Bandwidth Memory (HBM), a CPU relies on small, lightning-fast
“caches” (L1, L2, L3) built directly onto the processor chip.&lt;&#x2F;p&gt;
&lt;p&gt;In an MoE model, constantly jumping around between 128 different experts can
cause “cache thrashing”, where the CPU constantly has to dump its cache and
fetch new weights from the much slower main system RAM (normally DDR4&#x2F;DDR5,
we’re on DDR3!).&lt;&#x2F;p&gt;
&lt;p&gt;This flag tells the router to be smarter about how it picks experts, optimizing
the sequence so the weights stay neatly inside the CPU’s local cache for as long
as possible.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;--merge-up-gate-experts&lt;&#x2F;code&gt; fuses two per-expert projections into a single matmul,
which the logs confirm:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;fused_up_gate = 1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a software trick to bypass the memory bandwidth bottleneck we
discussed earlier.&lt;&#x2F;p&gt;
&lt;p&gt;Inside the experts, the math operations require data to be passed through
different layers. Normally, the processor would calculate an “up projection”,
write the result to memory, then load the weights for a “gate projection”,
calculate that, and combine them. That requires moving data across the memory
bus multiple times.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of doing two separate trips over the memory bus, it combines the operations into a single step.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;-t 8&lt;&#x2F;code&gt; matches physical cores. The machine has 16 SMT threads but only
8 cores. On a memory-bound workload, oversubscribing threads adds
scheduling cost without adding throughput: the cores are waiting on
DDR3, not on each other.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Memory pinning, repacking, KV cache.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;--mlock --run-time-repack --no-kv-offload
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;--run-time-repack&lt;&#x2F;code&gt; reorganizes weight matrices in memory immediately
before inference to match the CPU’s cache layout. The logs confirm:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;============ Repacked 265 tensors
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Processors have their own ultra-fast, built-in memory called caches (L1, L2, and L3). However, these caches expect data to be fed to them in very specific shapes and sizes.&lt;&#x2F;p&gt;
&lt;p&gt;If the AI’s weight matrices are sitting in system RAM in a generic layout, the CPU has to awkwardly pull the data in pieces, resulting in “cache misses” where the CPU stalls. &lt;code&gt;--run-time-repack&lt;&#x2F;code&gt; tells the engine to spend a few seconds during startup to physically reorganize the massive tables of numbers in the RAM so they perfectly align with how the CPU wants to ingest them. It pays a small time penalty upfront to guarantee maximum memory bandwidth during the actual text generation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;--mlock&lt;&#x2F;code&gt; is meant to pin the model in RAM so the OS cannot swap any
of it to disk.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;mlock&lt;&#x2F;code&gt; stands for “memory lock”, suprising, I know! In standard operating systems, if the system starts running out of RAM, it will quietly take data that hasn’t been used in a few seconds and “swap” (or page) it to the physical hard drive.&lt;&#x2F;p&gt;
&lt;p&gt;If an OS tries to swap out 27GB of AI weights to a disk, the generation speed
will instantly drop to zero while the system chokes trying to read it back.
&lt;code&gt;--mlock&lt;&#x2F;code&gt; tells the Linux kernel: “Pin this 27GB strictly in physical RAM. Do not
ever move it to the disk.”&lt;&#x2F;p&gt;
&lt;p&gt;Notice that if you’re not careful, you’ll see this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;warning: failed to mlock 27628376064-byte buffer
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  (after previously locking 0 bytes): Cannot allocate memory
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Try increasing RLIMIT_MEMLOCK (&amp;#39;ulimit -l&amp;#39; as root).
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The flag is fine; the kernel-side memlock limit isn’t set high enough
to pin a 27 GB buffer. This is not an LLM-shaped problem at all — it’s a
ulimit default — and it’s the kind of footgun the blackbox tools paper
over by simply not asking for the optimization in the first place.&lt;&#x2F;p&gt;
&lt;p&gt;Consider that for a moment, that many tools by default will just have no problem putting your model into swap if it decided that’s the best option. You can imagine how much this can hurt performance…&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;--no-kv-offload&lt;&#x2F;code&gt; tells the engine not to look for a GPU for the KV
cache. There isn’t one to find, but the flag short-circuits the check.&lt;&#x2F;p&gt;
&lt;p&gt;The KV (Key-Value) cache is the AI’s short-term memory — it stores the context of the current conversation so the model doesn’t have to re-read the entire prompt for every new token.&lt;&#x2F;p&gt;
&lt;p&gt;Because the KV cache is constantly being read from and written to, AI engines
usually try to “offload” it to a GPU, which has much faster memory than we do.&lt;&#x2F;p&gt;
&lt;p&gt;Since this specific setup is highly optimized to run purely on a CPU, letting
the engine search the hardware buses for a GPU that doesn’t exist is a waste of
time and could throw an error. This flag explicitly short-circuits that check,
telling the engine to just keep the short-term memory in the system RAM
alongside the weights.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Graph layout.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
	&lt;p&gt;I’ve tried my best to keep this easy to understand, but this part is just plain hard to make explain in a single blog post.&lt;&#x2F;p&gt;

&lt;&#x2F;blockquote&gt;
&lt;p&gt;Now onto dark arts. A common frustration in bleeding-edge AI software is that
the engine is being developed so fast that the developers don’t have time to
write official documentation. If you want to know how to optimize the engine,
you have to dig through the raw code or read the Github Pull Request (PR)
comments between the developers.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;-sm graph -smgs -sas -mea 256 --split-mode-f32
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These flags govern how the computational graph is allocated across
memory regions. The full documentation ultimatley lives in the code, even if it has some documentation.&lt;&#x2F;p&gt;
&lt;p&gt;The flag &lt;code&gt;-sm graph&lt;&#x2F;code&gt; tells the engine to use Split Mode in the Graph mode (often known in the industry as Tensor Parallelism). This is entirely about how you divide the massive math workload across multiple processors or memory regions (like multiple CPU sockets or GPUs).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Layer Split (The Default&#x2F;Fallback): The engine slices the model horizontally. Processor A calculates Layers 1–10, then sends the data over the system bus to Processor B, which calculates Layers 11–20. While Processor A is working, Processor B is sitting idle.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Graph Split (The Goal): The engine slices the computational graph vertically. Processor A and Processor B calculate different halves of Layer 1 at the exact same time, combine their answers, and move to Layer 2 together. This keeps all hardware running at 100% simultaneously, drastically improving generation speed.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On this run, the engine declines:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;=======================================================
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Split mode &amp;#39;graph&amp;#39; is not supported for Gemma4 external MTP
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  =&amp;gt; changing split mode to &amp;#39;layer&amp;#39;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;=======================================================
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because MTP creates a much more complicated web of math at the very end of the
network, this inference engine simply hasn’t gotten support yet to safely “graph
split” (vertically slice) an MTP architecture yet. When the engine boots up, it
detects the MTP layers, realizes -sm graph will break the math, and safely
downgrades to the slower, sequential layer split so the model can still run.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve included it because it will likely be very helpful in the future, so you should try your luck if you’re working on a newer version.&lt;&#x2F;p&gt;
&lt;p&gt;While &lt;code&gt;-sm graph&lt;&#x2F;code&gt; was disabled, these other flags still apply to how the engine manages memory:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-sas&lt;&#x2F;code&gt; (Split Across Sockets): Explicitly tells the engine how to divide the workload across different physical CPU sockets (NUMA nodes) on a server motherboard. You may note we only have one CPU, but we could get more later, it’s a nice optimization, just bench it to be safe if you do this, since older boards may break current day assumptions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--split-mode-f32&lt;&#x2F;code&gt;: When data is split across processors, it has to be stitched back together. This flag forces those intermediate connection points to use 32-bit floating-point precision (higher quality math). It prevents the AI from losing intelligence or hallucinating due to rounding errors during the split.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And don’t worry if you see this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Oops: tensor with strange name rope_freqs.weight
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It has a strange name. Strange names will not stop us here. :D&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Attention.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Look. &lt;code&gt;ikawrakow&lt;&#x2F;code&gt;, creator of ik_llama.cpp is beyond the word “craked”.&lt;&#x2F;p&gt;
&lt;p&gt;Kawrakow wrote custom CPU kernels to handle Flash Attention, bypassing the need
for a GPU during heavy context processing.&lt;&#x2F;p&gt;
&lt;p&gt;This let’s us do something that normally you only do on a GPU.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;--flash-attn on --mla-use 3
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Flash Attention fuses the attention softmax with its matmuls to avoid
materializing the full attention matrix. Duh, anyone knows this, but I’ll try to explain it.&lt;&#x2F;p&gt;
&lt;p&gt;To generate text, an AI has to calculate how every single word in
your prompt relates to every other word. Mathematically, this creates a grid of
size N×N (where N is the number of tokens).&lt;&#x2F;p&gt;
&lt;p&gt;If you give the AI a short sentence, that grid is small. But if you feed it a
100,000-word document, that matrix explodes into 10 billion cells. Normally, the
processor calculates this massive matrix and “materializes” it — meaning it
physically writes the entire giant grid out to the main system RAM, only to
immediately read it back for the next step.&lt;&#x2F;p&gt;
&lt;p&gt;Flash Attention applies the Kernel Fusion trick, but to the attention mechanism.
It calculates the attention scores in small chunks and fuses the math (the
softmax) so that the giant N×N matrix is never actually written to RAM. It is
calculated and consumed entirely inside the processor’s ultra-fast local cache.&lt;&#x2F;p&gt;
&lt;p&gt;Flash Attention was originally invented strictly for GPUs because it relies on
how GPU hardware handles memory blocks. &lt;strong&gt;Successfully porting this highly
complex, hardware-specific optimization to work on standard CPUs is a massive
software engineering achievement.&lt;&#x2F;strong&gt; Well done &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ikawrakow&quot;&gt;ikawrakow&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;--mla-use 3&lt;&#x2F;code&gt; enables Multi-Head Latent Attention. Earlier, we discussed the KV
Cache (the AI’s short-term memory of the conversation that prevents it from
having to re-read the whole prompt for every word).&lt;&#x2F;p&gt;
&lt;p&gt;In standard architectures, storing the raw Key and Value data for every single
token eats up RAM incredibly fast. Multi-Head Latent Attention (MLA) is a
breakthrough architecture that heavily compresses this short-term memory.
Instead of saving raw data for every token, it compresses the Keys and Values
into a much smaller, dense mathematical representation (a “latent” space).&lt;&#x2F;p&gt;
&lt;p&gt;This drastically reduces the memory footprint of the KV cache, allowing the
model to remember massive conversations without running out of system RAM. The
flag &lt;code&gt;--mla-use 3&lt;&#x2F;code&gt; simply tells the engine to activate a specific tier or kernel
implementation of this compression.&lt;&#x2F;p&gt;
&lt;p&gt;But all of this is just experimental stuff right, like the split mode graph?
Nah. The logs confirm both took:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;flash_attn    = 1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;fused_moe     = 1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;fused_up_gate = 1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The memory accounting from the logs:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;------------------- Layer sizes:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Layer  0:    825.98,   2048.00,   2873.98   77.00 MiB
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Layer 29:    840.59,   1024.00,   1864.59   77.00 MiB
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Layer 30:    748.00,    435.00,   1183.00   MiB (output layer)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;--------------------------------------------------------------------------
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Total   :  24852.46,  56755.00,  81607.46 MiB
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Memory required for model tensors + cache: 82355 MiB
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An 82 GB footprint in DDR3 on a 2016 Xeon. About 25 GB of weights and
56 GB of KV cache at the full 262K context. The KV cache is larger than
the model.&lt;&#x2F;p&gt;
&lt;p&gt;That a working configuration requires 25 flags, half of which are
undocumented and a quarter of which fail silently, is a reasonable
working definition of the usability moat described in &lt;a href=&quot;&#x2F;blog&#x2F;open-weights-not-open-source&#x2F;&quot;&gt;the first post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The engine loads a 25B-parameter MoE, runs speculative decoding against an MTP
drafter, and generates text at reading speed on hardware that was old when the
architecture in question hadn’t been invented yet.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;When we started this series a week ago, the state of local open-weights AI looked grim. We began by pulling back the curtain on the industry’s favorite marketing spin: the idea that dropping a massive, uncalibrated weights file onto a repository constitutes “open source.” We looked at the massive usability moat built out of missing documentation, silent defaults, and black-box wrappers that hide performance-killing decisions under the guise of user-friendliness.&lt;&#x2F;p&gt;
&lt;p&gt;In the second post, we rolled up our sleeves and waded into the muck. We hunted down obscure, unmerged pull requests, compiled specialized forks (ik_llama.cpp), flipped the standard logic of quantization on its head to build highly precise speculative decoding drafters, and wrote custom scripts to scrub infrastructure data leaks out of our GGUF metadata.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, in this post, we put our money where our mouth is. We dragged a 2016 enterprise relic out of the closet — NAY, out of the grave, a single Intel Xeon running on agonizingly slow DDR3 RAM with absolutely no GPU to speak of — and forced it to run a cutting-edge, 26-billion-parameter Mixture-of-Experts architecture at reading speed. We did without throwing exotic hardware at the problem. Instead we treated the deployment pipeline as a serious thing, and mapped the architecture directly to physical hardware, tuning memory allocation, and unlocking the absolute limits of CPU cache optimization.&lt;&#x2F;p&gt;
&lt;p&gt;The lesson here is simple: The bottleneck to running state-of-the-art AI locally
isn’t just in the silicon. It’s the need to understand how the inferrence engine
actually works. Deeply.&lt;&#x2F;p&gt;
&lt;p&gt;While a cluster of data-center graphics cards, a corporate API token, or a
massive budget are all extremly useful for specific workloads, for the ones that
the open models cover, you just need refurbed hardware and to refuse to let
black-box tools hold the steering wheel. Armed with the right fork, calibrated
quants, and an understanding of the memory architecture under your hood, the
usability moat vanishes.&lt;&#x2F;p&gt;
&lt;p&gt;The bleeding edge of Open Weight AI isn’t locked behind a paywall or a model proivider. If you’re already running a homelab, It’s sitting right there on the command line of a ten-year-old server.&lt;&#x2F;p&gt;
&lt;p&gt;Welcome to the other side of the moat. Now go &lt;a href=&quot;https:&#x2F;&#x2F;huggingface.co&#x2F;collections&#x2F;cafkafk&#x2F;gemma-4-drafters&quot;&gt;download the
quants&lt;&#x2F;a&gt; and get
your hands dirty.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for reading :D&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Quantizing Gemma 4&#x27;s MTP drafters</title>
          <pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/gemma-4-mtp/</link>
          <guid>https://point.free/blog/gemma-4-mtp/</guid>
          <description xml:base="https://point.free/blog/gemma-4-mtp/">&lt;p&gt;A while after Gemma 4 came out, Google released a set of
Multi-Token-Prediction (MTP) drafters for it. Pairing a large model
(the &lt;em&gt;verifier&lt;&#x2F;em&gt;) with a tiny MTP drafter (the &lt;em&gt;assistant&lt;&#x2F;em&gt;) enables
speculative decoding: the small model guesses the next few tokens, and
the big model verifies them in one parallel pass. When it works, the
throughput gain is most of the way to free.&lt;&#x2F;p&gt;
&lt;p&gt;To put it shortly: MTPs are one of the rare free lunches we get with LLMs. Or
well, on paper, like with free lunches, that’s the assumption.&lt;&#x2F;p&gt;
&lt;p&gt;These are notes on getting that working locally. The
&lt;a href=&quot;&#x2F;blog&#x2F;open-weights-not-open-source&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt; was about why this
should have been easier than it was.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;If you try to convert the Gemma 4 MTP drafter weights using mainline
&lt;code&gt;ggml-org&#x2F;llama.cpp&lt;&#x2F;code&gt;, the converter rejects them:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Model Gemma4AssistantForCausalLM is not supported
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Mainline supports the &lt;em&gt;base&lt;&#x2F;em&gt; Gemma 4 models, but it does not know what a
&lt;code&gt;gemma4_assistant&lt;&#x2F;code&gt; is. The converter lacks the class, and the runtime
lacks the MTP API. The runtime PR
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ggml-org&#x2F;llama.cpp&#x2F;pull&#x2F;18886&quot;&gt;#18886&lt;&#x2F;a&gt; has been in
draft for months. A companion converter PR
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ggml-org&#x2F;llama.cpp&#x2F;pull&#x2F;22738&quot;&gt;#22738&lt;&#x2F;a&gt; was opened
and closed unmerged with one of four tasks done.&lt;&#x2F;p&gt;
&lt;p&gt;The working path is a fork:
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ikawrakow&#x2F;ik_llama.cpp&quot;&gt;&lt;code&gt;ikawrakow&#x2F;ik_llama.cpp&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
specifically the &lt;code&gt;feat&#x2F;gemma-4-mtp&lt;&#x2F;code&gt; branch from
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ikawrakow&#x2F;ik_llama.cpp&#x2F;pull&#x2F;1744&quot;&gt;PR #1744&lt;&#x2F;a&gt;. The
resulting GGUFs only load in that fork. Downstream wrappers — Ollama,
LM Studio, jan.ai, &lt;code&gt;llama-cpp-python&lt;&#x2F;code&gt; — will all reject them until they
backport the changes.&lt;&#x2F;p&gt;
&lt;p&gt;This is the cost of running new architectures the week they ship: you
swap inference backends to match the model, not the other way around.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Drafters are tiny. The E2B drafter’s MTP head is 78M parameters; the
31B’s drafter is roughly 470M; the 26B-A4B’s is about 408M.&lt;&#x2F;p&gt;
&lt;p&gt;Their job is to predict tokens accurately enough that the verifier
&lt;em&gt;accepts&lt;&#x2F;em&gt; them, so acceptance rate dominates everything else. Aggressive
quantization causes the verifier to reject more drafts, and the pipeline
becomes slower than running the verifier alone.&lt;&#x2F;p&gt;
&lt;p&gt;The quantization policy for drafters is the inverse of what you’d do for
a large base model:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Do use:&lt;&#x2F;strong&gt; &lt;code&gt;bf16&lt;&#x2F;code&gt;, &lt;code&gt;f16&lt;&#x2F;code&gt;, &lt;code&gt;Q8_0&lt;&#x2F;code&gt;, &lt;code&gt;Q6_K&lt;&#x2F;code&gt;, &lt;code&gt;Q5_K_M&lt;&#x2F;code&gt;, &lt;code&gt;Q4_K_M&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Do not use:&lt;&#x2F;strong&gt; &lt;code&gt;IQ1_*&lt;&#x2F;code&gt;, &lt;code&gt;IQ2_*&lt;&#x2F;code&gt;, &lt;code&gt;Q2_K&lt;&#x2F;code&gt;, &lt;code&gt;Q3_*&lt;&#x2F;code&gt;. These cost more
rejected drafts than they save in load time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;imatrix&lt;&#x2F;code&gt; calibration is not available for these drafters at the moment.
PR #1744 builds the &lt;code&gt;gemma4_mtp&lt;&#x2F;code&gt; drafter graph with a hardcoded
&lt;code&gt;GGML_ASSERT(has_target_ctx)&lt;&#x2F;code&gt;, so standalone &lt;code&gt;llama-imatrix&lt;&#x2F;code&gt; runs abort
in &lt;code&gt;llama_decode&lt;&#x2F;code&gt; before producing anything. The IK fork’s signature
quants (&lt;code&gt;IQ4_KS&lt;&#x2F;code&gt;, &lt;code&gt;IQ4_KSS&lt;&#x2F;code&gt;, &lt;code&gt;IQ5_KS&lt;&#x2F;code&gt;) derive their precision-per-bit
advantage from imatrix-guided scale selection, so without an imatrix
they collapse to roughly K-quant quality at the same bit budget.
Shipping them under those labels would be misleading.&lt;&#x2F;p&gt;
&lt;p&gt;Quantizing directly from &lt;code&gt;bf16&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;f16&lt;&#x2F;code&gt; to &lt;code&gt;Q4_K_M&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;Q8_0&lt;&#x2F;code&gt; is the
realistic option until the tooling catches up. At ≥4 bits the precision
gap from missing the imatrix is small — single-digit percent on most
benchmarks. At Q3 and below it would matter, which is the other reason
Q3 isn’t a sensible target here.&lt;&#x2F;p&gt;
&lt;p&gt;One empirical surprise: on a 4060 Laptop GPU, pairing unsloth’s
&lt;code&gt;Gemma-4-E4B-it-Q4_K_M.gguf&lt;&#x2F;code&gt; verifier against both a &lt;code&gt;Q8_0&lt;&#x2F;code&gt; and a
&lt;code&gt;Q4_K_M&lt;&#x2F;code&gt; drafter at &lt;code&gt;--draft-max 3&lt;&#x2F;code&gt;, the &lt;code&gt;Q4_K_M&lt;&#x2F;code&gt; drafter beat the
&lt;code&gt;Q8_0&lt;&#x2F;code&gt; by ~13% in total throughput. The smaller drafter’s faster draft
step outweighed the acceptance-rate cost. The “always pick the
highest-bit drafter” rule assumes you are memory-bandwidth-rich and
compute-poor; on a laptop GPU you are neither.&lt;&#x2F;p&gt;
&lt;p&gt;Benchmark your own silicon.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;llama-quantize&lt;&#x2F;code&gt; silently embeds the absolute on-disk paths of your
imatrix file and calibration corpus into the GGUF metadata. There is no
flag to disable this at quantize time. The &lt;code&gt;*-f16.gguf&lt;&#x2F;code&gt; intermediate is
clean; only quantized files have the leak.&lt;&#x2F;p&gt;
&lt;p&gt;Inspect any quantized GGUF and the two offending keys are sitting there:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;nix-shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; python3Packages.gguf&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;run&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;  &lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;gguf-dump --no-tensors model.gguf&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Key&lt;&#x2F;th&gt;&lt;th&gt;What it leaks&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;quantize.imatrix.file&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Absolute path to the imatrix file on the build host&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;quantize.imatrix.dataset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Absolute path (and filename) of the calibration corpus&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Uploading the raw output of a quantization pipeline publishes your
infrastructure layout — usernames, ZFS pool names, directory structure
— alongside the weights.&lt;&#x2F;p&gt;
&lt;p&gt;The fix is &lt;code&gt;gguf_new_metadata&lt;&#x2F;code&gt; from the Python &lt;code&gt;gguf&lt;&#x2F;code&gt; package, which
rewrites the file with selected keys removed without touching the
tensors:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;nix-shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; python3Packages.gguf&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;run&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;  for f in &#x2F;srv&#x2F;models&#x2F;&amp;lt;MODEL&amp;gt;-GGUF&#x2F;*.gguf; do
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;    [ &amp;quot;$f&amp;quot; = &amp;quot;*-f16.gguf&amp;quot; ] &amp;amp;&amp;amp; continue
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;    python3 -m gguf.scripts.gguf_new_metadata \
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;      --remove-metadata quantize.imatrix.file \
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;      --remove-metadata quantize.imatrix.dataset \
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;      --force \
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;      &amp;quot;$f&amp;quot; &amp;quot;$f.clean&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;  done
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each rewrite runs at ~5–15s per GiB and shrinks the file by exactly the
size of the two strings removed (≈190 bytes).&lt;&#x2F;p&gt;
&lt;p&gt;Verify before uploading:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;gguf-dump&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;no-tensors&lt;&#x2F;span&gt; model-clean.gguf&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;grep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;v&lt;&#x2F;span&gt; INFO&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;kv_count&lt;&#x2F;code&gt; should be exactly 2 less than the original. The
&lt;code&gt;imatrix.*_count&lt;&#x2F;code&gt; integer fields stay (those carry no path information).
A smoke test confirms the rewritten file still loads:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;llama-completion&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;m&lt;&#x2F;span&gt; model-clean.gguf&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;jinja&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;The capital of France is&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;n&lt;&#x2F;span&gt; 20&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;temp&lt;&#x2F;span&gt; 0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Coherent output means the rewrite didn’t corrupt anything.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Sanitized quants in hand, the next step is pairing. A drafter is not a
standalone language model: it has to be paired with a verifier that
shares its exact vocabulary. For Gemma 4 that vocabulary is 262,144
tokens.&lt;&#x2F;p&gt;
&lt;p&gt;The size of that vocabulary is also the reason the MTP speedup applies
to structured output. The drafter sees the same &lt;code&gt;&amp;lt;|tool_call|&amp;gt;&lt;&#x2F;code&gt;,
&lt;code&gt;&amp;lt;|tool_response|&amp;gt;&lt;&#x2F;code&gt;, and &lt;code&gt;&amp;lt;|channel|&amp;gt;&lt;&#x2F;code&gt; tokens as the verifier, so
tool-calling agents and structured-generation workflows benefit on the
full response, not just the natural-language parts. The vocabulary
itself isn’t quantized — it lives in a separate GGUF section.&lt;&#x2F;p&gt;
&lt;p&gt;A working &lt;code&gt;ik_llama.cpp&lt;&#x2F;code&gt; invocation:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;llama-server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;model&lt;&#x2F;span&gt; gemma-4-31B-it-Q8_0.gguf &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;model-draft&lt;&#x2F;span&gt; gemma-4-31B-it-assistant-Q8_0.gguf &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;spec-type&lt;&#x2F;span&gt; mtp &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;draft-max&lt;&#x2F;span&gt; 3 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;draft-p-min&lt;&#x2F;span&gt; 0.0 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    -&lt;&#x2F;span&gt;ngld&lt;&#x2F;span&gt; 99 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;n-gpu-layers&lt;&#x2F;span&gt; 99 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;ctx-size&lt;&#x2F;span&gt; 32768 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    -&lt;&#x2F;span&gt;ctk&lt;&#x2F;span&gt; q8_0&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;ctv&lt;&#x2F;span&gt; q8_0 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    -&lt;&#x2F;span&gt;b&lt;&#x2F;span&gt; 1024&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;ub&lt;&#x2F;span&gt; 1024 &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;    --&lt;&#x2F;span&gt;jinja&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The relevant levers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--spec-type mtp&lt;&#x2F;code&gt; enables the speculative-decoding path from PR #1744.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--model-draft&lt;&#x2F;code&gt; is the drafter GGUF; its vocabulary must match the
verifier.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--draft-max 3&lt;&#x2F;code&gt; sets the speculative chain length. Values from 1 to 4
are all reasonable; &lt;code&gt;--spec-autotune&lt;&#x2F;code&gt; will probe and pick one for your
workload.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--draft-p-min 0.0&lt;&#x2F;code&gt; accepts all drafts; raising it shortens chains on
difficult prompts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--jinja&lt;&#x2F;code&gt; applies the model’s chat template, including Gemma 4’s
tool-call format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;PR #1744’s reference numbers, 31B verifier + 31B drafter at Q8_0&#x2F;Q8_0
on a data-center GPU:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Run&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Throughput&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Acceptance&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Baseline (no MTP)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~21 t&#x2F;s&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;—&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;MTP &lt;code&gt;--draft-max 1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~35 t&#x2F;s&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~89%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;MTP &lt;code&gt;--draft-max 2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~44 t&#x2F;s&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~83%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;MTP &lt;code&gt;--draft-max 3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~49 t&#x2F;s&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~74%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;MTP &lt;code&gt;--draft-max 4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~49 t&#x2F;s&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;~64%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;A bit more than 2× throughput, after all of the above.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The throughput gains are real, and on the right hardware they are
substantial. The work it takes to surface them is also real: undocumented
CLI divergences, an obscure fork, manual metadata sanitization,
quantization rules that invert the usual advice. None of this is in the
model card or the upstream README. The path to a working setup is
reconstructed from PR threads and stack traces.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;&#x2F;blog&#x2F;gemma-4-on-a-2016-xeon&#x2F;&quot;&gt;next post&lt;&#x2F;a&gt; in this series takes the result
and runs it on a 2016 Xeon with no GPU, which is where the command line stops
being a paragraph.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Open weights are not open source</title>
          <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/open-weights-not-open-source/</link>
          <guid>https://point.free/blog/open-weights-not-open-source/</guid>
          <description xml:base="https://point.free/blog/open-weights-not-open-source/">&lt;p&gt;I’ve been quantizing Gemma 4 and it’s MTP drafters recently. The next two posts
are about how that went. This one is about why it was so much work.&lt;&#x2F;p&gt;
&lt;p&gt;When a lab releases a model under an open license, what they almost always
release is the weights. Sometimes a tokenizer. Occasionally a short technical
report. Rarely the training data, data-processing code, training code,
evaluation harness, or the recipes used to produce the published quantizations.
People still call this open source, and I think that’s misleading.&lt;&#x2F;p&gt;
&lt;p&gt;If you can’t rebuild it, you can’t fork it. If you can’t fork it, the
word doesn’t mean what it used to.&lt;&#x2F;p&gt;
&lt;p&gt;Calling it open is like calling an executable binary open because you can
execute it. Unless you consider assembly code open source, I think it’s really
obvious why this misses the mark, and is exellent marketing spin.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The people releasing models don’t seem to feel responsible for whether anyone
can run them, or have good results. Its more like box ticking. Here it is?&lt;&#x2F;p&gt;
&lt;p&gt;There is no shared vocabulary for how a model should be packaged, or which
inference engine it expects, or what quantization recipe was used to make the
file on whatever hub they pick. The settings that actually decide whether a
model is usable on a given machine — &lt;code&gt;mlock&lt;&#x2F;code&gt;, KV-cache dtype, flash attention,
MoE routing, draft model pairing — live in PR descriptions and Discord
screenshots. The model card lists the benchmark scores and links a HuggingFace
space.&lt;&#x2F;p&gt;
&lt;p&gt;So you download the weights, get a result that’s slow or incoherent or both, and
you don’t know whether the model is bad, your quantization is bad, your runtime
is bad, or you’ve just configured something wrong.  Most people, reasonably,
conclude it’s just their hardware, or that open models don’t actually work for
normal users.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The tools that have grown up to paper over this make the problem worse, not
better. Ollama is the obvious example. It picks a quantization, runtime, context
and batch sizes for you, and doesn’t tell you what it picked or why.  When the
output is bad, there’s no thread to pull. You can’t tell if you’re holding it
wrong because the thing was designed so you can’t hold it at all. It’s just a
blackbox!&lt;&#x2F;p&gt;
&lt;p&gt;This wouldn’t matter much if the defaults were good. They aren’t. A
default Q4_0 of a small model with no imatrix calibration and a
mismatched chat template will be much worse than the same model run
carefully, and the user has no way of knowing the difference exists.&lt;&#x2F;p&gt;
&lt;p&gt;AND NO ONE REALLY TALKS ABOUT HOW MUCH THIS MATTERS!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Concretely: a while after Gemma 4 came out, Google released a set of
Multi-Token-Prediction drafters for it, designed to make the base
models faster via speculative decoding. The obvious thing to do is
download the GGUF and run it under &lt;code&gt;llama.cpp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;That doesn’t work, and the reasons it doesn’t work are a fair sample
of the genre:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Mainline &lt;code&gt;llama.cpp&lt;&#x2F;code&gt; doesn’t know what a &lt;code&gt;Gemma4AssistantForCausalLM&lt;&#x2F;code&gt;
is. The converter rejects the drafter outright. To convert it, you
have to find &lt;code&gt;ikawrakow&#x2F;ik_llama.cpp&lt;&#x2F;code&gt;, on a feature branch, from a PR
that hasn’t merged.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;llama-imatrix&lt;&#x2F;code&gt; aborts on that branch’s MTP graph because the build
hardcodes an assertion that a target context is bound. So you skip
imatrix calibration, and your Q4 quants are noticeably worse than the
ones every other model on the hub ships with.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;llama-quantize&lt;&#x2F;code&gt; writes the absolute on-disk paths of your imatrix
file and calibration corpus into the GGUF metadata. There’s no flag
to turn this off. If you upload without scrubbing, you publish your
home directory layout next to the weights.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;None of this is in the model card. None of it is in the upstream
README. You find it by trying things and reading stack traces.&lt;&#x2F;p&gt;
&lt;p&gt;No one does this. Seriously. I mean yes. Part of it is that they just use what
the people that did bother to do it made, fair. But there’s like 4 quants for
this on huggingface at the time of writing, one is mine. FOUR! For the state of
the art MTP&#x2F;MOE models!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The hardware to run a 30B-class MoE at reading speed isn’t exotic. A
five-year-old workstation with enough RAM will do it. The bottleneck isn’t the
silicon, it’s everything between the weights file and a working configuration:
which fork, which quant, which flags, which template, which version of which
template. Ohh, and getting it all running, good luck unless you’re… literally
an infrastructure engineer? Most people give up somewhere in the middle and go
back to the API, and I don’t blame them.&lt;&#x2F;p&gt;
&lt;p&gt;I do think the labs releasing these models could make this much less
bad than they have. Publishing the imatrix corpus would help. Publishing
the quantization recipe would help. Picking one reference runtime and
keeping the model working on it would help. Treating the deployment
story as part of the release, rather than something the community is
expected to reconstruct, would help.&lt;&#x2F;p&gt;
&lt;p&gt;Until that changes, “open source” for language models mostly means “someone else
has to figure out how to run it, and none of the freedoms that used to mean open
source are actually present”, and the people best positioned to figure it out
are charging by the token.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I’ll write up the actual quantization steps — which flags, which traps,
what the metadata leak looks like, how to scrub it — and what it took
to run the result on a 2016 Xeon with no GPU, in two follow-up posts
this week. Thanks for reading :)&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Another NixOS Election Cycle</title>
          <pubDate>Thu, 02 Oct 2025 00:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/moderators/</link>
          <guid>https://point.free/blog/moderators/</guid>
          <description xml:base="https://point.free/blog/moderators/">&lt;h2 id=&quot;and-here-i-thought-we-d-have-a-boring-election-cycle&quot;&gt;And here I thought we’d have a boring election cycle&lt;&#x2F;h2&gt;
&lt;p&gt;If you’ve not been following NixOS governance, recently the moderation team
decided to all collectively resign. I’ve been informed that I’ve been one of the
people that certain steering committee members have wanted to moderate harder,
specifically  because I’ve been calling out their undisclosed conflicts of
interest, and providing actual level headed, direct criticisms that they’ve yet
managed to answer.&lt;&#x2F;p&gt;
&lt;p&gt;This is despite their alleged pledge to respond to community concerns. One of
the people I’ve been led to believe specifically has been pushing for
aggressively moderating me has yet to respond to any messages I’ve sent them in
private, which to me is even more odd, they’re not rude, and could likely have
cleared up any legitimate moderation issues.&lt;&#x2F;p&gt;
&lt;p&gt;I think that, looking back at the previous steering committee, and even watching
their talks at NixCon, it was quite clear that most of them were not really
interested in governance. Paraphrasing, most of them said a version of “I’m not
the most competent person to be here”, and those were the ones that at least
have the insight to make that realization.&lt;&#x2F;p&gt;
&lt;p&gt;I think that many were there simply to add a new line to their resume.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-does-it-mean-for-me-running&quot;&gt;What does it mean for me running?&lt;&#x2F;h2&gt;
&lt;p&gt;Nothing. I’ll run. If enough people vote for me, I’ll do what I set out to do in
my candidate statement. If I’m not elected, I’ll put my focus elsewhere, and
make myself available to any elected Steering Committee members on policy and
governance questions, just like the last cycle.&lt;&#x2F;p&gt;
&lt;p&gt;I don’t think that the Steering Committee is the only (or even the most
effective) way for me to improve the project and ecosystem. But it is an option
I’d be foolish to throw away. And I have much I want to do.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the start.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;process&quot;&gt;&lt;em&gt;Process&lt;&#x2F;em&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;I’ve read the &lt;a href=&quot;https:&#x2F;&#x2F;www.haskellforall.com&#x2F;2025&#x2F;09&#x2F;steering-committee-retrospective.html&quot;&gt;Steering Committee retrospective from
Gabriella&lt;&#x2F;a&gt;. To me, the challenges raised here are of
primary concern.&lt;&#x2F;p&gt;
&lt;p&gt;Currently, the steering committee isn’t leading the community. And if the final
instance required for decisive action in the project is indescisive, then what’s
the point?&lt;&#x2F;p&gt;
&lt;p&gt;So that’s my primary concern. The steering committee should actually get things
done.&lt;&#x2F;p&gt;
&lt;p&gt;I think we can solve this.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;transparency&quot;&gt;&lt;em&gt;Transparency&lt;&#x2F;em&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Meeting notes and employers of board and steering committee memeber should be
made public - to the extend possible. There should be public logs of both.&lt;&#x2F;p&gt;
&lt;p&gt;Everything should default to being documented in public, including decisions and
how members vote.&lt;&#x2F;p&gt;
&lt;p&gt;If the steering committee finds certain subjects too sensitive, they may be
redacted, but even then, the fact that a vote or discussion took place should be
documented. Who voted for and against - even if we can’t say for what - should
be written down for everyone to see.&lt;&#x2F;p&gt;
&lt;p&gt;The steering committee must become auditable and accountable to everyone in the
project.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;unblocking-adoption&quot;&gt;&lt;em&gt;Unblocking Adoption&lt;&#x2F;em&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Flakes aren’t unstable. That’s mainly a naming convention at this point. It is a
major disadvantage for the project, and the official installer adds friction.&lt;&#x2F;p&gt;
&lt;p&gt;Flakes should be installed by default. Defaults should be sane.&lt;&#x2F;p&gt;
&lt;p&gt;Many decisions in the project aren’t made based on what’s best for the project,
but where measures to alleviate immediate harm. Now those same measures have
themselves become harmful.&lt;&#x2F;p&gt;
&lt;p&gt;By engaging with the community, and listening for places where their colleagues
are blocked or choosing alternatives to official tools, I’ll correct any
blockers with the steering committee and community, and ensure we become the
best choice.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I think Nix is a paradigm shift in how we do computers, and I want to convince
the rest of the world of that. I want to work with Nix for the rest of my
career, and for that to become a reality, I’m running for the steering committee
again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-final-question-will-you-go-the-distance&quot;&gt;A final question: Will you go the distance&lt;&#x2F;h2&gt;
&lt;p&gt;I know a lot of people are scared that they’ll end up voting for someone that
will turn passive and be checked out. I am scared of voting for such people. It
was  a major pain in the last election, that even if I was aligned with a
candidate and they got elected, they just didn’t actually push for anything, and
seemed to essentially give up.&lt;&#x2F;p&gt;
&lt;p&gt;If that’s something you’re scared will happen, I think specially if you’re a
long time community member, the best proof I can give that it wont happen if you
vote for me is that… I’m still here. I’d not want to waste your vote.&lt;&#x2F;p&gt;
&lt;p&gt;But I’d also like to temper your expectations. I can only do so much. If you
vote for  a bunch of people that are not gonna go the distance, then my primary
role becomes keeping you updated on why the process remains broken. I can be a
voice for accountability, but I cannot be the entire committee.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Tracking Sattelites with Consumer Components</title>
          <pubDate>Sun, 05 Jan 2025 06:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/first-tinygs-station/</link>
          <guid>https://point.free/blog/first-tinygs-station/</guid>
          <description xml:base="https://point.free/blog/first-tinygs-station/">&lt;h2 id=&quot;a-global-network-of-ground-stations&quot;&gt;A Global Network of Ground Stations&lt;&#x2F;h2&gt;
&lt;p&gt;At &lt;a href=&quot;https:&#x2F;&#x2F;events.ccc.de&#x2F;congress&#x2F;2024&#x2F;infos&#x2F;index.html&quot;&gt;38c3&lt;&#x2F;a&gt; I attended a
workshop on building a sattelite ground stations for communicating with LoRa
based sattelites, typically used for research or weather probes.&lt;&#x2F;p&gt;
&lt;p&gt;Generally speaking, these are so called
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CubeSat&quot;&gt;“cubesats”&lt;&#x2F;a&gt;, which are small,
&lt;em&gt;relatively&lt;&#x2F;em&gt; inexpensive sattelites usually built up of off the shelf components
in a modular fashion. In fact, it turns out that with one of these inexpensive
sattelites, a small launch would actually &lt;em&gt;only&lt;&#x2F;em&gt; cost in the range of
$50,000-$100,000, not a small amount, but still, a lot more accessible than what
you would initially imagine. Combine this with LoRa (literally &lt;strong&gt;Lo&lt;&#x2F;strong&gt;ng
&lt;strong&gt;Ra&lt;&#x2F;strong&gt;nge)  — a proprietary radio communication technique — and you have the
components for a globe spanning network of sattelites and amatur ground
stations.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;nano_rack_cube_sat.jpg&quot; alt=&quot;Nano Rack Cube Sat after being deployed from the ISS&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This has lead to a suprising amount of these &lt;a href=&quot;https:&#x2F;&#x2F;tinygs.com&#x2F;satellites&quot;&gt;sattelites currently in low-earth
orbit around the globe&lt;&#x2F;a&gt;. Typically these aren’t
geostationary (meaning located over the same point on the planet at all times),
and so, it is useful for e.g. a smaller university to have access to a globe
spanning network of sattelite stations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tinygs&quot;&gt;TinyGS&lt;&#x2F;h2&gt;
&lt;p&gt;Enter &lt;a href=&quot;https:&#x2F;&#x2F;tinygs.com&#x2F;&quot;&gt;TinyGS, tiny ground stations&lt;&#x2F;a&gt;. TinyGS is an open
network of Ground stations distributed across the globe, run by amateurs. It
allows operating LoRa based weather probes, sattelites, and other “flying
objects”, using consumer electronics.&lt;&#x2F;p&gt;
&lt;p&gt;The basic idea is that you get an ESP32 as well as a some sort of LoRa module,
an antenna, and flash the tinygs firmware onto it. Then you just connect it to
the tinygs servers using MQTT, and you will be able to opearte your board on the
tinygs website, as well as being able to contribute to the global sattelite
tracking effort.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;TinyGS_architecture.png&quot; alt=&quot;TinyGS software architecture diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build-your-own-ground-station&quot;&gt;Build your own Ground Station&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;hardware&quot;&gt;Hardware&lt;&#x2F;h3&gt;
&lt;p&gt;If you wanna build your own, the easiest possible route is just to acquire a
&lt;code&gt;LoRa32 V2.1_1.6 - 433MHZ CH9102F&lt;&#x2F;code&gt; board. Usually you can find these online, and
make sure that you get one with a small antenna.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;lora-board.png&quot; alt=&quot;LoRa32 V2.1_1.6 - 433MHZ CH9102F (With ANT500 antenna for reasons)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You’ll need to flash the firmware, the easiest way is to use the &lt;a href=&quot;https:&#x2F;&#x2F;installer.tinygs.com&#x2F;&quot;&gt;TinyGS web
flashing tool&lt;&#x2F;a&gt;, and sorry, but you’ll need to use
a chrome based browser for this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setup&quot;&gt;Setup&lt;&#x2F;h3&gt;
&lt;p&gt;What’s worse, you’ll also need to install telegram, and create an account, as
the TinyGS projects communications mainly happen there, and that means the
registration bot for your new board also lives on telegram.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;t.me&#x2F;joinchat&#x2F;DmYSElZahiJGwHX6jCzB3Q&quot;&gt;Join the TinyGS telegram group
here&lt;&#x2F;a&gt;, and then start a
conversation with &lt;a href=&quot;https:&#x2F;&#x2F;t.me&#x2F;tinygs_personal_bot&quot;&gt;the tinygs personal bot
here&lt;&#x2F;a&gt;. Also, make sure you join the TinyGS
community chat in the group first, as the bot will require you to be a member
before signing you up. When you are in that chat, send the &lt;code&gt;&#x2F;start&lt;&#x2F;code&gt; command to
the bot for some info about it’s usage. You’re mainly just interested in the
&lt;code&gt;&#x2F;mqtt&lt;&#x2F;code&gt; command, which gives you your credentials for the mqtt server.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;tinybot.png&quot; alt=&quot;Registering My Own Station meoweather with the bot.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now with your credentials, and your participation in the TinyGS community (hi!),
you’ll want to plug in your flashed board. After a few moments, it should start
it’s own WiFi AP, that you can connect to. On the screen of your board, it
should show the IP address that you’ll then want to connect to on the boards
WiFi. This will give you a configuration inteface.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;TinyGS_dashboard.png&quot; alt=&quot;TinyGS Dashboard&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here, you enter the configuration, and then configure a ground station name,
create an admin password (to be used with the &lt;code&gt;admin&lt;&#x2F;code&gt; account), enter the WiFI
SSID and Password that you want the board to use for internet connectivity, your
lattitude and longitude (this doesn’t have to be &lt;em&gt;exact&lt;&#x2F;em&gt;, but should be vaguely
correct withing 25km~ because it is used to determine what sattelites to try and
connect to), and a timezone. Further, you’ll want to add your MQTT credentials
from the telegram bot.&lt;&#x2F;p&gt;
&lt;p&gt;If you’ve done everything correctly, you’ll receive a message on telegram from
the bot, like I did in the above screenshot. You’re now on the network.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;start-operating-your-sattelite&quot;&gt;Start operating your sattelite&lt;&#x2F;h3&gt;
&lt;p&gt;After you’ve setup your station, you’ll want to &lt;code&gt;&#x2F;login&lt;&#x2F;code&gt; with the bot to be able to operate it fully.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;login.png&quot; alt=&quot;Sending &#x2F;login command to bot to get passwordless login link.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This will give you access to even more information about your device, and the
ability to edit it’s description and image, and to control how it is tracking
sattelites, or setup manual tracking if you wanna just track something specific,
or you don’t like the automatic selection.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;operate.png&quot; alt=&quot;The operator overview&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Below that, you’ll find a log of the packets you have recieved so far.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;captures.png&quot; alt=&quot;Captured pacets&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice here that the red circle indicated a CRC checksum error, meaning you recieved a faulty package. Also notice that there are two packets with a CRC error that were caught by just one station (meaning just your station). In this case, if you click on the packet, you’ll get the text that:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unrecognized packet. This packet does not match the known structure of this
satellite. It might be an unknown packet or just terrestrial noise.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;However, for those that don’t have a CRC error, that’s a real sattelite packet you’ve caught. Well done!. If you click on it you can even read the details about what you caught.&lt;&#x2F;p&gt;
&lt;p&gt;For example, the &lt;code&gt;HOD-HOD-1A&lt;&#x2F;code&gt; capture from above provides the following information when you click on it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;first-tinygs-station&#x2F;capture.png&quot; alt=&quot;HOD-HOD-1A capture&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As you can see, it shows what the content of the packet was, both as text, hexadecimal, and parsed json that you can expand and browse through. Below that, you’ll see a list of other stations that caught the packet. The view to the side shows the geographical location of the stations that caught the sattelite communication.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;i-wanna-capture-more-packets&quot;&gt;I wanna capture more packets!&lt;&#x2F;h3&gt;
&lt;p&gt;As you will likely realize after running your station for a few days, you’re
probably not capturing a lot of packets. This is because the default antenna
doesn’t really perform well, and likely, you’ll also ideally want to make sure
that your station is outside, and isn’t obstructed, and that weather conditions
are favorable (anecdotally, I also tend to capture much more packets at night).&lt;&#x2F;p&gt;
&lt;p&gt;I’ll not elaborate more on this in this post, as it is something I’m working on
myself, but I may follow up later with a separate post on what it takes to
increase the amount of packets you capture. In short, you’ll want a 1&#x2F;4-wave
ground plane antenna.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;obligatory-conclusion&quot;&gt;Obligatory Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;With inexpensive consumer hardware, it is possible to build your own sattelite
ground station, and join a globe spanning network of space enthusiasts capturing
sattelite data.&lt;&#x2F;p&gt;
&lt;p&gt;That is pretty cool :3&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Conventional Commits Change my Brain</title>
          <pubDate>Wed, 24 Jul 2024 00:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/conventional-commits/</link>
          <guid>https://point.free/blog/conventional-commits/</guid>
          <description xml:base="https://point.free/blog/conventional-commits/">&lt;h2 id=&quot;what-is-a-conventional-commit&quot;&gt;What is a conventional commit?&lt;&#x2F;h2&gt;
&lt;p&gt;In case you’re not aware, &lt;a href=&quot;https:&#x2F;&#x2F;www.conventionalcommits.org&quot;&gt;conventional
commits&lt;&#x2F;a&gt; is a standard format for writing
commit summaries. It looks like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;build(deps): bump git2 from 0.18.3 to 0.19.0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Bumps [git2](https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;git2-rs) from 0.18.3 to 0.19.0.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- [Changelog](https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;git2-rs&#x2F;blob&#x2F;master&#x2F;CHANGELOG.md)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- [Commits](https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;git2-rs&#x2F;compare&#x2F;git2-0.18.3...git2-0.19.0)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;---
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;updated-dependencies:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- dependency-name: git2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  dependency-type: direct:production
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  update-type: version-update:semver-minor
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Signed-off-by: dependabot[bot] &amp;lt;support@github.com&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This example is from &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dependabot&quot;&gt;dependabot&lt;&#x2F;a&gt;, which does
conform to conventional commits. Notice that only the first line, the &lt;em&gt;commit
summary&lt;&#x2F;em&gt;, is part of the conventional commits spec here. The last line is a
“footer”&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, or technically, a
&lt;a href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;git-interpret-trailers&quot;&gt;&lt;em&gt;trailer&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; added by the &lt;code&gt;git commit -s&lt;&#x2F;code&gt; flag, &lt;code&gt;-s&lt;&#x2F;code&gt; short for &lt;code&gt;--signoff&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The exact spec looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;lt;type&amp;gt;[optional scope]: &amp;lt;description&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[optional body]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[optional footer(s)]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unlike many project specific standards, such as that of
&lt;a href=&quot;https:&#x2F;&#x2F;angular.dev&#x2F;&quot;&gt;angular&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nixos&#x2F;nixpkgs&quot;&gt;nixpkgs&lt;&#x2F;a&gt;,
what sets conventional commits apart is that it aims to be a universal commit
standard, a bit like how &lt;a href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;semantic versioning&lt;&#x2F;a&gt; seeks to be
a universal software versioning standard.&lt;&#x2F;p&gt;
&lt;p&gt;In the same sense as semantic versioning provides meaning through version
numbers, such as a &lt;code&gt;major&lt;&#x2F;code&gt; number increasing meaning a breaking change,
conventional commits also seeks to encode information about the state of a
project in the commit summaries, and provides enough information to reasonably
tell when it’s time to do a patch, minor, or major version bump.&lt;&#x2F;p&gt;
&lt;p&gt;It further also provides ways to specify if a commit contains a breaking change,
via a git footer.&lt;&#x2F;p&gt;
&lt;p&gt;It may be easiest to explain this by just showing you the spec.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;The commit contains the following structural elements, to communicate intent
to the consumers of your library:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;fix:&lt;&#x2F;strong&gt; a commit of the &lt;em&gt;type&lt;&#x2F;em&gt; &lt;code&gt;fix&lt;&#x2F;code&gt; patches a bug in your codebase (this correlates with &lt;a href=&quot;http:&#x2F;&#x2F;semver.org&#x2F;#summary&quot;&gt;&lt;code&gt;PATCH&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; in Semantic Versioning).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;feat:&lt;&#x2F;strong&gt; a commit of the &lt;em&gt;type&lt;&#x2F;em&gt; &lt;code&gt;feat&lt;&#x2F;code&gt; introduces a new feature to the codebase (this correlates with &lt;a href=&quot;http:&#x2F;&#x2F;semver.org&#x2F;#summary&quot;&gt;&lt;code&gt;MINOR&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; in Semantic Versioning).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;BREAKING CHANGE:&lt;&#x2F;strong&gt; a commit that has a footer &lt;code&gt;BREAKING CHANGE:&lt;&#x2F;code&gt;, or appends a &lt;code&gt;!&lt;&#x2F;code&gt; after the type&#x2F;scope, introduces a breaking API change (correlating with &lt;a href=&quot;http:&#x2F;&#x2F;semver.org&#x2F;#summary&quot;&gt;&lt;code&gt;MAJOR&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; in Semantic Versioning).
A BREAKING CHANGE can be part of commits of any &lt;em&gt;type&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;types&lt;&#x2F;em&gt; other than &lt;code&gt;fix:&lt;&#x2F;code&gt; and &lt;code&gt;feat:&lt;&#x2F;code&gt; are allowed, for example &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;conventional-changelog&#x2F;commitlint&#x2F;tree&#x2F;master&#x2F;%40commitlint&#x2F;config-conventional&quot;&gt;@commitlint&#x2F;config-conventional&lt;&#x2F;a&gt; (based on the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;angular&#x2F;angular&#x2F;blob&#x2F;22b96b9&#x2F;CONTRIBUTING.md#-commit-message-guidelines&quot;&gt;Angular convention&lt;&#x2F;a&gt;) recommends &lt;code&gt;build:&lt;&#x2F;code&gt;, &lt;code&gt;chore:&lt;&#x2F;code&gt;,
&lt;code&gt;ci:&lt;&#x2F;code&gt;, &lt;code&gt;docs:&lt;&#x2F;code&gt;, &lt;code&gt;style:&lt;&#x2F;code&gt;, &lt;code&gt;refactor:&lt;&#x2F;code&gt;, &lt;code&gt;perf:&lt;&#x2F;code&gt;, &lt;code&gt;test:&lt;&#x2F;code&gt;, and others.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;footers&lt;&#x2F;em&gt; other than &lt;code&gt;BREAKING CHANGE: &amp;lt;description&amp;gt;&lt;&#x2F;code&gt; may be provided and follow a convention similar to
&lt;a href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;git-interpret-trailers&quot;&gt;git trailer format&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Additional types are not mandated by the Conventional Commits specification, and have no implicit effect in Semantic Versioning (unless they include a BREAKING CHANGE).&lt;&#x2F;p&gt;
&lt;p&gt;A scope may be provided to a commit’s type, to provide additional contextual information and is contained within parenthesis, e.g., &lt;code&gt;feat(parser): add ability to parse arrays&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;So basically, if there is a type &lt;code&gt;fix&lt;&#x2F;code&gt;, that’s a &lt;code&gt;PATCH&lt;&#x2F;code&gt; bump to your semver, a
&lt;code&gt;feat&lt;&#x2F;code&gt; is a &lt;code&gt;MINOR&lt;&#x2F;code&gt; bump, and a &lt;code&gt;BREAKING CHANGE:&lt;&#x2F;code&gt; footer or a &lt;code&gt;!&lt;&#x2F;code&gt; after the
type&#x2F;scope is a &lt;code&gt;MAJOR&lt;&#x2F;code&gt; bump.&lt;&#x2F;p&gt;
&lt;p&gt;If we for instance have commit with the summary &lt;code&gt;fix: change windows-only imports to be windows-only&lt;&#x2F;code&gt;, that’s a &lt;code&gt;PATCH&lt;&#x2F;code&gt; change, and if we are on version
&lt;code&gt;3.2.48&lt;&#x2F;code&gt;, then next version will have to be at least &lt;code&gt;3.2.49&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If we instead had a summary &lt;code&gt;feat: add --no-|show-symlinks flags for filtering output&lt;&#x2F;code&gt;, then that would a &lt;code&gt;MINOR&lt;&#x2F;code&gt; change, and again, if we were on &lt;code&gt;3.2.48&lt;&#x2F;code&gt;,
next release would be &lt;code&gt;3.3.0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, if we had a summary &lt;code&gt;feat(flags)!: add --classify=always,auto,never&lt;&#x2F;code&gt;,
even thou it has a &lt;code&gt;feat&lt;&#x2F;code&gt; type, the &lt;code&gt;!&lt;&#x2F;code&gt; indicates this is a breaking change, and
so we must cut a new &lt;code&gt;MAJOR&lt;&#x2F;code&gt; version on next release if we include this commit,
meaning that if we were on &lt;code&gt;3.2.48&lt;&#x2F;code&gt;, we’d go to &lt;code&gt;4.0.0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Yes. Breaking changes means a new major version. Yes, that might seem sever to
you if  you’re not used to being at the helm of something being used by a lot of
people, but that’s how we make these sausages (at least if we’re actually trying
to do it correctly). The guy who authored the semver spec, &lt;a href=&quot;https:&#x2F;&#x2F;tom.preston-werner.com&#x2F;&quot;&gt;Tom
Preston-Werner&lt;&#x2F;a&gt; (also known for co-founding
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&quot;&gt;GitHub&lt;&#x2F;a&gt; and creating &lt;a href=&quot;https:&#x2F;&#x2F;gravatar.com&#x2F;&quot;&gt;gravatar&lt;&#x2F;a&gt;) has
a blog post about this called &lt;a href=&quot;https:&#x2F;&#x2F;tom.preston-werner.com&#x2F;2022&#x2F;05&#x2F;23&#x2F;major-version-numbers-are-not-sacred&quot;&gt;Major Version Numbers are Not
Sacred&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;What people end up doing in practice is building up a lot of breaking changes
and then releasing them all at once, to not constantly destroy the API&#x2F;ABI and
UX of their software. How this ties in with a more continuous development is a
very interesting question, e.g. how does
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eza-community&#x2F;eza&quot;&gt;eza&lt;&#x2F;a&gt; manage to release a new version
every week, yet also work on breaking changes like config files or moving to a
new command line parser (specifically &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;clap-rs&#x2F;clap&quot;&gt;clap&lt;&#x2F;a&gt;).
I think such a discussion is far out of scope for this post, but I may write
about it in the future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conventional-commits-and-linguistic-relativity&quot;&gt;Conventional Commits and Linguistic Relativity&lt;&#x2F;h2&gt;
&lt;p&gt;If you were to ask wikipedia what “Behavioral Design” means, it would reply:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Behavioural design is a sub-category of design, which is concerned with how
design can shape, or be used to influence human behaviour.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Now, how is that relevant to us as developers, maintainers, or just hobbyist
hackers?&lt;&#x2F;p&gt;
&lt;p&gt;Well you see, the design of conventional commits, whether intentional or not,
has  a lot of decisions that end up shaping how contributors interact with your
project.&lt;&#x2F;p&gt;
&lt;p&gt;When I initially forked &lt;code&gt;eza&lt;&#x2F;code&gt;, I mostly moved us to conventional commits fairly
early because I was concerned with a maintenance burden. I knew that &lt;code&gt;exa&lt;&#x2F;code&gt; had
been a project  of maintainer burnout, and what I was trying to do was create
longevity for the project. That meant that if there was something I could
offload to someone or something else, I would, including changelogs.&lt;&#x2F;p&gt;
&lt;p&gt;And yes, conventional commits means I don’t have to write changelogs, I can
automate it, and it means  I don’t have to think too hard about what version is
next, it’s automatically generated. In fact, I can release eza every week
because  a release is just running two scripts, doing a &lt;code&gt;cargo publish&lt;&#x2F;code&gt;, and a
&lt;code&gt;nix-update eza&lt;&#x2F;code&gt; in the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nixos&#x2F;nixpkgs&quot;&gt;nixpkgs&lt;&#x2F;a&gt; repo and
opening a PR.&lt;&#x2F;p&gt;
&lt;p&gt;While that release velocity is great, I found another, much more interesting
perk of using conventional commits. Namely that conventional commits lead  to
better commits, better commit summaries, better PRs, and better structured
commits.&lt;&#x2F;p&gt;
&lt;p&gt;For instance, if a project just allows a commit summary to be an arbitrary
string, what you’ll often end up with is either something like &lt;code&gt;made extensions work&lt;&#x2F;code&gt;, a single commit that  encompasses vast refactorings of the codebase,
introduces a feature, fixes 3 different bugs, and is one big monolithic and
unrevievable mess.&lt;&#x2F;p&gt;
&lt;p&gt;On the other hand, it also saves you from the series of &lt;code&gt;wip&lt;&#x2F;code&gt;, &lt;code&gt;wip 2&lt;&#x2F;code&gt;,
&lt;code&gt;formatted code and added quantum cryptography&lt;&#x2F;code&gt;, &lt;code&gt;made compile&lt;&#x2F;code&gt;. These are
equally unreviewable, and completely destroy your git log.&lt;&#x2F;p&gt;
&lt;p&gt;Now, you may have the discipline of projects like
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nixos&#x2F;nixpkgs&quot;&gt;nixpkgs&lt;&#x2F;a&gt; of  asking contributors to rebase
their commits, so that they each represent unique atomic changes. But even then,
what conventional commits gives you is a language to express what these changes actually are.&lt;&#x2F;p&gt;
&lt;p&gt;Before I had conventional commits as something I could just write without
looking at the spec, I would genuinly struggle putting words to what my changes
did. It made it hard to create good PRs to projects.&lt;&#x2F;p&gt;
&lt;p&gt;Now, it’s much easier. I just go:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;refactor(parser): used enums instead of bools in match logic&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fix(parser): capital letters not differentiated&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fix(parser): long lines ignored&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;feat(parser): add long flags&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;docs(parser): document long flag usage&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;style: change flag rendering&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ci: check parser flags workflow&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Not only does this make my PR much more structured, but by getting into that
habit, I find that  my work also becomes much more organized. Instead of just
working on some hodgepodge mix of things at the same  time and committing either
to save my work or to put all of it together in a disorganized sack of a single
commit, I find that I am much more able to dissect a problem into discrete
solvable steps.&lt;&#x2F;p&gt;
&lt;p&gt;I’d even go as far as saying this makes you a better programmer, as breaking
down a large problem into small solvable chunks is a great problem solving
strategy.&lt;&#x2F;p&gt;
&lt;p&gt;What conventional commits does is it gives you this language to describe the
steps it  takes to solve a problem, and getting familiar with that vocabulary
not only makes you a better programmer, but it makes it much easier to work with
you, and it heavily reduced the burden on maintainers.&lt;&#x2F;p&gt;
&lt;p&gt;Linguistic relativity is the idea that the structure of a language influences
the speakers world view and cognition, changing how you interact with your
surroundings. Linguistic relativity is a hypothesis, but I find it pretty easy
to prove the weak case that if you can’t signify something, you will struggle to
operate with it.&lt;&#x2F;p&gt;
&lt;p&gt;In other words, conventional commits get you merged faster, and makes your code
better. Hopefully you’re sold by this point.&lt;&#x2F;p&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;There are some tools for dealing with these, such as &lt;a href=&quot;https:&#x2F;&#x2F;commondatastorage.googleapis.com&#x2F;chrome-infra-docs&#x2F;flat&#x2F;depot_tools&#x2F;docs&#x2F;html&#x2F;git-footers.html&quot;&gt;git-footers&lt;&#x2F;a&gt;. Personally, I don’t really use those. But it’s good to know they exist. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>rustls and aws-sdk seems incompatible with FOSS</title>
          <pubDate>Mon, 17 Jun 2024 14:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/rusts-ring-problem/</link>
          <guid>https://point.free/blog/rusts-ring-problem/</guid>
          <description xml:base="https://point.free/blog/rusts-ring-problem/">&lt;p&gt;I should preface this with the fact that I am by no means a lawyer or anything
like it. Nothing here constitutes a legal argument or should be taken as true. I
may be completely wrong or have missed crucial details.&lt;&#x2F;p&gt;
&lt;p&gt;As part of a rust project I’ve been working on at dayjob, I’ve had to audit all
dependencies for license compatibility with the AGPLv3, our preferred license.
Sadly, I encountered what I think is a major ecosystem blocker, and we will
likely not be able to license the code under AGPLv3, or any GPL license for that
matter, having to go with a more permissive, but compatible license until the
problem this post is about is fixed. Which is a shame, and something I wanna
bring more attention to.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;A fairly fundamental crate in rust is
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;briansmith&#x2F;ring&quot;&gt;ring&lt;&#x2F;a&gt;, providing “safe, fast, small crypto
using Rust”. To understand how fundamental it is, consider that other crates
such as &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustls&#x2F;rustls&quot;&gt;rustls&lt;&#x2F;a&gt;, the
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;awslabs&#x2F;aws-sdk-rust&quot;&gt;aws-sdk-rust&lt;&#x2F;a&gt; crate, and
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustls&#x2F;sct.rs&quot;&gt;sct&lt;&#x2F;a&gt; make use of ring. And this is by no
means an exhaustive list.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with ring, as you may well notice if you dare read its rather
convoluted
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;briansmith&#x2F;ring?tab=License-1-ov-file#readme&quot;&gt;license&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, is
that amongst it’s licenses is the OpenSSL license. The problem with the OpenSSL
license is it’s equivalent to a BSD4 clause license. That is, it contains the
problematic advertisement clause.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;txt&quot; class=&quot;language-txt z-code&quot;&gt;&lt;code class=&quot;language-txt&quot; data-lang=&quot;txt&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt; * 3. All advertising materials mentioning features or use of this
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt; *    software must display the following acknowledgment:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt; *    &amp;quot;This product includes software developed by the OpenSSL Project
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt; *    for use in the OpenSSL Toolkit. (http:&#x2F;&#x2F;www.openssl.org&#x2F;)&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This clause is &lt;a href=&quot;https:&#x2F;&#x2F;opensource.stackexchange.com&#x2F;questions&#x2F;8040&#x2F;why-does-the-clause-3-of-4-clause-bsd-makes-it-incompatible-with-gpl&quot;&gt;well
known&lt;&#x2F;a&gt;
for being GPL-incompatible, and indeed, if you look up the OpenSSL license on
the &lt;a href=&quot;https:&#x2F;&#x2F;gnu.org&quot;&gt;gnu.org&lt;&#x2F;a&gt; list &lt;a href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;licenses&#x2F;license-list.en.html#OpenSSL&quot;&gt;of gpl compatible
licenses&lt;&#x2F;a&gt;, it is
indeed the case that the license is considered GPL-incompatible.&lt;&#x2F;p&gt;
&lt;p&gt;But so what? Big deal?&lt;&#x2F;p&gt;
&lt;p&gt;Big deal… yes. This means that if you want to interface with s3 storage&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;[2]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, or
use rustls, you’ll be GPL incompatible!&lt;&#x2F;p&gt;
&lt;p&gt;For example, consider the following GNU Affero General Public License Version 3
projects that use crates in the &lt;code&gt;aws-sdk&lt;&#x2F;code&gt; suite, or &lt;code&gt;rustls&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zed-industries&#x2F;zed&quot;&gt;zed&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;signalapp&#x2F;Signal-Calling-Service&quot;&gt;Signal-Calling-Service&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;deuxfleurs-org&#x2F;garage&quot;&gt;garage s3&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;quickwit-oss&#x2F;quickwit&quot;&gt;quickwit&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustdesk&#x2F;rustdesk&quot;&gt;rustdesk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And these are just some quick examples I found with a quick github search, there
is probably much more software currently out there in the rust ecosystem that’s
using a license that its crates are fundamentally incompatible with&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;[3]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;While this is a problem the &lt;code&gt;ring&lt;&#x2F;code&gt; crate &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;briansmith&#x2F;ring&#x2F;issues&#x2F;1827&quot;&gt;seems to be aware
of&lt;&#x2F;a&gt;, it’s sad to see that there
is such a large wound on the FOSS compatibility of the rust crate ecosystem. Not
to put any blame anywhere. I am well aware that if this was easy to fix, it
wouldn’t be a problem anymore, and anyone wanting to criticize the ring devs
should spend the effort helping them fix the situation, rather than complaining,
they seem eager to solve this. But it is something I think needs more awareness.&lt;&#x2F;p&gt;
&lt;p&gt;Update 2024-06-19: We’ll try to go with EUPL-1.2, as it is compatible with all
BSD licenses. Also, it seems to have many other useful properties. This does
not make the problem disappear however, but it does create a path forward for a
stronger license for rust projects affected that want SaaS loophole
protections.&lt;&#x2F;p&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;This is a problem the ring devs are working on. Let it be a lesson to start your project off using &lt;a href=&quot;https:&#x2F;&#x2F;reuse.software&#x2F;&quot;&gt;REUSE&lt;&#x2F;a&gt; or paying the price down the line &amp;gt;:3 &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;Yes, there are other crates than the aws-sdk, but when investigating this for the project in question, none seem to be tennable solutions. Vet your dependencies! &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Yes, there are potential ways to mitigate this, but by a quick skim, I haven’t seen any of those implemented in these projects, and implementing them would likely be both architecturally ugly, and horribly inefficient. For… reasons, I’ll not actually elaborate on how you could potentially circumvent licenses like this, because I’m really not a lawyer. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Merge or Rebase</title>
          <pubDate>Wed, 29 May 2024 13:40:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/git-merge-rebase/</link>
          <guid>https://point.free/blog/git-merge-rebase/</guid>
          <description xml:base="https://point.free/blog/git-merge-rebase/">&lt;p&gt;This isn’t the article that’s gonna explain merge vs rebase for people that
haven’t used git before (sorry). Rather, this is gonna be about some more meta
things for maintainers, release engineers, and other people who care about
development process.&lt;&#x2F;p&gt;
&lt;p&gt;Git gives you a lot of options. How you use it isn’t prescribed in advance.
There are a lot of ways that people might use git differently, but here, I’m
more seeking to investigate some of the ways of using git that are relevant to
people in charge of git repositories with a non-trivial amount of contributors,
like myself.&lt;&#x2F;p&gt;
&lt;p&gt;While I enjoy having these things done differently between projects I’m working
in and part of maintaining — as it gives some diversity to the methods I get
to use in my work, and let’s me continuously evaluate multiple methods&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; in
practice — I do think it makes sense that for a single project, there is
consistency in the way it’s developed, so that expectations can be set, and
procedures can be learned and become second nature.&lt;&#x2F;p&gt;
&lt;p&gt;There are two main questions for a project to decide when it comes to merging via git.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;How to merge feature branch changes from PRs.&lt;&#x2F;li&gt;
&lt;li&gt;How to merge newest changes into outdated branches.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I’ll discuss both, and then summariese my observations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;merging-branches&quot;&gt;Merging branches&lt;&#x2F;h2&gt;
&lt;p&gt;When some developer starts working on a software feature, especially in open
source, those changes, typicall, will be made in a separate branch that has
branched off from the main branch. This is often called a feature branch. This
allows the developer to work on their feature in isolation, and, at some point,
put those changes back into the main branch, for all people to use.&lt;&#x2F;p&gt;
&lt;p&gt;This is what some may call trunk based development, although the lines get fuzzy
about how long a PR should live. That discussion is out of scope for this post,
but I’d love to follow up with a post about that at some point.&lt;&#x2F;p&gt;
&lt;p&gt;When moving changes from your feature branch into main, you can have potentially three possible options for merging.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Fast Forward&lt;&#x2F;li&gt;
&lt;li&gt;Rebase and Fast Forward&lt;&#x2F;li&gt;
&lt;li&gt;Merge&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For fast forward, main may not have changed while you were working, and so you
can “fast forward” your changes on top of main, without having to worry about
any conflicts. This is, for both developers and maintainers, extremely easy,
with some reservations that will be discussed later.&lt;&#x2F;p&gt;
&lt;p&gt;Another option is to take the changes from the updated main branch, and &lt;code&gt;git pull --rebase origin main&lt;&#x2F;code&gt; them into your feature branch, placing your changes on top of the latest changes from main. As you may guess, this allows you to &lt;code&gt;git merge --ff-only&lt;&#x2F;code&gt; your changes into the main branch.&lt;&#x2F;p&gt;
&lt;p&gt;The final strategy is the classical merge. You may decide to merge your changes, and the changes in main together, using a special commit that represents the operation of merging the two together, a merge commit. Such a commit has special properties, such as having two parents, and being the result of the unification of two separate branches.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, if you’re not doing just a simple fast forward, either a rebase-ff or
merge may require that you solve potential code conflicts. For instance, someone
may have changed a line that you have also changed, leading to the two versions colliding. For the merge, you resolve this by making the merge commit define the merged version, for a rebase, you’ll go through your changes and adjust them so they fit cleanly onto the branch you’re pulling.&lt;&#x2F;p&gt;
&lt;p&gt;One important difference to note for us, is between the two, merging into main
typically gets done by the maintainer, where as rebasing gets done by the
developer working on the feature branch.&lt;&#x2F;p&gt;
&lt;p&gt;Rebasing also has some downsides. For example, if the person rebasing doesn’t
have the PGP private key of the people who’s commit are included in the rebase,
they cannot sign the commits. This means that if Alice made 3 commits and signed
them with her PGP signature, Bob can’t later rebase those changes onto some
other commit without breaking that signature. This is because, while the code
doesn’t change, the commit revision does, and so the signature is wrong.&lt;&#x2F;p&gt;
&lt;p&gt;Merging does not have this issue, as a merge is simply the actual merge commit,
containing the new state of the branch, that potentially specifies how to
rearrange everything so as to not cause any conflicts. Thus it doesn’t suffer
from breaking the signatures.&lt;&#x2F;p&gt;
&lt;p&gt;Now, if you’re using rebase for merges into main, as we do in eza, you may still
want a signature verifying that a trusted person has indeed verified these
changes are up to whatever standard they guarantee (eza at best guarantees that
it runs on my linux box that you should be able to install it on NixOS&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;[2]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;). The
way we solve this is by tagging all our releases with a signed tag, making sure
you know that I’ve personally said that this is the codebase I want you to run
for a given release.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;git-merge-rebase&#x2F;signed-tags.png&quot; alt=&quot;Signed tag&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But even then, it’s coping. It’s not as nice as having a tree full of the
signatures of everyone that’s committed, right on their commits.&lt;&#x2F;p&gt;
&lt;p&gt;Another point raised against rebases is they rewrite history. This is true,
unlike a merge that just merges two branches and keeps both in history, the
rebase will make it appear as thou the feature branch was developed on top of
the main branch. I don’t personally think this is a huge concern, except the
loss of potential pretty &lt;code&gt;git log --graph&lt;&#x2F;code&gt; outputs.&lt;&#x2F;p&gt;
&lt;p&gt;One of the annoyances of merges, in comparison, is that they’re very noisy.
Consider this output from nixpkgs:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; log&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;oneline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;bfb7a882678e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;314109 from trofi&#x2F;githooks.tests-fix-eval&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;47bdef656cc5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;311260 from purepani&#x2F;update-svelte-language-tools&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fc165a03b23a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309524 from r-ryantm&#x2F;auto-update&#x2F;enet&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;3de810d52cbe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309724 from r-ryantm&#x2F;auto-update&#x2F;secp256k1&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;1d6a2f5a4d4d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309787 from r-ryantm&#x2F;auto-update&#x2F;python311Packages.minio&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;a36fa5451c44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309426 from Rconybea&#x2F;add-sphinxcontrib-ditaa&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;890f8e436a56&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309476 from r-ryantm&#x2F;auto-update&#x2F;goperf&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;dfa36c1d67f5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;312557 from r-ryantm&#x2F;auto-update&#x2F;intune-portal&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;7d8ed5ce921d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;291853 from greaka&#x2F;grafana&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;d0a20d7c5955&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;314112 from khaneliman&#x2F;bicep&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;4d2462511f06&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;314099 from mrkline&#x2F;snapper-and-borgbackup-doc-fix&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;3e3ac0e7baa8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;305516 from OPNA2608&#x2F;init&#x2F;lomiri&#x2F;ayatana-indicator-display&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;a46ce7c77d9d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; svelte-language-server: convert to buildNpmPackage&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;7962cbb2326b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;314082 from superherointj&#x2F;bicep-0.27.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;5771dbfa7d2f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bicep: fix updater script&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;2db4e7d035f8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;313729 from pluiedev&#x2F;zhf-24.05&#x2F;gobang&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;44744fc83f3c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; githooks.tests: fix eval&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;0f3add331c6a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; segger-jlink: 794l -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;796&lt;&#x2F;span&gt;b&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This… isn’t nice, and makes history way harder to read. Compare to eza:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; log&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;oneline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;22dbeec2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (HEAD -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; main, origin&#x2F;main, origin&#x2F;HEAD&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump libc from 0.2.154 to 0.2.155&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;82e4f0f3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump trycmd from 0.15.1 to 0.15.2&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;bbede6d4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (tag: v0.18.16&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chore:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; release eza v0.18.16&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;70891fa1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs(README&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; use 3 columns for packaging status badge&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;e8e0b6da&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix: change windows-only imports to be windows-only&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;15528d8b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs(install&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix typo in &lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;INSTALL.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;26e5943a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs: update INSTALL.md&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;20241984&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump DeterminateSystems&#x2F;nix-installer-action from 10 to 11&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;feff970d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs(man&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; replace decay with color-scale&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;a1c36389&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump DeterminateSystems&#x2F;flake-checker-action from 5 to 7&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;7437c2a1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (tag: v0.18.15&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chore:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; release eza v0.18.15&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;f1ef455b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; feat(devtools&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; add optional tag argument to deb-package.sh&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;23502d3c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix(devtools&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; correct command for latest tag in deb-package.sh&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;292cf7ec&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; feat(devtools&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; return to original commit at the end of deb-package.sh&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;4f542eaf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs(reaedme&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; add some keywords for benefit of ctrl-f&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;6d6612d2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs(readme&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; move heading out of collapsed section&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;abe9f587&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs(readme&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; correct heading levels in markdown&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;01a9c2aa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; docs(readme&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; add how to find man pages in terminal and online. Partly fixes &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;967&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;f78e4bb6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (tag: v0.18.14&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chore:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; release eza v0.18.14&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;01919cdd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump palette from 0.7.5 to 0.7.6&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;414f70ba&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump unicode-width from 0.1.11 to 0.1.12&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;1554472a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump libc from 0.2.153 to 0.2.154&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;bebd39c0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build(deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bump uzers from 0.11.3 to 0.12.0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;df7d51fc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; feat: add icon for &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;cron.minutely&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; directory&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;8b7dc5f5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (tag: v0.18.13&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chore:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; release eza v0.18.13&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;c0df8ecd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; feat: generate completion&#x2F;manpage tarballs on release&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;8afb5cc2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (tag: v0.18.12&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fix:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; checking for deref flag in file_name&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;a4782d1d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; feat: add scheme filetype and icons&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;87b36785&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix: allow unused imports for freebsd&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;99562e3a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (tag: v0.18.11&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chore:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; release eza v0.18.11&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;07f67708&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix: build aarch64, arm without libgit2&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;17733e9a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix(netbsd&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; enable the rule only for NetBSD.&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;7664a1fb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ci: bump NetBSD version to 10.0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;462fc344&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix(netbsd&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix clippy lints&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;75f1f8cf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; (tag: v0.18.10&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chore:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; release eza v0.18.10&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Isn’t that a lot nicer? I think so.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, what may be lost is that it’s no longer obvious from what PR a change
originated. It also isn’t obvious to me when some feature branch was created,
how long it was worked on and so on. This isn’t… really that important either,
but it’s nice to have in logs. But you can just look at branches if you need to
know this for tooling or something.&lt;&#x2F;p&gt;
&lt;p&gt;For nixpkgs, you get a to have a visual overview of how branches end up in main.
It looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; log&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;oneline&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;graph&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 4d4571b20a29 (HEAD -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; devpi-loadcredential&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;nixos&#x2F;devpi-server:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; fix loading credentials as DynamicUser&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   bfb7a882678e Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;314109 from trofi&#x2F;githooks.tests-fix-eval&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 44744fc83f3c githooks.tests: fix eval&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;47bdef656cc5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;311260 from purepani&#x2F;update-svelte-language-tools&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;a46ce7c77d9d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; svelte-language-server: convert to buildNpmPackage&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fc165a03b23a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309524 from r-ryantm&#x2F;auto-update&#x2F;enet&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;8e729c70a119&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; enet: 1.3.17 -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1&lt;&#x2F;span&gt;.3.18&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;3de810d52cbe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309724 from r-ryantm&#x2F;auto-update&#x2F;secp256k1&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;f96a90834c5e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; secp256k1: 0.4.1 -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;0&lt;&#x2F;span&gt;.5.0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;1d6a2f5a4d4d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309787 from r-ryantm&#x2F;auto-update&#x2F;python311Packages.minio&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;24d453186792&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; python311Packages.minio: 7.2.6 -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;7&lt;&#x2F;span&gt;.2.7&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;a36fa5451c44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309426 from Rconybea&#x2F;add-sphinxcontrib-ditaa&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;197d6261ebf8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; python311Packages.sphinxcontrib-ditaa: init at 1.0.2&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;51de558f5634&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; maintainers: add rconybea&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;890f8e436a56&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;309476 from r-ryantm&#x2F;auto-update&#x2F;goperf&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;8eea66b3f69a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; goperf: 0-unstable-2023-11-08 -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;0&lt;&#x2F;span&gt;-unstable-2024-05-10&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;dfa36c1d67f5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;312557 from r-ryantm&#x2F;auto-update&#x2F;intune-portal&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;010c4a334eaf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; intune-portal: 1.2404.23-jammy -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1&lt;&#x2F;span&gt;.2404.25-jammy&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;7d8ed5ce921d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;291853 from greaka&#x2F;grafana&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\ &lt;&#x2F;span&gt;\&lt;span class=&quot;z-invalid z-illegal z-extraneous-spaces-after-line-continuation z-shell&quot;&gt;  &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;254dbdcc6296&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; grafanaPlugins.grafana-oncall-app: init at 1.5.1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;0e5f44658ee6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; maintainers&#x2F;team-list: add fslabs&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;8d6f8c9ed75a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; maintainers: add lpostula&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;7bda925dacb2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; maintainers: add greaka&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;d0a20d7c5955&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Merge pull request &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;314112 from khaneliman&#x2F;bicep&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another problem worth considering is that a rebase may — as
&lt;a href=&quot;https:&#x2F;&#x2F;astrid.tech&quot;&gt;Astrid&lt;&#x2F;a&gt; pointed out — results in main being in a state
where a &lt;code&gt;git bisect&lt;&#x2F;code&gt; of a build command may fail, if you haven’t ensured that
all commits in the feature branch still worked after being rebased on top of the
latest main.&lt;&#x2F;p&gt;
&lt;p&gt;Now this is rare, but rare isn’t really a good argument for not caring here, as
breaking once would be extremely annoying for people working on a bugfix,
leading to false &lt;code&gt;git dissect&lt;&#x2F;code&gt; positives.&lt;&#x2F;p&gt;
&lt;p&gt;There are solutions to this. You could (perhaps) have each commit in a branch
run against CI. This may be outside of your compute budget thou. Another option
is to run your build command, e.g. &lt;code&gt;cargo build&lt;&#x2F;code&gt; on each commit after a rebase,
but then, this kind of checking step usually falls on the maintainer, and we, as
maintainers, should seek to limit our own burdens as much as possible (to
prevent burnout&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;[3]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, the killer of most FOSS projects).&lt;&#x2F;p&gt;
&lt;p&gt;To eza, this isn’t fatal, but a very interesting point worth keeping in mind.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;updating-a-branch&quot;&gt;Updating a branch&lt;&#x2F;h2&gt;
&lt;p&gt;Of course, since there may be multiple people all working on separate branches,
there is another problem. One person might have worked on something, at the same
time as you worked on something else, and then gotten their changes merged
before you had a chance. But if that happens, your changes might now conflict
with what was in the main branch when you started, and worse, their changes may
make ruin your work, or even make it unable to compile!&lt;&#x2F;p&gt;
&lt;p&gt;The first choice a project should make, is whether or not to allow outdated
feature branches to be merged. The problem with tolerating outdated branches is
you will not be able to fix any problems related to integrating the code with
the main codebase before merging it. This puts the burden of ensuring the code
works on the maintainer, rather than the developer, and this is bad!&lt;&#x2F;p&gt;
&lt;p&gt;If you do choose to not allow this, another question faces you: how should the
main branch be merged into the feature branch when the feature branch is out of
date with the main branch.&lt;&#x2F;p&gt;
&lt;p&gt;Your options are either to merge the main branch into your feature branch, or to
rebase your changes on top of main, making it like if you had started working on
the latest changes.&lt;&#x2F;p&gt;
&lt;p&gt;To me, it’s a more simple dilemma, merges shouldn’t exist if they don’t
meaningfully represent merging two things together. Simply updating your branch
is what rebase does best, and having merges both from feature branches into main
and from main into your feature branch is absolutely tasteless. This clutters
your history for no reason. It also makes it harder for you to fix your commits
when the reviewer tells you that you had a faulty commit 3 commits before you
merged main into your feature branch and kept working for 4 more commits.&lt;&#x2F;p&gt;
&lt;p&gt;In general, rebasing with merge commits is tedious, and we only consider merges
viable for the main branch under the premise that we won’t later need to rebase
main, because everything that gets into main is in a state of being up to
standard.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly, code forges lack a feature to only allow updating branches with the
projects  preferred standard, unlike for merges where rebase, squash, and merge
are all options, that all can be disabled by the repositories owner(s).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;So what where the tradeoffs?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Merging feature branches into main
&lt;ul&gt;
&lt;li&gt;Merges.
&lt;ul&gt;
&lt;li&gt;Preserves history.&lt;&#x2F;li&gt;
&lt;li&gt;Gives you &lt;code&gt;git log --graph&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Doesn’t break PGP signatures.&lt;&#x2F;li&gt;
&lt;li&gt;Creates ugly &lt;code&gt;git log&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Gives weak protection that all commits build (if you have CI)&lt;&#x2F;li&gt;
&lt;li&gt;Puts burden of verification on maintainer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Rebase.
&lt;ul&gt;
&lt;li&gt;Rewrites history.&lt;&#x2F;li&gt;
&lt;li&gt;No &lt;code&gt;git log --graph&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Breaks PGP signatures.&lt;&#x2F;li&gt;
&lt;li&gt;Creates useful &lt;code&gt;git log&lt;&#x2F;code&gt; output.&lt;&#x2F;li&gt;
&lt;li&gt;Needs more care if you want all commits to be validated.&lt;&#x2F;li&gt;
&lt;li&gt;Puts burden of verification on committer (mostly).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Fast Forward.
&lt;ul&gt;
&lt;li&gt;Like a rebase, but with less drawback.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Updating your feature branch.
&lt;ul&gt;
&lt;li&gt;Merges.
&lt;ul&gt;
&lt;li&gt;merges make &lt;code&gt;git rebase -i&lt;&#x2F;code&gt; difficult, when asked to change your commits.&lt;&#x2F;li&gt;
&lt;li&gt;It makes your &lt;code&gt;git log&lt;&#x2F;code&gt; unreadable.&lt;&#x2F;li&gt;
&lt;li&gt;Doesn’t provide any benefits.&lt;&#x2F;li&gt;
&lt;li&gt;Mostly just a quirk that git even allows this, it doesn’t make sense.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Rebase.
&lt;ul&gt;
&lt;li&gt;The preffered choice.&lt;&#x2F;li&gt;
&lt;li&gt;Fits like a glove for updating your feature branch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As a maintainer, remember that what where really trying to do if offload any
non-maintainer burdens onto relavant roles, like developers and reviewers. We
may wear multiple hats, often we are the final reviewers, but even then, it
shouldn’t be our job to ensure a clean merge, we should meerly verify it.&lt;&#x2F;p&gt;
&lt;p&gt;The main goal is always: maintainers shouldn’t need to fix the feature branch!&lt;&#x2F;p&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;This also applies for formatters. I personally mostly use alejandra for nix, but dayjob uses nixfmt (the RFC 166 version). I just hit a format button before commiting anyways, so it’s just cool to see the different options and feel out which ones I truly prefer. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Because I don’t have any MacOS, Windows, or BSD boxes to test on, and we don’t have any maintainers that do with the spoons to be involved in giving such guarantees. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;Consider reading this excellent resource &lt;a href=&quot;https:&#x2F;&#x2F;opensource.guide&#x2F;maintaining-balance-for-open-source-maintainers&#x2F;&quot;&gt;https:&#x2F;&#x2F;opensource.guide&#x2F;maintaining-balance-for-open-source-maintainers&#x2F;&lt;&#x2F;a&gt;, and this mozilla worksheet &lt;a href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1esQQBJXQi1x_-1AcRVPiCRAEQYO4Qlvali0ylCvKa_s&#x2F;edit?pli=1#heading=h.xd8n2v3f4866&quot;&gt;https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1esQQBJXQi1x_-1AcRVPiCRAEQYO4Qlvali0ylCvKa_s&#x2F;edit?pli=1#heading=h.xd8n2v3f4866&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Grok Git Repos</title>
          <pubDate>Wed, 15 May 2024 00:00:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/grok-git-repos/</link>
          <guid>https://point.free/blog/grok-git-repos/</guid>
          <description xml:base="https://point.free/blog/grok-git-repos/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;Git is often perceived as a necessary evil, a tool to be tolerated rather than mastered.&lt;&#x2F;p&gt;
&lt;p&gt;But treating your primary work tool as a mystery is a vulnerability. When the abstraction leaks — and it always does — the developer who understands the internals can surgically repair the damage. In contrast, those who rely on surface-level knowledge often leave behind a sloppy timeline. A history riddled with vague messages and botched merges signals a lack of care that code quality alone cannot hide.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, we often learn git through folklore — memorizing obscure commands to save us when things go wrong, without understanding why they work. We rely on luck rather than logic.&lt;&#x2F;p&gt;
&lt;p&gt;To escape this ritualistic dependency, we must strip away the interface. To truly &lt;em&gt;grok&lt;&#x2F;em&gt; git, we will ignore the high-level commands and build a repository from the ground up, proving that the magic is actually just simple, elegant engineering.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;creating-a-git-repository-from-scratch&quot;&gt;Creating a Git Repository from Scratch&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s create a folder for us to work in.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; mkdir grok&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; cd grok&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, we have a folder. A folder isn&#x27;t a git repository, as we can
verify.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fatal:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; not a git repository (or any of the parent directories&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As the &lt;code&gt;status&lt;&#x2F;code&gt; subcommand tells us, neither is the directory
we currently created, of any of it parent directories a git repository.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;If that wasn&#x27;t the case for you, that would be because you created
the folder &lt;code&gt;grok&lt;&#x2F;code&gt; as a subdirectory of a git repository.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The error seems to mention a &lt;code&gt;.git&lt;&#x2F;code&gt; folder. Turns out, when
speaking of a git repository, we are actually referring to this folder
in most cases&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. So, in theory, it should be simple enough to create a
git repository right, just create a &lt;code&gt;.git&lt;&#x2F;code&gt; folder and we are
good to go?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; mkdir .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fatal:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; not a git repository (or any of the parent directories&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ohh, apparently not so.&lt;&#x2F;p&gt;
&lt;p&gt;If we were to look up the definition of a &lt;em&gt;repository&lt;&#x2F;em&gt; in the git
&lt;a href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;gitglossary#Documentation&#x2F;gitglossary.txt-aiddefrepositoryarepository&quot;&gt;glossary&lt;&#x2F;a&gt;,
we would see the following.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A collection of refs together with an object database containing all
objects which are reachable from the refs, possibly accompanied by
meta data from one or more porcelains. A repository can share an
object database with other repositories via alternates mechanism.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Ahh, simple. Seems like we need to have some refs and an object database
with all the objects refs can reach. Also, there might be meta data from
porcelains?&lt;&#x2F;p&gt;
&lt;p&gt;Although the definition may seem complex, the underlying concept is straightforward. Rather than summarizing it briefly, we will demonstrate its simplicity through a practical, step-by-step example.&lt;&#x2F;p&gt;
&lt;p&gt;First, we need an &lt;em&gt;object database&lt;&#x2F;em&gt;. Well, database sounds a bit hard,
we could just make a folder for it instead in our git repository.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; mkdir .git&#x2F;objects&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, we also need a &lt;em&gt;collection of refs&lt;&#x2F;em&gt;. No issue, just make a folder
for them.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; mkdir&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; .git&#x2F;refs&#x2F;heads&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What are heads? Don&#x27;t worry, we&#x27;ll get to it. Now we have the bare
minimum for a repository thou, right?&lt;&#x2F;p&gt;
&lt;p&gt;Well, let&#x27;s try to find out!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fatal:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; not a git repository (or any of the parent directories&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It appears we are missing a critical component.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; echo &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ref: refs&#x2F;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; .git&#x2F;HEAD&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, is this finally a repository? Let&#x27;s see what git thinks the status
is.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;On&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; branch main&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;No&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commits yet&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;nothing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; to commit (create&#x2F;copy files and use &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git add&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; to track&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Seems like it is! …So now we have a git repository, that was &lt;em&gt;easy&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;committing-to-a-repository&quot;&gt;Committing to a Repository&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;creating-objects&quot;&gt;Creating Objects&lt;&#x2F;h2&gt;
&lt;p&gt;While creating a git repository manually is an interesting exercise, it is of little value unless we can populate it with files.&lt;&#x2F;p&gt;
&lt;p&gt;We likely will want to fill this repository with text files. For the
occasion, you can use fortune to generate something, but if you use what
I got, you&#x27;ll be able to compare your hashes to the ones in the
article.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;If a listener nods his head when you&#x27;re explaining your program,
wake him up.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That is very wise indeed. We want to add this to the repository. But
how?&lt;&#x2F;p&gt;
&lt;p&gt;Well, one way to add it is the following, using the git
&lt;code&gt;hash-object&lt;&#x2F;code&gt; subcommand.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ echo &amp;quot;If a listener nods his head when you&amp;#39;re explaining your program, wake him up.&amp;quot; | git hash-object --stdin -w
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;665e95f1674e9466cb429bdfebaf1b8792ef0eec
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Okay, two questions now. What is
&lt;code&gt;665e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;code&gt;, and what did
&lt;code&gt;hash-object&lt;&#x2F;code&gt; just do?&lt;&#x2F;p&gt;
&lt;p&gt;We can inspect the git repository to investigate. Examining the directory tree structure provides some insight.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; tree .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.git&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; HEAD&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; objects&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   └── 66&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;       └── 5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; refs&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; heads&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; directories, 2 files&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here, we see that our object “database” in the objetcs folder has seen
some change. There is a folder, &lt;code&gt;66&lt;&#x2F;code&gt;, with a file that has an
equally vexing name,
&lt;code&gt;5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I wonder what is in this file. Let&#x27;s try to take a look at it.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; cat .git&#x2F;objects&#x2F;66&#x2F;5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;WKX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;Y&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   &lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;݆!rB-8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;}&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;ɢ,xSOŋE598&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;}&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;y?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;                            &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-job z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-job z-shell&quot;&gt;%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The file does not contain plain text; it appears to be in a binary format. We can use the &lt;code&gt;file&lt;&#x2F;code&gt; command to determine its type.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; file .git&#x2F;objects&#x2F;66&#x2F;5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.git&#x2F;objects&#x2F;66&#x2F;5e95f1674e9466cb429bdfebaf1b8792ef0eec:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; zlib compressed data&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Apparently, it&#x27;s some data compressed with zlib. That means it&#x27;s
likely DEFLATE compressed (RFC 1951) in a zlib wrapper (RFC 1950)&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;[2]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There is actually a neat hack we can use to view this data&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;[3]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; printf &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;\x1f\x8b\x08\x00\x00\x00\x00\x00&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; - .git&#x2F;objects&#x2F;66&#x2F;5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;gzip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;dc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;blob&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 78If a listener nods his head when you&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;re explaining your program, wake him up.
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;gzip: stdin: unexpected end of file
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We have located our string. The output begins with &lt;code&gt;blob&lt;&#x2F;code&gt;, which specifies the git object’s file type, followed by &lt;code&gt;78&lt;&#x2F;code&gt;, indicating the blob’s size in bytes&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-1&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;[4]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Objects in git have 3 primary types:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;blob&lt;&#x2F;li&gt;
&lt;li&gt;tree&lt;&#x2F;li&gt;
&lt;li&gt;commit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When we ran the &lt;code&gt;hash-object&lt;&#x2F;code&gt; subcommand, we created a blob.
Regarding the name, that is just the sha1 hash (RFC 3174) of the object,
and some other metadata and such&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-5-1&quot;&gt;&lt;a href=&quot;#fn-5&quot;&gt;[5]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. The actual output of the command
was this hash. It is 40 characters long.&lt;&#x2F;p&gt;
&lt;p&gt;The name of the directory in the object database is the first two
characters of the hash, that is &lt;code&gt;66&lt;&#x2F;code&gt;, and the actual object
files name is the 38 other characters.&lt;&#x2F;p&gt;
&lt;p&gt;Manually decompressing objects for inspection is inefficient. Instead, we can use the hash &lt;code&gt;665e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;code&gt; to inspect the newly created object.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inspecting-objects&quot;&gt;Inspecting Objects&lt;&#x2F;h2&gt;
&lt;p&gt;We do this with the &lt;code&gt;git cat-file&lt;&#x2F;code&gt; subcommand. To see the
file type of an object, we use the type flag &lt;code&gt;-t&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; 665e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;blob&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That means that the type (&lt;code&gt;-t&lt;&#x2F;code&gt;) of the object we made is a
blob, as we saw by inspecting it. What if we wanna see the contents of
the blob? We use &lt;code&gt;-p&lt;&#x2F;code&gt; for print.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; 665e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;If&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; a listener nods his head when you&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;re explaining your program, wake him up.
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This procedure is significantly more convenient than the manual decompression hack used earlier.&lt;&#x2F;p&gt;
&lt;p&gt;Also, another useful flag to know is &lt;code&gt;-s&lt;&#x2F;code&gt;, for size.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;s&lt;&#x2F;span&gt; 665e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;78&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This matches the &lt;code&gt;78&lt;&#x2F;code&gt; observed earlier, confirming the object size in bytes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;index&quot;&gt;Index&lt;&#x2F;h2&gt;
&lt;p&gt;Okay, enough about the blob. It seems like we have added an object –
with some text – into the git repository now. We might wonder if this
is reflected in the &lt;code&gt;git status&lt;&#x2F;code&gt; of the repo.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;On&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; branch main&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;No&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commits yet&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;nothing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; to commit (create&#x2F;copy files and use &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git add&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; to track&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Adding an object to the database stores the data, but it does not tell git where that file belongs in your project. This is the purpose of the &lt;strong&gt;index&lt;&#x2F;strong&gt; (or staging area): to build the tree structure for the next commit. Without being registered in the index, our blob is essentially a “loose” object. If it remains unreferenced, it will eventually be removed by &lt;code&gt;git gc&lt;&#x2F;code&gt; (garbage collection).&lt;&#x2F;p&gt;
&lt;p&gt;To actually commit our object, we must first register it in the index.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; update-index&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;cacheinfo&lt;&#x2F;span&gt; 100633 665e95f1674e9466cb429bdfebaf1b8792ef0eec truth.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The long string is the hash of the blob object we created, and
&lt;code&gt;truth.txt&lt;&#x2F;code&gt; is a fitting filename.&lt;&#x2F;p&gt;
&lt;p&gt;What about &lt;code&gt;100633&lt;&#x2F;code&gt;? Looking at
&lt;code&gt;man git update-index&lt;&#x2F;code&gt; we see that…&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;--cacheinfo &amp;lt;mode&amp;gt;,&amp;lt;object&amp;gt;,&amp;lt;path&amp;gt;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;--cacheinfo &amp;lt;mode&amp;gt; &amp;lt;object&amp;gt; &amp;lt;path&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Directly insert the specified info into the index.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;For backward compatibility, you can also give these
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;three arguments as three separate parameters, but
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;new users are encouraged to use a single-parameter
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;form.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Although the documentation suggests the single-parameter form for new users, we have used the separate parameter form here for clarity. The value &lt;code&gt;100633&lt;&#x2F;code&gt; is the mode of the file. In git, this mode is a 6-digit octal number that defines the file type and permissions, similar to standard UNIX file modes but restricted to a few specific values.&lt;&#x2F;p&gt;
&lt;p&gt;But crucially, for blobs in git, we only have 3 modes available&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-6-1&quot;&gt;&lt;a href=&quot;#fn-6&quot;&gt;[6]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;100644 a normal file&lt;&#x2F;li&gt;
&lt;li&gt;100755 a executable file&lt;&#x2F;li&gt;
&lt;li&gt;120000 a symbolic link&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Let&#x27;s take a look at the repo structure again.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; tree .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.git&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; HEAD&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; objects&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   └── 66&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;       └── 5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; refs&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; heads&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; directories, 3 files&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here we notice that there now is an &lt;code&gt;index&lt;&#x2F;code&gt; file. So all we
did was add some index &lt;code&gt;file&lt;&#x2F;code&gt;? …well, slow down. Let&#x27;s do
a sanity check with &lt;code&gt;git status&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;On&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; branch main&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;No&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commits yet&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;Changes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; to be committed:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-compound z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;use&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git rm --cached &amp;lt;file&amp;gt;...&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; to unstage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-compound z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; file:   truth.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;Changes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; not staged for commit:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-compound z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;use&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git add&#x2F;rm &amp;lt;file&amp;gt;...&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; to update what will be committed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-compound z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-compound z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;use&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git restore &amp;lt;file&amp;gt;...&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; to discard changes in working directory&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-compound z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;deleted:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;    truth.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Aha!&lt;&#x2F;p&gt;
&lt;p&gt;So we did something, we staged (added) the truth.txt file… but we also
have unstaged changes saying we deleted it?&lt;&#x2F;p&gt;
&lt;p&gt;Well, yes. We have told git that the blob object we created is in the
working-&lt;em&gt;tree&lt;&#x2F;em&gt;, and it has the actual blob for this in its object
database… but apparently can&#x27;t find the file we told it about. This
makes sense, since we just created the blob from stdin and didn&#x27;t
actually add any files.&lt;&#x2F;p&gt;
&lt;p&gt;Because the file exists in the index but is missing from the actual working directory, git correctly assumes it has been removed.&lt;&#x2F;p&gt;
&lt;p&gt;Hmm, while we are at it, let&#x27;s take a look at &lt;code&gt;.git&#x2F;index&lt;&#x2F;code&gt;,
just to see what that is about.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; cat .git&#x2F;index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;DIRCf^gNfB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;  truth.txtqblr33il&lt;span class=&quot;z-meta z-group z-expansion z-job z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-job z-shell&quot;&gt;%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This confirms it is not a text file. We can verify its type using the &lt;code&gt;file&lt;&#x2F;code&gt; command.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; file .git&#x2F;index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.git&#x2F;index:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Git index, version 2, 1 entries&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The output identifies it as a &lt;code&gt;Git index, version 2&lt;&#x2F;code&gt; with &lt;code&gt;1 entries&lt;&#x2F;code&gt;. This single entry corresponds to the file we just added. To see what this actually looks like on disk, we can inspect the raw binary data.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; hexdump&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;C&lt;&#x2F;span&gt; .git&#x2F;index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 49 52 43 00 00 00 02  00 00 00 01 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;DIRC............&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 81 a4  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 66 5e 95 f1  67 4e 94 66 cb 42 9b df&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;....f^..gN.f.B..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;eb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; af 1b 87 92 ef 0e ec  00 09 74 72 75 74 68 2e&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;..........truth.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 78 74 00 c1 b9 71 62  b4 ab c1 c2 6c 72 33 33&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;txt...qb....lr33&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;92&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 69 92 99 ac 6c 8e ff&lt;&#x2F;span&gt;                           &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.i...l..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(I removed the offset from the output)&lt;&#x2F;p&gt;
&lt;p&gt;The first 4 bytes, &lt;code&gt;DIRC&lt;&#x2F;code&gt;, are the “magic number” — a constant value used to identify the file format (short for “Directory Cache”). Following some padding bytes&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-7-1&quot;&gt;&lt;a href=&quot;#fn-7&quot;&gt;[7]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, the &lt;code&gt;02&lt;&#x2F;code&gt; indicates the version number. The rest of the file contains the entry data, including the filename &lt;code&gt;truth.txt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If we were to add another file, likely patterns would emerge in the binary structure. Investigating how the index looks in a larger project is an excellent way to learn more, so I have included it in the &lt;em&gt;Exercises&lt;&#x2F;em&gt; section below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tree-objects&quot;&gt;Tree Objects&lt;&#x2F;h2&gt;
&lt;p&gt;Back on track, we&#x27;ve now made the index thingy, and we&#x27;ll have to
write it with the &lt;code&gt;write-tree&lt;&#x2F;code&gt; subcommand.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git write-tree&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;a6325f064bac723691f20c0b1ed2bea82a1728fd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;git status&lt;&#x2F;code&gt; does not seem to have changed, but if we check
what&#x27;s in repo&#x27;s file structure, we&#x27;ll see something did change.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;  tree .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; HEAD&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; objects&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   ├── 66&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   │   └── 5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   └── a6&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;       └── 325f064bac723691f20c0b1ed2bea82a1728fd&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; refs&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; heads&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; directories, 4 files&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We notice the &lt;code&gt;a6325f064bac723691f20c0b1ed2bea82a1728fd&lt;&#x2F;code&gt;
sha-1 hash refers to a new object. Interesting, wonder what this is.&lt;&#x2F;p&gt;
&lt;p&gt;To thoroughly understand this object, we will inspect it manually by examining the raw file. This is the “hard way,” but it offers the most insight into the underlying data structure.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; file .git&#x2F;objects&#x2F;a6&#x2F;325f064bac723691f20c0b1ed2bea82a1728fd&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.git&#x2F;objects&#x2F;a6&#x2F;325f064bac723691f20c0b1ed2bea82a1728fd:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; zlib compressed data&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Okay, that&#x27;s zlib compressed data. We know that, so let&#x27;s use that
same hack to figure out what is inside of this blob.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; printf &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;\x1f\x8b\x08\x00\x00\x00\x00\x00&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; - .git&#x2F;objects&#x2F;a6&#x2F;325f064bac723691f20c0b1ed2bea82a1728fd&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;gzip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;dc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 37100644 truth.txtf^gNfB&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;gzip:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; stdin: unexpected end of file&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This object is not a blob, but a &lt;em&gt;tree&lt;&#x2F;em&gt; — one of the three primary git object types. The number &lt;code&gt;37100644&lt;&#x2F;code&gt; initially appears confusing, but it is actually two separate values concatenated: the size (&lt;code&gt;37&lt;&#x2F;code&gt; bytes) and the file mode (&lt;code&gt;100644&lt;&#x2F;code&gt;). Following this are the filename and a binary sequence &lt;code&gt;f^gNfB&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The sequence &lt;code&gt;f^gNfB&lt;&#x2F;code&gt; matches data we previously observed in the &lt;code&gt;hexdump&lt;&#x2F;code&gt; of the &lt;code&gt;.git&#x2F;index&lt;&#x2F;code&gt; file. Identifying its specific purpose is left as an exercise for the reader.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s look at the contents the canonical way.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; a6325f064bac723691f20c0b1ed2bea82a1728fd&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;100644&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; blob 665e95f1674e9466cb429bdfebaf1b8792ef0eec    truth.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;an-experiment-with-tree-objects&quot;&gt;An Experiment with Tree Objects&lt;&#x2F;h2&gt;
&lt;p&gt;An important concept to explore is how a tree object handles multiple files. To demonstrate this, we will create another blob.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; echo &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;AMOGUS&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; hash-object&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;stdin&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;w&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;f58617716d903fb842b5606a335ff1406b9a21d3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And add it to our index file.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git update-index&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;cacheinfo&lt;&#x2F;span&gt; 100633 f58617716d903fb842b5606a335ff1406b9a21d3 amogus.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, let&#x27;s look at the repository. We have 3 objects in our objects
database.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; tree .git&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; HEAD&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;├──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; objects&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   ├── 66&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   │   └── 5e95f1674e9466cb429bdfebaf1b8792ef0eec&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   ├── a6&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   │   └── 325f064bac723691f20c0b1ed2bea82a1728fd&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   └── f5&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;       └── 8617716d903fb842b5606a335ff1406b9a21d3&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; refs&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;└──&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; heads&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; directories, 5 files&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s dump the index binary.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; hexdump&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;C&lt;&#x2F;span&gt; .git&#x2F;index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 49 52 43 00 00 00 02  00 00 00 02 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;DIRC............&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 81 a4  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 f5 86 17 71  6d 90 3f b8 42 b5 60 6a&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.......qm.?.B.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;j&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;33&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 5f f1 40 6b 9a 21 d3  00 0a 61 6d 6f 67 75 73&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;3_.@k.!...amogus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;2e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 74 78 74 00 00 00 00  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.txt............&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 81 a4  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 66 5e 95 f1  67 4e 94 66 cb 42 9b df&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;....f^..gN.f.B..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;eb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; af 1b 87 92 ef 0e ec  00 09 74 72 75 74 68 2e&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;..........truth.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 78 74 00 54 52 45 45  00 00 00 06 00 2d 31 20&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;txt.TREE.....-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 0a 94 c6 2b 91 4b 84  9d 9a 2e 3c 20 e4 3e 93&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;0...+.K....&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; .&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;1b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 69 3f 19 3d bd&lt;&#x2F;span&gt;                                 &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;.i?.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nothing too spectacular here, we notice that we see both amogus.txt and
truth.txt. We also see TREE at the end of the file, that must be our
tree object.&lt;&#x2F;p&gt;
&lt;p&gt;However, what happens when we run &lt;code&gt;write-tree&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git write-tree&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;aee76412ed220742aeaf02ca1c50519bcea013e1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s dump the index again.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; hexdump&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;C&lt;&#x2F;span&gt; .git&#x2F;index&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 49 52 43 00 00 00 02  00 00 00 02 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;DIRC............&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 81 a4  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 f5 86 17 71  6d 90 3f b8 42 b5 60 6a&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.......qm.?.B.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;j&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;33&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 5f f1 40 6b 9a 21 d3  00 0a 61 6d 6f 67 75 73&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;3_.@k.!...amogus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;2e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 74 78 74 00 00 00 00  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.txt............&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 00 00 81 a4  00 00 00 00 00 00 00 00&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;................&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 00 00 00 66 5e 95 f1  67 4e 94 66 cb 42 9b df&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;....f^..gN.f.B..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;eb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; af 1b 87 92 ef 0e ec  00 09 74 72 75 74 68 2e&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;..........truth.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 78 74 00 54 52 45 45  00 00 00 19 00 32 20 30&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;txt.TREE.....2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;0a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ae e7 64 12 ed 22 07  42 ae af 02 ca 1c 50 51&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;...d..&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;.B.....PQ|
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;9b ce a0 13 e1 07 2b 99  c5 b6 0e 3d 53 33 c9 21  |......+....=S3.!|
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;dd b1 75 41 41 84 b1 d8  ec                       |..uAA....|
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The data following the &lt;code&gt;TREE&lt;&#x2F;code&gt; identifier has increased in size. We will now inspect the contents of this newly written tree.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; aee76412ed220742aeaf02ca1c50519bcea013e1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;100644&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; blob f58617716d903fb842b5606a335ff1406b9a21d3    amogus.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;100644&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; blob 665e95f1674e9466cb429bdfebaf1b8792ef0eec    truth.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we seem to have two files inside of the tree.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;time-to-commit&quot;&gt;Time to Commit&lt;&#x2F;h2&gt;
&lt;p&gt;So now, it&#x27;s time to create a commit. Above, when we did write tree, we
created the &lt;code&gt;tree&lt;&#x2F;code&gt; object
&lt;code&gt;aee76412ed220742aeaf02ca1c50519bcea013e1&lt;&#x2F;code&gt;. This includes
both of the blobs we made.&lt;&#x2F;p&gt;
&lt;p&gt;So how do we commit that? It&#x27;s actually really simple, we just use &lt;code&gt;git commit-tree&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commit-tree aee76412ed220742aeaf02ca1c50519bcea013e1&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;m&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;initial commit&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;87a1aa833dccca5ea503e9a7ff81c51fe82c85c6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we now look at the &lt;code&gt;.git&lt;&#x2F;code&gt; repository, we will see a new
object, &lt;code&gt;87a1aa833dccca5ea503e9a7ff81c51fe82c85c6&lt;&#x2F;code&gt; created.
We can verify the type of this new object.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; 87a1aa833dccca5ea503e9a7ff81c51fe82c85c6&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;commit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unsurprisingly, it&#x27;s a commit object. If we look what is inside, we see
something that may look familiar to people that regularly use git.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; 87a1aa833dccca5ea503e9a7ff81c51fe82c85c6&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; aee76412ed220742aeaf02ca1c50519bcea013e1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;author&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Christina Sørensen &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;christina@cafkafk.com&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1715792150&lt;&#x2F;span&gt; +0200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;committer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Christina Sørensen &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;christina@cafkafk.com&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1715792150&lt;&#x2F;span&gt; +0200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;initial&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commit&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A fun thing to do now is to try and run &lt;code&gt;git log&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git log&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fatal:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; your current branch appears to be broken&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Seems like our branch is broken hu? Let&#x27;s fix that. Let&#x27;s quickly
remind ourself of the contents of &lt;code&gt;.git&#x2F;HEAD&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; cat .git&#x2F;HEAD&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;ref:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; refs&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This doesn&#x27;t refer to anything. We can easily fix this, let&#x27;s make a
new branch. But what git subcommand will we use this time? None
actually, as it turns out, branches are just files in
&lt;code&gt;.git&#x2F;refs&#x2F;heads&#x2F;&lt;&#x2F;code&gt; that contain the sha-1 hash of some
commit. The name of the file becomes the name of the branch.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; echo 87a1aa833dccca5ea503e9a7ff81c51fe82c85c6 &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; .git&#x2F;refs&#x2F;heads&#x2F;main&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we just need to switch to that branch. Instead of doing
&lt;code&gt;git switch main&lt;&#x2F;code&gt; we can just change the reference in the
repository directory &lt;code&gt;.git&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; echo &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ref: refs&#x2F;heads&#x2F;main&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; .git&#x2F;HEAD&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you&#x27;re following along, and you have some PS1 git branch feature,
you may have noticed something incredible just after running that
command.&lt;&#x2F;p&gt;
&lt;p&gt;First, if we run &lt;code&gt;git status&lt;&#x2F;code&gt; now, we see that there no
longer are any changes to be committed.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;On&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; branch main&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;Changes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; not staged for commit:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-compound z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;use&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git add&#x2F;rm &amp;lt;file&amp;gt;...&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; to update what will be committed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-compound z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-compound z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;use&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git restore &amp;lt;file&amp;gt;...&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; to discard changes in working directory&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-compound z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;deleted:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;    amogus.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;deleted:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;    truth.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; changes added to commit (use &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git add&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; and&#x2F;or &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;git commit -a&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Also, we can now run &lt;code&gt;git log&lt;&#x2F;code&gt;!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; log&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;commit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 87a1aa833dccca5ea503e9a7ff81c51fe82c85c6 (HEAD -&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;Author:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Christina Sørensen &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;christina@cafkafk.com&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;Date:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;   Wed May 15 18:55:50 2024 +0200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;initial&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commit&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Something else that&#x27;s cool is we can run
&lt;code&gt;git log --format=raw&lt;&#x2F;code&gt;, and see output similar to what we got
from &lt;code&gt;git cat-file -p&lt;&#x2F;code&gt; on the commit objects sha-1.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git log&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-option z-shell&quot;&gt;=&lt;&#x2F;span&gt;raw&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;commit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 87a1aa833dccca5ea503e9a7ff81c51fe82c85c6&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; aee76412ed220742aeaf02ca1c50519bcea013e1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;author&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Christina Sørensen &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;christina@cafkafk.com&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1715792150&lt;&#x2F;span&gt; +0200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;committer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Christina Sørensen &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;christina@cafkafk.com&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1715792150&lt;&#x2F;span&gt; +0200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;initial&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commit&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git cat-file&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; 87a1aa833dccca5ea503e9a7ff81c51fe82c85c6&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; aee76412ed220742aeaf02ca1c50519bcea013e1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;author&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Christina Sørensen &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;christina@cafkafk.com&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1715792150&lt;&#x2F;span&gt; +0200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;committer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; Christina Sørensen &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;christina@cafkafk.com&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-file-descriptor z-shell&quot;&gt;1715792150&lt;&#x2F;span&gt; +0200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;initial&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commit&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But what about those files that are deleted? We can solve that with
&lt;code&gt;git checkout&lt;&#x2F;code&gt; like this.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git checkout HEAD&lt;span class=&quot;z-keyword z-operator z-end-of-options z-shell&quot;&gt; --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; amogus.txt truth.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now if we run &lt;code&gt;git status&lt;&#x2F;code&gt; we get.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; git status&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;On&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; branch main&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;nothing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; to commit, working tree clean&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With this, we have successfully created a commit from scratch.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusions&quot;&gt;Conclusions&lt;&#x2F;h1&gt;
&lt;p&gt;Starting from an empty directory, we have successfully initialized a repository, staged files, created a branch, and committed our work — all without using the standard git commands.&lt;&#x2F;p&gt;
&lt;p&gt;Is this efficient? Certainly not.&lt;&#x2F;p&gt;
&lt;p&gt;However, by bypassing the porcelain commands, we have exposed the elegant simplicity of git’s plumbing. Understanding how objects, trees, and references interact transforms the system from a black box into a logical machine. This deeper understanding will help you internalize the tool, making complex operations intuitive rather than terrifying.&lt;&#x2F;p&gt;
&lt;p&gt;There are still open questions: how does a &lt;code&gt;pull&lt;&#x2F;code&gt; work? How do we manually &lt;code&gt;rebase&lt;&#x2F;code&gt;? That is a topic for another day — or perhaps a therapy session. For now, we will leave them as an exercise for the curious reader.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;exercises&quot;&gt;Exercises&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;What does the &lt;code&gt;hexdump -C&lt;&#x2F;code&gt; look like of the
&lt;code&gt;.git&#x2F;index&lt;&#x2F;code&gt; if we add another blob with
&lt;code&gt;hash-object&lt;&#x2F;code&gt; and &lt;code&gt;update-index&lt;&#x2F;code&gt;?&lt;&#x2F;li&gt;
&lt;li&gt;Can you discern any patterns from this. What more can you learn
about the index file format.&lt;&#x2F;li&gt;
&lt;li&gt;What does the zlib compressed data look like inside of the tree
object after if we add another blob?&lt;&#x2F;li&gt;
&lt;li&gt;What does the &lt;code&gt;.git&#x2F;index&lt;&#x2F;code&gt; look like after running
&lt;code&gt;update-index&lt;&#x2F;code&gt; with a tree blob in the object database?&lt;&#x2F;li&gt;
&lt;li&gt;What does the &lt;code&gt;.git&#x2F;index&lt;&#x2F;code&gt; look like after running
&lt;code&gt;update-index&lt;&#x2F;code&gt; and &lt;code&gt;write-tree&lt;&#x2F;code&gt; with a tree
blob in the object database?&lt;&#x2F;li&gt;
&lt;li&gt;Can you figure out what the myserious &lt;code&gt;f^gNfB&lt;&#x2F;code&gt; means?&lt;&#x2F;li&gt;
&lt;li&gt;What does the &lt;code&gt;hexdump -C&lt;&#x2F;code&gt; look like of the
&lt;code&gt;.git&#x2F;index&lt;&#x2F;code&gt; inside a larger project.&lt;&#x2F;li&gt;
&lt;li&gt;Can you discern any patterns from this. What more can you learn
about the index file format.&lt;&#x2F;li&gt;
&lt;li&gt;Does changing the size of the blob from 78 to some other number
inside of the zlib compressed data influence
&lt;code&gt;git cat-file -s&lt;&#x2F;code&gt;? You will need to decompress and
recompress the data from and into the proper zlib format&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-8-1&quot;&gt;&lt;a href=&quot;#fn-8&quot;&gt;[8]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;footnotes&quot;&gt;Footnotes&lt;&#x2F;h1&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;We don&#x27;t have to put our git repo in &lt;code&gt;.git&lt;&#x2F;code&gt;. We could
use the &lt;code&gt;GIT_DIR&lt;&#x2F;code&gt; environment variable, or the
&lt;code&gt;--git-dir=&amp;lt;path&amp;gt;&lt;&#x2F;code&gt; flag. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;the zlib wrapper (RFC 1950) — unlike gzip wrapper (RFC 1952) —
doesn&#x27;t store file name and other file system information, which is
fine, considering how git manages this elsewhere. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;From this &lt;a href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;22834&#x2F;how-to-uncompress-zlib-data-in-unix&quot;&gt;unix.stachexchange
answer&lt;&#x2F;a&gt;.
Here, we concatenate the gzip magic number and compression method,
and concatenate (the actual reason for cat existing) this with the
file. We then pipe it into gzip, who can now understand and
decompress it. Still, we didn&#x27;t finish the file with the 8 byte
footer, so gzip gets confused, but that doesn&#x27;t matter, we get to
see the data regardless. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;en&#x2F;v2&#x2F;Git-Internals-Git-Objects&quot;&gt;https:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;en&#x2F;v2&#x2F;Git-Internals-Git-Objects&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;If you&#x27;re interested in finding out how the hash is generated,
start &lt;a href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;masak&#x2F;2415865&quot;&gt;here&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-6&quot;&gt;
&lt;p&gt;Read more
herehttps:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;sv&#x2F;v2&#x2F;Git-Internals-Git-Objects &lt;a href=&quot;#fr-6-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-7&quot;&gt;
&lt;p&gt;The mortal enemy of C has many names: empty bytes, null bytes, nop
bytes. &lt;a href=&quot;#fr-7-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-8&quot;&gt;
&lt;p&gt;One approach could be to use the hack, with the additional padding
at the end, to extract the file. Then, after changing the number,
compressing it again, and removing the prepend and appended gzip
magic numbers. &lt;a href=&quot;#fr-8-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Institutional Math</title>
          <pubDate>Fri, 10 Nov 2023 14:03:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/institutional-math/</link>
          <guid>https://point.free/blog/institutional-math/</guid>
          <description xml:base="https://point.free/blog/institutional-math/">&lt;h3 id=&quot;foreword-from-the-future&quot;&gt;Foreword from the future&lt;&#x2F;h3&gt;
&lt;p&gt;As 2025 is coming to an end… I’ve been reading over some of my old posts. The
tone here is obviously on the more polemic side, but it would be a disservice to
my former self to erase the record of my views on academia when I was on the
inside.&lt;&#x2F;p&gt;
&lt;p&gt;I think it’s worthwhile to conserve not just the more reasoned and polished
version of “why did you leave academia” — that I now often find myself
regurgitating — but also conserving the “emotion” behind that decision.&lt;&#x2F;p&gt;
&lt;p&gt;Because any after the fact rationalization aside, the fundamental decision
wasn’t rational, it was emotional. Experienced. Not up for argument. It was an
incommensurable experience of a normal science that wasn’t suited to my taste.
It was the observation of the fundamental sin in the heart of academia as an
institution.&lt;&#x2F;p&gt;
&lt;p&gt;If nothing else, then as a warning to my future self to never make the fault of
Epimetheus again. Before Newtons birthday seems an apt time to spit on the grave
of the enlightenment. So &lt;code&gt;&#x2F;spit&lt;&#x2F;code&gt;, cheers, and onward!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I’ve been wanting to write something terse, dense, with academic heft on this
subject a long time. Sadly, I fear I’ll never write such a thing. But I need to
speak my heart. I left the mathematical asylum, but I need some closure, and
eating Curry isn’t cutting it anymore.&lt;&#x2F;p&gt;
&lt;p&gt;Grigori Perelman rejected the fields medal, and the Clay Institute awarded
monetary prize for solving one of the “Millenium Problems”. Evariste Galois laid
dormant for 10 years after his death in the drawers of Liouville. Gauss and
Newton let their personal quibbles turn into abuse of power. Grothendieck left the
whole thing behind, burned all his papers. Kaczynski became a domestic
terrorist. Lovely field indeed!&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m not interested in money or fame; I don’t want to be on display like an
animal in a zoo.&lt;&#x2F;p&gt;
&lt;p&gt;– &lt;cite&gt;Grigori Perelman&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The QED project is but ruins — visions of better times. If the proof isn’t
surveyable, then it isn’t solvable! Mathematics isn’t just syntactics, no,
they’re new age incarnations on the &lt;em&gt;platonic plane of ideas&lt;&#x2F;em&gt;, they’re &lt;em&gt;universal
truths&lt;&#x2F;em&gt; of the &lt;em&gt;universe!&lt;&#x2F;em&gt;… Nonsense.&lt;&#x2F;p&gt;
&lt;p&gt;Mathematics is &lt;strong&gt;circlejerking on tautological systems&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Lockhart can lament all he wants, at least in primary school the problems are
trivial, and if you’re done fast you can do something actually useful with the
research stipend called public school. At the prestigious academy, the queen of
sciences is growing ever more complicated year by year… but ironically, the
material taught is the perfect problems for proof systems, we’re teaching
students only to replicate.  Since the primary concern of these problems is less
work for the validator, the true test of your “learning outcome” is your ability
to solve solved problems systematically. We must preserve the human validator,
by turning said human into a mistaken mockery of the computer.&lt;&#x2F;p&gt;
&lt;p&gt;Science, knowledge, the university itself. Open is its doors to any and all.
Come research for Boeing and Lockheed, at the faculty of partitioning of 7 hole
toruses by means of ballistics, or if it feels too theoretical to indirectly
maim and kill people in foreign countries, why not study applied mathematics,
and develop social models for companies like Palantir? Profiling, what’s that?
Do you not believe in the infallible probabilities?&lt;&#x2F;p&gt;
&lt;p&gt;“We need a new Bourbaki” we young people may say to each other, but we all know
well that we’d rather get ours and leave this corpse rotting and dying. If
anything, what’s needed isn’t more fuel on the fire. Institutional science is
systematically pissing in the super soaker wielded by various tyrants,
profiteers and oligarchies around the planar graph we all live on. If we are to
change mathematics, we should get to the roots of the problem, like we have
always done. The foundation on which we built has a crisis, and that foundation
isn’t mathematical, it’s social.&lt;&#x2F;p&gt;
&lt;p&gt;And for myself, for my mathematical circlejerking?&lt;&#x2F;p&gt;
&lt;p&gt;I keep it between friends, private, like good sex. The smut we produce we
encrypt and keep safe so as to not show something profane to the plutocrats of
the academy. Encrypting — hoping to be kept in those drawers until saner heads
emerge to open it.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>RIME</title>
          <pubDate>Thu, 09 Nov 2023 16:02:00 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/rime/</link>
          <guid>https://point.free/blog/rime/</guid>
          <description xml:base="https://point.free/blog/rime/">&lt;blockquote&gt;
&lt;p&gt;This isn’t a tutorial, it’s more a “here’s what that thing I’ve been working
on is about.”&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-5-1&quot;&gt;&lt;a href=&quot;#fn-5&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I like Nix a lot. It’s a so called “obvious good idea”. Even with much of its
baggage, some technical, some cultural, it’s probably one of the most interesting
things currently happening in software, and you’re making a mistake if you’re
not paying attention to it.&lt;&#x2F;p&gt;
&lt;p&gt;My desktop, laptop, build server, and even my IRC-bounce server in the “cloud”
runs Nix. This makes it easy for me to provision my systems from a single source
of version controlled truth. What has made that even better is that all the
software projects I maintain include a so called Nix flake, and I make sure to
upstream the projects I could imagine people would find some value in to nixpkgs
every week on release.&lt;&#x2F;p&gt;
&lt;p&gt;One particular project I maintain is called eza, it’s that fork of exa, that you
may or may not even be aware that you’re running if you’re a former exa
user&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[2]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Eza relies heavily on Nix. The first way Nix showed up was to help us remove
vagrant, a product from HashiCorp, the company famous for making terraform. This
was partially because I was uncomfortable with the vagrant business license, but
further because Nix could replace it while providing unique benefits. But we do
so much more with Nix.&lt;&#x2F;p&gt;
&lt;p&gt;The Nix flake sets up the development environment for contributors, in a way
that matches the same environment as I myself develop on effortlessly for devs.
It helps ensure that commits follow conventional commits, and checks if the code
conforms to a battery of linters. It further makes it easy to format all
source, and helps build eza in a declarative way.&lt;&#x2F;p&gt;
&lt;p&gt;In general, I like to think that we at eza run a tight ship. This is necessary,
because we’re working in a surprisingly hard domain, where there is a lot of
side-effects — what else would you expect from something so closely tied to the
file system.&lt;&#x2F;p&gt;
&lt;p&gt;This means that we enforce semantic versioning as well, and generate changelogs
that make breaking changes clear.&lt;&#x2F;p&gt;
&lt;p&gt;Now with all that in mind, let me quickly explain the lifecycle of a eza version.&lt;&#x2F;p&gt;
&lt;p&gt;We start on Thursday, after a release was just made. For most of the week, we
slowly and steadily merge pull requests. Then, when Thursday comes, based on
whether or not a breaking change was introduced (as is easily parsed from our
commit summaries thanks to conventional commits), we determine the next version
of eza automatically, and justfile recipes (think make files but less pain)
cross compiles binaries for the platforms we support, and cuts and tags the new
release, as well as making a “proper” github release.&lt;&#x2F;p&gt;
&lt;p&gt;Then, after all that is done, there’s only two things left. First, I run &lt;code&gt;cargo publish&lt;&#x2F;code&gt;, to send the newest eza version to crates.io, from which it is
immediately available for download via &lt;code&gt;cargo install eza&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;[3]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Secondly, I
update the nixpkgs package (that I, reasonably enough, am the maintainer of),
and await someone with commit bit set to merge it.&lt;&#x2F;p&gt;
&lt;p&gt;Now, it is often merged quite quickly these days, I think that there is a small
group of commiters who’s gotten used to looking for my batch of software updates
and merge them without much fuss. But even with a same day merge, due to the
nature of nixpkgs, this newest version will actually first be available in some
days, usually four to five.&lt;&#x2F;p&gt;
&lt;p&gt;This is because the nixpkgs unstable branch lags behind the main branch&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;[4]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; by
a bit. The reasons for why this is are overly technical, but sufficient to say
that even while nixpkgs-unstable is the most up to date package distribution in
aggregate, compared to arch-extra, which usually has the newest version of eza
within a day, for packages like eza, it lags behind.&lt;&#x2F;p&gt;
&lt;p&gt;There of course is a potential solution to this, one that I did use for bit.
See, since eza has a &lt;code&gt;flake.nix&lt;&#x2F;code&gt; file, one can just refer to that directly in
their NixOS config, by making it a flake input (if one does use flakes that is).&lt;&#x2F;p&gt;
&lt;p&gt;This is great, that way, you don’t have to wait for nixpkgs-unstable to catch up
with our latest release, but there is a catch.&lt;&#x2F;p&gt;
&lt;p&gt;Flake inputs have no notion of versioning.&lt;&#x2F;p&gt;
&lt;p&gt;Now, if you’ve been keeping your ear to the ground, there has, withing the last
few month been two major improvements on this front. Firstly came flakehub, a
proprietary platform by many NixOS veterans. Later came the, seemingly spiteful
flakestry.dev, by other NixOS veteran.  Between the lines, it’s farily clear
that this is a direct reaction to flakehub being closed source.&lt;&#x2F;p&gt;
&lt;p&gt;The selling point of both of these platforms is the following: you add a github
action, and whenever you make a proper github release, that action will push
your flake to the respective platform.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with both however, at least to me, as someone that distributes software
to a fair few amount of users, but even further, just as someone that likes to tinker with
my system and loves to make it all neat is the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;People need to add a github action to their repos.&lt;&#x2F;li&gt;
&lt;li&gt;Only repos that have done this, and has released after, can actually be used.&lt;&#x2F;li&gt;
&lt;li&gt;This only works for github.&lt;&#x2F;li&gt;
&lt;li&gt;If this brittle setup breaks in the future, of if releases stop coming, you’ll
have to move to a different source.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And I tried to see if these limitations weren’t too annoying for me to use for
some months.  But aside from the technical limitations, the closed nature of
flakehub got to me (at the time, flakestry.dev didn’t exist).&lt;&#x2F;p&gt;
&lt;p&gt;Having had this in the back of my head lead to many shower thoughts, which lead
to additional shower thoughts, which lead to generally very long showers. Some
weeks ago, those shower thoughts collided into a sudden, immediate hacking run,
and rime was born.&lt;&#x2F;p&gt;
&lt;p&gt;Now, three weeks later, we’re sorta at a place where all the essential features
we want are in place.&lt;&#x2F;p&gt;
&lt;p&gt;Those things include supporting not just github, but gitlab, codeberg, forgejo,
gitea, sourcehut, and even flakehub&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-1&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;[5]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, supporting semver requirements,
whether that be getting any version that is a version $\le 0.3.48$, or just only
getting minor and patch updates, but not major version bumps without manual
intervention. And like, a lot more features. But really, what makes it great is that I can
just specify:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; class=&quot;language-nix z-code&quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attrset-or-function z-nix&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;  &lt;span class=&quot;z-entity z-other z-attribute-name z-multipart z-nix&quot;&gt;description&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-bind z-nix&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-nix&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-double z-start z-nix&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;My Configuration&lt;span class=&quot;z-punctuation z-definition z-string z-double z-end z-nix&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-bind z-nix&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;  &lt;span class=&quot;z-entity z-other z-attribute-name z-multipart z-nix&quot;&gt;inputs&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-bind z-nix&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-attrset-or-function z-nix&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;    &lt;span class=&quot;z-entity z-other z-attribute-name z-multipart z-nix&quot;&gt;eza&lt;&#x2F;span&gt;.&lt;span class=&quot;z-entity z-other z-attribute-name z-multipart z-nix&quot;&gt;url&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-bind z-nix&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-nix&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-double z-start z-nix&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;http:&#x2F;&#x2F;rime.cx&#x2F;v1&#x2F;github&#x2F;cafkafk&#x2F;eza.tar.gz&lt;span class=&quot;z-punctuation z-definition z-string z-double z-end z-nix&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-bind z-nix&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;    ... &lt;span class=&quot;z-entity z-other z-attribute-name z-multipart z-nix&quot;&gt;your&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-other z-attribute-name z-multipart z-nix&quot;&gt;other&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-other z-attribute-name z-multipart z-nix&quot;&gt;inputs&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-attrset z-nix&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;  &lt;span class=&quot;z-variable z-parameter z-name z-nix&quot;&gt;outputs&lt;&#x2F;span&gt; &lt;span class=&quot;z-invalid z-illegal&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-attrset-or-function z-nix&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;    &lt;span class=&quot;z-keyword z-operator z-nix&quot;&gt;... &lt;span class=&quot;z-invalid z-illegal&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;l&lt;&#x2F;span&gt; &lt;span class=&quot;z-invalid z-illegal&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;r&lt;&#x2F;span&gt; &lt;span class=&quot;z-invalid z-illegal&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;l&lt;&#x2F;span&gt; &lt;span class=&quot;z-invalid z-illegal&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;s&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-nix&quot;&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-entity z-function z-nix&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-nix&quot;&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And like that, the eza flake input will always be the latest released (excluding
pre-releases) version.&lt;&#x2F;p&gt;
&lt;p&gt;This really puts nixpkgs into perspective for me. For projects that already have
their own flakes, the value of nixpkgs mainly becomes it being a hand crafted
manually updated package whenever there is a new version.&lt;&#x2F;p&gt;
&lt;p&gt;And while I’m determined to make eza available to as many users as possible, and
having it in nixpkgs will obviously help that… for my own use at least, it’s
just so much more neat to have it as a flake input, but without having to
include unreleased, potentially unstable changes.&lt;&#x2F;p&gt;
&lt;p&gt;It clearly to me also opens some routes to a more decentralized NixOS landscape,
since it adds a sort of layer between the latest raw flake and the users
computer, reminding me of the layer of snow that build up when you place
something sturdy in a hostile, cold climate with a lot of snow(flakes). A layer
called rime.&lt;&#x2F;p&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;Although much of the work has been done by
&lt;a href=&quot;https:&#x2F;&#x2F;asylum.madhouse-project.org&#x2F;&quot;&gt;Gergely Nagy&lt;&#x2F;a&gt;, who I’ve been able to
successfully nerdsnipe. &lt;a href=&quot;#fr-5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Since distributions shim in eza in the place of exa nowadays. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Although, sadly, it’s impossible to include man pages and completions via
crates.io. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;Technically, the “master” branch, but let’s not indulge that anachronism. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;And it’s written to be easily extendible, so adding new forges is
trivial. &lt;a href=&quot;#fr-4-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Adding dollar sign (apply) to nix</title>
          <pubDate>Thu, 03 Aug 2023 14:34:33 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/nix-dollar-sign/</link>
          <guid>https://point.free/blog/nix-dollar-sign/</guid>
          <description xml:base="https://point.free/blog/nix-dollar-sign/">&lt;blockquote&gt;
&lt;p&gt;This post is very low quality for comedic effect.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;a-detailed-list-of-instructions&quot;&gt;A detailed list of instructions&lt;&#x2F;h2&gt;
&lt;p&gt;Take one &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NixOS&#x2F;nix&quot;&gt;nix&lt;&#x2F;a&gt;, apply &lt;a href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;cafkafk&#x2F;210926e24f4e18d1a0c28b9458b36c1a&quot;&gt;this patch&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;What does this do? It adds a new token &lt;code&gt;$&lt;&#x2F;code&gt; to the nix languages parser and exposes
it as &lt;code&gt;__dollar&lt;&#x2F;code&gt;, essentially by copying the way this works for &lt;code&gt;__lessThan&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Hack on your nix:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;nix develop
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;.&#x2F;bootstrap.sh
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;.&#x2F;configure $configureFlags --prefix=$(pwd)&#x2F;outputs&#x2F;out
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;make -j $NIX_BUILD_CORES
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;outputs&#x2F;out&#x2F;bin&#x2F;nix repl
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now in the &lt;code&gt;nix repl&lt;&#x2F;code&gt; that just opened:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;nix-repl&amp;gt; __dollar = x: y: builtins.foldl&amp;#39; (a: b: a b) x y
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This makes &lt;code&gt;$&lt;&#x2F;code&gt; an infix operator that’s essentially just a generic apply.&lt;&#x2F;p&gt;
&lt;p&gt;Now just create a toy example to demonstrate:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;nix-repl&amp;gt; concat = x: y: z: (x + y + z)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;nix-repl&amp;gt; concat $ [&amp;quot;literally&amp;quot; &amp;quot; &amp;quot; &amp;quot;dollar sign&amp;quot;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And your repl will say:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;quot;literally dollar sign&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Tadaa! That’s all it takes to add the &lt;code&gt;$&lt;&#x2F;code&gt; operator to nix, just like Haskell.&lt;&#x2F;p&gt;
&lt;p&gt;The end  $\text{\(^ヮ^)&#x2F;}$&lt;&#x2F;p&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;&lt;pre data-lang=&quot;diff&quot; class=&quot;language-diff z-code&quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;diff --git a&#x2F;src&#x2F;libexpr&#x2F;parser.y b&#x2F;src&#x2F;libexpr&#x2F;parser.y
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;index 201370b90..4b26af623 100644
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-header z-from-file&quot;&gt;&lt;span class=&quot;z-meta z-header z-from-file z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-from-file z-diff&quot;&gt;---&lt;&#x2F;span&gt; a&#x2F;src&#x2F;libexpr&#x2F;parser.y
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-header z-to-file&quot;&gt;&lt;span class=&quot;z-meta z-header z-to-file z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-to-file z-diff&quot;&gt;+++&lt;&#x2F;span&gt; b&#x2F;src&#x2F;libexpr&#x2F;parser.y
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-range z-unified&quot;&gt;&lt;span class=&quot;z-meta z-range z-unified z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-toc-list z-line-number z-diff&quot;&gt;-353,6 +353,7&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-section z-diff&quot;&gt;void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; %left AND
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; %nonassoc EQ NEQ
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; %nonassoc &amp;#39;&amp;lt;&amp;#39; &amp;#39;&amp;gt;&amp;#39; LEQ GEQ
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;%nonassoc &amp;#39;$&amp;#39; DOL
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; %right UPDATE
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; %left NOT
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; %left &amp;#39;+&amp;#39; &amp;#39;-&amp;#39;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-range z-unified&quot;&gt;&lt;span class=&quot;z-meta z-range z-unified z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-toc-list z-line-number z-diff&quot;&gt;-411,6 +412,8&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-section z-diff&quot;&gt;expr_op&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   | expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data-&amp;gt;symbols.create(&amp;quot;__lessThan&amp;quot;)), {$3, $1})); }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   | expr_op &amp;#39;&amp;gt;&amp;#39; expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data-&amp;gt;symbols.create(&amp;quot;__lessThan&amp;quot;)), {$3, $1}); }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   | expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data-&amp;gt;symbols.create(&amp;quot;__lessThan&amp;quot;)), {$1, $3})); }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;  | expr_op &amp;#39;$&amp;#39; expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data-&amp;gt;symbols.create(&amp;quot;__dollar&amp;quot;)), {$1, $3}); }
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;  | expr_op DOL expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data-&amp;gt;symbols.create(&amp;quot;__dollar&amp;quot;)), {$3, $1})); }
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   | expr_op AND expr_op { $$ = new ExprOpAnd(makeCurPos(@2, data), $1, $3); }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   | expr_op OR expr_op { $$ = new ExprOpOr(makeCurPos(@2, data), $1, $3); }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   | expr_op IMPL expr_op { $$ = new ExprOpImpl(makeCurPos(@2, data), $1, $3); }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;diff --git a&#x2F;src&#x2F;libexpr&#x2F;primops.cc b&#x2F;src&#x2F;libexpr&#x2F;primops.cc
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;index ddf529b9e..00622a142 100644
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-header z-from-file&quot;&gt;&lt;span class=&quot;z-meta z-header z-from-file z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-from-file z-diff&quot;&gt;---&lt;&#x2F;span&gt; a&#x2F;src&#x2F;libexpr&#x2F;primops.cc
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-header z-to-file&quot;&gt;&lt;span class=&quot;z-meta z-header z-to-file z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-to-file z-diff&quot;&gt;+++&lt;&#x2F;span&gt; b&#x2F;src&#x2F;libexpr&#x2F;primops.cc
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-range z-unified&quot;&gt;&lt;span class=&quot;z-meta z-range z-unified z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-toc-list z-line-number z-diff&quot;&gt;-3583,6 +3583,24&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-section z-diff&quot;&gt;static RegisterPrimOp primop_lessThan({&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;     .fun = prim_lessThan,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; });
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;static void prim_dollar(EvalState &amp;amp; state, const PosIdx pos, Value * * args, Value &amp;amp; v)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    state.forceValue(*args[0], pos);
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    state.forceValue(*args[1], pos);
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    &#x2F;&#x2F; pos is exact here, no need for a message.
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    CompareValues comp(state, noPos, &amp;quot;&amp;quot;);
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    v.mkBool(comp(args[0], args[1]));
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;static RegisterPrimOp primop_dollar({
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    .name = &amp;quot;__dollar&amp;quot;,
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    .args = {&amp;quot;e1&amp;quot;, &amp;quot;e2&amp;quot;},
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    .doc = R&amp;quot;(
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;      Just like haskell :)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    )&amp;quot;,
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;    .fun = prim_dollar,
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;});
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; &#x2F;*************************************************************
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;  * String manipulation
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
 &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>The Pull-Request Heist</title>
          <pubDate>Thu, 03 Aug 2023 14:34:33 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/the-pr-heist/</link>
          <guid>https://point.free/blog/the-pr-heist/</guid>
          <description xml:base="https://point.free/blog/the-pr-heist/">&lt;blockquote&gt;
&lt;p&gt;Your effort to remain what you are is what limits you.&lt;&#x2F;p&gt;
&lt;p&gt;– &lt;cite&gt;The Puppet Master&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;the-beginning&quot;&gt;The Beginning&lt;&#x2F;h2&gt;
&lt;p&gt;May 3, 2014. Benjamin “Ogham” Sago has just made his first commit to
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogham&#x2F;exa&quot;&gt;Exa&lt;&#x2F;a&gt;. This will go on to be one of the most
used ls alternatives, with ~22k stars, 655 forks, and 151 contributors.&lt;&#x2F;p&gt;
&lt;p&gt;For almost a decade, he maintains exa. Yet, around 2021, activity is drastically
slowing. Eventually, the project falls dead.&lt;&#x2F;p&gt;
&lt;p&gt;With 63 open pull requests, 276 issues, and some major bugs, the project is on
its deathbed. The &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogham&#x2F;exa&quot;&gt;users are begging&lt;&#x2F;a&gt; for activity.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, other projects are being advertised in the issues for various
features. Features that — mind you — are already finished in the
pull-requests, but without anyone to merge. The situation is dire, are we all
doomed to use &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lsd-rs&#x2F;lsd&quot;&gt;LSDeluxe&lt;&#x2F;a&gt; and endure its awful color scheme?&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That’s where I somehow came in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-rabbit-hole-yak-shave&quot;&gt;The rabbit hole yak-shave&lt;&#x2F;h2&gt;
&lt;p&gt;The terminal emulator kitty is really neat. So is exa, and I’ve been using exa
for a fairly long time. Never have I given it much more thought than installing
it from nixpkgs, I’m for the most part blisfully unaware of the projects state
(which speaks to it’s quality no doubt).&lt;&#x2F;p&gt;
&lt;p&gt;Kitty has a feature. You can type &lt;code&gt;ctrl+shift+e&lt;&#x2F;code&gt;, and it highlights links with
letters, a bit like vim easy-motions, and allows you to effortlessly open them
in your browser.&lt;&#x2F;p&gt;
&lt;p&gt;As a keyboard only extremist, this pleases me.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, the thing is, when I exa some directory, I can’t “easy motion” for
files. And I want that. So I look into it. Turns out, kitty has that feature!
And so does ls!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ls --hyperlink=auto
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Neat!&lt;&#x2F;p&gt;
&lt;p&gt;Then, tragedy… exa doesn’t. What! A bit of searching reaveals to me a PR on
exa. It’s been there since April. It’s awsome!&lt;&#x2F;p&gt;
&lt;p&gt;But it isn’t merged. Why? I orient myself in the issues. I try to figure out who
to complain to. But there is none, the project looks dead.&lt;&#x2F;p&gt;
&lt;p&gt;I dip my toes in some forks, see if I can get this done. Seems trivial. Then, my
partners has to help sister move. I have the weekend free. The nerd snipe
tinglies are coming on. A &lt;a href=&quot;http:&#x2F;&#x2F;www.catb.org&#x2F;jargon&#x2F;html&#x2F;H&#x2F;hacking-run.html&quot;&gt;hacking run&lt;&#x2F;a&gt; is imminent — whether I like it or not.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;onto-the-programming&quot;&gt;Onto the programming&lt;&#x2F;h2&gt;
&lt;p&gt;Fork other forks, we’ll write our own! Call it eza, old habits die hard, and the
x is next to the z on my keyboard. This will suffice. In one bold move we have
already solved half of the hard problems of computer science&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-8-1&quot;&gt;&lt;a href=&quot;#fn-8&quot;&gt;[2]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, I’d say that’s a
good start.&lt;&#x2F;p&gt;
&lt;p&gt;Now we just have to get those pull request over in our repo. One way to do this
is the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git fetch \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    git@github.com:ogham&#x2F;exa.git&#x2F;pull&#x2F;&amp;lt;pr-id&amp;gt;&#x2F;head:&amp;lt;target-branch&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This way, we can take a pull request branch from exa, and copy it into a branch
in our repo. The problem is, there’s 63 pull-requests!?! We’d have to do this
for each of them, push the branch to github, then slowly click through the webui
and make that pull request, one at a time.&lt;&#x2F;p&gt;
&lt;p&gt;As a keyboard only extremist, this displeases me.&lt;&#x2F;p&gt;
&lt;p&gt;There is no way we’re doing this. If only we had a list of all those repo-ids,
we’d be able to at least automate the fetching.&lt;&#x2F;p&gt;
&lt;p&gt;Then, lightbulb. Github has a &lt;a href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;en&#x2F;rest&#x2F;pulls&#x2F;pulls?apiVersion=2022-11-28&quot;&gt;REST-API&lt;&#x2F;a&gt; ripe for our queries&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;[3]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. A bearer
token is created. An absolute unit of a curl request is crafted. The world
pauses for a moment as we lay the fate of the project into the wire.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;curl -L \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         -H &amp;quot;Accept: application&#x2F;vnd.github+json&amp;quot; \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         -H &amp;quot;Authorization: Bearer &amp;lt;the-bearer-token&amp;gt;&amp;quot; \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         -H &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         &amp;#39;https:&#x2F;&#x2F;api.github.com&#x2F;repos&#x2F;ogham&#x2F;exa&#x2F;pulls?per_page=100&amp;#39; &amp;gt; open-prs-full.json
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we wait for the response.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;after-the-suspense&quot;&gt;After the Suspense&lt;&#x2F;h2&gt;
&lt;p&gt;Well. It worked.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat open-prs-full.json | head -n 10
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json z-code&quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-begin z-json&quot;&gt;[&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;  &lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-json&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;url&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;api.github.com&#x2F;repos&#x2F;ogham&#x2F;exa&#x2F;pulls&#x2F;1221&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;id&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-json&quot;&gt;1446083658&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;node_id&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;PR_kwDOATIZtM5WMXxK&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;html_url&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;github.com&#x2F;ogham&#x2F;exa&#x2F;pull&#x2F;1221&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;diff_url&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;github.com&#x2F;ogham&#x2F;exa&#x2F;pull&#x2F;1221.diff&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;patch_url&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;github.com&#x2F;ogham&#x2F;exa&#x2F;pull&#x2F;1221.patch&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;issue_url&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;api.github.com&#x2F;repos&#x2F;ogham&#x2F;exa&#x2F;issues&#x2F;1221&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;number&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-json&quot;&gt;1221&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;    &lt;span class=&quot;z-invalid z-illegal z-expected-mapping-key z-json&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal z-expected-mapping-key z-json&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal z-expected-mapping-key z-json&quot;&gt;.&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Was this what we needed? We do see a &lt;code&gt;number&lt;&#x2F;code&gt; property there, and if we look in
the &lt;code&gt;html_url&lt;&#x2F;code&gt; property, we see that it matches the expected url for that pull
request. Now here is the part where I’d shown off my jq prowess, but I have no
such thing. So instead, I make do with some regex.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat open-prs-full.json \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | rg -i &amp;#39;pulls&#x2F;\d+&amp;quot;&amp;#39; -o \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | tr -d &amp;quot;pulls&#x2F;&amp;quot; \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | uniq \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | tee pr-ids.txt \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | wc -l
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;63
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The number of lines is right, but is the output?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat pr-ids | head -n 5
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1221&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1219&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1210&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1204&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1202&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ahh, close enough, a little adjustment and we are there:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat open-prs-full.json \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | rg -i &amp;#39;pulls&#x2F;\d+&amp;quot;&amp;#39; -o \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | tr -d &amp;quot;pulls&#x2F;&amp;quot; \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    | tr -d &amp;#39;&amp;quot;&amp;#39; \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;gt; pr-ids.txt
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now did we get it?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat pr-ids.txt | head -n 5
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text z-code&quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1221
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1221
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1219
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1219
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1210
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Seems we did!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-part-where-we-jam-those-pull-requests-into-github&quot;&gt;The Part Where We Jam Those Pull-Requests into GitHub&lt;&#x2F;h2&gt;
&lt;p&gt;At this point, the estrofem tablet under my tongue had dissolved, and I’d woken
from my groggy morning state. A purely performative crack of the knuckles were
in order, as I leaned over my desk like a hawk that’s caught sight of a mouse.&lt;&#x2F;p&gt;
&lt;p&gt;If you’re a keyboard-only extremist like me, web-ui is a nuisance to be solved.
GitHub has &lt;code&gt;gh&lt;&#x2F;code&gt;, or the GitHub CLI. It is extremely useful to sync your nixpkgs
fork, and send your package definition pull requests. But today, old reliable
was gonna learn some new tricks.&lt;&#x2F;p&gt;
&lt;p&gt;Then I paused. And stared.&lt;&#x2F;p&gt;
&lt;p&gt;In my head flashed visions of old &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=tc4ROCJYbm0&quot;&gt;Bell Labs informational videos&lt;&#x2F;a&gt; on the Unix
Operating System. The voice of Brain W. Kerninghan echoed in my head — “I
think the notion of pipelining is the fundamental contribution of the
system…”. The hacking cgi was front and center as I said out loud “It’s a UNIX
system, I know this!”. Temporarily absolved of my mortal coil, I resided in
waves of abstraction and shell, time and language lost their meaning to the
beauty of the baud. It was as if every bit moved in concert with my thoughts, as
if the collective will of every electron in my sillicon rock filled out the
sails of my spaceship gently surfing on the stream of raw information entering
and exiting me. As I slowly raised my cup of tea to my mouth, not for one moment
breaking this intimate emergence and embodiment of me in my code, in my will, in
my craft, before me it appeared, at the end of time and space itself. The final
destination, the one truth of programming, the zen was ever closer. Then the tea
— hotter than a NVidia GPU running KDE — removed my taste buds faster than a
Arch maintainer removes system critical boot code. What had been my ticket to
enlightenment turned into a leaky abstraction all over my desk.&lt;&#x2F;p&gt;
&lt;p&gt;However, I had tried so hard and gone so far, there was no way that in the end,
it wouldn’t really matter.&lt;&#x2F;p&gt;
&lt;p&gt;Now — armed with a more modest disposition, xargs, and the GitHub CLI — I
went to work. Soon, emerged the command that would seal my fate:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zsh&quot; class=&quot;language-zsh z-code&quot;&gt;&lt;code class=&quot;language-zsh&quot; data-lang=&quot;zsh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; pr-ids.txt &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;&#x2F;span&gt;    &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;xargs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;  -&lt;&#x2F;span&gt;I&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-job z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-job z-shell&quot;&gt;%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;n1&lt;&#x2F;span&gt; sh&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;c&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;    &lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;git fetch git@github.com:ogham&#x2F;exa.git pull&#x2F;%&#x2F;head:pr-%; git checkout pr-%; git push; gh pr create --title \&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;(exa PR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;) &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-job z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-job z-shell&quot;&gt;%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;body&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\&amp;#39;&lt;&#x2F;span&gt;github.com&#x2F;ogham&#x2F;exa&#x2F;pulls&#x2F;&lt;span class=&quot;z-meta z-group z-expansion z-job z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-job z-shell&quot;&gt;%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape z-shell&quot;&gt;\&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As a smut novel once said&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-9-1&quot;&gt;&lt;a href=&quot;#fn-9&quot;&gt;[4]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: There comes a time in every woman’s life where she
reaches a crossroads. A chance to choose between two paths. One is unknown,
filled with potential and struggles that demand growth and change, but could
lead to new beginnings. The other is familiar, grooved with well-worn ruts and
established twists, muddy holes and isolation. The path that, while lonely, fits
like a glove.&lt;&#x2F;p&gt;
&lt;p&gt;When — if — I hit enter, I’d be down the road of committing myself to
maintaining the damn thing. Were I not to, I’d never downlive the internal
shame. Were I to do it, I’d have allocated quite a substantial amount of time in
my life to pesky users, stubborn contributors, and the chore and dull drag of
changelogs, version bumps, and releases.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;the-pr-heist&#x2F;unfolding-paths.webp&quot; alt=&quot;Unfolding paths&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As I hit enter, and as the pr tab on the repo slowly grew in the web interface,
I hoped this wouldn’t be a mistake.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-aftermath&quot;&gt;The Aftermath&lt;&#x2F;h2&gt;
&lt;p&gt;Over the next two days, me and &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sbatial&quot;&gt;sbatial&lt;&#x2F;a&gt; would go onto hack on eza. When monday
came, 63 had been reduced to 18.&lt;&#x2F;p&gt;
&lt;p&gt;Hyperlinks, SE-linux contexts, git repo statuses, human readable relative
dates, more security fixes than I have fingers to count them on. And the darn
grid bug, the pesky bugger had been swatted and was now but a stain on the git
history.&lt;&#x2F;p&gt;
&lt;p&gt;With flakes, CI, and sheer will, we had overcome. Trying out eza was as imple as running:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cargo install eza
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or if one was so inclined:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;shell&quot; class=&quot;language-shell z-code&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;nix run github:cafkafk&#x2F;eza
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But had we won?&lt;&#x2F;p&gt;
&lt;p&gt;The battle, no doubt, but not the war.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reflections-on-devops-and-infra&quot;&gt;Reflections on DevOps and Infra&lt;&#x2F;h2&gt;
&lt;p&gt;In the excellent talk at Chaos Communication Conference 36: &lt;a href=&quot;https:&#x2F;&#x2F;media.ccc.de&#x2F;v&#x2F;36c3-11241-from_managerial_feudalism_to_the_revolt_of_the_caring_classes&quot;&gt;From Managerial
Feudalism to the Revolt of the Caring Classes&lt;&#x2F;a&gt;, the late David Graeber
summarizes a core problem in modernity as eloquently as only he could:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[Whenever] I say, talk to a Marxist theorist, wherever, they try to explain
value, which is what they always like to do, they always take the example of a
[bottle].&lt;&#x2F;p&gt;
&lt;p&gt;[…] Well, look at this bottle, you know. [It] takes a certain amount of
socially necessary labor time to produce this, say it takes, you know, this much
time, this much resources. It’s always about production of stuff.&lt;&#x2F;p&gt;
&lt;p&gt;But a teacup or a bottle. […] You produce a cup once, you wash it like 10000
times. Most work isn’t actually about producing new things, it’s about
maintaining things. […]&lt;&#x2F;p&gt;
&lt;p&gt;So I think that what we need to do is we need to start over. We need to realign.
First of all, think about [work], not as producers, but as carers.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;point.free&#x2F;blog&#x2F;the-pr-heist&#x2F;bike-mechanic.webp&quot; alt=&quot;Bike mechanic&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I spend four years of my life studying “the queen of the sciences”, mathematics
herself. One view that I particularly enjoyed were that of the toolmaker. Sure,
we were studying abstract structures, but that’s being a student. A
mathematician was a tool maker.&lt;&#x2F;p&gt;
&lt;p&gt;That view might have a stink of applied mathmatics, but I think it’s true even
for those who’d call themselves pure&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;[5]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This too is true in DevOps, in systems programming, in infrastructure. At the
end of the day, we’re toolmakers.&lt;&#x2F;p&gt;
&lt;p&gt;In my mispend youth, in the grips of startup culture, the idea of the elusive
10x developer, while just a mirage was still very alluring. Regardless of the
obviously wrong and problematic discurse related to it, there is no doubt that
some people move mountains, and others don’t. I wanted to move mountains.&lt;&#x2F;p&gt;
&lt;p&gt;What I’ve later came to learn is that’s just an illusion. The idea of the lone
genious, burning the midnight oil is just a myth. John Carmack, Linus Torvalds,
George Hotz, they’re just a personality cult.&lt;&#x2F;p&gt;
&lt;p&gt;And this isn’t just some clever insight I’ve come to, &lt;a href=&quot;https:&#x2F;&#x2F;www.simplethread.com&#x2F;the-10x-programmer-myth&#x2F;&quot;&gt;it’s stolen&lt;&#x2F;a&gt;. But I like my
iteration on it.&lt;&#x2F;p&gt;
&lt;p&gt;A certain Archmage of Infrastructure has the right idea about being a
“force multiplier”. What really matters to move these mountains is to enable
those that want to move them. The most dedicated cyclist in the world will cycle
less than an average bikesmith will enable others to do.&lt;&#x2F;p&gt;
&lt;p&gt;In this creating of tools, and in this care work of maintaining them, we are
force multipliers, and in our multiplication of force, the impossible becomes
possible.&lt;&#x2F;p&gt;
&lt;p&gt;This is the point of DevOps. This is the point of infra. This is the next level
of abstractions hackers should strive for if they wanna boil the ocean.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;post-credit-scene&quot;&gt;Post-Credit Scene&lt;&#x2F;h2&gt;
&lt;p&gt;From 5:00-19:00, for two days, I had hacked. 3 meals a day, hydrating, and a
walk in nature had supported this endeavor&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-7-1&quot;&gt;&lt;a href=&quot;#fn-7&quot;&gt;[6]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;At last, a knock on the door, my partner had come home. After a hug and some
pleasantrise, came the question:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;So, what did you do with your weekend?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I eagerly typed &lt;code&gt;eza&lt;&#x2F;code&gt; in my terminal emulator, and showed how there were now
letters next to the entries, and clicking them copied the text.&lt;&#x2F;p&gt;
&lt;p&gt;What should have been pure awe was a look of slight concern, followed by a
shoulder shrug and a kiss on the forehead.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;That’s all you did while I was gone?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;It’s all love, I bet it’s just a bad screenshot on their git repo &amp;lt;3 &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-8&quot;&gt;
&lt;p&gt;See the first quote
&lt;a href=&quot;https:&#x2F;&#x2F;cafkafk.dev&#x2F;posts&#x2F;breaking_file.html&quot;&gt;here&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-8-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;And we’d never scrape a website, that’s rude :^) &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-9&quot;&gt;
&lt;p&gt;“Arabella Stone, Nashville’s darling, is eager to shuck her
prim-and-proper rep, and a few wild months spent checking items off her ’ summer
bucket list’ is the way to do it. First up: kiss the man she’s crushed on since
she wore a training bra, the bad boy of country himself, Blue bassist Charlie
Tucker. For Charlie, a beautiful woman flirting with him isn’t out of the
norm—but a beautiful woman bolting after the hottest kiss of his life sure is.
And when he finds out his kiss-and-run Cinderella is none other than Arabella
Stone, daughter of his label’s CEO, he knows he’s in trouble. Because not only
is she a Stone, she’s also his employee for the next few months at the recording
studio he just bought. Over the course of one thrilling summer, Arabella and
Charlie chip away at her bucket list and fight the simmering attraction between
them…knowing that once it’s all over, so is their time together.”&lt;&#x2F;p&gt;
&lt;p&gt;Steamy. &lt;a href=&quot;#fr-9-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;Which really should be called theoretical. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-7&quot;&gt;
&lt;p&gt;All this rise and grind never sleep never eat never enjoy your life stuff is stupid. If you wanna be even like mildly consistent, you gotta get this right. Dumb stuff like hacking is like the last thing you get to in mazlows hierachy&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-10-1&quot;&gt;&lt;a href=&quot;#fn-10&quot;&gt;[7]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; for a reason. &lt;a href=&quot;#fr-7-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-10&quot;&gt;
&lt;p&gt;Yes, I know it’s “debunked”, it’s a working model geez louise. &lt;a href=&quot;#fr-10-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Warts and all</title>
          <pubDate>Mon, 24 Jul 2023 16:10:10 +0000</pubDate>
          <author>Christina Sørensen</author>
          <link>https://point.free/blog/warts/</link>
          <guid>https://point.free/blog/warts/</guid>
          <description xml:base="https://point.free/blog/warts/">&lt;h2 id=&quot;learning&quot;&gt;Learning&lt;&#x2F;h2&gt;
&lt;p&gt;The better you get the worse you get. The more I learn the more I learn that I
don’t know much.&lt;&#x2F;p&gt;
&lt;p&gt;This can be overwhelming at times. I think it’s pretty normal to feel this way.
But I also see it can easily become a limiting type of negative feedback.&lt;&#x2F;p&gt;
&lt;p&gt;Looking back at old projects, old essays, old anything, I see flaws. I was so
naive. Simultaneously, I feel like I see how my output has gotten better.&lt;&#x2F;p&gt;
&lt;p&gt;But realizing this negative feedback loop — as in keeping with the theme —
just makes you even more insecure! Because, if this model is true (and it
generally seems to be), then this post I’m writing right now will seem so bad to
me in a year… not to imagine 10 years!&lt;&#x2F;p&gt;
&lt;p&gt;Knowing this, it’s easy to fall into perfectionism. There’s always something to
improve after all. But this is dangerous. Because, while it might be the case
that in 10 years, I can easily see all the flaws, right now I can’t. And it
seems to be my experience that no matter how much I correct, no matter how much
time I spend trying to make something perfect, I only realize what was actually
missing much later.&lt;&#x2F;p&gt;
&lt;p&gt;Worst, things don’t even make it out the door. Perfectionism can kill projects.
When that happens, I don’t realize the flaws. The projects I never finished
because I didn’t know how to explain it the &lt;em&gt;right&lt;&#x2F;em&gt; way or didn’t know just how to
say what I wanted to say perfectly, those I still don’t know how to improve.&lt;&#x2F;p&gt;
&lt;p&gt;Granted, they might just still be out of my reach, and thus simply never get
finished because of this, but I feel everything I do is out of my reach, even
when doing it. And then it’s done, and I hate it a little. And then a year goes
by, and I hate it a lot.&lt;&#x2F;p&gt;
&lt;p&gt;I have to finish things to improve. Incomplete things are in a constant state of
improvement. They’re too maleable to be at fault&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. They’re beyond critique
because they’re meerly in progress, they’re not solid enough to grasp and
criticise.&lt;&#x2F;p&gt;
&lt;p&gt;Ideally, I shouldn’t get discouraged by feeling stupid. In fact, I’m starting to
feel stupid, and I’m kinda glad about that, because I know how much I had to
learn to be this dumb. But I dislike everyone’s complex with wanting to be the
wisest of all the G(r)eeks by pretending that they don’t know anything.&lt;&#x2F;p&gt;
&lt;p&gt;Knowing that you know nothing is a paradox, and a platitude.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;He who knows, does not speak. He who speaks, does not know.&lt;&#x2F;p&gt;
&lt;p&gt;– &lt;cite&gt;Lao Tsu&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is a dumb quote. It should really be:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Those who speaks, does not know. Those who knows, does not speak, and plateaus.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;You can’t know things, you can only know them more. So knowing, isn’t a
destination, but a process. But it’s a painful one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;self-redaction&quot;&gt;Self Redaction&lt;&#x2F;h2&gt;
&lt;p&gt;I feel like contemporary culture expects a self redaction from the individual of
their history. You’re not supposed to fail in public. In a spectacle, there are
just dunkers and those that are dunked on. Being wrong is death of your socially
distributed ego.&lt;&#x2F;p&gt;
&lt;p&gt;What this false internet reality leaves out is the numerous failures that lie at
the end of everything even remotely sort of cool. Without this ever in the
public eye, the culture perpetuates and intensifies perfectionism in us all.&lt;&#x2F;p&gt;
&lt;p&gt;I think that to some extend, this isn’t just a moral issue, but also an
individual one. The idea of being unable to fail in public means you can’t grow
in public either.&lt;&#x2F;p&gt;
&lt;p&gt;This I find limiting.&lt;&#x2F;p&gt;
&lt;p&gt;Further, for those around us, the network effects of being imperfect seem to be
worthwhile. In fact, I’d argue that in a time of flawless, but false public
personas, being not just a finished product but a evolving history is a much
more potent and intersting identity to embody. And it’s one that anyone with any
sense should find preferable to the superficially flawles.&lt;&#x2F;p&gt;
&lt;p&gt;I feel like I’ve already made numerous public mistakes, and I don’t see that
slowing down, and maybe I shouldn’t want that, each one is a sign of me going in
the right direction.&lt;&#x2F;p&gt;
&lt;p&gt;I don’t know how to end this.&lt;&#x2F;p&gt;
&lt;hr&gt;&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Reference implementations and their consequences have been a disaster for
the human race. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
    </channel>
</rss>
