Course Tonight

Course Tonight

Did You Know?

Advanced visual search system powered by Ajax

Chapter 30: Internals

Estimated reading: 5 minutes 5 views

Section 30.1: Repo A git repository is an on-disk data structure that stores metadata for a set of files and directories. It resides in your project’s .git/ folder. Every time you commit data to Git, it gets stored here. The .git/ directory contains every single commit.

The basic structure of a Git repository is as follows:

.git/
 objects/
 refs/

Section 30.2: Objects Git is fundamentally a key-value store. When you add data to Git, it creates an object and uses the SHA-1 hash of the object’s contents as a key. Therefore, any content in Git can be looked up by its hash.

To retrieve the contents of an object using its hash, you can use the following command:

git cat-file -p 4bb6f98

There are four types of objects in Git:

  • Blob
  • Tree
  • Commit
  • Tag

Section 30.3: HEAD ref HEAD is a special ref in Git. It always points to the current object. You can see where it’s currently pointing by checking the .git/HEAD file.

Typically, HEAD points to another ref, as shown below:

$ cat .git/HEAD
ref: refs/heads/mainline

However, it can also point directly to an object, as shown below:

$ cat .git/HEAD
4bb6f98a223abc9345a0cef9200562333

When HEAD is pointing directly to an object instead of a ref, it is known as a “detached head” state.

Section 30.4: Refs A ref in Git is essentially a pointer. It is a name that points to an object. For example:

"master" --> 1a410e...

Refs are stored as plain text files in the .git/refs/heads/ directory.

$ cat .git/refs/heads/mainline
4bb6f98a223abc9345a0cef9200562333

Although commonly referred to as branches, it’s important to note that in Git, there is no such thing as a branch, only a ref.

Using refs allows you to navigate Git more conveniently by providing names to refer to objects. It’s much easier to use a specific name to access a particular place in Git rather than using its hash directly.

Section 30.5: Commit Object A commit in Git is an object that contains metadata and pointers to other objects, rather than directly storing changed files or data. The commit object includes the following information:

  • Hash of a tree
  • Hash of a parent commit (previous commit)
  • Author name/email and committer name/email
  • Commit message

To view the contents of a commit, you can use the following command:

$ git cat-file commit 5bac93
tree 04d1daef...
parent b7850ef5...
author Geddy Lee <glee@rush.com>
commiter Neil Peart <npeart@rush.com>

First commit!

Tree A tree object in Git represents a folder in a traditional filesystem. It serves as a nested container for files or other folders. The tree object contains:

  • Zero or more blob objects (file contents)
  • Zero or more tree objects (subdirectories)

Similar to using ls or dir to list the contents of a folder, you can list the contents of a tree object in Git:

$ git cat-file -p 07b1a631
100644 blob b91bba1b .gitignore
100644 blob cc0956f1 Makefile
040000 tree 92e1ca7e src
...

You can find the files in a commit by first finding the hash of the tree object in the commit, and then examining the tree:

$ git cat-file commit 4bb6f93a
tree 07b1a631
parent ...
author ...
commiter ...

$ git cat-file -p 07b1a631
100644 blob b91bba1b   .gitignore
100644 blob cc0956f1   Makefile
040000 tree 92e1ca7e   src
...

Section 30.7: Blob Object A blob object in Git contains arbitrary binary file contents. It can store raw text, source code, blog articles, or any other file data. To view the contents of a blob, you can use the following command:

$ git cat-file -p d429810
package com.example.project

class Foo {
  ...
}
...

For example, you can browse a tree to see its contents and then examine the content of a specific blob within it:

$ git cat-file -p 07b1a631
100644 blob b91bba1b   .gitignore
100644 blob cc0956f1   Makefile
040000 tree 92e1ca7e   src
100644 blob cae391ff   Readme.txt

$ git cat-file -p cae391ff
Welcome to my project! This is the readme file.

Section 30.8: Creating new Commits The git commit command performs the following actions:

  1. Creates blobs and trees that represent the contents of your project directory. These are stored in .git/objects.
  2. Creates a new commit object containing your author information, commit message, and the root tree created in the previous step. The commit object is also stored in .git/objects.
  3. Updates the HEAD reference in .git/HEAD to point to the hash of the newly-created commit.

This process adds a new snapshot of your project to Git and connects it to the previous state.

Section 30.9: Moving HEAD When you run git checkout on a specific commit (specified by hash or reference), you are instructing Git to update your working directory to match the state of the project when that commit was made. This involves:

  1. Updating the files in the working directory to match the tree inside the commit.
  2. Updating HEAD to point to the specified hash or reference.

Section 30.10: Moving refs around Using git reset --hard allows you to move references (refs) to a specific hash or reference. For example, to move MyBranch to b8dc53, you would do the following:

$ git checkout MyBranch # moves HEAD to MyBranch
$ git reset --hard b8dc53 # makes MyBranch point to b8dc53

Section 30.11: Creating new Refs Running git checkout -b <refname> creates a new ref that points to the current commit. For example:

$ cat .git/head
1f324a

$ git checkout -b TestBranch

$ cat .git/refs/heads/TestBranch
1f324a

In this example, a new branch named TestBranch is created that points to the same commit as the current commit (1f324a).

Leave a Comment

Share this Doc

Chapter 30: Internals

Or copy link

CONTENTS