<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: kataoka_nopeNoshishi</title>
    <description>The latest articles on Forem by kataoka_nopeNoshishi (@nopenoshishi).</description>
    <link>https://forem.com/nopenoshishi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F972087%2F1b8d0dd0-d860-40c9-b7b3-c7f5e96b66ff.jpg</url>
      <title>Forem: kataoka_nopeNoshishi</title>
      <link>https://forem.com/nopenoshishi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nopenoshishi"/>
    <language>en</language>
    <item>
      <title>Testing Multipart Upload Requests in Axum: Three Approaches</title>
      <dc:creator>kataoka_nopeNoshishi</dc:creator>
      <pubDate>Mon, 14 Apr 2025 11:38:47 +0000</pubDate>
      <link>https://forem.com/nopenoshishi/testing-multipart-upload-requests-in-axum-three-approaches-5c13</link>
      <guid>https://forem.com/nopenoshishi/testing-multipart-upload-requests-in-axum-three-approaches-5c13</guid>
      <description>&lt;p&gt;Multipart uploads are often essential when building APIs for file uploads or complex form submissions. Testing them thoroughly is just as important as implementing them. This article provides an overview of three distinct testing approaches for multipart requests in Axum, taken from &lt;a href="https://github.com/nopeNoshishi/axum-multipart-test-examples" rel="noopener noreferrer"&gt;my demo repository&lt;/a&gt;. I will walk through the structure, sample code, and the benefits and drawbacks of each approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction: How Axum Handles Tests
&lt;/h2&gt;

&lt;p&gt;Axum itself demonstrates various testing patterns in its &lt;a href="https://github.com/tokio-rs/axum/blob/main/examples/testing/src/main.rs" rel="noopener noreferrer"&gt;official repository&lt;/a&gt;. In that example, we see how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use method like &lt;code&gt;tower::ServiceExt&lt;/code&gt; to send requests without starting a real server.&lt;/li&gt;
&lt;li&gt;Use request client like &lt;code&gt;reqwest&lt;/code&gt; to send requests with HTTP server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These official examples confirm that Axum offers a flexible testing environment. Inspired by those patterns, this article explores three ways to test file uploads (multipart requests) specifically. My goal is to provide you with multiple strategies, each with varying levels of realism and complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Approaches
&lt;/h2&gt;

&lt;p&gt;It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Oneshot approach&lt;/strong&gt; (lightweight, no full server).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Axum Test&lt;/strong&gt; (using specialized test crates).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Server with Reqwest&lt;/strong&gt; (fully simulates real requests).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each approach has its own folder (and code sample) in the &lt;code&gt;examples/&lt;/code&gt; directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Oneshot Testing
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Oneshot&lt;/strong&gt; approach uses &lt;a href="https://docs.rs/tower/latest/tower/trait.ServiceExt.html#method.oneshot" rel="noopener noreferrer"&gt;&lt;code&gt;tower::ServiceExt::oneshot&lt;/code&gt;&lt;/a&gt;. It allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test your Axum service without HTTP server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is a simplified version of the &lt;code&gt;oneshot&lt;/code&gt; test (&lt;code&gt;examples/oneshot.rs&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;AxumBody&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tower&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ServiceExt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// for oneshot&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;common_multipart_rfc7578&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;multipart&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;MultipartForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;MultipartBody&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;http_body_util&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BodyExt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[tokio::test]&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_with_oneshot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Prepare Axum app&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Create a multipart form&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;MultipartForm&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.add_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hoge-able"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.add_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"csv"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"./dummy/test_upload.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Create request&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.content_type&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;MultipartBody&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/upload"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;AxumBody&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Send request using oneshot&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="nf"&gt;.oneshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Check response body&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.into_body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nf"&gt;.to_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response_body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Files uploaded successfully"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact, there is no definition that successfully converts multipart structures of crates such as reqwest into &lt;code&gt;http::Body&lt;/code&gt;. &lt;br&gt;
Therefore, it is very easy to convert multipart structures to &lt;code&gt;httt::Body&lt;/code&gt; if there is a structure that defines multipart structures and can convert them directly to &lt;code&gt;http::Body&lt;/code&gt; (implementing &lt;code&gt;into_stream()&lt;/code&gt;).&lt;/p&gt;
&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast&lt;/strong&gt;: No need to bind to a real port or run a live server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolated&lt;/strong&gt;: Tests focus on your application logic rather than network overhead or environment variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple&lt;/strong&gt;: Minimal setup, straightforward assertion on requests/responses.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Axum Test
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Axum Test&lt;/strong&gt; approach uses the &lt;a href="https://crates.io/crates/axum-test" rel="noopener noreferrer"&gt;&lt;code&gt;axum-test&lt;/code&gt;&lt;/a&gt; crate. This library is specifically designed to help test Axum applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use &lt;code&gt;TestServer&lt;/code&gt; with a mock transport, removing the need for a real network connection.&lt;/li&gt;
&lt;li&gt;It provides an intuitive API for building requests, handling multipart data, and asserting responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a short look at &lt;code&gt;examples/axum_test_example.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum_test&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;multipart&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;MultipartForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Part&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum_test&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TestServer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[tokio::test]&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_with_axum_test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Prepare Axum app&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;TestServer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.mock_transport&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Create multipart form&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./dummy/test_upload.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Part&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.file_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test_upload.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.mime_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/csv"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;MultipartForm&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.add_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hoge-able"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.add_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"csv"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Send the request&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="nf"&gt;.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/upload"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.multipart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.assert_status_ok&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.assert_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Files uploaded successfully"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Axum-Specific&lt;/strong&gt;: Tailored for Axum, so it feels very natural to write these tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Powerful Assertions&lt;/strong&gt;: Includes methods like &lt;code&gt;assert_text&lt;/code&gt;, making response checks more expressive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No External Server&lt;/strong&gt;: Uses an internal &lt;code&gt;mock_transport&lt;/code&gt; and never binds to a port.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. HTTP Server with Reqwest
&lt;/h3&gt;

&lt;p&gt;Lastly, there is the &lt;strong&gt;full integration test&lt;/strong&gt; approach. This technique starts an actual Axum server listening on a TCP socket, and then uses &lt;a href="https://crates.io/crates/reqwest" rel="noopener noreferrer"&gt;Reqwest&lt;/a&gt; to send multipart requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Closely simulates real-world scenarios.&lt;/li&gt;
&lt;li&gt;Helps you catch issues that only appear in a truly networked environment (e.g. timeouts, actual HTTP headers).&lt;/li&gt;
&lt;li&gt;Great for end-to-end testing, though slower than the previous methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An excerpt from &lt;code&gt;examples/http_server_with_reqwest.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;multipart&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Part&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[tokio::test]&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_with_http_server&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Prepare Axum app&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1:3001"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="nf"&gt;.local_addr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Spawn the server&lt;/span&gt;
        &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Create multipart form&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./dummy/test_upload.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Part&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.file_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test_upload.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.mime_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hoge-able"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"csv"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Send request using Reqwest&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://{}/upload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="nf"&gt;.multipart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Files uploaded successfully"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Closest to Production&lt;/strong&gt;: Involves real network connections, actual HTTP protocols, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E2E Scenarios&lt;/strong&gt;: Useful for testing external dependencies or any networking layers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catch Subtleties&lt;/strong&gt;: May discover issues (like CORS, TLS, or routing) that other tests miss.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Testing file uploads in Axum does not have to be overly complicated. Whether you’re optimizing for speed, code simplicity, or realism, these three approaches give you flexibility:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Oneshot&lt;/strong&gt;: Quick unit-like tests for your Axum routes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Axum Test&lt;/strong&gt;: A specialized library for Axum, which makes for concise tests.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Server&lt;/strong&gt;: A complete integration approach using a live server and a Reqwest client.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Adopting the right approach—or mixing them together—ensures you have robust coverage. You can keep your tests fast while still ensuring your application behaves correctly when actual users upload files. &lt;/p&gt;

&lt;p&gt;Happy testing!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>axum</category>
      <category>multiplatform</category>
      <category>testing</category>
    </item>
    <item>
      <title>Create blob object (Git)</title>
      <dc:creator>kataoka_nopeNoshishi</dc:creator>
      <pubDate>Sat, 25 Mar 2023 08:23:04 +0000</pubDate>
      <link>https://forem.com/nopenoshishi/create-blob-object-git-1eje</link>
      <guid>https://forem.com/nopenoshishi/create-blob-object-git-1eje</guid>
      <description>&lt;h1&gt;
  
  
  Hello Dev community!
&lt;/h1&gt;

&lt;p&gt;I'm noshishi, a apprentice engineer in Tokyo.&lt;br&gt;
This article is about understanding Git from the inside by creating a simple program that add and commit.&lt;/p&gt;

&lt;p&gt;I would like to continue my &lt;a href="https://dev.to/nopenoshishi/make-your-original-git-analyze-section-139d"&gt;previous article&lt;/a&gt; on developing Git using Rust. Let's start by implementing the code to create a blob object.&lt;/p&gt;

&lt;p&gt;The repository I actually created is &lt;a href="https://github.com/nopeNoshishi/nss"&gt;My original git nss&lt;/a&gt;. The quality of the code isn't quite there yet and many parts are still incomplete, but you can do a straight line of local development!&lt;/p&gt;
&lt;h1&gt;
  
  
  Blob Object
&lt;/h1&gt;

&lt;p&gt;"Blob" is an object that corresponds to file data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// env method&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Pathbuf sturuct&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PathBuf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// File sturuct&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Trait for File sturuct&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="c1"&gt;// sha1 calculate crate&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Sha1&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"first.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Gathering the file content&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;current_dir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// get cwd&lt;/span&gt;
    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;PathBuf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// to absolute path&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// open file&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// create buffer&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// write buffer&lt;/span&gt;

    &lt;span class="c1"&gt;// objectは `header`+`\0`+`content`&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;blob_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"blob {}&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s"&gt;{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Note: In Rust, len() function returns the byte count of a string, not the character count.&lt;/span&gt;

    &lt;span class="c1"&gt;// Content to be stored&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"blob content: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blob_content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Calculate hash value&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;blob_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Sha1&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_content&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"blob hash: {:x}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blob_hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before executing, we are using an external crate called sha1, so we list the dependency in Cargo.toml as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
sha-1 = "0.9.1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's create a new file &lt;code&gt;first.txt&lt;/code&gt; and run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;echo &lt;/span&gt;Hello World! &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; first.txt
% &lt;span class="nb"&gt;echo &lt;/span&gt;This is my original git project! &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; first.txt
% cargo run
blob content: blob 45Hello World!
This is my original git project!
blob &lt;span class="nb"&gt;hash&lt;/span&gt;: b4aa0076e9b36b2aed8ca8a21ccdd210c905660a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Does this match the Blob object created by Git? You can use the git hash-object command to verify that it really does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% git hash-object first.txt
b4aa0076e9b36b2aed8ca8a21ccdd210c905660a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Excellent! They matched properly!&lt;/p&gt;

&lt;p&gt;Finally, we implement the process of writing the Object to the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// omitting...&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//add&lt;/span&gt;

&lt;span class="c1"&gt;// Compression crate&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flate2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Compression&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//add&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flate2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;write&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ZlibEncoder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//add&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// omitting ...&lt;/span&gt;

    &lt;span class="c1"&gt;// Compressing the stored　content in the object&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ZlibEncoder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;Compression&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;blob_content&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Write by bytes&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;compressed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// hash to string&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:x}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blob_hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Up to 2 characters of the hash value is the directory path and 38 characters is the file path&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="nf"&gt;.split_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Specify the save location by absolute path&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;current_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;current_dir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// path/to/ngit&lt;/span&gt;
    &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".git/objects"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// path/to/ngit/.git/objects&lt;/span&gt;
    &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// path/to/ngit/.git/objects/b4&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;object_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Not moving&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a directory to store in `.git/obejects/`&lt;/span&gt;
    &lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_dir_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// file path is 38 characters of the hash value&lt;/span&gt;
    &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// path/to/ngit/.git/objects/b4/aa0076e9b36b2aed8ca8a21ccdd210c905660a&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;object_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// File contents are compressed contents&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;compressed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we used a new external crate, we will also add it to the toml file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
flate2 = "1.0.25" # add
sha-1 = "0.9.1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% cargo run
blob content: blob 45Hello World!
This is my original git project!
blob &lt;span class="nb"&gt;hash&lt;/span&gt;: b4aa0076e9b36b2aed8ca8a21ccdd210c905660a

&lt;span class="c"&gt;# Objects are properly stored.&lt;/span&gt;
% &lt;span class="nb"&gt;ls&lt;/span&gt; .git/objects/b4
aa0076e9b36b2aed8ca8a21ccdd210c905660a

&lt;span class="c"&gt;# look at the contents with `git-cat-file`&lt;/span&gt;
% git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; aa0076e9b36b2aed8ca8a21ccdd210c905660a
Hello World!
This is my original git project!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can easily create a blob object. In the next article, we will create a function to create this blob! See the next one if you like!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thanks for reading to the end!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>git</category>
      <category>programming</category>
    </item>
    <item>
      <title>Make original Git by Rust! (Analyze section)</title>
      <dc:creator>kataoka_nopeNoshishi</dc:creator>
      <pubDate>Sun, 12 Feb 2023 08:18:13 +0000</pubDate>
      <link>https://forem.com/nopenoshishi/make-your-original-git-analyze-section-139d</link>
      <guid>https://forem.com/nopenoshishi/make-your-original-git-analyze-section-139d</guid>
      <description>&lt;h1&gt;
  
  
  Hello Dev community!
&lt;/h1&gt;

&lt;p&gt;I'm noshishi, a apprentice engineer in Tokyo.&lt;br&gt;
This article is about understanding Git from the inside by creating a simple program that &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But it's a very long story, so I'll post the development section separately!&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Foreword
&lt;/h1&gt;

&lt;p&gt;The starting point is 'If I could understand git, I could make it?!!' &lt;/p&gt;

&lt;p&gt;I took this opportunity to try out a new programming language, so I decided to try &lt;strong&gt;&lt;code&gt;Rust&lt;/code&gt;&lt;/strong&gt; this time. The repository I actually created is &lt;a href="https://github.com/nopeNoshishi/nss" rel="noopener noreferrer"&gt;My original git nss&lt;/a&gt;. The quality of the code isn't quite there yet and many parts are still incomplete, but you can do a straight line of local development!&lt;/p&gt;

&lt;p&gt;If you give me a &lt;strong&gt;star&lt;/strong&gt;, I'll be happy to fly, and of course I'll be waiting for your contributions! Feel free to touch this repository any way you like!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please forgive us for not being able to explain some of the details in this article alone. Also, we use &lt;code&gt;Rust&lt;/code&gt; for development, but &lt;code&gt;Python&lt;/code&gt; for the stage where we uncover Git's internals!&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  TOC
&lt;/h1&gt;



&lt;ul&gt;
&lt;li&gt;
Git Inside?

&lt;ul&gt;
&lt;li&gt;Where is repository&lt;/li&gt;
&lt;li&gt;Object&lt;/li&gt;
&lt;li&gt;Index&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Analyze Object

&lt;ul&gt;
&lt;li&gt;blob&lt;/li&gt;
&lt;li&gt;tree&lt;/li&gt;
&lt;li&gt;commit&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Analyze Index

&lt;ul&gt;
&lt;li&gt;Specification&lt;/li&gt;
&lt;li&gt;Index&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Background of Command

&lt;ul&gt;
&lt;li&gt;add&lt;/li&gt;
&lt;li&gt;commit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Digression

&lt;ul&gt;
&lt;li&gt;Deciphering Tree&lt;/li&gt;
&lt;li&gt;
HEAD and Branch
&lt;/li&gt;
&lt;li&gt;
Plumbing commands
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Finally&lt;/li&gt;
&lt;li&gt;What you need&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  Git Inside
&lt;/h1&gt;

&lt;p&gt;First, we will unpack how Git handles data, based on the official documentation.&lt;br&gt;
The Git command system is very complex.&lt;br&gt;
But, Git data structure is very simple!&lt;/p&gt;
&lt;h2&gt;
  
  
  Where is repository
&lt;/h2&gt;

&lt;p&gt;A repository is the directory under the control of Git, and the folder &lt;code&gt;.git&lt;/code&gt; in the directory created by &lt;code&gt;init&lt;/code&gt; or &lt;code&gt;clone&lt;/code&gt; is the actual state of the repository.&lt;/p&gt;

&lt;p&gt;Let's put an empty folder called &lt;code&gt;project&lt;/code&gt; under Git's control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/noshishi/project
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;span class="c"&gt;# nothing yet&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git init
Initialized empty Git repository &lt;span class="k"&gt;in&lt;/span&gt; /home/noshishi/project/.git/
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;.git&lt;/code&gt; directory consists of the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.git
├── HEAD
├── (index)  // Not created by `init`!
├── config
*
├── objects/
└── refs/
    ├── heads/
    └── tags/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The path types of Git repositories are difficult to understand at first glance. We have added &lt;code&gt;/&lt;/code&gt; to the directory path so that you can refer to it. Also, we have omitted parts that are not explained in this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Object
&lt;/h2&gt;

&lt;p&gt;Git manage versions by &lt;strong&gt;file data&lt;/strong&gt; called &lt;strong&gt;objects&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Objects are stored in &lt;code&gt;.git/objects&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Types
&lt;/h3&gt;

&lt;p&gt;Objects has four types, &lt;code&gt;blob&lt;/code&gt;、&lt;code&gt;tree&lt;/code&gt;、&lt;code&gt;commit&lt;/code&gt;、&lt;code&gt;tag&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The contents of each and the corresponding data will be as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;blob&lt;/code&gt; ... File data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tree&lt;/code&gt; ... Directory data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;commit&lt;/code&gt; ... Metadata to manage the &lt;code&gt;tree&lt;/code&gt; of the repository&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tag&lt;/code&gt; ... Metadata for a specific &lt;code&gt;commit&lt;/code&gt; * Not explained at this article.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Image with &lt;code&gt;first.txt&lt;/code&gt; in the &lt;code&gt;project&lt;/code&gt; repository&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F4f9a06f6-d69b-97f0-c01f-74277e1590a6.png" class="article-body-image-wrapper"&gt;&lt;img alt="Object=png" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F4f9a06f6-d69b-97f0-c01f-74277e1590a6.png" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Structure
&lt;/h3&gt;

&lt;p&gt;The Object is &lt;strong&gt;FILE DATA&lt;/strong&gt;, so it has a &lt;code&gt;file name (path)&lt;/code&gt; and the &lt;code&gt;data&lt;/code&gt; stored in it, just like a normal file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File name (path)&lt;/strong&gt;&lt;br&gt;
The file name (path) is &lt;strong&gt;40-character string&lt;/strong&gt;. This is a hash (&lt;code&gt;sha-1&lt;/code&gt;2) of object &lt;strong&gt;data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Actually, the first two are the directory path and the remaining 38 are the file path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data&lt;/strong&gt;&lt;br&gt;
Object data is compressed by &lt;code&gt;zlib&lt;/code&gt;1. The decompressed data consists of two parts: &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;content&lt;/code&gt;. The two elements are then separated by &lt;code&gt;\0&lt;/code&gt; (null byte).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;header&lt;/code&gt; is a combination of the object type and the size of &lt;code&gt;content&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;content&lt;/code&gt; contains the corresponding data in an easy-to-handle format, as indicated by the &lt;strong&gt;type&lt;/strong&gt;. (Later we will see the details).&lt;/p&gt;

&lt;p&gt;How to Create &lt;code&gt;blob&lt;/code&gt; Object&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2m8iowm5anhqzb5jplhh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2m8iowm5anhqzb5jplhh.png" width="800" height="606"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Index (staging area)
&lt;/h2&gt;

&lt;p&gt;The actual index used when you &lt;code&gt;add&lt;/code&gt; is a file &lt;code&gt;.git/index&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure
&lt;/h3&gt;

&lt;p&gt;The index stores data of files marked by &lt;code&gt;add&lt;/code&gt; with meta information. The stored data contains the latest file data at the time of &lt;code&gt;add&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is important to note that &lt;strong&gt;all data recorded in the index is in file data units&lt;/strong&gt;.&lt;br&gt;
I will describe meta information in detail later, but the storage format is exactly defined as shown in &lt;a href="https://github.com/git/git/blob/v2.12.0/Documentation/technical/index-format.txt" rel="noopener noreferrer"&gt;index-format&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hmm.... feel sleepy....&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wait!&lt;/p&gt;

&lt;p&gt;Let's actually analyze the object and the index!&lt;/p&gt;
&lt;h1&gt;
  
  
  Analyze Object
&lt;/h1&gt;

&lt;p&gt;Before starting the analysis work, create all of the &lt;code&gt;blob&lt;/code&gt;, &lt;code&gt;tree&lt;/code&gt;, and &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
Just add the files in &lt;code&gt;project&lt;/code&gt; and commit.&lt;/p&gt;

&lt;p&gt;Createing the following two files...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;first.txt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello World!
This is first.txt.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;second.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;second&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This is second.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;next, &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nt"&gt;-A&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'initial'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the contents of &lt;code&gt;.git/objects&lt;/code&gt; are now as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.git/
└── objects/
    ├── 48/
    |   └── c972ae2bb5652ada48573daf6d27c74db5a13f
    ├── af/
    |   └── 22102d62f1c8e6df5217b4cba99907580b51af
    ├── da/
    |   └── f3f26f3fa03da346999c3e02d5268cb9abc5c5
    └── f7/
        └── f18b17881d80bb87f281c2881f9a4663cfcf84
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;**From now on, hash values in the text will omit the number of characters. 3&lt;/em&gt;*&lt;/p&gt;



&lt;p&gt;The corresponding data and hash values for each are summarized below.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;hash value&lt;/th&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;th&gt;correspond data&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;f7f18b1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;blob&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;first.txt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;af22102&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;blob&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;second.py&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;daf3f26&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tree&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;project direcrtory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;48c972a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;commit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;commit version 1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;*The analysis work will be conducted interactively using Python, an interpreted language.&lt;/p&gt;
&lt;h2&gt;
  
  
  blob
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;blob&lt;/code&gt; is an object corresponding to file data.&lt;br&gt;
The image looks like this.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c7thhlc2kwqrglscdj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c7thhlc2kwqrglscdj5.png" alt="Blob.png" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Data
&lt;/h3&gt;

&lt;p&gt;First, let's look at &lt;code&gt;f7f18b1&lt;/code&gt;, which corresponds to &lt;code&gt;first.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;...Oops, I failed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% python
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; with open&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.git/objects/f7/f18b17881d80bb87f281c2881f9a4663cfcf84'&lt;/span&gt;, &lt;span class="s1"&gt;'r'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as f:
...     contnet &lt;span class="o"&gt;=&lt;/span&gt; f.read&lt;span class="o"&gt;()&lt;/span&gt;
UnicodeDecodeError: &lt;span class="s1"&gt;'utf-8'&lt;/span&gt; codec can&lt;span class="s1"&gt;'t decode byte 0xca in position 3: invalid continuation byte
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the content is compressed, attempting to read the content as-is as a string 4 will fail.&lt;br&gt;
Therefore, we read the content as binary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; with open&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.git/objects/f7/f18b17881d80bb87f281c2881f9a4663cfcf84'&lt;/span&gt;, &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as f: &lt;span class="c"&gt;# read binary!&lt;/span&gt;
...     contnet &lt;span class="o"&gt;=&lt;/span&gt; f.read&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; content
b&lt;span class="s1"&gt;'x\x01K\xca\xc9OR06d\xf0H\xcd\xc9\xc9W\x08\xcf/\xcaIQ\xe4\n\xc9\xc8,V\x00\xa2\xb4\xcc\xa2\xe2\x12\xbd\x92\x8a\x12=\x00\xfa-\r\x03'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I read successfully and the byte string.&lt;/p&gt;

&lt;p&gt;Now, decompress the content with &lt;code&gt;zlib&lt;/code&gt;, as described in the official documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; import zlib
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed &lt;span class="o"&gt;=&lt;/span&gt; zlib.decompress&lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed
b&lt;span class="s1"&gt;'blob 31\x00Hello World!\nThis is first.txt.'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed.split&lt;span class="o"&gt;(&lt;/span&gt;b&lt;span class="s1"&gt;'\0'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;b&lt;span class="s1"&gt;'blob 31'&lt;/span&gt;, b&lt;span class="s1"&gt;'Hello World!\nThis is first.txt.'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We found that a &lt;code&gt;blob&lt;/code&gt; consists of the following elements&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;header&lt;/code&gt; ... &lt;code&gt;blob 31&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Null byte&lt;/code&gt; ... &lt;code&gt;\x00&lt;/code&gt;　※hex notation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content&lt;/code&gt; ... &lt;code&gt;Hello World!\nThis is first.txt.&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  File name
&lt;/h3&gt;

&lt;p&gt;We should check whether the hash value of the object is indeed correct.&lt;/p&gt;

&lt;p&gt;The file name of the object should be the value obtained by hashing &lt;code&gt;decompressed&lt;/code&gt; with the hash function &lt;code&gt;sha1&lt;/code&gt;, so check it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; import hashlib
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; blob &lt;span class="o"&gt;=&lt;/span&gt; b&lt;span class="s1"&gt;'blob 31\x00Hello World!\nThis is first.txt.'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; sha1 &lt;span class="o"&gt;=&lt;/span&gt; hashlib.sha1&lt;span class="o"&gt;(&lt;/span&gt;blob&lt;span class="o"&gt;)&lt;/span&gt;.hexdigest&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; sha1
&lt;span class="s1"&gt;'f7f18b17881d80bb87f281c2881f9a4663cfcf84'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, exact match!&lt;/p&gt;


&lt;h3&gt;
  
  
  How about another file
&lt;/h3&gt;

&lt;p&gt;Let's also look at &lt;code&gt;af22102&lt;/code&gt;, which corresponds to the other &lt;code&gt;second.py&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; with open&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.git/objects/af/22102d62f1c8e6df5217b4cba99907580b51af'&lt;/span&gt;, &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as f:
...     contnet &lt;span class="o"&gt;=&lt;/span&gt; f.read&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed &lt;span class="o"&gt;=&lt;/span&gt; zlib.decompress&lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed
b&lt;span class="s1"&gt;'blob 44\x00def second():\n    print("This is second.py")'&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; blob &lt;span class="o"&gt;=&lt;/span&gt; b&lt;span class="s1"&gt;'blob 44\x00def second():\n    print("This is second.py")'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; sha1 &lt;span class="o"&gt;=&lt;/span&gt; hashlib.sha1&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;.hexdigest&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; sha1
&lt;span class="s1"&gt;'af22102d62f1c8e6df5217b4cba99907580b51af'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be summarized as follows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;header&lt;/code&gt; ... &lt;code&gt;blob 44&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Null byte&lt;/code&gt; ... &lt;code&gt;\x00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content&lt;/code&gt; ... &lt;code&gt;def second():\n    print("This is second.py")&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the &lt;code&gt;sha1&lt;/code&gt; values (hash values) derived from the data also matched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supplemental&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;blob&lt;/code&gt; itself does not hold the filename of the corresponding file data.&lt;/p&gt;

&lt;p&gt;Instead of &lt;code&gt;blob&lt;/code&gt;, the object that manages its name is &lt;code&gt;tree&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Tree
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tree&lt;/code&gt; is an object corresponding to directory data.&lt;br&gt;
The image looks like this.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue0azcr7sfvopq0qjxpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue0azcr7sfvopq0qjxpo.png" alt="Tree.png" width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will analyze it in the same way as for &lt;code&gt;blob&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; with open&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.git/objects/da/f3f26f3fa03da346999c3e02d5268cb9abc5c5'&lt;/span&gt;, &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as f:
...     content &lt;span class="o"&gt;=&lt;/span&gt; f.read&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed &lt;span class="o"&gt;=&lt;/span&gt; zlib.decompress&lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed
b&lt;span class="s1"&gt;'tree 74\x00100644 first.txt\x00\xf7\xf1\x8b\x17\x88\x1d\x80\xbb\x87\xf2\x81\xc2\x88\x1f\x9aFc\xcf\xcf\x84100644 second.py\x00\xaf"\x10-b\xf1\xc8\xe6\xdfR\x17\xb4\xcb\xa9\x99\x07X\x0bQ\xaf'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed.split&lt;span class="o"&gt;(&lt;/span&gt;b&lt;span class="s1"&gt;'\0'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;b&lt;span class="s1"&gt;'tree 74'&lt;/span&gt;,
 b&lt;span class="s1"&gt;'100644 first.txt'&lt;/span&gt;,
 b&lt;span class="s1"&gt;'\xf7\xf1\x8b\x17\x88\x1d\x80\xbb\x87\xf2\x81\xc2\x88\x1f\x9aFc\xcf\xcf\x84100644 second.py'&lt;/span&gt;,
 b&lt;span class="s1"&gt;'\xaf"\x10-b\xf1\xc8\xe6\xdfR\x17\xb4\xcb\xa9\x99\x07X\x0bQ\xaf'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;tree&lt;/code&gt; has multiple contents, so we seem a bit complicated.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;tree&lt;/code&gt; contnet is composed of repeating &lt;code&gt;mode&lt;/code&gt;5, &lt;code&gt;path&lt;/code&gt; and &lt;code&gt;hash&lt;/code&gt;, which are meta information about the data in the directory,&lt;/p&gt;

&lt;p&gt;If you simply separate them with &lt;code&gt;\0&lt;/code&gt;, the hash value of the previous data and the meta information of the next file data are attached to each other.&lt;/p&gt;

&lt;p&gt;This is because the meta information and the hash value are separated by &lt;code&gt;\0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, we will check the data stored in the first one.&lt;br&gt;
Looking at the split, like &lt;code&gt;first.txt&lt;/code&gt; is stored, right?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; temp &lt;span class="o"&gt;=&lt;/span&gt; decompressed.split&lt;span class="o"&gt;(&lt;/span&gt;b&lt;span class="s1"&gt;'\0'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; temp[1]
b&lt;span class="s1"&gt;'100644 first.txt'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; temp[2]
b&lt;span class="s1"&gt;'\xf7\xf1\x8b\x17\x88\x1d\x80\xbb\x87\xf2\x81\xc2\x88\x1f\x9aFc\xcf\xcf\x84100644 second.py'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to split &lt;code&gt;temp[2]&lt;/code&gt; well, let's take it out by 20 bytes.&lt;br&gt;
Array access of byte strings can be byte.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; temp[2][0:20]
b&lt;span class="s1"&gt;'\xf7\xf1\x8b\x17\x88\x1d\x80\xbb\x87\xf2\x81\xc2\x88\x1f\x9aFc\xcf\xcf\x84'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; temp[2][0:20].hex&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="s1"&gt;'f7f18b17881d80bb87f281c2881f9a4663cfcf84'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; temp[2][20:]
b&lt;span class="s1"&gt;'100644 second.py'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repeating the same process revealed the following.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;header&lt;/code&gt; ... &lt;code&gt;tree 74&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Null byte&lt;/code&gt; ... &lt;code&gt;\x00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content1&lt;/code&gt; ... &lt;code&gt;100644 first.txt\x00f7f18b1...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content2&lt;/code&gt; ... &lt;code&gt;100644 second.py\x00af22102...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The management of &lt;code&gt;tree&lt;/code&gt; hashes is described in (Digression) deciphering Tree bytes!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supplemental&lt;/strong&gt;&lt;br&gt;
A &lt;code&gt;tree&lt;/code&gt; may contain not only a &lt;code&gt;blob&lt;/code&gt; but also a &lt;code&gt;tree&lt;/code&gt;.&lt;br&gt;
That is, if there is a directory within a directory.&lt;br&gt;
This is because &lt;code&gt;tree&lt;/code&gt;, like &lt;code&gt;blob&lt;/code&gt;, does not keep the directory name of itself and the corresponding data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Commit
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;commit&lt;/code&gt; contains the &lt;code&gt;tree&lt;/code&gt; of the repository directory with meta information.&lt;br&gt;
The image looks like this.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkktkqbukvd5v5nedq94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkktkqbukvd5v5nedq94.png" alt="Commit.png" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's analyze!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; with open&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.git/objects/48/c972ae2bb5652ada48573daf6d27c74db5a13f'&lt;/span&gt;, &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as f:
...     content &lt;span class="o"&gt;=&lt;/span&gt; f.read&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed &lt;span class="o"&gt;=&lt;/span&gt; zlib.decompress&lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed
b&lt;span class="s1"&gt;'commit 188\x00tree daf3f26f3fa03da346999c3e02d5268cb9abc5c5\nauthor nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900\ncommitter nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900\n\ninitial\n'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed.split&lt;span class="o"&gt;(&lt;/span&gt;b&lt;span class="s1"&gt;'\0'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;b&lt;span class="s1"&gt;'commit 188'&lt;/span&gt;,
 b&lt;span class="s1"&gt;'tree daf3f26f3fa03da346999c3e02d5268cb9abc5c5\nauthor nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900\ncommitter nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900\n\ninitial\n'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# a little bit more&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; header, content &lt;span class="o"&gt;=&lt;/span&gt; decompressed.split&lt;span class="o"&gt;(&lt;/span&gt;b&lt;span class="s1"&gt;'\0'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; header
b&lt;span class="s1"&gt;'commit 188'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; content
b&lt;span class="s1"&gt;'tree daf3f26f3fa03da346999c3e02d5268cb9abc5c5\nauthor nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900\ncommitter nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900\n\ninitial\n'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; content.split&lt;span class="o"&gt;(&lt;/span&gt;b&lt;span class="s1"&gt;'\n'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;b&lt;span class="s1"&gt;'tree daf3f26f3fa03da346999c3e02d5268cb9abc5c5'&lt;/span&gt;,
 b&lt;span class="s1"&gt;'author nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900'&lt;/span&gt;, 
 b&lt;span class="s1"&gt;'committer nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1674995860 +0900'&lt;/span&gt;, 
 b&lt;span class="s1"&gt;''&lt;/span&gt;, 
 b&lt;span class="s1"&gt;'initial'&lt;/span&gt;,
 b&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The stored data are as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;header&lt;/code&gt; ... &lt;code&gt;commit 188&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Null byte&lt;/code&gt; ... &lt;code&gt;\x00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tree&lt;/code&gt; ... &lt;code&gt;tree daf3f26f3fa03da346999c3e02d5268cb9abc5c5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author&lt;/code&gt; ... &lt;code&gt;author nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 167...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;committer&lt;/code&gt; ... &lt;code&gt;committer nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 167...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;message&lt;/code&gt; ... &lt;code&gt;initial&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see that it contains the &lt;code&gt;tree&lt;/code&gt; hash value that you saw in the &lt;code&gt;tree&lt;/code&gt; chapter earlier, information about the repository owner and the person who made the commit, and the message.&lt;/p&gt;

&lt;p&gt;I will go ahead with the commit and analyze it again.&lt;br&gt;
Edit &lt;code&gt;first.txt&lt;/code&gt; as follows and &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;first.txt(version2)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello World!
This is first.txt.
Version2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add first.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'second'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the contents of &lt;code&gt;.git/objects&lt;/code&gt; are now as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.git/
└── objects/
    ├── 3f/
    |   └── f934272  # new tree .. project repo version 2
    ├── 37/
    |   └── 349c9b0  # new commit .. "second"
    ├── 48/
    |   └── c972ae2  # old commit .. "initial"
    ├── af/
    |   └── 22102d6  # old blob .. second.py version 1
    ├── c8/
    |   └── 843b4db  # new blob .. first.txt version 2
    ├── da/
    |   └── f3f26f3  # old tree .. project repo version 1
    └── f7/
        └── f18b178  # new blob .. first.txt version 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the new commit...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; with open&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.git/objects/37/349c9b05c73281008e7b6b7453b595bb034a52'&lt;/span&gt;, &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as f:
...     content &lt;span class="o"&gt;=&lt;/span&gt; f.read&lt;span class="o"&gt;()&lt;/span&gt;
... 
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed &lt;span class="o"&gt;=&lt;/span&gt; zlib.decompress&lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; decompressed
b&lt;span class="s1"&gt;'commit 235\x00tree 3ff9342727caf81397740327aa406c1cc6d4408e\nparent 48c972ae2bb5652ada48573daf6d27c74db5a13f\nauthor nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1675174139 +0900\ncommitter nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 1675174139 +0900\n\nsecond\n'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The stored data are as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;header&lt;/code&gt; ... &lt;code&gt;commit 188&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Null byte&lt;/code&gt; ... &lt;code&gt;\x00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tree&lt;/code&gt; ... &lt;code&gt;tree daf3f26f3fa03da346999c3e02d5268cb9abc5c5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;parent&lt;/code&gt; ... &lt;code&gt;parent 48c972ae2bb5652ada48573daf6d27c74db5a13f&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author&lt;/code&gt; ... &lt;code&gt;author nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 167...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;committer&lt;/code&gt; ... &lt;code&gt;committer nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt; 167...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;message&lt;/code&gt; ... &lt;code&gt;second&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The new commit stored the hash value of the previous version of &lt;code&gt;commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supplemental&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The difference against &lt;code&gt;blob&lt;/code&gt; or &lt;code&gt;tree&lt;/code&gt; is that &lt;code&gt;commit&lt;/code&gt; does not store the actual data in the repository. But it has meta data starting from &lt;code&gt;tree&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key-Value Store
&lt;/h2&gt;

&lt;p&gt;Some of you may have an idea of what I'm talking about.&lt;/p&gt;

&lt;p&gt;If you unravel a &lt;code&gt;commit&lt;/code&gt;, you can get a &lt;code&gt;tree&lt;/code&gt;, and if you unravel a &lt;code&gt;tree&lt;/code&gt;, you can get a &lt;code&gt;blob&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F665545d3-7b06-df09-bc82-909dc4174ec1.png" class="article-body-image-wrapper"&gt;&lt;img alt="つながり.png" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F665545d3-7b06-df09-bc82-909dc4174ec1.png" width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The version flow shows the history because &lt;code&gt;commit&lt;/code&gt; knows the hash value of the previous &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
This image shows the history of the current commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F94be8594-4225-0089-056e-fe0d204d1ad5.png" class="article-body-image-wrapper"&gt;&lt;img alt="つながり.png" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F94be8594-4225-0089-056e-fe0d204d1ad5.png" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So Git manages file versions from &lt;strong&gt;the starting point, which is the hash value of the object&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Info)&lt;/strong&gt;&lt;br&gt;
Officially, Git is called &lt;strong&gt;Address (hash) File System&lt;/strong&gt;.&lt;br&gt;
The hash function itself is an &lt;code&gt;invertible transformation&lt;/code&gt;, so the original data cannot be restored from the hash value, but as long as the hash value depends on the contents of the object to begin with, it may be called a &lt;strong&gt;value-value store&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In a world without version control systems like Git, what do you do when you &lt;strong&gt;want to keep your current files and work on something new with the same files&lt;/strong&gt;?&lt;br&gt;
Perhaps one way you might think of doing this is to copy the file and put it in another folder.&lt;br&gt;
In fact, this seemingly weird management method is the closest form of version control that supports Git.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Info)&lt;/strong&gt;&lt;br&gt;
Git is a storage system that makes clever use of the OS file system.&lt;/p&gt;
&lt;h1&gt;
  
  
  Analize Index
&lt;/h1&gt;

&lt;p&gt;The index (staging area) is veiled, but like the object, the design is very simple.&lt;br&gt;
(On the other hand, it is a bit quirky to analyze. The dismantling of the index sucked up dozens of hours...&lt;/p&gt;

&lt;p&gt;I'm going to analyze &lt;code&gt;.git/index&lt;/code&gt;, which has been committed for the second time.&lt;/p&gt;
&lt;h2&gt;
  
  
  Specification
&lt;/h2&gt;

&lt;p&gt;In order to analyze, we need to understand the design specification of &lt;code&gt;index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Referring to &lt;a href="https://git-scm.com/docs/index-format" rel="noopener noreferrer"&gt;Index format&lt;/a&gt; in the official document, we found the following specifications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Index Format
Header
    - 4 bytes   Index header                * DIRC
    - 4 bytes   Index version   　　　　     * basic version 2
    - 32 bits   number of entries in index  * Entries are the meta information for each file.

エントリー
    - 32 bits   create file time
    - 32 bits   create file time at nano
    - 32 bits   modify file time
    - 32 bits   modify file time at nano
    - 32 bits   device id
    - 32 bits   inode
    - 32 bits   Permission (mode)
    - 32 bits   user id
    - 32 bits   group id
    - 32 bits   file size
    - 160 bits  `blob` hash value
    - 16 bits   filename size               * Number of bytes in filename string
    - ?  bytes  filename                    * Variable depending on file name
    - 1-8 bytes padding                     * Variable depending on entry

... The same thing continues by number of entries ....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Index
&lt;/h3&gt;

&lt;p&gt;Now that we have the specifications, we will read them again in python.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;index&lt;/code&gt; is uncompressed, but reads in binary format as well as the object because all meta information is stored in bytes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; with open&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.git/index'&lt;/span&gt;, &lt;span class="s1"&gt;'rb'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as f:
...     index &lt;span class="o"&gt;=&lt;/span&gt; f.read&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index
b&lt;span class="s1"&gt;'DIRC\x00\x00\x00\x02\x00\x00\x00\x02c\xd9 \xf4\x05\xeb\x80\xb2c\xd9 \xf4\x05\xeb\x80\xb2\x01\x00\x00\x06\x00\xb8\'&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;07&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;81&lt;span class="se"&gt;\x&lt;/span&gt;a4&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;01&lt;span class="se"&gt;\x&lt;/span&gt;f5&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;14&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;c8&lt;span class="se"&gt;\x&lt;/span&gt;84&lt;span class="p"&gt;;&lt;/span&gt;M&lt;span class="se"&gt;\x&lt;/span&gt;b8&lt;span class="se"&gt;\x&lt;/span&gt;06&lt;span class="se"&gt;\x&lt;/span&gt;e5&lt;span class="se"&gt;\x&lt;/span&gt;d6Z&lt;span class="se"&gt;\x&lt;/span&gt;12&lt;span class="se"&gt;\x&lt;/span&gt;efV&lt;span class="se"&gt;\x&lt;/span&gt;bfK&lt;span class="se"&gt;\x&lt;/span&gt;eeQ&lt;span class="se"&gt;\x&lt;/span&gt;e7&lt;span class="se"&gt;\x&lt;/span&gt;15&lt;span class="se"&gt;\'\x&lt;/span&gt;93&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\t&lt;/span&gt;first.txt&lt;span class="se"&gt;\x&lt;/span&gt;00c&lt;span class="se"&gt;\x&lt;/span&gt;d6hv&lt;span class="se"&gt;\x&lt;/span&gt;17&lt;span class="se"&gt;\x&lt;/span&gt;a5&lt;span class="se"&gt;\x&lt;/span&gt;05nc&lt;span class="se"&gt;\x&lt;/span&gt;d6hv&lt;span class="se"&gt;\x&lt;/span&gt;17&lt;span class="se"&gt;\x&lt;/span&gt;a5&lt;span class="se"&gt;\x&lt;/span&gt;05n&lt;span class="se"&gt;\x&lt;/span&gt;01&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;06&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;b8&lt;span class="se"&gt;\'\x&lt;/span&gt;14&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;81&lt;span class="se"&gt;\x&lt;/span&gt;a4&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;01&lt;span class="se"&gt;\x&lt;/span&gt;f5&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;14&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00,&lt;span class="se"&gt;\x&lt;/span&gt;af&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;10-b&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;f1&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;c8&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;e6&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;dfR&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;17&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;b4&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;cb&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;a9&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;99&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;07X&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;0bQ&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;af&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;second.py&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00TREE&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;19&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;002 0&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;?&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;f94&lt;/span&gt;&lt;span class="se"&gt;\'\'\x&lt;/span&gt;&lt;span class="s2"&gt;ca&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;f8&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;13&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;97t&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;03&lt;/span&gt;&lt;span class="se"&gt;\'\x&lt;/span&gt;&lt;span class="s2"&gt;aa@l&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;1c&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;c6&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;d4@&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;8e&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;f2&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;e4&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;d7:&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;95&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;c1?&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;18&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;d3&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;e9&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;7f&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;8fp&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;9c&lt;/span&gt;&lt;span class="nv"&gt;$N&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;c9dX&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;a4'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks readable in places.&lt;br&gt;
You can see the original &lt;code&gt;DIRC&lt;/code&gt;, &lt;code&gt;first.txt&lt;/code&gt; and &lt;code&gt;second.py&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Since 32bits is 4bytes, it can be easily pulled out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[0:4]
b&lt;span class="s1"&gt;'DIRC'&lt;/span&gt; &lt;span class="c"&gt;# Index header -&amp;gt; DIRC&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[4:8]
b&lt;span class="s1"&gt;'\x00\x00\x00\x02'&lt;/span&gt; &lt;span class="c"&gt;# Index version =&amp;gt; 2&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[8:12]
b&lt;span class="s1"&gt;'\x00\x00\x00\x02'&lt;/span&gt; &lt;span class="c"&gt;# number of entries =&amp;gt; 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;index&lt;/code&gt; manages metadata per file, so you will have two entries, &lt;code&gt;first.txt&lt;/code&gt; and &lt;code&gt;second.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the purpose of this article&lt;/strong&gt;, I will just take a quick look at the meta information from the next creation time to the group ID, which is not very important except for the mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[12:16]
b&lt;span class="s1"&gt;'c\xd9 \xf4'&lt;/span&gt; &lt;span class="c"&gt;# ctime&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[16:20]
b&lt;span class="s1"&gt;'\x05\xeb\x80\xb2'&lt;/span&gt; &lt;span class="c"&gt;# ctime nano&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[21:24]
b&lt;span class="s1"&gt;'\xd9 \xf4'&lt;/span&gt; &lt;span class="c"&gt;# mtime&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[24:28]
b&lt;span class="s1"&gt;'\x05\xeb\x80\xb2'&lt;/span&gt;  &lt;span class="c"&gt;# mtime nano&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[28:32]
b&lt;span class="s1"&gt;'\x01\x00\x00\x06'&lt;/span&gt; &lt;span class="c"&gt;# dev id&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[32:36]
b&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;b8'&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;07"&lt;/span&gt; &lt;span class="c"&gt;# inode&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[36:40]
b&lt;span class="s1"&gt;'\x00\x00\x81\xa4'&lt;/span&gt; &lt;span class="c"&gt;# mode&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[41:44]
b&lt;span class="s1"&gt;'\x00\x01\xf5'&lt;/span&gt; &lt;span class="c"&gt;# user id&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[44:48]
b&lt;span class="s1"&gt;'\x00\x00\x00\x14'&lt;/span&gt; &lt;span class="c"&gt;# gorup id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the key points to look at.&lt;br&gt;
First is the file size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# file size&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[48:52]
b&lt;span class="s1"&gt;'\x00\x00\x00('&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[48:52][0]
0
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[48:52][1]
0
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[48:52][2]
0
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[48:52][3]
40
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file size of the next file to come is found to be 40bytes.&lt;/p&gt;

&lt;p&gt;Next is the hash value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# hash&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[52:72]
b&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;c8&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;84;M&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;b8&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;06&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;e5&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;d6Z&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;12&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;efV&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;bfK&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;eeQ&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;e7&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;15'&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;93"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[52:72].hex&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="s1"&gt;'c8843b4db806e5d65a12ef56bf4bee51e7152793'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see the hash value matches the one in version 2 &lt;code&gt;first.txt&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;And the size of the filename.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# filename size&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[72:74]
b&lt;span class="s1"&gt;'\x00\t'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[72:74][0]
0
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[72:74][1]
9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This size (in bytes) is very important, without it, you will have to search for the next file name by your feeling.&lt;/p&gt;

&lt;p&gt;Now that we know the filename is 9 bytes, we can...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[74:83]
b&lt;span class="s1"&gt;'first.txt'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can extract the file name without missing anything.&lt;/p&gt;

&lt;p&gt;Finally, padding depends on the number of bytes used to represent the entry.&lt;br&gt;
The calculation method is to find &lt;strong&gt;X bytes&lt;/strong&gt; such that the bytes up to the padding plus the &lt;strong&gt;X bytes&lt;/strong&gt; to be padded is a multiple of 8.&lt;/p&gt;

&lt;p&gt;Expressed as a formula, X (padding), y (filename size), a (remainder)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs0yp5i0vzkckcfxyp4w.png" class="article-body-image-wrapper"&gt;&lt;img alt="math1=png" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs0yp5i0vzkckcfxyp4w.png" width="800" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, from &lt;code&gt;creation time&lt;/code&gt; to &lt;code&gt;file size&lt;/code&gt;, 62 bytes, and the &lt;code&gt;file name&lt;/code&gt; is 9 bytes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm090hfwpdh8k0yfhe6cn.png" class="article-body-image-wrapper"&gt;&lt;img alt="math2=png" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm090hfwpdh8k0yfhe6cn.png" width="800" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We found the bytes of padding was 1 byte.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[83:84]
b&lt;span class="s1"&gt;'\x00'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[83:85]
b&lt;span class="s1"&gt;'\x00c'&lt;/span&gt; &lt;span class="c"&gt;# There's one that isn't a null bite, and it's from the second bite!&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; index[83:86]
b&lt;span class="s1"&gt;'\x00c\xd6'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bytes of padding up to the next entry &lt;code&gt;creation time&lt;/code&gt; was correctly matched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Actually, when you &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;tree&lt;/code&gt; is not created.&lt;br&gt;
You commit, then &lt;code&gt;tree&lt;/code&gt; will be generated from &lt;code&gt;index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index&lt;/code&gt; has important role to link added file data to &lt;code&gt;blob&lt;/code&gt;s and manage which versions of files are committed.&lt;/p&gt;

&lt;p&gt;You may have heared git dealed a snapshot, not difference.&lt;br&gt;
In other words, when indexes have not been updated, file data will always remain unless explicitly excluded.&lt;br&gt;
And that means that everything you commit can be restored through the index.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Info)&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;index&lt;/code&gt; is an important entity that holds the key to whether or not a file is subject to version control in Git.&lt;/p&gt;
&lt;h1&gt;
  
  
  Background of Command
&lt;/h1&gt;

&lt;p&gt;Now that we know how Git handles data, let's take a quick look at how the commands behave.&lt;/p&gt;

&lt;p&gt;The command has many options, so more complex behavior can be achieved, but I only describe a basic role.&lt;/p&gt;
&lt;h2&gt;
  
  
  add
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;add&lt;/code&gt; is responsible for adding, deleting, and updating the target file data to the index.&lt;br&gt;
When added, git creates a &lt;code&gt;blob&lt;/code&gt; of the &lt;strong&gt;instantaneous(latest)&lt;/strong&gt; file data.&lt;/p&gt;

&lt;p&gt;The plumbing commands that make this happen are &lt;code&gt;hash-object&lt;/code&gt; and &lt;code&gt;update-index&lt;/code&gt;.&lt;br&gt;
※In Plumbing commands chapter, I describe the detail.&lt;/p&gt;
&lt;h2&gt;
  
  
  commit
&lt;/h2&gt;

&lt;p&gt;Git create a &lt;code&gt;tree&lt;/code&gt; corresponding to the repository directory based on the index created, and then create a &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
After the &lt;code&gt;commit&lt;/code&gt; is successfully created, change the hash value of the &lt;code&gt;commit&lt;/code&gt; that the &lt;code&gt;HEAD&lt;/code&gt; and &lt;code&gt;branch&lt;/code&gt; point to.&lt;/p&gt;

&lt;p&gt;The plumbing commands that accomplish this are &lt;code&gt;write-tree&lt;/code&gt;, &lt;code&gt;commit-tree&lt;/code&gt;, and &lt;code&gt;update-ref&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Digression
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Deciphering Tree
&lt;/h2&gt;

&lt;p&gt;We'll look into the byte in a bit.&lt;/p&gt;

&lt;p&gt;What is the maximum value of a number that can be represented by a single (unsigned) byte?&lt;br&gt;
2^8 - 1 = 255. This corresponds to the maximum number of hexadecimal digits that can be represented by two hexadecimal digits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; temp[2][0]
247　 &lt;span class="c"&gt;# = `\xf7`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used the &lt;code&gt;hex()&lt;/code&gt; function quickly above, but if you look at it one byte at a time...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;hex &lt;span class="k"&gt;in &lt;/span&gt;temp[2][0:20]:
...     &lt;span class="nb"&gt;hash&lt;/span&gt; +&lt;span class="o"&gt;=&lt;/span&gt; format&lt;span class="o"&gt;(&lt;/span&gt;hex, &lt;span class="s1"&gt;'x'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;
&lt;span class="s1"&gt;'f7f18b17881d80bb87f281c2881f9a4663cfcf84'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can get the hash value of the &lt;code&gt;blob&lt;/code&gt; corresponding to &lt;code&gt;first.txt&lt;/code&gt; as a string!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hash&lt;/code&gt; are 40 characters, but each character is a value calculated in hexadecimal. So the trick is that one byte can represent two characters .&lt;/p&gt;

&lt;p&gt;&lt;code&gt;commit&lt;/code&gt; stores the hash value as a string, but for some reason the &lt;code&gt;tree&lt;/code&gt; stores the hash value directly as bytes, not as a string.&lt;/p&gt;

&lt;p&gt;There was some discussion on stackoverflow as to why.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/42009133/how-to-inflate-a-git-tree-object" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/42009133/how-to-inflate-a-git-tree-object&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  HEAD and Branch
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Branch&lt;/code&gt; is responsible for marking specific &lt;code&gt;commit&lt;/code&gt; objects.&lt;br&gt;
It is stored under &lt;code&gt;.git/refs/heads/&lt;/code&gt;.&lt;br&gt;
You can easily see the contents with the Linux command &lt;code&gt;cat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since we were working on the &lt;code&gt;master&lt;/code&gt; branch earlier, we can look at &lt;code&gt;.git/refs/heads/master&lt;/code&gt; and see ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;cat&lt;/span&gt; .git/refs/heads/master
37349c9b05c73281008e7b6b7453b595bb034a52
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hash value of the last committed &lt;code&gt;commit&lt;/code&gt; object was stored.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;HEAD&lt;/code&gt; indicates which &lt;code&gt;commit&lt;/code&gt; object you are basing your file edits on.&lt;br&gt;
HEAD can point directly to a &lt;code&gt;commit&lt;/code&gt; object, but it basically goes through &lt;code&gt;branch&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;.git/HEAD&lt;/code&gt; is what it is.&lt;/p&gt;

&lt;p&gt;The data is stored as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;cat&lt;/span&gt; .git/HEAD
ref: refs/heads/master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It contained the path about where the &lt;code&gt;master&lt;/code&gt; branch is stored.&lt;/p&gt;

&lt;p&gt;If you want to point directly to a commit (detached head), use &lt;code&gt;checkout&lt;/code&gt; to move &lt;code&gt;HEAD&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% git checkout 37349c9b05c73281008e7b6b7453b595bb034a52
% &lt;span class="nb"&gt;cat&lt;/span&gt; .git/HEAD
ref: 37349c9b05c73281008e7b6b7453b595bb034a52
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Plumbing commands
&lt;/h2&gt;

&lt;p&gt;To further manipulate Git at a low level, there is a command for every single action.&lt;br&gt;
(These are god-like commands created by Mr. Linus for ordinary people like me.)&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;cat-file&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command allows you to see the contents of an object.&lt;br&gt;
We worked hard earlier to analyze the object, but this single command is the solution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# See object type&lt;/span&gt;
% git cat-file &lt;span class="nt"&gt;-t&lt;/span&gt; af22102d62f1c8e6df5217b4cba99907580b51af &lt;span class="c"&gt;# second.py&lt;/span&gt;
blob

&lt;span class="c"&gt;# Output object content&lt;/span&gt;
% git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; af22102d62f1c8e6df5217b4cba99907580b51af &lt;span class="c"&gt;# second.py&lt;/span&gt;
def second&lt;span class="o"&gt;()&lt;/span&gt;:
    print&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"This is second.py"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;hash-object&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;You can hash file data, etc. or store them in &lt;code&gt;.git/objects&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's create &lt;code&gt;third.rs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Third&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;   
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# calculate hash value&lt;/span&gt;
% git hash-object
4aa58eed341d5134f73f2e9378b4895e216a5cd5

&lt;span class="c"&gt;# Create blob object&lt;/span&gt;
% git hash-object &lt;span class="nt"&gt;-w&lt;/span&gt;
4aa58eed341d5134f73f2e9378b4895e216a5cd5
% &lt;span class="nb"&gt;ls&lt;/span&gt; .git/objects/4a
a58eed341d5134f73f2e9378b4895e216a5cd5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;update-index&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command adds the target file to the index.&lt;br&gt;
Note, however, that no object is created.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;ls-files&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command provides a concise view of the contents of the index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# see the latest index&lt;/span&gt;
% git ls-files
first.txt
second.py

&lt;span class="c"&gt;# add index third.rs cache&lt;/span&gt;
% git update-index &lt;span class="nt"&gt;--add&lt;/span&gt; third.rs 
% git ls-files
first.txt
second.py
third.rs
% git ls-files &lt;span class="nt"&gt;-s&lt;/span&gt;
100644 c8843b4db806e5d65a12ef56bf4bee51e7152793 0       first.txt
100644 af22102d62f1c8e6df5217b4cba99907580b51af 0       second.py
100644 4aa58eed341d5134f73f2e9378b4895e216a5cd5 0       third.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;write-tree&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;We create a &lt;code&gt;tree&lt;/code&gt; based on the contents of the index.&lt;br&gt;
All directories, not just repository directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% git write-tree
109e41a859caa3e3b87e8f59744b0b1845efe275
% &lt;span class="nb"&gt;ls&lt;/span&gt; .git/objects/10 
9e41a859caa3e3b87e8f59744b0b1845efe275
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;commit-tree&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;We create the &lt;code&gt;commit&lt;/code&gt; with the hash of the (repository directory) &lt;code&gt;tree&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enter the hash value of the parent `commit` and the &lt;/span&gt;
&lt;span class="c"&gt;# hash value of the `tree` you just created&lt;/span&gt;
% git commit-tree &lt;span class="nt"&gt;-p&lt;/span&gt; 37349c9b05c73281008e7b6b7453b595bb034a52 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'third commit'&lt;/span&gt; 109e41a859caa3e3b87e8f59744b0b1845efe275
ddb3c0d94d860ff657e2cdb82f5513f7db2924f1
% &lt;span class="nb"&gt;ls&lt;/span&gt; .git/objects/dd 
b3c0d94d860ff657e2cdb82f5513f7db2924f1　#　object is created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;update-ref&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;We can't just &lt;code&gt;commit-tree&lt;/code&gt; and follow the history, because no one will see the commits you made.&lt;br&gt;
This is because no one can see the commits we have made.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Because the git log follows the history sequentially &lt;/span&gt;
&lt;span class="c"&gt;# from the commit pointed to by HEAD, the commit you&lt;/span&gt;
&lt;span class="c"&gt;# just created is not yet referenced.&lt;/span&gt;
% git log
commit 37349c9b05c73281008e7b6b7453b595bb034a52 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt;
Author: nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt;
Date:   Tue Jan 31 23:08:59 2023 +0900

    second

commit 48c972ae2bb5652ada48573daf6d27c74db5a13f
Author: nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt;
Date:   Sun Jan 29 21:37:40 2023 +0900

    initial

&lt;span class="c"&gt;# Change the branch's references.&lt;/span&gt;
% git update-ref refs/heads/master ddb3c0d 37349c9 &lt;span class="c"&gt;# new-hash old-hash&lt;/span&gt;
% git log
commit ddb3c0d94d860ff657e2cdb82f5513f7db2924f1 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt;
Author: nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt;
Date:   Thu Feb 2 21:17:24 2023 +0900

    third commit

commit 37349c9b05c73281008e7b6b7453b595bb034a52
Author: nopeNoshishi &amp;lt;nope@noshishi.jp&amp;gt;
Date:   Tue Jan 31 23:08:59 2023 +0900

    second

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In creating Git, it is difficult to suddenly create something as sophisticated as &lt;code&gt;add&lt;/code&gt; or &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
Therefore, while implementing the plumbing command , we will create &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt; in the development section to bypass the functionality of this command.&lt;/p&gt;

&lt;h1&gt;
  
  
  Finally
&lt;/h1&gt;

&lt;p&gt;Thank you for reading all the way to the end!!!&lt;br&gt;
This is still a rough explanation, but I hope it contributes to your understanding.&lt;br&gt;
If you may ok, please star my repository!&lt;/p&gt;

&lt;h1&gt;
  
  
  Reference Site
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/doc" rel="noopener noreferrer"&gt;Officail Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What you need
&lt;/h1&gt;

&lt;p&gt;Listed here are the key elements in making git.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html" rel="noopener noreferrer"&gt;Binary&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.stanford.edu/class/cs101/bits-bytes.html" rel="noopener noreferrer"&gt;Byte&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Bitwise_operation" rel="noopener noreferrer"&gt;Bitwise operation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://users.ece.utexas.edu/~ryerraballi/CPrimer/chap3/chap3.htm" rel="noopener noreferrer"&gt;n-decimal system and character strings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/String_(computer_science)" rel="noopener noreferrer"&gt;String&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://geekyhumans.com/de/most-popular-data-compression-algorithms/" rel="noopener noreferrer"&gt;Compression algorithms&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thesslstore.com/blog/what-is-a-hash-function-in-cryptography-a-beginners-guide/" rel="noopener noreferrer"&gt;Hash function&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.javatpoint.com/linux-file-system#:~:text=What%20is%20the%20Linux%20File,more%20information%20about%20a%20file." rel="noopener noreferrer"&gt;File system&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Annotation
&lt;/h1&gt;

&lt;h3&gt;
  
  
  zlib
&lt;/h3&gt;

&lt;p&gt;&lt;span id="q1"&gt;1: This is a free software to compress data losslessly. The main compression algorithm called Deflate is very interesting.&lt;a href="https://www.zlib.net/" rel="noopener noreferrer"&gt;Official Site&lt;/a&gt; back to article&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  sha1
&lt;/h3&gt;

&lt;p&gt;&lt;span id="q2"&gt;2: One of the very famous SHA-based hash functions, characterized by the generation of a 60-bit (20-byte) hash value. Incidentally, the probability of a collision of sha1 hash values is said to be astronomical.&lt;a href="https://pthree.org/2014/03/06/the-reality-of-sha1/#:~:text=It%20should%20take%202%5E160,in%20about%202%5E80%20operations." rel="noopener noreferrer"&gt;The Reality of SHA1&lt;/a&gt;  back to article&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  hash number
&lt;/h3&gt;

&lt;p&gt;&lt;span id="q3"&gt;3: When you specify a hash value directly in a Git command, you may only use 7 characters. As mentioned in [^2](#ano-2), this means that even with a small input hash value, we can find a specific object because there are almost no hash collisions. It is similar to the feeling of pressing tab in &lt;code&gt;shell&lt;/code&gt; to receive input assistance. back to article&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  compressed string
&lt;/h3&gt;

&lt;p&gt;&lt;span id="q4"&gt;4: Compressed data is stored in a form that does not correspond to a character code. Therefore, it cannot be read as a specific character code. back to article&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  mode
&lt;/h3&gt;

&lt;p&gt;&lt;span id="q5"&gt;5: The mode (permission) can of course also be expressed in binary. And since there are few combinations, certain combinations can be expressed in computation. back to article&lt;/span&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>learning</category>
      <category>codenewbie</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Understanding Git through images</title>
      <dc:creator>kataoka_nopeNoshishi</dc:creator>
      <pubDate>Thu, 05 Jan 2023 15:22:20 +0000</pubDate>
      <link>https://forem.com/nopenoshishi/understanding-git-through-images-4an1</link>
      <guid>https://forem.com/nopenoshishi/understanding-git-through-images-4an1</guid>
      <description>&lt;h1&gt;
  
  
  Hello Dev community!
&lt;/h1&gt;

&lt;p&gt;I am a newbie, still a few months into my career as a developer in Japan. I was inspired by &lt;a href="https://dev.to/unseenwizzard/learn-git-concepts-not-commands-4gjc"&gt;Nico Riedmann's Learn git concepts, not commands&lt;/a&gt;, and I have summarized git in my own way. Of course, I supplemented it with reading the &lt;a href="https://git-scm.com/doc" rel="noopener noreferrer"&gt;official documentation &lt;/a&gt;as well.&lt;br&gt;
Understanding git from its system structure makes git more fun. I have recently become so addicted to git that I am in the process of creating my own git system.&lt;/p&gt;

&lt;p&gt;Recently, I wrote how to make software like git!&lt;br&gt;
&lt;a href="https://dev.to/nopenoshishi/make-your-original-git-analyze-section-139d"&gt;Make original git&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
What is Git?

&lt;ul&gt;
&lt;li&gt;Manage versions and Distribute work&lt;/li&gt;
&lt;li&gt;Using Git means&lt;/li&gt;
&lt;li&gt;Understanding by image&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Start new work

&lt;ul&gt;
&lt;li&gt;Repositories&lt;/li&gt;
&lt;li&gt;Copy the repository and start working&lt;/li&gt;
&lt;li&gt;(Supplemental) Working Directory&lt;/li&gt;
&lt;li&gt;Change and Add files&lt;/li&gt;
&lt;li&gt;Adapt to remote repositories&lt;/li&gt;
&lt;li&gt;View Differences&lt;/li&gt;
&lt;li&gt;(Aside) One step called staging area&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Branch

&lt;ul&gt;
&lt;li&gt;Create new branch&lt;/li&gt;
&lt;li&gt;Work in Branches&lt;/li&gt;
&lt;li&gt;(Aside)Git-Flow and GitHub-Flow&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Merge

&lt;ul&gt;
&lt;li&gt;Fast Forward&lt;/li&gt;
&lt;li&gt;No Fast Forward&lt;/li&gt;
&lt;li&gt;Deal with Conflicts&lt;/li&gt;
&lt;li&gt;Delete unnecessary branches&lt;/li&gt;
&lt;li&gt;(aside) What is the branch?&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Rebase

&lt;ul&gt;
&lt;li&gt;Move the branch&lt;/li&gt;
&lt;li&gt;Deal with rebase conflicts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Keep local repositories up-to-date

&lt;ul&gt;
&lt;li&gt;Branch and Repository&lt;/li&gt;
&lt;li&gt;Check the latest status&lt;/li&gt;
&lt;li&gt;Update to the latest status&lt;/li&gt;
&lt;li&gt;Deal with pull conflicts&lt;/li&gt;
&lt;li&gt;(Aside) Identity of pull requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Useful Functions

&lt;ul&gt;
&lt;li&gt;Correct the commit&lt;/li&gt;
&lt;li&gt;Delete the commit&lt;/li&gt;
&lt;li&gt;Evacuate the work&lt;/li&gt;
&lt;li&gt;Bring the commit&lt;/li&gt;
&lt;li&gt;Mastering HEAD&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

End

&lt;ul&gt;
&lt;li&gt;Source code management without Git&lt;/li&gt;
&lt;li&gt;Where is the remote repository&lt;/li&gt;
&lt;li&gt;Pointer&lt;/li&gt;
&lt;li&gt;To further understand Git&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Reference&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a id="markdown-what-is-git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Git?
&lt;/h1&gt;

&lt;p&gt;&lt;a id="markdown-manage-distribute"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Manage versions and Distribute work
&lt;/h3&gt;

&lt;p&gt;Git is a type of source code management system called a distributed version control system.&lt;br&gt;
Git is a tool to facilitate development work by &lt;strong&gt;recording and tracking the changelog (version) of files&lt;/strong&gt;, comparing past and current files, and clarifying changes.&lt;br&gt;
The system also allows &lt;strong&gt;multiple developers to edit files at once&lt;/strong&gt;, so the work can be distributed.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-using-git-means"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Git means
&lt;/h3&gt;

&lt;p&gt;First, make a copy of the file or other files in a storage location that can be shared by everyone (from now on referred to as "remote repository") on your computer (from now on referred to as "local repository"), and then add or edit new code or files.&lt;br&gt;
Then, the files will be updated by registering them from the local repository to the remote repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsdhsqagzc7h8u5akod6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsdhsqagzc7h8u5akod6.png" alt="git_workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-understading-by-image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Understading by image
&lt;/h3&gt;

&lt;p&gt;When dealing with Git, it is important to follow "how to work" from "what" to "what".&lt;br&gt;
If you only operate commands, you may not understand what is happening and use the wrong command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When manipulating Git, try to imagine what is happening before and after the operation.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-start-new-work"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start new work
&lt;/h2&gt;

&lt;p&gt;&lt;a id="markdown-repositories"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Repositories
&lt;/h3&gt;

&lt;p&gt;A repository in Git is a storage for files, which can be remote or local.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remote Repository&lt;/strong&gt; is a repository where the source code is placed on a server on the Internet and can be shared by everyone.&lt;br&gt;
&lt;strong&gt;Local repository&lt;/strong&gt; is a repository where the source code is located on your computer and only you can make changes.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-copy-the-repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Copy the repository and start working
&lt;/h3&gt;

&lt;p&gt;First, prepare your own development environment.&lt;br&gt;
All you need only to do is decide in which directory you will work.&lt;br&gt;
For example, your home directory is fine, or any directory you normally use.&lt;/p&gt;

&lt;p&gt;Next, copy and bring the files from the remote repository.&lt;br&gt;
This is called &lt;code&gt;clone&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frml9wqair7kg7wsisi9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frml9wqair7kg7wsisi9u.png" alt="clone"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The remote repository called &lt;code&gt;project&lt;/code&gt; contains only &lt;code&gt;first.txt&lt;/code&gt;, and this is the image when you &lt;code&gt;clone&lt;/code&gt; the remote repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, you may create a local repository first and then reflect the remote repository.&lt;br&gt;
This is called &lt;code&gt;initialize&lt;/code&gt; and allows you to convert a directory you are already working on into a repository.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-working-directory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  (Supplemental) Working Directory
&lt;/h3&gt;

&lt;p&gt;A working directory is not any special directory, but a directory where you always work on your computer.&lt;br&gt;
It's easier to understand if you think of it as a directory where you can connect to the target directory that Git manages (in this case, &lt;code&gt;project&lt;/code&gt;) with a Git staging area or local repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffoxzc5v3gd5d11umzzj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffoxzc5v3gd5d11umzzj8.png" alt="wroking directory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-change-and-add-file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Change and Add file
&lt;/h3&gt;

&lt;p&gt;Changes to the source code are made through the working directory, the staging area.&lt;br&gt;
Actually, in the working directory, we work.&lt;/p&gt;

&lt;p&gt;Let's create a new file called &lt;code&gt;second.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjld228v47s0o3c0zyjc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjld228v47s0o3c0zyjc.png" alt="new file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, move the modified file to the staging area.&lt;br&gt;
This is called &lt;code&gt;add&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is a feature of Git that there is a cushion before changes are reflected in the local repository.&lt;br&gt;
I will explain why this cushion exists in more detail later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rsaucz4mwif9mqgqh4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rsaucz4mwif9mqgqh4j.png" alt="add"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we registere the content in the staging area to the local repository.&lt;br&gt;
This is called &lt;code&gt;commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By the way, we can comment when you &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
In this case, we added a file, so write &lt;code&gt;git commit -m 'add second.txt'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F879r8a67bbpd686bm23s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F879r8a67bbpd686bm23s.png" alt="commit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you commit, a &lt;strong&gt;commit object&lt;/strong&gt; is created in the repository.&lt;br&gt;
A simple explanation of a commit object is the data that has the updater's information and the modified file.&lt;br&gt;
(All data is saved, not just the differences, but the entire state of the file at that moment (snapshot).&lt;br&gt;
Please refer to &lt;a href="https://git-scm.com/book/en/v2/Git-Internals-Git-Objects" rel="noopener noreferrer"&gt;Git Objects&lt;/a&gt; for more information about Git objects.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-adapt-to-remote"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adapt to remote repositories
&lt;/h3&gt;

&lt;p&gt;Then, the work is done!&lt;br&gt;
The last step is to reflect the changes in the local repository to the remote repository.&lt;br&gt;
This is called &lt;code&gt;push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0ijlyrhm1gwgn44374q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0ijlyrhm1gwgn44374q.png" alt="push"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It may be easier to understand if you think of it as a commit to a remote repository.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-view-differences"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  View Differences
&lt;/h3&gt;

&lt;p&gt;Changes between the same file are called &lt;code&gt;diff&lt;/code&gt;.&lt;br&gt;
We can see the changing points in the file.&lt;/p&gt;

&lt;p&gt;I won't go into the details of the commands, but here are three that I use frequently.&lt;br&gt;
&lt;code&gt;git diff --stage&lt;/code&gt; to see the changes from the original working directory before you &lt;code&gt;add&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;git diff --stage&lt;/code&gt; to see changes to the working directory after &lt;code&gt;add&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;git diff &amp;lt;commit&amp;gt; &amp;lt;commit&amp;gt;&lt;/code&gt; to compare commits.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-staging-area"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  (Aside) One step called staging area
&lt;/h3&gt;

&lt;p&gt;As development work grows, we often make many changes in one working directory.&lt;br&gt;
What happens if you put all the changes in a local repository at once?&lt;br&gt;
In this case, when parsing the commits, you may not know where a feature was implemented.&lt;/p&gt;

&lt;p&gt;In Git, it is recommended to do one &lt;code&gt;commit&lt;/code&gt; per feature.&lt;br&gt;
This is why there is a staging area where you can subdivide the &lt;code&gt;commit&lt;/code&gt; unit into smaller units.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i00yr7n7bv01fi217zl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i00yr7n7bv01fi217zl.png" alt="staging area"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The concept of Git is to stage only what is needed, and then proceed with the work or &lt;code&gt;commit&lt;/code&gt; ahead of time to promote efficient development that can be traced back through the history of each implementation.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-summary1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;The basic workflow is to &lt;code&gt;clone&lt;/code&gt; once and then &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, and &lt;code&gt;push&lt;/code&gt; for each working.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F9dccfc0e-f2d9-5405-29c4-890f34894308.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F9dccfc0e-f2d9-5405-29c4-890f34894308.gif" alt="basic.gif"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clone&lt;/code&gt;: Make a copy from the remote repository to your development environment (local repository and working directory).&lt;br&gt;
&lt;code&gt;add&lt;/code&gt;: Add files from the working directory to the staging area and prepare them for commit.&lt;br&gt;
&lt;code&gt;commit&lt;/code&gt;: Register the file from the staging area to the local repository. At this time, a commit object is created.&lt;br&gt;
&lt;code&gt;push&lt;/code&gt;: Register changes from the local repository to the remote repository.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-branch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Branch
&lt;/h1&gt;

&lt;p&gt;We create a &lt;code&gt;branch&lt;/code&gt; to change and add files in multiple branches.&lt;br&gt;
The files saved in the &lt;code&gt;main&lt;/code&gt; branch are in ongoing use.&lt;br&gt;
The reason for the separate branches is to work &lt;strong&gt;without affecting the currently running source code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-create-new-branch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create new branch
&lt;/h3&gt;

&lt;p&gt;Let's create the branch called &lt;code&gt;develop&lt;/code&gt;!&lt;br&gt;
We can create a branch with &lt;code&gt;git branch &amp;lt;new branch&amp;gt;&lt;/code&gt; or &lt;code&gt;git checkout -b &amp;lt;new branch&amp;gt;&lt;/code&gt;.&lt;br&gt;
The former just create a branch, the latter create a branch and moves you to that branch.&lt;br&gt;
(Branches are maintained in the repository.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrmfyntnpy9met5cc3l5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrmfyntnpy9met5cc3l5.png" alt="new branch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key point when generating branches is &lt;strong&gt;which branch to derive from&lt;/strong&gt;.&lt;br&gt;
We can specify the source as &lt;code&gt;git checkout -b &amp;lt;new branch&amp;gt; &amp;lt;from branch&amp;gt;&lt;/code&gt;.&lt;br&gt;
If we don't, the branch you are currently working on becomes the &lt;code&gt;&amp;lt;from branch&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A branch is actually a &lt;strong&gt;pointer&lt;/strong&gt; to the commit (strictly speaking, a hash of commit objects).&lt;br&gt;
Generating a new branch means that the new branch indicate to the commit that the from　branch pointed to as well.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-work-in-branches"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Work in Branches
&lt;/h3&gt;

&lt;p&gt;Moving the branch is called &lt;code&gt;checking out&lt;/code&gt;.&lt;br&gt;
The pointer to the branch you are currently working on is called &lt;code&gt;HEAD&lt;/code&gt;.&lt;br&gt;
So, moving from the &lt;code&gt;main&lt;/code&gt; branch to the &lt;code&gt;develop&lt;/code&gt; branch means changing the &lt;code&gt;HEAD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floxgrl33lwvjz3n39pkp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floxgrl33lwvjz3n39pkp.png" alt="checkout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now both branches point to the commit named &lt;code&gt;Atr3ul&lt;/code&gt;.&lt;br&gt;
You just added &lt;code&gt;second.txt&lt;/code&gt; by committing in the &lt;code&gt;main&lt;/code&gt; branch, so you are ahead of the commit &lt;code&gt;f27baz&lt;/code&gt;.&lt;br&gt;
From here, let's say you change &lt;code&gt;second.txt&lt;/code&gt; in the &lt;code&gt;develop&lt;/code&gt; branch and make a new commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfk2fgoa06mq3pmbd2g8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfk2fgoa06mq3pmbd2g8.png" alt="new commit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, as shown in the figure, the &lt;code&gt;develop&lt;/code&gt; branch created a commit called &lt;code&gt;m9sgle&lt;/code&gt; and pointed to that commit.&lt;/p&gt;

&lt;p&gt;The current HEAD position (working branch position), what stage the file has been worked on, or the status of who is working on it is called &lt;code&gt;status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are familiar with object-oriented, you may understand the reason for the arrow on the commit.&lt;br&gt;
It represents the relationship between a "parent" commit and a "child" commit.&lt;br&gt;
The assumption is that &lt;code&gt;parent←-child&lt;/code&gt;, that is, how much the child (commit) born from the parent (commit) has grown (changed).&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-gitflow-githubflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  (Aside)Git-Flow and GitHub-Flow
&lt;/h3&gt;

&lt;p&gt;The way branches to manage will vary on development team.&lt;br&gt;
On the other hand, like programming naming conventions, there is a general model for how to grow branches in Git.&lt;br&gt;
Here are two simple ones. I think it's enough to know that there is such a thing.&lt;/p&gt;



&lt;p&gt;The "Git Flow" is a fairly complex and intricate structure.&lt;br&gt;
I think it's a model of how Git should be used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qa7upoeya40kmmtu1ch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qa7upoeya40kmmtu1ch.png" alt="git flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Definition of each branch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;master&lt;/code&gt;: Branch to release a product. No working on this branch.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;development&lt;/code&gt;: Branch to develope a product. When ready to release, merge to &lt;code&gt;release&lt;/code&gt;. No working on this branch.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;feature&lt;/code&gt;: Branch for adding features, merged into development when ready for release.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hotfix&lt;/code&gt;: For urgent post-release work (critical bug fixes, etc.), branch off from master, merge into master, and merge into develop.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;release&lt;/code&gt;: For preparation of product release. Branch from &lt;code&gt;develop&lt;/code&gt; with features and bug fixes to be released.&lt;br&gt;
When ready for release, merge to master and merge to develop.&lt;/p&gt;



&lt;p&gt;The "GitHub Flow" is a somewhat simplified model of the Git Flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39y36qwrpkuaiw0oryw2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39y36qwrpkuaiw0oryw2.png" alt="github flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it consists of only &lt;code&gt;master&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt;.&lt;br&gt;
The important difference is the cushion of &lt;code&gt;pull requests&lt;/code&gt; (explained in the pull below), which allows integration between branches.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-summary2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Basically, since there is no work on main (master), we create a branch for each work unit we want to do and create a new commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2Ff5158fea-ea6c-a033-11f7-27a9b152539c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2Ff5158fea-ea6c-a033-11f7-27a9b152539c.gif" alt="branch_anime.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;branch&lt;/code&gt;: New pointer to the commit&lt;br&gt;
&lt;code&gt;checkout&lt;/code&gt;: Move &lt;code&gt;HEAD&lt;/code&gt; to change the &lt;code&gt;branch&lt;/code&gt; to work on.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-merge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Merge
&lt;/h1&gt;

&lt;p&gt;integrating the branches is called &lt;code&gt;merge&lt;/code&gt;.&lt;br&gt;
Basically, we merge into the &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;develop&lt;/code&gt; branch.&lt;br&gt;
Be careful not to mistake the subject of which branch is merging (absorbing) which branch.&lt;br&gt;
We will always move (HEAD) to the branch from which you are deriving, and then do the integration from the branch from which you are deriving.&lt;/p&gt;

&lt;p&gt;I am currently working on the &lt;code&gt;feature&lt;/code&gt; branch and have created the following &lt;code&gt;third.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faq641yqw80zrlyek0cg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faq641yqw80zrlyek0cg6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;third.txt&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Hello, World! I'm noshishi, from Japan.
I like dancing on house music.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Then We &lt;code&gt;add&lt;/code&gt; and finished up to &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-fast-forward"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fast Forward
&lt;/h3&gt;

&lt;p&gt;When the &lt;code&gt;feature&lt;/code&gt; branch points to the commit that can be traced back to the &lt;code&gt;develop&lt;/code&gt; branch, the &lt;code&gt;develop&lt;/code&gt; branch is in a &lt;code&gt;fast-forward&lt;/code&gt; state.&lt;/p&gt;

&lt;p&gt;First, move to &lt;code&gt;develop&lt;/code&gt; with &lt;code&gt;checkout&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qdb3duz1zrsy0dqm2vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qdb3duz1zrsy0dqm2vw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, the &lt;code&gt;develop&lt;/code&gt; branch has not progressed at all, so to &lt;code&gt;merge&lt;/code&gt; the &lt;code&gt;feature&lt;/code&gt; branch will simply move the commit forward.&lt;br&gt;
In this case, the &lt;code&gt;develop&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt; branches share the same commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxr6f11juckcuz18zp85j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxr6f11juckcuz18zp85j.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-no-fast-forward"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  No Fast Forward
&lt;/h3&gt;

&lt;p&gt;What if the &lt;code&gt;develop&lt;/code&gt; branch has progressed to a new commit by commit or merge?&lt;br&gt;
This is called a &lt;code&gt;no fast-forward&lt;/code&gt; situation.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;develop&lt;/code&gt; branch, you have made changes to &lt;code&gt;first.txt&lt;/code&gt; and have finished &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
So the &lt;code&gt;develop&lt;/code&gt; branch and the &lt;code&gt;feature&lt;/code&gt; branch are completely split.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07tzgemk4dbqknuw7xqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07tzgemk4dbqknuw7xqx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try to &lt;code&gt;merge&lt;/code&gt; a &lt;code&gt;feature&lt;/code&gt; branch from a &lt;code&gt;develop&lt;/code&gt; branch, Git will check your changelog against each other.&lt;br&gt;
If there are no conflicting edits, a &lt;code&gt;merge commit&lt;/code&gt; is created immediately.&lt;br&gt;
This is called an &lt;code&gt;automatic merge&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F208vi5pnttui4rckp1pj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F208vi5pnttui4rckp1pj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-deal-with-conflicts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deal with Conflicts
&lt;/h3&gt;

&lt;p&gt;In the &lt;code&gt;no fast-forward&lt;/code&gt; state, the differences in work content. is called &lt;code&gt;conflict&lt;/code&gt;.&lt;br&gt;
In this case, we must manually fix the &lt;code&gt;conflict&lt;/code&gt; content and &lt;code&gt;commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;develop&lt;/code&gt; branch, we created the following &lt;code&gt;third.txt&lt;/code&gt; and &lt;code&gt;committed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;third.txt&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Hello, World! I'm nope, from USA.
I like dancing on house music.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;develop&lt;/code&gt; branch, &lt;code&gt;I'm nope, from USA&lt;/code&gt;.&lt;br&gt;
In the &lt;code&gt;feature&lt;/code&gt; branch, &lt;code&gt;I'm noshishi, from Japan&lt;/code&gt;.&lt;br&gt;
The content of the first line is in conflict.&lt;/p&gt;

&lt;p&gt;If you do a &lt;code&gt;merge&lt;/code&gt; at this time, a &lt;code&gt;conflict&lt;/code&gt; will occur.&lt;br&gt;
Git will ask you to &lt;code&gt;commit&lt;/code&gt; after resolving the &lt;code&gt;conflict&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz0m5oxvw2yjyk7uup4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz0m5oxvw2yjyk7uup4o.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;(The branch we work on is the &lt;code&gt;develop&lt;/code&gt; branch)&lt;/p&gt;

&lt;p&gt;If you look at &lt;code&gt;third.txt&lt;/code&gt; as instructed, you will see the following additions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;third.txt　（after conflict）&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
Hello, World! I'm noshishi, from Japan.
=======
Hello, World! I'm nope, from USA.
&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; feature
I like dancing on house music.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The upper &lt;code&gt;HEAD&lt;/code&gt;, separated by &lt;code&gt;=======&lt;/code&gt;, represents the contents of the &lt;code&gt;develop&lt;/code&gt; branch.&lt;br&gt;
The lower side represents the &lt;code&gt;feature&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;You first considered which one to adopt, and decided to adopt the changes made in the &lt;code&gt;feature&lt;/code&gt; branch this time.&lt;br&gt;
The only operation then is to edit &lt;code&gt;third.txt&lt;/code&gt; by hand (delete unnecessary parts).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;third.txt　(After editing)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Hello, World! I'm noshishi, from Japan.
I like dancing on house music.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And the next thing you do is &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
The &lt;code&gt;conflict&lt;/code&gt; is resolved and a new &lt;code&gt;merge commit&lt;/code&gt; is created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzuw6ub99c14azdf7wtn1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzuw6ub99c14azdf7wtn1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conflicts are feared by beginners, but once you learn this, you will no longer be afraid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you &lt;code&gt;merge&lt;/code&gt; and resolve the &lt;code&gt;conflict&lt;/code&gt;, why not &lt;code&gt;merge&lt;/code&gt; again?&lt;br&gt;
When you &lt;code&gt;merge&lt;/code&gt; once, the &lt;code&gt;develop&lt;/code&gt; branch enters the &lt;code&gt;merge&lt;/code&gt; state, and if there are no &lt;code&gt;conflicts&lt;/code&gt;, the new files are automatically &lt;code&gt;added&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt;.&lt;br&gt;
So it is not a special &lt;code&gt;commit&lt;/code&gt; after &lt;code&gt;conflict&lt;/code&gt; is resolved.&lt;br&gt;
That's why it's called &lt;code&gt;merge commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-delete-unnecessary-branches"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete unnecessary branches
&lt;/h3&gt;

&lt;p&gt;The merged branch is basically useless, so we will delete it.&lt;br&gt;
If we leave a branch alone, you can move from the branch you want to delete to another branch and &lt;code&gt;git branch -d &amp;lt;branch&amp;gt;&lt;/code&gt;.&lt;br&gt;
You may think the commits on that branch are deleted.&lt;br&gt;
In fact, the commits are carried over to the merged branch.&lt;br&gt;
You can use &lt;code&gt;git log&lt;/code&gt; to see all the commits you've made on the branch and the commits on the merged branch.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-what-is-the-branch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  (Aside) What is the branch
&lt;/h3&gt;

&lt;p&gt;We said that a branch is a pointer to a commit, but it also holds another important data.&lt;br&gt;
It is all the commits that have been made on that branch.&lt;/p&gt;

&lt;p&gt;A branch is a collection of commits, and it has a pointer to the latest commit in that collection. (Strictly speaking, the commit can trace back to previous commits.)&lt;/p&gt;

&lt;p&gt;The following diagram illustrates this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznbj7bp1f75h127ngxga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznbj7bp1f75h127ngxga.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we can think of branches on a horizontal axis like Git Flow.&lt;br&gt;
By the way, if you draw the above diagram with branches on the horizontal axis, it looks like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv78f8s5px2y77w37ow6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv78f8s5px2y77w37ow6x.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-summary3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;fast-forward merge&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F4abed1f6-7431-50d5-b90a-58e152633096.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F4abed1f6-7431-50d5-b90a-58e152633096.gif" alt="fast_merge.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;no fast-forward merge&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F3a29143b-fe53-3df7-352c-ccd569373685.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F3a29143b-fe53-3df7-352c-ccd569373685.gif" alt="nofast_merge1.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;no fast-forward merge with conflict&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F2898da3a-dc15-e1fd-c991-61d80ca0f6a1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2918231%2F2898da3a-dc15-e1fd-c991-61d80ca0f6a1.gif" alt="nofast_merge2.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;merge&lt;/code&gt;: To integrate (absorb) a working branch (such as &lt;code&gt;feature&lt;/code&gt;) into a specific branch (such as &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;develop&lt;/code&gt;) and create a new commit.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-rebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Rebase
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;Rebase&lt;/code&gt; is the process of merging branches by changing the commit from which the branch is derived.&lt;br&gt;
It is similar to &lt;code&gt;merge&lt;/code&gt;, except that the branch you are working on is the destination branch.&lt;/p&gt;

&lt;p&gt;Suppose you are working on the &lt;code&gt;develop&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt; branches.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgky31nkk1ly8n2228f8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgky31nkk1ly8n2228f8c.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-move-branch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Move the branch
&lt;/h3&gt;

&lt;p&gt;You may think to reflect the current commit on &lt;code&gt;develop&lt;/code&gt; branch into &lt;code&gt;feature&lt;/code&gt; branch.&lt;br&gt;
You need to move &lt;code&gt;feature&lt;/code&gt; branch from the &lt;code&gt;gp55sw&lt;/code&gt; commit to the &lt;code&gt;3x7oit&lt;/code&gt; commit.&lt;/p&gt;

&lt;p&gt;This can be moved at once from the &lt;code&gt;feature&lt;/code&gt; branch by doing a &lt;code&gt;git rebase develop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa95wz8byjyt59ss1ka1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa95wz8byjyt59ss1ka1r.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This process is more like re-growing the &lt;code&gt;feature&lt;/code&gt; branch from the latest commit on the &lt;code&gt;develop&lt;/code&gt; branch than doing a &lt;code&gt;merge&lt;/code&gt;.&lt;br&gt;
The difference is that you move the entire commit and make a new commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4j31fhavdw8jr355etm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4j31fhavdw8jr355etm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One reason for such a move is that it is &lt;code&gt;fast-forward&lt;/code&gt; and easy to &lt;code&gt;merge&lt;/code&gt; at any time.&lt;br&gt;
The other reason is that the commits are aligned so that the commit history can be easily traced and the order in which files are updated is consistent.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-deal-with-rebase-conflicts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deal with rebase conflicts
&lt;/h3&gt;

&lt;p&gt;Of course there is also a &lt;code&gt;conflict&lt;/code&gt; in &lt;code&gt;rebase&lt;/code&gt;.&lt;br&gt;
You added &lt;code&gt;fourth.txt&lt;/code&gt; in the &lt;code&gt;feature&lt;/code&gt; branch, but you didn't change &lt;code&gt;fourth.txt&lt;/code&gt; in the &lt;code&gt;develop&lt;/code&gt; branch.&lt;br&gt;
There is &lt;code&gt;conflict&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, if the following changes are covered by each other, &lt;code&gt;conflict&lt;/code&gt; will occur.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7b2tivydbvj04jfwvqy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7b2tivydbvj04jfwvqy3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can just deal with it the same way you would with &lt;code&gt;merge&lt;/code&gt;.&lt;br&gt;
However, After you have checked the diff and finished editing the file, you should finish your work with &lt;code&gt;git rebase --continue&lt;/code&gt;.&lt;br&gt;
You don't have to &lt;code&gt;commit&lt;/code&gt;, it will commit automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rebase&lt;/code&gt;: Move the commit from which the derived branch to a new commit.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-keep-up-to-date"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Keep local repositories up-to-date
&lt;/h1&gt;

&lt;p&gt;After some local work, you may be faced with a situation where the remote repository has been updated by another developer.&lt;br&gt;
In this case, you can use &lt;code&gt;pull&lt;/code&gt; to re-install the information from the remote repository back into the local repository.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-branch-and-repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Branch and Repository
&lt;/h3&gt;

&lt;p&gt;Branches are stored in each repository.&lt;br&gt;
This is the branch where the actual work is done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqaaaby69064si0c19re.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqaaaby69064si0c19re.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, the local repository has the copied branches of the remote repository.&lt;br&gt;
This is called a "remote tracking branch".&lt;br&gt;
It is a branch with a name that is tied to the remote branch in &lt;code&gt;remotes/&amp;lt;remote branch&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is only monitoring the remote repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2bc9gohvc13tmbccs07k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2bc9gohvc13tmbccs07k.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-check-the-latest-status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the latest status
&lt;/h3&gt;

&lt;p&gt;Suppose you have a situation where the &lt;code&gt;develop&lt;/code&gt; branch in the remote repository is one step ahead of the remote tracking branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tkr948lzvpvop4ulyvn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tkr948lzvpvop4ulyvn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reflecting the latest status of a branch in a remote repository on a remote tracking branch is called &lt;code&gt;fetch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzc33058vtour7jzpremw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzc33058vtour7jzpremw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-update-to-the-status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Update to the latest status
&lt;/h3&gt;

&lt;p&gt;If you want to have it reflected in your local branch, you can do a &lt;code&gt;pull&lt;/code&gt;.&lt;br&gt;
When you &lt;code&gt;pull&lt;/code&gt;, the local remote tracking branch is updated first.&lt;br&gt;
Then &lt;code&gt;merge&lt;/code&gt; to the local branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fir7pzfo5tbi2rlzamocj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fir7pzfo5tbi2rlzamocj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time, there was a commit that went one branch ahead of the &lt;code&gt;develop&lt;/code&gt; branch, so you created a new commit by &lt;code&gt;merge&lt;/code&gt; into the local &lt;code&gt;develop&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-deal-with-pull-conflicts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deal with pull conflicts
&lt;/h3&gt;

&lt;p&gt;When a remote repository commit conflict with a local repository commit, you face the &lt;code&gt;conflict&lt;/code&gt; between the remote tracking branch and the local branch when you &lt;code&gt;pull&lt;/code&gt;.&lt;br&gt;
In the following case, the &lt;code&gt;remotes/develop&lt;/code&gt; and &lt;code&gt;develop&lt;/code&gt; branches are in conflict.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf12jos6v87kzlq42veh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf12jos6v87kzlq42veh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;push&lt;/code&gt; is &lt;code&gt;fetch&lt;/code&gt; and &lt;code&gt;merge&lt;/code&gt;, you can solve in the same way as &lt;code&gt;conflict&lt;/code&gt; in &lt;code&gt;merge&lt;/code&gt;.&lt;br&gt;
This time, &lt;code&gt;develop&lt;/code&gt; &lt;code&gt;merges&lt;/code&gt; &lt;code&gt;remotes/develop&lt;/code&gt;, so the working branch is &lt;code&gt;develop&lt;/code&gt;.&lt;br&gt;
Open the folder that caused the problem and &lt;code&gt;commit&lt;/code&gt; when you have fixed it.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-identity-of-pull-requests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  (Aside) Identity of pull requests
&lt;/h3&gt;

&lt;p&gt;Basically, the relationship between remote and local is pull from the remote repository to the local repository and push from the local repository to the remote repository.&lt;br&gt;
However, GitHub and other services have a mechanism to send a request before merge from a branch in a remote repository to a branch such as main.&lt;br&gt;
This is because if a developer pushes to the main branch and updates the remote repository, no one can check it and a major failure may occur.&lt;br&gt;
&lt;code&gt;Pull request&lt;/code&gt; is to insert a process where a higher level developer reviews the code once.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyge3as35z6o70kpmfg6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyge3as35z6o70kpmfg6f.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(info)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pull&lt;/code&gt;: &lt;code&gt;fetch&lt;/code&gt; + &lt;code&gt;merge&lt;/code&gt;. &lt;code&gt;pull&lt;/code&gt; is to reflect the state of the remote repository in the local repository.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-useful-functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Useful Functions
&lt;/h1&gt;

&lt;p&gt;&lt;a id="markdown-correct-the-commit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Correct the commit
&lt;/h3&gt;

&lt;p&gt;To &lt;code&gt;commit&lt;/code&gt; to correct a previous commit is called &lt;code&gt;revert&lt;/code&gt;.&lt;br&gt;
For example, suppose you added &lt;code&gt;second.txt&lt;/code&gt; to your local repository with &lt;code&gt;m9sgLe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you &lt;code&gt;revert&lt;/code&gt;, the commit is revoked and &lt;code&gt;second.txt&lt;/code&gt; is no longer in the local repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcanu9jk4l6nsbi63ctph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcanu9jk4l6nsbi63ctph.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The merit of &lt;code&gt;revert&lt;/code&gt; is that it allows you to leave &lt;code&gt;commit&lt;/code&gt;. &lt;br&gt;
Distinguish this from &lt;code&gt;reset&lt;/code&gt;, which will be introduced later.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-delete-the-commit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete the commit
&lt;/h3&gt;

&lt;p&gt;To undo the current latest commit and work on it again is called &lt;code&gt;reset&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--soft&lt;/code&gt; option allows you to go back to the stage immediately after &lt;code&gt;add&lt;/code&gt;.&lt;br&gt;
The &lt;code&gt;--mixed&lt;/code&gt; option allows you to go back to the stage where you were working in the working directory.&lt;br&gt;
The &lt;code&gt;--hard &amp;lt;commit&amp;gt;&lt;/code&gt; option removes all commits up to the commit point you are returning to and moves &lt;code&gt;head&lt;/code&gt; to the specified commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flz3mktussfo4x7kp2pni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flz3mktussfo4x7kp2pni.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;reset&lt;/code&gt; &lt;strong&gt;completely deletes&lt;/strong&gt; the commit, it is recommended that you do not use it unless you have a good reason, especially for the '--hard' option.&lt;/p&gt;

&lt;p&gt;If you want to get your commits back, you can use &lt;code&gt;git reflog&lt;/code&gt; to see the commits you have deleted.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-evacuate-the-work"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Evacuate the work
&lt;/h3&gt;

&lt;p&gt;Since you can't move to another branch if there are change files, you have to choose between going to &lt;code&gt;commit&lt;/code&gt; or discarding your changes.&lt;br&gt;
This is where &lt;code&gt;stash&lt;/code&gt; comes in handy.&lt;br&gt;
You can temporarily evacuate files in the working directory or staging area.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm91v8mhpwny9ox8e6of4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm91v8mhpwny9ox8e6of4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you want to move to another branch, &lt;code&gt;stash&lt;/code&gt; and when you return, use &lt;code&gt;stash pop&lt;/code&gt; to retrieve the evacuated files and resume work.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-bring-the-commit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bring the commit
&lt;/h3&gt;

&lt;p&gt;Bringing any commit to the current branch to create a commit is called &lt;code&gt;cherry-pick&lt;/code&gt;.&lt;br&gt;
It is a very nice feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbfrdpetxvxyiczmatrfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbfrdpetxvxyiczmatrfx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is used when you want to bring back &lt;strong&gt;only&lt;/strong&gt; features previously implemented in a &lt;code&gt;feature&lt;/code&gt; branch and use them for work in the current &lt;code&gt;develop&lt;/code&gt; branch, for example.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-mastering-head"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mastering HEAD
&lt;/h3&gt;

&lt;p&gt;I explained that HEAD is a pointer to the branch you are currently working on.&lt;br&gt;
I also explained that a branch is a pointer to a commit.&lt;/p&gt;

&lt;p&gt;See the figure below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fczpaxk8j3u52kall7m74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fczpaxk8j3u52kall7m74.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HEAD points to the &lt;code&gt;develop&lt;/code&gt; branch, and the &lt;code&gt;develop&lt;/code&gt; branch points to the commit &lt;code&gt;eaPk76&lt;/code&gt;.&lt;br&gt;
So, HEAD in this situation refers to the commit &lt;code&gt;eaPk76&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Have you often seen Git documentation or articles that use &lt;code&gt;HEAD&lt;/code&gt; after a command?&lt;br&gt;
For example, &lt;code&gt;git revert HEAD&lt;/code&gt;.&lt;br&gt;
This is a command that can be achieved because you can replace &lt;code&gt;HEAD&lt;/code&gt; with commit.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-end"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  End
&lt;/h1&gt;

&lt;p&gt;&lt;a id="markdown-source-code-managemaent-without-git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Source code management without Git
&lt;/h3&gt;

&lt;p&gt;Mercurial has the same history as Git.&lt;br&gt;
Mercurial has a very simple command line interface (CLI) that sacrifices the flexibility of Git.&lt;br&gt;
Recently, based on Mercurial, Meta released a new source code management system called Sapling as open source.&lt;br&gt;
I would like to try it again and write about my impressions.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-where-is-the-remote-repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Where is the remote repository
&lt;/h3&gt;

&lt;p&gt;A hosting service is a service that rents a server for a remote repository.&lt;br&gt;
Typical examples are GitHub, Bitbucket, and Aws Code Commit for private use.&lt;br&gt;
Git and Git Hub are completely different.&lt;br&gt;
By the way, as mentioned above, we can use our own servers for remote repositories.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-pointer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pointer
&lt;/h3&gt;

&lt;p&gt;If you have been exposed to programming that deals directly with memory, such as the C programming language, you will somehow know what a "pointer" is.&lt;br&gt;
On the other hand, for a beginning programmer, it seems very vague.&lt;/p&gt;

&lt;p&gt;I said that commit objects are stored in the repository.&lt;br&gt;
If there are many commit objects in the repository, how can you select the one you want?&lt;/p&gt;

&lt;p&gt;We need a label (address) to locate a particular commit object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu4ec8yzfvf0yiavtu1zu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu4ec8yzfvf0yiavtu1zu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The "pointer" is a valuable data that indicates us to the label so that we don't forget it.&lt;/p&gt;

&lt;p&gt;The label, by the way, is converted into a mysterious string through a &lt;code&gt;hash function&lt;/code&gt;.&lt;br&gt;
If you are curious, please refer to &lt;a href="https://stackoverflow.com/questions/7225313/how-does-git-compute-file-hashes" rel="noopener noreferrer"&gt;How does Git compute file hashes?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-to-further-understading-git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  To further understand Git
&lt;/h3&gt;

&lt;p&gt;There are many things I failed to mention in this article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The core of Git is a simple key-value type data store&lt;/li&gt;
&lt;li&gt;Details of the Git object that is the value&lt;/li&gt;
&lt;li&gt;How to relate with each objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope to fully explore this someday.&lt;/p&gt;

&lt;p&gt;&lt;a id="markdown-references"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/doc" rel="noopener noreferrer"&gt;Git Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/unseenwizzard/learn-git-concepts-not-commands-4gjc"&gt;Learn git concepts, not commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>image</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
