<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on DNKYr&#39;s blog</title>
        <link>https://dnkyr.xyz/post/</link>
        <description>Recent content in Posts on DNKYr&#39;s blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Sun, 24 May 2026 16:02:32 -0700</lastBuildDate><atom:link href="https://dnkyr.xyz/post/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Write my own Git from scratch(0)</title>
            <link>https://dnkyr.xyz/post/dgit-0/</link>
            <pubDate>Sun, 24 May 2026 16:02:32 -0700</pubDate>
            <guid>https://dnkyr.xyz/post/dgit-0/</guid>
            <description>&lt;h1 id=&#34;what-is-git&#34;&gt;What is Git?&#xA;&lt;/h1&gt;&lt;p&gt;Git can mean many things depending on Linus&amp;rsquo;s mood — &amp;ldquo;global information tracker&amp;rdquo; on a good day, or &lt;a class=&#34;link&#34; href=&#34;https://git.kernel.org/pub/scm/git/git.git/tree/README?id=e83c5163316f89bfbde7d9ab23ca2e25604af290&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;&amp;ldquo;goddamn idiotic truckload of sh*t&amp;rdquo;&lt;/a&gt; when it breaks. Created by Linus Torvalds in April 2005 over the span of around 7 days, Git is a distributed version control system built to simplify Linux kernel development (instead of mailing patches around). Fast forward to today, Git has become an indispensable tool for developers and software engineers worldwide, and &lt;a class=&#34;link&#34; href=&#34;https://www.github.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GitHub&lt;/a&gt;—built on top of Git—is the largest code hosting platform on the planet.&lt;/p&gt;&#xA;&lt;h1 id=&#34;what-does-git-actually-do&#34;&gt;What does Git actually do?&#xA;&lt;/h1&gt;&lt;p&gt;Let me tell you a story about someone I know. Whenever this person writes an essay, they create countless versions: draft 1, draft 2, final draft, really-final draft, absolutely-final-never-touch-again draft&amp;hellip; Every time they need to revise, they copy the previous version and start over. Now imagine doing this with code. Fixing one bug might introduce three more. Halfway through a refactor, you realize you&amp;rsquo;ve gone down the wrong path—but which version was the &amp;ldquo;good&amp;rdquo; one? Manually copying and pasting every time is a recipe for chaos.&lt;/p&gt;&#xA;&lt;p&gt;Git automates all of that. It tracks every version of your files, stores them efficiently, and adds handy features like &lt;code&gt;diff&lt;/code&gt; (see what changed between versions) and &lt;code&gt;log&lt;/code&gt; (see the history and dependencies of each commit).&lt;/p&gt;&#xA;&lt;h1 id=&#34;why-rewrite-git&#34;&gt;Why rewrite Git?&#xA;&lt;/h1&gt;&lt;p&gt;I came across a video by &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/@ThePrimeTimeagen&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ThePrimeagen&lt;/a&gt; where he talked about how Linus Torvalds wrote a working version of Git in just 7 days—no AI, no LLMs, nothing but C and sheer willpower. Meanwhile, today&amp;rsquo;s CS students have ChatGPT, Claude, and countless articles explaining Git&amp;rsquo;s internals. Rebuilding a Git clone should be doable in a month or two, and the process is a fantastic way to deeply understand how Git works under the hood—file system operations, SHA-1 hashing, object storage, and more.&lt;/p&gt;&#xA;&lt;p&gt;At the time, I was also really interested in Rust, so I decided to write my Git implementation in Rust. Before diving in, I asked Claude to validate the idea:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Claude discussing writing Git in Rust&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;180px&#34; data-flex-grow=&#34;75&#34; height=&#34;1011&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dnkyr.xyz/post/dgit-0/Claude-discussion-git-rust.png&#34; width=&#34;762&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Verdict: totally feasible. Git doesn&amp;rsquo;t require complex lifetimes, the borrow checker, async, or any of Rust&amp;rsquo;s more intimidating features. The learning curve is manageable.&lt;/p&gt;&#xA;&lt;h1 id=&#34;how-git-works-under-the-hood&#34;&gt;How Git works under the hood&#xA;&lt;/h1&gt;&lt;p&gt;In Git, everything is an object stored inside &lt;code&gt;.git/objects&lt;/code&gt;. There are four types of objects:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Blob&lt;/strong&gt;: A blob represents a file. It stores the file content as a byte string in the format &lt;code&gt;blob &amp;lt;size&amp;gt;\0&amp;lt;content&amp;gt;&lt;/code&gt;, then uses SHA-1 to generate a unique hash that identifies that specific state of the file. Given the hash, Git can look up the object in &lt;code&gt;.git/objects&lt;/code&gt; and retrieve its content. The original filename is stored in the tree object that references this blob.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Commit&lt;/strong&gt;: This is the object most Git users interact with daily (&lt;code&gt;git commit&lt;/code&gt;). A commit consists of:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A &lt;strong&gt;tree&lt;/strong&gt; representing the state of the repository&lt;/li&gt;&#xA;&lt;li&gt;A &lt;strong&gt;parent&lt;/strong&gt; pointing to the previous commit (the first commit in a Git repository has no parent)&lt;/li&gt;&#xA;&lt;li&gt;An &lt;strong&gt;author&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;A &lt;strong&gt;committer&lt;/strong&gt; (early Git didn&amp;rsquo;t have remotes; developers emailed patches, so the coder and the committer weren&amp;rsquo;t always the same person)&lt;/li&gt;&#xA;&lt;li&gt;A &lt;strong&gt;commit message&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Tag&lt;/strong&gt;: A tag is a named reference to a specific commit, typically used to mark release versions (e.g., v1.0, v2.0). Tags can be lightweight or annotated (with author, date, and a message).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Tree&lt;/strong&gt;: A tree contains multiple blobs (and other trees). It&amp;rsquo;s a complete snapshot of the project&amp;rsquo;s directory structure at a given point in time. Like blobs, trees also have their own SHA-1 hash.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;A flowchart showing .git/objects internal implementation&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;322px&#34; data-flex-grow=&#34;134&#34; height=&#34;1068&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dnkyr.xyz/post/dgit-0/git-object-implementation.png&#34; srcset=&#34;https://dnkyr.xyz/post/dgit-0/git-object-implementation_hu_442ebdb505a07329.png 800w, https://dnkyr.xyz/post/dgit-0/git-object-implementation.png 1437w&#34; width=&#34;1437&#34;&gt;&lt;/p&gt;&#xA;&lt;h1 id=&#34;plumbing-vs-porcelain&#34;&gt;Plumbing vs. Porcelain&#xA;&lt;/h1&gt;&lt;p&gt;When you use Git day-to-day—&lt;code&gt;commit&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;reset&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;—you&amp;rsquo;re using &lt;strong&gt;porcelain&lt;/strong&gt; commands. These are high-level commands that don&amp;rsquo;t directly manipulate the underlying objects. Porcelain commands were added after Linus handed over maintenance to Junio Hamano, to make Git more user-friendly.&lt;/p&gt;&#xA;&lt;p&gt;What Linus actually built in those legendary 7 days were the &lt;strong&gt;plumbing&lt;/strong&gt; commands: &lt;code&gt;cat-file&lt;/code&gt;, &lt;code&gt;hash-object&lt;/code&gt;, &lt;code&gt;ls-tree&lt;/code&gt;, &lt;code&gt;log&lt;/code&gt;, &lt;code&gt;init&lt;/code&gt;, etc. These commands operate directly on individual objects. And these are exactly the commands this series will implement.&lt;/p&gt;&#xA;&lt;h1 id=&#34;why-rust&#34;&gt;Why Rust?&#xA;&lt;/h1&gt;&lt;p&gt;Linus wrote Git in C. C is low-level and requires manual memory management—which makes it blazingly fast, but prone to bugs like memory leaks and buffer overflows if the developer isn&amp;rsquo;t careful.&lt;/p&gt;&#xA;&lt;p&gt;Other languages (Go, JavaScript, Python) use garbage collectors to automatically clean up memory at runtime. The trade-off is slower execution and unpredictable pauses.&lt;/p&gt;&#xA;&lt;p&gt;Rust sits in a sweet spot: its borrow checker and lifetime system catch memory errors at compile time, giving you C-like speed with Go-like safety guarantees.&lt;/p&gt;&#xA;&lt;p&gt;&lt;del&gt;Or maybe I&amp;rsquo;ve just joined the Rust cult.&lt;/del&gt;&lt;/p&gt;&#xA;&lt;p&gt;Either way, this Git project is a learning project to get comfortable with Rust. Let&amp;rsquo;s get started!&lt;/p&gt;&#xA;&lt;h1 id=&#34;setting-up-the-rust-development-environment&#34;&gt;Setting up the Rust development environment&#xA;&lt;/h1&gt;&lt;h2 id=&#34;standard-setup-macos--linux&#34;&gt;Standard setup (macOS / Linux)&#xA;&lt;/h2&gt;&lt;p&gt;If you&amp;rsquo;re on macOS or a common Linux distro (Debian, Red Hat, Arch, etc.), just run:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl --proto &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;=https&amp;#39;&lt;/span&gt; --tlsv1.2 -sSf https://sh.rustup.rs | sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also install via your system package manager (Homebrew, apt, dnf, pacman, etc.). See the &lt;a class=&#34;link&#34; href=&#34;https://www.rust-lang.org/tools/install/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Rust website&lt;/a&gt; or your distro&amp;rsquo;s wiki for details.&lt;/p&gt;&#xA;&lt;h2 id=&#34;my-setup-nixos&#34;&gt;My setup (NixOS)&#xA;&lt;/h2&gt;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;If you don&amp;rsquo;t use Nix or NixOS, feel free to skip this section.&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;I use NixOS as my daily driver. Its defining features are reproducibility and declarative configuration. It manages package versions and dependencies in &lt;code&gt;/nix/store&lt;/code&gt; using a hash-based approach similar to Git&amp;rsquo;s SHA-1. Long story short: the standard Rust installation method doesn&amp;rsquo;t apply.&lt;/p&gt;&#xA;&lt;p&gt;I set up my Rust dev environment using a Nix flake to create a dev shell, then use &lt;code&gt;direnv&lt;/code&gt; to automatically activate it when I enter the project directory. If you&amp;rsquo;ve worked with JavaScript/Go/Rust/Python, think of &lt;code&gt;flake.nix&lt;/code&gt; as &lt;code&gt;package.json&lt;/code&gt;/&lt;code&gt;go.mod&lt;/code&gt;/&lt;code&gt;Cargo.toml&lt;/code&gt;/&lt;code&gt;pyproject.toml&lt;/code&gt;. Flake also generates a &lt;code&gt;flake.lock&lt;/code&gt;—like &lt;code&gt;package-lock.json&lt;/code&gt;/&lt;code&gt;go.sum&lt;/code&gt;/&lt;code&gt;Cargo.lock&lt;/code&gt;/&lt;code&gt;poetry.lock&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t need to write a Rust dev flake from scratch—Nix comes with a Rust template. Just run:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nix flake init -t templates#rust&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This generates the following &lt;code&gt;flake.nix&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  inputs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    naersk&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;github:nix-community/naersk/master&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nixpkgs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;github:NixOS/nixpkgs/nixpkgs-unstable&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    utils&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;github:numtide/flake-utils&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  outputs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      self&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      nixpkgs&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      utils&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      naersk&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    utils&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;lib&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;eachDefaultSystem (&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      system:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pkgs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; nixpkgs { &lt;span style=&#34;color:#66d9ef&#34;&gt;inherit&lt;/span&gt; system; };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        naersk-lib &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; pkgs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;callPackage naersk { };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        defaultPackage &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; naersk-lib&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;buildPackage &lt;span style=&#34;color:#e6db74&#34;&gt;./.&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        devShell &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; pkgs;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          mkShell {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            buildInputs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              cargo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              rustc&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              rustfmt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              rustPackages&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;clippy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            RUST_SRC_PATH &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rustPlatform&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;rustLibSrc;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    );&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, inside the directory containing &lt;code&gt;flake.nix&lt;/code&gt;, run:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nix develop&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This generates a &lt;code&gt;flake.lock&lt;/code&gt; and sets up a development environment with &lt;code&gt;cargo&lt;/code&gt; (Rust package manager), &lt;code&gt;rustc&lt;/code&gt; (Rust compiler), &lt;code&gt;rustfmt&lt;/code&gt; (formatter), and &lt;code&gt;clippy&lt;/code&gt; (linter).&lt;/p&gt;&#xA;&lt;p&gt;If you don&amp;rsquo;t want to type &lt;code&gt;nix develop&lt;/code&gt; every time, use &lt;code&gt;direnv&lt;/code&gt; to automate it. Create a &lt;code&gt;.envrc&lt;/code&gt; file in the project root:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;use flake&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the dev shell activates automatically whenever you &lt;code&gt;cd&lt;/code&gt; into the project.&lt;/p&gt;&#xA;&lt;h1 id=&#34;summary&#34;&gt;Summary&#xA;&lt;/h1&gt;&lt;p&gt;This article covered:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;What Git is and why we need it&lt;/li&gt;&#xA;&lt;li&gt;My motivation for rewriting Git from scratch&lt;/li&gt;&#xA;&lt;li&gt;Git&amp;rsquo;s internal object model (Blob, Commit, Tag, Tree)&lt;/li&gt;&#xA;&lt;li&gt;Plumbing vs. Porcelain commands&lt;/li&gt;&#xA;&lt;li&gt;Why Rust is a great fit for this project&lt;/li&gt;&#xA;&lt;li&gt;Setting up the development environment (standard + NixOS)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;Next article: let&amp;rsquo;s actually write some code!&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
