{"id":654,"date":"2020-02-02T07:20:18","date_gmt":"2020-02-02T07:20:18","guid":{"rendered":"http:\/\/nitk.acm.org\/blog\/?p=654"},"modified":"2020-02-02T07:27:57","modified_gmt":"2020-02-02T07:27:57","slug":"how-git-actually-works","status":"publish","type":"post","link":"https:\/\/nitk.acm.org\/blog\/2020\/02\/02\/how-git-actually-works\/","title":{"rendered":"How Git Actually Works"},"content":{"rendered":"<p>git add Blog<\/p>\n<p>git commit -m \u201cHow Git Works under the Hood\u201d<\/p>\n<p>Most of you would be familiar with the above written commands, but do you actually know what happens when you run them? In this blog, we\u2019ll try to find out how Git and other Version Control Systems actually work.<\/p>\n<p>According to Linus Torvalds, the creator of Git, <em>\u201cIn many ways you can just see git as a filesystem \u2014 it\u2019s content addressable, and it has a notion of versioning, but I really designed it coming at the problem from the viewpoint of a filesystem person (hey, kernels is what I do), and I actually have absolutely zero interest in creating a traditional SCM system.\u201d<\/em><\/p>\n<p>Let\u2019s dive deep and look exactly what is this filesystem. After initializing a git repository (git init), a directory .git is created. The structure of a .git directory is as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-661\" src=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.131.jpeg\" alt=\"\" width=\"727\" height=\"151\" srcset=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.131.jpeg 727w, https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.131-300x62.jpeg 300w\" sizes=\"auto, (max-width: 727px) 100vw, 727px\" \/><\/p>\n<p>Most of the fuctionality of Git is based on its objects present in objects subfolder or the Git object database. There are four objects in Git \u2014 the blob, the tree, the commit and the tag. The blob, tree and commit objects stores the actual data of the project. These objects reference each other to compose the filesystem.<\/p>\n<p>Just below the branch node, is our first object, the commit. The commit has information on the author, the committer, and the commit message. The commit object also has a reference to a tree. The tree is our second object, and can be understood as a directory. Eventually, the tree will reference a blob, which is our third object. The <em>content <\/em>of a file (not the file itself) is stored as a Blob in Git. The diagram below depicts these relationships more clearly:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-663\" src=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.11.jpeg\" alt=\"\" width=\"191\" height=\"465\" srcset=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.11.jpeg 194w, https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.11-123x300.jpeg 123w\" sizes=\"auto, (max-width: 191px) 100vw, 191px\" \/><\/p>\n<p>Let\u2019s now take a look at how the objects reference each other, through the SHA-1. SHA stands for \u201cSecure Hash Algorithm\u201d, and is a unique 40 character hash of the content of the object it is named after. The commit object holds a reference to the tree SHA, and the tree object holds a reference to the blob SHA. This reference chain is used to traverse the Git filesystem.<\/p>\n<p>Let\u2019s see an example of how this actually works. To start, let\u2019s take a look at the contents of .git\/objects folder of a git repository after creating one file and running a single commit.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-662\" src=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.13.jpeg\" alt=\"\" width=\"733\" height=\"214\" srcset=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.13.jpeg 733w, https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.13-300x88.jpeg 300w\" sizes=\"auto, (max-width: 733px) 100vw, 733px\" \/><\/p>\n<p>The commit creates three sub-directories in the objects folder. Each sub-directory is labeled by the first two characters of the SHA of the folder\u2019s respective object. Looking inside the folders, we find the remaining 38 characters of the SHA. The first object references the Blob, the second object references the Commit, and the third object references the Tree.<\/p>\n<p>To actually view the content of a Git object in the command line, run the command: git cat-file -p [<em>SHA]. <\/em>Running this command with our \u201ccommit\u201d, the SHA shown above will produce the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-659\" src=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.122.jpeg\" alt=\"\" width=\"734\" height=\"176\" srcset=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.122.jpeg 730w, https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.122-300x72.jpeg 300w\" sizes=\"auto, (max-width: 734px) 100vw, 734px\" \/><\/p>\n<p>The content of the commit object contains information on the commit and has a reference to the tree object by its SHA. Now let\u2019s take a look at tree object\u2019s content using the tree object\u2019s SHA:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-658\" src=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.121.jpeg\" alt=\"\" width=\"748\" height=\"122\" srcset=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.121.jpeg 730w, https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.121-300x49.jpeg 300w\" sizes=\"auto, (max-width: 748px) 100vw, 748px\" \/><\/p>\n<p>This shows that the tree object contains information on the blob(s) it references. Because our project only has one file, we only see one blob listed in the tree. Likewise blob contains the actual content in the project files at the time of commit.<\/p>\n<p>Git uses the SHA to reference each of the three objects in Git, and can subsequently be used to traverse the Git structure. To dive deeper, let\u2019s create a new file called \u201ctext.txt\u201d and make a second commit. Like the first commit, three more objects (the blob, the tree and the commit), will appear in our objects folder. The new tree object that is created, however, will now contain a reference to two blobs rather than one:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-660\" src=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.12.jpeg\" alt=\"\" width=\"730\" height=\"139\" srcset=\"https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.12.jpeg 730w, https:\/\/nitk.acm.org\/blog\/wp-content\/uploads\/2020\/01\/WhatsApp-Image-2020-01-28-at-22.12.12-300x57.jpeg 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<p>The first blob references the <em>same <\/em>blob from our first commit. This is because The initially committed file was never changed, and Git does not create new blobs for files that have not changed.The second blob contains the content of the new file that was created before our second commit.<\/p>\n<p>This blog has covered the core functionalities of how Git stores the data in objects and how it keeps the history of commits. There is much more to explore in Git and Version Control Systems. You can always refer resources like <a href=\"https:\/\/git-scm.com\/\">https:\/\/git-scm.com\/<\/a> to learn more about Git.<\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Happy Gitting<\/em><\/p>\n<p><em>&#8211; Harsh Agarwal<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>git add Blog git commit -m \u201cHow Git Works under the Hood\u201d Most of you would be familiar with the above written commands, but do you actually know what happens when you run them? In this blog, we\u2019ll try to find out how Git and other Version Control Systems actually work. According to Linus Torvalds,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[25,10],"tags":[],"class_list":["post-654","post","type-post","status-publish","format-standard","hentry","category-sanganitra","category-tech"],"_links":{"self":[{"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/posts\/654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/comments?post=654"}],"version-history":[{"count":6,"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/posts\/654\/revisions"}],"predecessor-version":[{"id":677,"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/posts\/654\/revisions\/677"}],"wp:attachment":[{"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/media?parent=654"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/categories?post=654"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nitk.acm.org\/blog\/wp-json\/wp\/v2\/tags?post=654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}