Pages

Sunday, March 3, 2019

Git - Understanding the .git directory structure

Every git local repository contains a .git directory which is hidden. This .git is the core directory for the local repository and provides many details. Lets understand the contents of the .git location. This directory contains information that lets git to work.
jagadishsample$Mon Feb 18@ tree .git/
.git/
├── HEAD
├── branches
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-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

9 directories, 15 files

Config - The file contains the settings for your repository. This will contain url of the remote repo, your mail,user name etc. Every time we use the “git config” command it comes over here.

Description - Contains the description of the repository and details.

Info : exclude
- if we want to tell git to ignore certain files for pushing them to the local repo we can use 2 ways,

Adding the files types to the .gitignore file is one way
Adding the file types that need to be ignored by the git can be added to the exclude file in this info location. This file will not be shared like .gitignore file

Hooks - this directory contains certain scripts that can be run automatically at git stages. If you want to execute an action when a commit is done, you can write a post hook script and code your action in here.

Before understanding other directories, let understand commit structure:

Objects - A commit is basically a snapshot of the working directory. Every time we create a file and commit it, git compress it and stores in its own data structure. This compressed object will have unique name, hash and will be stored under the objects directory.

Now i have created a file named “one” and committed it to the local repository. We can use the “git show” command to view the commit details as,
jagadishsample$Mon Feb 18@ git show
commit 0bfba39f1e6ddc56a5a55183f8af206e2da9a18b (HEAD -> master)
Author: jagadish
Date:   Mon Feb 18 19:26:22 2019 +0530

   first commit

diff --git a/one b/one
new file mode 100644
index 0000000..e69de29


A commit basically made up of 4 things,
    Name of the working directory snapshot or hash
   A Comment
   Information about the commit details like user etc
   Hash of the parent commit

Once the commit is done, we can see certain directories created under the objects directory as below,
jagadishsample$Mon Feb 18@ tree .git/objects/
.git/objects/
├── 0b
│   └── fba39f1e6ddc56a5a55183f8af206e2da9a18b
├── 5f
│   └── cffbd6e4c5c5b8d81f5e9314b20e338e3ffff5
├── e6
│   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
├── info
└── pack

5 directories, 3 files

If we can see the commit id starts with the 0b, and the first directory in the object directory also has the name 0b.

The hash of the file created started with 0b and hence the file which is compressed will be stored under the 0b directory in objects. We can see 3 hashes
  First would be for our files
  Second hash is for the snapshot created when we committed
  The third one is for the commit. A Commit is an object in itself and third hash contain            details about that

Now if we uncompress the commit file using
jagadishsample$Mon Feb 18@ git cat-file -p 0bfba39f1e6ddc56a5a55183f8af206e2da9a18b
tree 5fcffbd6e4c5c5b8d81f5e9314b20e338e3ffff5
author jagadish 1550498182 +0530
committer jagadish 1550498182 +0530

first commit

I passed the commit hash which i got by “git show”. It gives me all the details like who is the committer, commit message, author and snapshot hash. If we compare the snapshot hash with the directory structure in objects, we can see both start with same. 

Now if we uncompress the snapshot commit hash,
jagadishsample$Mon Feb 18@ git cat-file -p 5fcffbd6e4c5c5b8d81f5e9314b20e338e3ffff5
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    one
This will give you all the details about the files that we committed.

HEAD - the HEAD file always represents a pointer to the branch that we are working on. If we do a “cat HEAD” , we see
jagadish.git$Tue Feb 19@ cat HEAD
ref: refs/heads/master

And if we do a “cat refs/heads/master”, this will refer the branch that we are working currently,
jagadish.git$Tue Feb 19@ cat refs/heads/master
0bfba39f1e6ddc56a5a55183f8af206e2da9a18b

If we observe , we are actually pointing to the commit hash that we did earlier,
jagadish.git$Tue Feb 19@ git show
commit 0bfba39f1e6ddc56a5a55183f8af206e2da9a18b (HEAD -> master)
Author: jagadish
Date:   Mon Feb 18 19:26:22 2019 +0530

   first commit

diff --git a/one b/one
new file mode 100644
index 0000000..e69de29

No comments :

Post a Comment