Have you ever felt curious about what is inside the .git folder? We all have seen the folder at the top of our every project(of course if the project has git inside), but do you know what's inside that folder and what are they for?
In this tutorial, we will learn everything which is inside the .git folder. So without any further delay, let's dive deep into it.
Before we start, I want to make a short note of what is the .git folder and how to convert your local repository to a git repository:
What is a .git folder and How to create it?
This folder is the heart of the version control system. If you want to enable the power of the version control system in your project, this single folder is everything you need. When you do git init
, then this .git folder is created. If you want to back up or clone your repository, copying this single folder elsewhere will give you almost everything you need.
What is inside the .git folder?
Inside this folder, you will find a bunch of folders and files. Now, the number of files and folders may vary depending on what kind of work you are doing(like connecting with a remote repository or not, number of branches etc). So to know the exact number, I read gitrepository-layout and Git-Internals-Plumbing-and-Porcelain both with another bunch of blogs. In gitrepository-layout, you will find way too much information that may not be present in your .git folder(if you open an existing project). In Git-Internals-Plumbing-and-Porcelain you will find a little lesser(for example log folder). So after reading the official git book, numerous blogs, stackoverflow answers and running multiple experiments in my system, I conclude the followings:
hooks/: This folder contains your client or server-side hook scripts. When we do
git init
some sample hooks are installed. But these are disabled by default. If you remove the .sample suffix from the filename you can enable this file and read them.info/: Inside this folder, there is a file, named exclude which stores excluded patterns that you don’t want to track in a .gitignore file.
logs/: It stores the records of all the changes you made. If you open the files you will find information about the log details, like what kind of changes you made, your name, email etc. Here you will find a HEAD file and a ref folder.
logs/HEAD: This stores the information about all the changes that have been made.
logs/refs/heads/branch-name: This stores the information about changes made in that branch.
logs/refs/remotes/branch-name: You will find this folder if your project is connected to a remote repository. This folder saves the information about changes in that particular branch of the remote repository.
objects/: This folder stores all the content like files, commits etc. Initially, you will just find a pack and info subfolders.
objects/[0-9a-f][0-9a-f]: Every time you staged something, 1 folder will be created for storing the backup of the change you made. After you commit, it will create another 2 folders, in which one for storing the directory listing (tree) for that commit and another for storing that commit's message.
The output of your commit and git add is a 40-character checksum hash, where the first two characters of the hash (SHA-1 hash) are the name of the folder and the rest 38 characters will be the name of the file inside it. Objects found here are often called unpacked (or loose) objects. You can read this blog to get some visual explanations.
objects/packs: you will find pack files here. Pack files store many objects in compressed form, along with index files to allow them to be randomly accessed.
objects/info: Additional information about the object store is recorded in this directory.
refs/: References or commit hash(40-character checksum data generated by SHA algorithm) into the commit objects are stored in these folders.
refs/heads/branch-name: This records the most recent commit or last commit object's SHA id of that particular branch.
refs/remotes/branch-name: If you have connected your local repository with a remote repository or cloned a remote repository, only then this subfolder will be created. It records the most recent or last commit objects of branches, which are taken from a remote repository.
refs/tags/name: The tag object is very much like a commit object. It contains a tagger, a date, a message, and a pointer. The main difference is, generally, a tag points to a commit. It always points to the same commit but gives it a friendlier name. There are two types of tags: annotated and lightweight. Annotated tags are more complex. Though if you want, you can tag any Git Object.
COMMIT_EDITMSG: This file stores the message from your most recent commit or last commit.
config: This file contains your project-specific configuration option.
description: Used only by the GitWeb( Git web interface) program.
HEAD: Points to the branch you currently have checked out or the current branch.
index: Here Git stores your staging area information.
packed-refs: Records the same information as refs/heads/, refs/tags/ but in a more efficient way.
So, this is the end. Though I focused entirely on the theory part, I hope you guys enjoyed this one. There will be a next part of this blog which will be entirely focused on the Practical Approach. Meet you at my next blog. Bye Bye!!!