<?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>DEV Community: root</title>
    <description>The latest articles on DEV Community by root (@shiva).</description>
    <link>https://dev.to/shiva</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%2F257797%2F71f6f9b8-2be8-418d-b7bc-8e6ead465ed4.jpeg</url>
      <title>DEV Community: root</title>
      <link>https://dev.to/shiva</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shiva"/>
    <language>en</language>
    <item>
      <title>Fixing Mistakes in Git</title>
      <dc:creator>root</dc:creator>
      <pubDate>Sun, 11 Oct 2020 11:54:22 +0000</pubDate>
      <link>https://dev.to/shiva/fixing-mistakes-in-git-1k5j</link>
      <guid>https://dev.to/shiva/fixing-mistakes-in-git-1k5j</guid>
      <description>&lt;p&gt;Let's be real here, we all make mistakes when we code and to make matters worse we persist those changes in a version control system like Github. Sometimes they are benign and on the other hand it can cause a lot of damage.&lt;/p&gt;

&lt;p&gt;In this blog I will discuss ways by which you can fix your mistakes when using git. &lt;/p&gt;

&lt;p&gt;PS: Keeping your commits "Atomic" would go a long way in helping you fix your mistakes, since you can throw a commit the introduced the issue with confidence.&lt;/p&gt;

&lt;p&gt;There are a lot of ways you can fix mistakes in commits and each way is suitable under a specific circumstance. From a practical stand point we can broadly classify mistakes into types types&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pushed commit to remote repository&lt;/li&gt;
&lt;li&gt;Commits that are not pushed to remote repository&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Pushed to remote
&lt;/h1&gt;

&lt;p&gt;When commits are pushed to remote, To be on the safer side we should assume that other people might have already pulled the changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git revert
&lt;/h2&gt;

&lt;p&gt;you can easily remove a commit from the repository by doing a &lt;code&gt;git revert&lt;/code&gt;.&lt;br&gt;
Revert does not actually remove the commit, instead it will create a new commit which reverts the changes done in the commit.&lt;/p&gt;

&lt;p&gt;Revert in action.&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;# find the commit hash of the commit you want to revert&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; 
d77ce47 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; add instructions
e3a5bd7 bad commit
e6f780f first commit


&lt;span class="c"&gt;# Revert the commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git revert e3a5bd7
git revert e3a5bd7
&lt;span class="o"&gt;[&lt;/span&gt;master 5c69f9f] Revert &lt;span class="s2"&gt;"bad commit"&lt;/span&gt;
 1 file changed, 2 deletions&lt;span class="o"&gt;(&lt;/span&gt;-&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# list commits again&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
5c69f9f &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; Revert &lt;span class="s2"&gt;"bad commit"&lt;/span&gt;
d77ce47 add instructions
e3a5bd7 bad commit
e6f780f first commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Not pushed to remote
&lt;/h1&gt;

&lt;p&gt;We have a lot of options when it comes to fixing mistakes that are not pushed.&lt;br&gt;
Depending on the situation we can choose different approaches&lt;/p&gt;
&lt;h2&gt;
  
  
  Mistake in the last commit
&lt;/h2&gt;

&lt;p&gt;If the mistake is in the last commit we can use&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;commit amend&lt;/li&gt;
&lt;li&gt;git reset&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Commit amend
&lt;/h3&gt;

&lt;p&gt;With commit amend you can make changes and add the changes on top of the last commit.&lt;/p&gt;

&lt;p&gt;Scenario:&lt;br&gt;
I created a new feature but I missed to add an file which should be part of that 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="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
6a1d188 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; added new feature
90c9958 first commit

&lt;span class="c"&gt;# we missed the feature.txt which should be in the last commit.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git status
On branch master
Untracked files:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add &amp;lt;file&amp;gt;..."&lt;/span&gt; to include &lt;span class="k"&gt;in &lt;/span&gt;what will be committed&lt;span class="o"&gt;)&lt;/span&gt;
    feature.txt

nothing added to commit but untracked files present &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add"&lt;/span&gt; to track&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Add the file and use amend to modify commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git add feature.txt
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;--amend&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;master d2bd903] added new feature
 Date: Sun Oct 11 15:19:09 2020 +0530
 2 files changed, 2 insertions&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;
 create mode 100644 feature.txt

&lt;span class="c"&gt;# check log&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
d2bd903 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; added new feature
90c9958 first commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Git reset
&lt;/h3&gt;

&lt;p&gt;Git reset is very versatile. simply put we can use reset to undo commits.&lt;/p&gt;

&lt;p&gt;to undo last 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="nv"&gt;$ &lt;/span&gt;git reset HEAD^1
Unstaged changes after reset:
M   README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fixing intermediate commit
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Git reset
&lt;/h3&gt;

&lt;p&gt;if do not wish to keep changes after the commit you want to change you can undo all the commits from the bad 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="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
36c4f05 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; fix bug
e344740 added new feature
90c9958 first commit

&lt;span class="c"&gt;# for fixing mistake in `e344740 added new feature` &lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git reset e344740~1
Unstaged changes after reset:
M   README.md

&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; 
90c9958 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; first commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The disadvantage of using this is that the commits after the commit that you want to change are also lost. This can be troublesome for you if you need the other commits, in that case you can use &lt;code&gt;git rebase&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git rebase
&lt;/h3&gt;

&lt;p&gt;To fix commit without removing / modifying other commits we can use rebase.&lt;/p&gt;

&lt;p&gt;Scenario:&lt;br&gt;
delete the commit &lt;code&gt;fix bug&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="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
cf037c9 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; add &lt;span class="nb"&gt;test &lt;/span&gt;file
36c4f05 fix bug
e344740 added new feature
90c9958 first commit

&lt;span class="nv"&gt;$ &lt;/span&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; 36c4f05~1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fi%2Fwt91n4z2vec5iq3uihh9.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%2Fi%2Fwt91n4z2vec5iq3uihh9.png" alt="Screenshot 2020-10-11 at 5.10.43 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-i&lt;/code&gt; is for interactive mode, this command will open a text editor allowing you to enter what you want to do with each commit.&lt;/p&gt;

&lt;p&gt;to delete a commit we should specify &lt;code&gt;drop&lt;/code&gt; for the corresponding 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%2Fi%2Fiugtqopvo9c997fc4ka5.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%2Fi%2Fiugtqopvo9c997fc4ka5.png" alt="Screenshot 2020-10-11 at 5.15.20 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;once you exit from editor the rebase will be applied and check git logs to see the commits&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;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
608fc51 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; add &lt;span class="nb"&gt;test &lt;/span&gt;file
e344740 added new feature
90c9958 first commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you want to modify the commit you can specify &lt;code&gt;edit&lt;/code&gt; instead of drop.&lt;br&gt;
it will pause the rebasing at that commit and you can make changes then continue the rebasing with &lt;code&gt;git rebase --continue&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Hope this was informative, stay tuned for more git related blogs :)&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Git does not store Diffs </title>
      <dc:creator>root</dc:creator>
      <pubDate>Sun, 04 Oct 2020 19:10:43 +0000</pubDate>
      <link>https://dev.to/shiva/git-does-not-store-diffs-3dbn</link>
      <guid>https://dev.to/shiva/git-does-not-store-diffs-3dbn</guid>
      <description>&lt;p&gt;This is a common misconception around git. For a git beginner it makes logical sense to assume so, as Git exposes commit as diffs to the end user as that makes it easier to identify changes as shown in the image 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%2Fi%2Fpbwkajhdomwk7l10csp4.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%2Fi%2Fpbwkajhdomwk7l10csp4.png" alt="Screenshot 2020-10-04 at 11.31.10 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But Git does not internally store diffs for each commit, it creates a snapshot of the files during each commit.&lt;br&gt;
This means that if you create a file in one commit and modify the same file in second commit, Git will have 2 snapshots for the same file.&lt;/p&gt;

&lt;p&gt;To show you how git internally stores these files, we are going to dig into the &lt;code&gt;.git/&lt;/code&gt; folder. Understanding how git handles files will give a better picture, check out my blog on &lt;a href="https://dev.to/shiva/git-objects-haj"&gt;Git Objects&lt;/a&gt; for the same. &lt;br&gt;
&lt;em&gt;TLDR&lt;/em&gt; : All the files we add to git repository are added as objects in the &lt;code&gt;.git/objects/&lt;/code&gt; repository.&lt;/p&gt;

&lt;p&gt;(Please skip over to the &lt;em&gt;Why ?&lt;/em&gt; section at the end for the reasoning behind using snapshots vs diffs)&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's see this in action
&lt;/h2&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;mkdir &lt;/span&gt;gitinternals &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;gitinternals &lt;span class="c"&gt;# create and cd into a dir&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git init &lt;span class="c"&gt;# initialize git&lt;/span&gt;
Initialized empty Git repository &lt;span class="k"&gt;in&lt;/span&gt; /Users/home/gitinternals/.git/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now that we have a fresh git repository lets create a file and commit 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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# Hello world"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md
&lt;span class="nv"&gt;$ &lt;/span&gt;git add README.md
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add readme file"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;master &lt;span class="o"&gt;(&lt;/span&gt;root-commit&lt;span class="o"&gt;)&lt;/span&gt; 0948529] Add readme file
 1 file changed, 1 insertion&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;
 create mode 100644 README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take a look at the git object directory, it will have the readme file stored.&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; tree &lt;span class="nt"&gt;-a&lt;/span&gt; .git/objects/
.git/objects/
├── 09
│   └── 4852928af802dfe0f463359c7ade3f7a21fffa
├── 71
│   └── 6ed1421c738a75abe6e0c4812ad4aacee0e11a
├── a5
│   └── ef91ee14be786131cbecfd2eb8c7fef8a2510d
├── info
└── pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The objects directory has three objects, we can check the type of object file with the &lt;code&gt;cat-file -t&lt;/code&gt; plumbing command.&lt;br&gt;
with that we can see the &lt;code&gt;716e&lt;/code&gt; is the Blob file, which should be our &lt;code&gt;README.md&lt;/code&gt; file, as we only have one blob file in our repository. using &lt;code&gt;cat-file -p&lt;/code&gt; we can see the contents of the object file.&lt;br&gt;
Please feel free to refer back to &lt;a href="https://dev.to/shiva/git-objects-haj"&gt;Git Objects&lt;/a&gt;, if you want to know more on Git objects.&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; git cat-file &lt;span class="nt"&gt;-t&lt;/span&gt; 716e
blob

&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 716e
&lt;span class="c"&gt;# Hello world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's modify the readme to add a &lt;code&gt;.&lt;/code&gt; at the end of the file and create a commit again&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; README.md
&lt;span class="nv"&gt;$ &lt;/span&gt;git add README.md
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Update readme"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;master ccab425] Update readme
 1 file changed, 1 insertion&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checking the objects directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree -a .git/objects/
.git/objects/
├── 09
│   └── 4852928af802dfe0f463359c7ade3f7a21fffa
├── 28
│   └── af00ee0e3e44d7806dc1c2d7f1a9c9d75cfd8e
├── 5f
│   └── a99c8ea90f41ae4601f92ea7475832e6fb773d
├── 71
│   └── 6ed1421c738a75abe6e0c4812ad4aacee0e11a
├── a5
│   └── ef91ee14be786131cbecfd2eb8c7fef8a2510d
├── cc
│   └── ab425bf34937b0e02ed807724af39812e8988b
├── info
└── pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;there are a few more objects in the directory. to get the blob file we can check each file for the type and figure out which one is the new version of &lt;code&gt;README.md&lt;/code&gt; but there is a better methodological approach to it.&lt;/p&gt;

&lt;p&gt;we can take the current commit hash and check what tree that has points to and from the tree hash we should be able to get the blob hash, Please refer to &lt;a href="https://dev.to/shiva/git-objects-haj"&gt;Git Objects&lt;/a&gt; in case if you are unfamiliar with commits and trees objects.&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;# get hash of current commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--short&lt;/span&gt; HEAD
ccab425
&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;# check content of the commit to get tree hash&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; ccab425
tree 28af00ee0e3e44d7806dc1c2d7f1a9c9d75cfd8e
parent 094852928af802dfe0f463359c7ade3f7a21fffa
author root &amp;lt;root@email.com&amp;gt; 1601836557 +0530
committer root &amp;lt;root@email.com&amp;gt; 1601836557 +0530

Update readme
&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;# check content of tree `28af00`&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 28af00
100644 blob 5fa99c8ea90f41ae4601f92ea7475832e6fb773d    README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the hash of new &lt;code&gt;README.md&lt;/code&gt; snapshot is &lt;code&gt;5fa99c&lt;/code&gt;, lets inspect the old and new snapshot content.&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;# New snapshot hash&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 5fa99c
&lt;span class="c"&gt;# Hello world&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Old snapshot hash&lt;/span&gt;
git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 716ed1
&lt;span class="c"&gt;# Hello world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Why ?
&lt;/h1&gt;

&lt;p&gt;This might seem un efficient to store each version of file as snapshot as storing just the diffs would be most efficient use of storage. so it is only natural to ask why ?&lt;/p&gt;

&lt;p&gt;Storing diffs and applying diffs on top of base file version can become pretty computationally expensive when you are on large projects with thousands or even millions of files.&lt;br&gt;
The diff based approach is used by SVN and there are common issues with large projects taking hours just to checkout as CPU and IO becomes bottleneck to apply those diffs.&lt;/p&gt;

&lt;p&gt;And SVN was popular when storage was costlier than compute but the tables have changed now. storage is much more cheaper in this day and age, which makes Git the perfect choice for version control.&lt;/p&gt;

&lt;p&gt;Git has some optimization built in for compressing objects so that they take lesser storage on disk, which we will cover in an upcoming blog :).&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Git Objects</title>
      <dc:creator>root</dc:creator>
      <pubDate>Sat, 03 Oct 2020 20:33:08 +0000</pubDate>
      <link>https://dev.to/shiva/git-objects-haj</link>
      <guid>https://dev.to/shiva/git-objects-haj</guid>
      <description>&lt;p&gt;I always loved git, In this series of blogs I am documenting about git internals that I learned along the way.&lt;/p&gt;

&lt;p&gt;In this blog I am writing about Git Objects, Simply put Object is the storage Unit of Git. All the files, commits, trees and tags in a git repository is stored as Objects. If you are new to Git this will seem a bit cloudy, don't worry, the weather will clear up as you go along with the blog.&lt;/p&gt;

&lt;p&gt;Let's start off by creating a new git repo for us to experiment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;gitinternals &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;gitinternals &lt;span class="c"&gt;# create and cd into a dir&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git init &lt;span class="c"&gt;# initialize git&lt;/span&gt;
Initialized empty Git repository &lt;span class="k"&gt;in&lt;/span&gt; /Users/home/gitinternals/.git/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;with the above commands you will have initialized a git repository locally. This will have created a &lt;code&gt;.git&lt;/code&gt; folder inside your repository. this is where git stores all its internal data related to this repository.&lt;br&gt;
A quick &lt;code&gt;tree -a&lt;/code&gt; on the current folder will display the files and folders created by git.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;tree &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt;
└── .git
    ├── HEAD
    ├── config
    ├── description
    ├── hooks
    │   ├── applypatch-msg.sample
    │   ├── commit-msg.sample
    │   ├── fsmonitor-watchman.sample
    │   ├── post-update.sample
    │   ├── pre-applypatch.sample
    │   ├── pre-commit.sample
    │   ├── pre-merge-commit.sample
    │   ├── pre-push.sample
    │   ├── pre-rebase.sample
    │   ├── pre-receive.sample
    │   ├── prepare-commit-msg.sample
    │   └── update.sample
    ├── info
    │   └── exclude
    ├── objects
    │   ├── info
    │   └── pack
    └── refs
        ├── heads
        └── tags

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



&lt;p&gt;we are interested in the &lt;code&gt;.git/objects&lt;/code&gt; directory, this is also referred to as the Object database of git. initially it just has the &lt;code&gt;info&lt;/code&gt; and &lt;code&gt;pack&lt;/code&gt; folders, no objects just yet.&lt;/p&gt;

&lt;h1&gt;
  
  
  Blob objects
&lt;/h1&gt;

&lt;p&gt;Git considers all the physical files that user work with in the git repo be it text files, images, audio, video as BLOB(Binary Large OBject).&lt;br&gt;
Let's create new file in the folder and check how git reacts to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# Hello world"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md
&lt;span class="nv"&gt;$ &lt;/span&gt;tree &lt;span class="nt"&gt;-a&lt;/span&gt; .git/objects/
.git/objects/
├── info
└── pack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;tree&lt;/code&gt; on the objects directory reveals that there is no changes in the object storage, This is because git has not started tracking the file yet. you can confirm this by giving the command &lt;code&gt;git status&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git status
On branch master

No commits yet

Untracked files:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add &amp;lt;file&amp;gt;..."&lt;/span&gt; to include &lt;span class="k"&gt;in &lt;/span&gt;what will be committed&lt;span class="o"&gt;)&lt;/span&gt;
        README.md

nothing added to commit but untracked files present &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add"&lt;/span&gt; to track&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;README.md&lt;/code&gt; file is listed under the untracked files yet. that means that git does not care what you do with the file. The &lt;code&gt;git status&lt;/code&gt; gives us info on how to make git track the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add README.md
&lt;span class="nv"&gt;$ &lt;/span&gt; tree &lt;span class="nt"&gt;-a&lt;/span&gt; .git/objects/
.git/objects/
├── 71
│   └── 6ed1421c738a75abe6e0c4812ad4aacee0e11a
├── info
└── pack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;at last we see some activity in the objects folder. &lt;br&gt;
The string &lt;code&gt;716ed1421c738a75abe6e0c4812ad4aacee0e11a&lt;/code&gt; is the SHA-1 hash of the README.md file.&lt;br&gt;
the first 2 letters of the hash is used as a folder and remaining string is used as the file name.&lt;/p&gt;

&lt;p&gt;we can verify the hash of the file with the &lt;code&gt;hash-object&lt;/code&gt; plumbing command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git hash-object README.md
716ed1421c738a75abe6e0c4812ad4aacee0e11a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;we can also check the contents, type and size of a object with the &lt;code&gt;cat-file&lt;/code&gt; plumbing command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 716ed1421c738a75abe6e0c4812ad4aacee0e11a
&lt;span class="c"&gt;# Hello world&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;get cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 716e &lt;span class="c"&gt;# we need not type the whole hash, a hash prefix which uniquely identifies the hash can also be used.&lt;/span&gt;
&lt;span class="c"&gt;# Hello world&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-t&lt;/span&gt; 716e &lt;span class="c"&gt;# checking type of object&lt;/span&gt;
blob

&lt;span class="nv"&gt;$ &lt;/span&gt; git cat-file &lt;span class="nt"&gt;-s&lt;/span&gt; 716e &lt;span class="c"&gt;# checking size of object&lt;/span&gt;
14
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we see the type of object is blob, which is expected for the file README.md&lt;/p&gt;

&lt;h1&gt;
  
  
  Commit Objects
&lt;/h1&gt;

&lt;p&gt;Let's create a new commit in our repository and we will look at how the objects directory has reacted to our commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add readme file"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;master &lt;span class="o"&gt;(&lt;/span&gt;root-commit&lt;span class="o"&gt;)&lt;/span&gt; 0948529] Add readme file
 1 file changed, 1 insertion&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;
 create mode 100644 README.md

&lt;span class="nv"&gt;$ &lt;/span&gt; tree &lt;span class="nt"&gt;-a&lt;/span&gt; .git/objects/
.git/objects/
├── 09
│   └── 4852928af802dfe0f463359c7ade3f7a21fffa
├── 71
│   └── 6ed1421c738a75abe6e0c4812ad4aacee0e11a
├── a5
│   └── ef91ee14be786131cbecfd2eb8c7fef8a2510d
├── info
└── pack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We see two more objects &lt;code&gt;0948&lt;/code&gt; and &lt;code&gt;a5ef&lt;/code&gt;, let's check these type of objects with the &lt;code&gt;cat-file&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-t&lt;/span&gt; 0948
commit

&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-t&lt;/span&gt; a5ef
tree
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;we that &lt;code&gt;0948&lt;/code&gt; is a commit object and &lt;code&gt;a5ef&lt;/code&gt; is a tree object.&lt;br&gt;
let's check the contents of the commit object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 0948
tree a5ef91ee14be786131cbecfd2eb8c7fef8a2510d
author root &amp;lt;root@email.com&amp;gt; 1601801983 +0530
committer root &amp;lt;root@email.com&amp;gt; 1601801983 +0530

Add readme file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;tree a5ef91ee14be786131cbecfd2eb8c7fef8a2510d&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the tree that this commit is pointing to, more on Tree next :)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;author root &lt;a href="mailto:root@email.com"&gt;root@email.com&lt;/a&gt; 1601801983 +0530&lt;br&gt;
committer root &lt;a href="mailto:root@email.com"&gt;root@email.com&lt;/a&gt; 1601801983 +0530&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next two lines contain the author and committer info.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Add readme file&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then separated by a new line we have the commit message.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tree Object
&lt;/h1&gt;

&lt;p&gt;Tree objects stores a group of blob objects and tree objects. conceptually it makes it easier for us to think of tree object as snapshot of the folder. &lt;br&gt;
Each folder can have multiple files and multiple folders within them, Likewise Tree object can have multiple blob objects or multiple trees in them.&lt;/p&gt;

&lt;p&gt;Lets inspect the content of the tree object &lt;code&gt;a5ef&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; a5ef
100644 blob 716ed1421c738a75abe6e0c4812ad4aacee0e11a    README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This tree object has only one file in it as we have added only one file to the git repository.&lt;/p&gt;

&lt;p&gt;the tree object content has four parts&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;part&lt;/th&gt;
&lt;th&gt;description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100644&lt;/td&gt;
&lt;td&gt;100 means that it is a normal blob object and 644 is the file permission on the disk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;blob&lt;/td&gt;
&lt;td&gt;type of object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;716ed1421c738a75abe6e0c4812ad4aacee0e11a&lt;/td&gt;
&lt;td&gt;object name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;README.md&lt;/td&gt;
&lt;td&gt;file name&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Tag Object
&lt;/h1&gt;

&lt;p&gt;Adding a new tag to our current commit, let's observe how our object directory reacts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v0.0.1 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"my version 0.0.1"&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt; tree &lt;span class="nt"&gt;-a&lt;/span&gt; .git/objects/
.git/objects/
├── 08
│   └── a57a8e9c4b340f5674b96652595bf6727b35bd
├── 09
│   └── 4852928af802dfe0f463359c7ade3f7a21fffa
├── 71
│   └── 6ed1421c738a75abe6e0c4812ad4aacee0e11a
├── a5
│   └── ef91ee14be786131cbecfd2eb8c7fef8a2510d
├── info
└── pack


&lt;span class="nv"&gt;$ &lt;/span&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; 08a5
object 094852928af802dfe0f463359c7ade3f7a21fffa
&lt;span class="nb"&gt;type &lt;/span&gt;commit
tag v0.0.1
tagger root &amp;lt;root@email.com&amp;gt; 1601811513 +0530

my version 0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Upon checking the contents of the Tag object file &lt;code&gt;08a5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;we see that the tag object points to the current commit &lt;code&gt;0948&lt;/code&gt;. and it has the tag information along with the author who created the tag.&lt;/p&gt;

&lt;p&gt;Hope this gave you some insight on internal working of git. Follow me for more git internal related blogs :)&lt;/p&gt;

</description>
      <category>git</category>
    </item>
  </channel>
</rss>
