Skip to content

Commit

Permalink
Update and verify create commit step
Browse files Browse the repository at this point in the history
  • Loading branch information
Yijun2 committed Feb 28, 2024
1 parent b173b83 commit 5f0d65a
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 161 deletions.
4 changes: 2 additions & 2 deletions pages/1-git-folder.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
layout: default
title: Create first commit
title: Create .git
---

Welcome to our workshop's journey into Git's inner workings! Normally, when we start versioning changes in our projects, we rely on commands like `git add` and `git commit` to track our modifications. However, to truly grasp the magic behind how Git saves and manages these changes, we're going to dive deeper and take a hands-on approach, doing it all manually, without relying on those commands.
Expand Down Expand Up @@ -58,6 +58,6 @@ Now git status thinks that we are on branch `main` and we kinda achive what we a


<footer style="width: 100%; display: flex; justify-content: space-between; padding: 20px 0;">
<a href="" style="float: left; margin-left: 10px;">Previous Step: Setup</a>
<a href="../index.html" style="float: left; margin-left: 10px;">Previous Step: Setup</a>
<a href="./2-blob.html" style="float: right; margin-right: 10px;">Next Step: Make a blob</a>
</footer>
54 changes: 2 additions & 52 deletions pages/2-blob.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Now, when we execute `git cat-file -p 35d7a9` or `git show 35d7a9`, it should di
```
This repository was made manually without git init!
```
>> You can also use `git cat-file -t 35d7a9` to see the type of the object. In this case, it should print out as a `blob`.
> You can also use `git cat-file -t 35d7a9` to see the type of the object. In this case, it should print out as a `blob`.
**Note: Did you find it curious that the hash from your `README.md` file matches the one mentioned here before you even hashed it on your machine? That's Git's magic at work, utilizing SHA-1 hashing to create a checksum for the objects. If the hash in your `.git` folder matches the one here, it indicates that the files are indentical according to Git.**

Expand Down Expand Up @@ -92,58 +92,8 @@ Now my `.git` folder looks like this:

We have gotten a new `index` file here. Now lets look at the our staging now with `git status`, you should see that now `README.md` is staged and ready for commit.

### Create a tree object

After creating a blob object for your `README.md` file, the next step is to create a tree object. A tree object in Git represents a directory and its contents, which could be other directories (sub-trees) or files (blobs). For our simple repository, the tree object will just contain the `README.md` blob and its name.

A tree object lists all blobs (files) and trees (directories) that reside in a directory. This is typically achive by command `git commit -m "commit message"`.

Each entry in a tree object has a mode, type, SHA-1 hash, and name. Here's an example of what a tree object might look like:

```
100644 blob abc123456789... README.md
```

* 100644 is the file mode for a regular file.
* blob indicates that this entry is a file (blob).
* abc123456789... is the SHA-1 hash of the blob object for README.md.
* README.md is the name of the file.

[When you are ready, click here to start the creation of your first tree object.](create-tree-object.md) for a detailed steps.

## Step 6: Create a Commit Object

<!-- A commit object records the state of your repository at a certain point in time. To create a commit object:
Write a commit message that describes the changes you are committing.
Include details such as the author, committer, and the timestamp.
Create a SHA-1 hash for the commit metadata and the tree object that records the directory structure of your project.
Store the commit object in the `.git/objects` directory. -->


A commit object in Git encapsulates the state of a repository at a given point in time. It includes the following information:
* **Tree SHA-1:** The SHA-1 hash of the tree object that represents the directory structure of the commit.
* **Parent SHA-1:** The SHA-1 hash of the commit's parent(s). For the first commit, this field is absent.
* **Author:** The name, email of the author of the changes, and the timestamp.
* **Committer:** The name, email of the person who committed the changes, and the timestamp.
* **Commit Message:** A descriptive message explaining the commit.

Here's an example of what a commit object might look like (simplified):
```
tree 2f3a123456789...
author John Doe <[email protected]> 1625592667 -0400
committer John Doe <[email protected]> 1625592667 -0400
Initial commit
```

After we have created blob and tree object, it is time to create a commit object from scratch!

[Here is a detailed steps on how to do it](create-commit-object.md)

By the end of these steps, you will have manually created the initial commit for your repository.

<footer style="width: 100%; display: flex; justify-content: space-between; padding: 20px 0;">
<a href="./1-git-folder.html" style="float: left; margin-left: 10px;">Previous Step: .git folder</a>
<a href="3-tree-commit.html" style="float: right; margin-right: 10px;">Next Step: Create blob </a>
<a href="3-tree-commit.html" style="float: right; margin-right: 10px;">Next Step: Create a commit </a>
</footer>
85 changes: 85 additions & 0 deletions pages/3-tree-commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
layout: default
title: Create a commit
---

### Create a tree object

After creating a blob object for your `README.md` file, the next step is to create a tree object. A tree object in Git represents a directory and its contents, which could be other directories (sub-trees) or files (blobs). For our simple repository, the tree object will just contain the `README.md` blob and its name. When we use `git commit -m "commit message"`, it updates the tree objects from `index` file we just created.

Lets make our tree by running command:

```
git write-tree
```

Now our .git folder looks like following:

```
.git
├── HEAD
├── index
├── objects
│   ├── 35
│   │   └── d7a9a460c597c8a29b210b2bed894a5281088e
│   └── 86
│   └── 046e36f9b11251cf800033cec1c524502a6ce4
└── refs
└── heads
```

A new object is now created under `.git/objects` and the hash was `86046e36f9b11251cf800033cec1c524502a6ce4`. We can verify with `git cat-file -t 86046e` and `git cat-file -p 86046e`.

## Create a Commit Object

Lets have a sync and do a `git status`, and we should see the result is the same as last time. Same as `git add` the command `git commit -m message` performs several operations internally, and update tree structure is part of it. As you may have guessed, lets make a new commit object.

A commit object in Git encapsulates the state of a repository at a given point in time. It includes the following information:
* **Tree SHA-1:** The SHA-1 hash of the tree object that represents the directory structure of the commit.
* **Parent SHA-1:** The SHA-1 hash of the commit's parent(s). For the first commit, this field is absent.
* **Author:** The name, email of the author of the changes, and the timestamp.
* **Committer:** The name, email of the person who committed the changes, and the timestamp.
* **Commit Message:** A descriptive message explaining the commit.

Here's an example of what a commit object might look like (simplified):
```
tree 2f3a123456789...
author John Doe <[email protected]> 1625592667 -0400
committer John Doe <[email protected]> 1625592667 -0400
Initial commit
```

To achive this, we can use plumbing command:

```
git commit-tree 86046e36f9b11251cf800033cec1c524502a6ce4 -m "initial commit"
```

This is what `.git` looks like now:

```
.git
├── HEAD
├── index
├── objects
│   ├── 35
│   │   └── d7a9a460c597c8a29b210b2bed894a5281088e
│   ├── 79
│   │   └── e1fd1b22c75a812e59672d973cae307c036ef3
│   └── 86
│   └── 046e36f9b11251cf800033cec1c524502a6ce4
└── refs
└── heads
```

You should have received a new object with a different hash than what shows above, this is because the content of the commit object is different, like autor and comitter.

Lets verify the new object with `git cat-file -t` and `git cat-file -p`



<footer style="width: 100%; display: flex; justify-content: space-between; padding: 20px 0;">
<a href="./2-blob.html" style="float: left; margin-left: 10px;">Previous Step: Create blob</a>
<a href="./4-branch.html" style="float: right; margin-right: 10px;">Next Step: Branching</a>
</footer>
65 changes: 0 additions & 65 deletions pages/create-blob-object.md

This file was deleted.

42 changes: 0 additions & 42 deletions pages/create-commit-object.md

This file was deleted.

0 comments on commit 5f0d65a

Please sign in to comment.