git show explained in-depth [Practical Examples]

git show command cheatsheet

git-show is a command to view objects such as blobs, trees, commits, and tags. You can check an object's details by specifying the SHA1.

git show <SHA1>

Use the pretty option to control the length of viewable metadata.

Advertisement
git show --pretty=<decoration>

The decoration can be oneline, short, medium, full, fuller, raw, or a formatted string.

OR

abbreviate the SHA1 or not.

git show --abbrev-commit

git show --no-abbrev-commit

It would be best to understand git objects before seeing practical examples of the above commands.

For that reason, we will explain git objects, creating them from scratch. We will then manipulate them using the git-show command. What is more? Let's dive into section two of this tutorial.

 

Understand git objects before applying git-show

Think of git as an API for version control. You can interact with the API through two routes: plumbing and porcelain commands.

Advertisement

You mostly interact with the high-level (porcelain) commands such as git init, stage, and commit. That is fine. But if you want to deeply understand what happens in the background, you should use low-level (plumbing) commands as follows.

 

Initialize a repository

A repository is a collection of commits. Commit objects reference trees. Tree objects, in turn, reference blobs and other trees. Finally, blobs contain file objects.

Git, collectively, refers to the three primary object types as objects. To interact with the objects, we need a naming system. So, instead of cramming the 40 characters in the SHA1, we use an easy-to-remember name. The naming system is called refs.

The objects and refs are directories created inside the .git subdirectory on initializing a repo. Git tells us it cannot recognize a repository before we initialize it.

git status

git show explained in-depth [Practical Examples]

Instead of running git init, let's create the folders manually.

mkdir .git
mkdir .git/objects
mkdir .git/refs​

git show explained in-depth [Practical Examples]

For git to track the versions of files, it must be aware of the pointer to the latest commit: HEAD. The HEAD is a file in the .git subdirectory, referencing the latest branch tip.

Advertisement

A branch is a named reference to a commit. Since a branch is part of the object naming system, git stores it in the objects directory we created above. However, instead of calling the named references branches, git refers to them as heads.

Let's create the directory.

mkdir .git/refs/heads

And fool git that the latest commit lies in the main branch. Although we have not created the main branch, git trusts us.

echo "ref: refs/heads/main" > .git/HEAD

At this point, git considers our directory a repository: it has the HEAD file and objects and refs (with data about the latest branch) directories.

Let's list the files and their contents.

ls .git
cat .git/HEAD
ls .git/refs
ls .git/refs/heads​

git show explained in-depth [Practical Examples]

And recheck the status.

Advertisement
git status

git show explained in-depth [Practical Examples]

The API is intelligent enough to realize that we are on the main branch and have not made any commits yet. Let's move to the next step in the git-show tutorial: staging changes from scratch.

 

Stage changes

Staging changes entails creating a blob, updating the index, and creating a tree object.

 

Create a blob

Before creating a blob, the objects' directory is empty. Running the ls command on the .git directory

ls .git/objects

returns nothing.

git show explained in-depth [Practical Examples]

Let us create a blob and reinspect the directory.

echo "first content" | git hash-object --stdin -w

Here, we are creating a blob of SHA1 using the hash-object method. We tie the string, first content, to the blob using the standard input option, --stdin, and a write operation, -w, to the database.

Advertisement

We get a lengthy output. Mark its first two characters and recheck the objects directory.

ls .git/objects
ls .git/objects/66

The objects directory has a subdirectory beginning with two characters of the blob object. Inside the subdirectory are the remaining parts of the SHA1. Git partitions SHA1 objects that way to ease their search.

git show explained in-depth [Practical Examples]

How do you know the SHA1 is a blob? You can view the object type, content, or size using the cat-file command.

 

How to view blob objects without the git-show command

Type

Supply the -t option in the cat-file command.

Advertisement
git cat-file -t <SHA1>
git cat-file -t 66bc72995f76e56c0b92a7371cb3de2c9b3b8558

 

Content

Replace the -t with -p option in the cat-file command.

git cat-file -p <SHA1>
git cat-file -p 66bc72995f76e56c0b92a7371cb3de2c9b3b8558
​

OR

List all objects with their types and sizes.

git cat-file --batch-check --batch-all-objects

OR

Print the full path to the object.

Advertisement
find .git/objects -type f

git show explained in-depth [Practical Examples]

 

Update the index

The update-index command

git update-index --add --cacheinfo 100644 66bc72995f76e56c0b92a7371cb3de2c9b3b8558 file1.txt

helps in caching the blob details.

We are updating the database with a blob id 66bc72995f76e56c0b92a7371cb3de2c9b3b8558, containing the contents of a new file, file1.txt. We do that by caching a 16-bit file mode of value 100644. A value of 100644 in the git database means we handle a normal file; 100755, executable, while 120000 is a symbolic link.

We have created the blob and new file at the index. The problem is that git cannot account for the new file in the working directory. It thinks we have deleted an old file and staged a new one on caching the blob with the new file.

git status

git show explained in-depth [Practical Examples]

We can correct the confusion by inserting the blob's content into the new file.

git cat-file -p 66bc72995f76e56c0b92a7371cb3de2c9b3b8558 > file1.txt

Then recheck the status and confirm the new file's content.

git status
cat file.txt

git show explained in-depth [Practical Examples]

 

Create a tree

Let's create a tree from the blob.

git write-tree 66bc72995f76e56c0b92a7371cb3de2c9b3b8558

We get a new object. Let's git-show its type and content.

git cat-file -t b4032b5f2e25e7c55cadd69b5980cceab3cde275
git cat-file -p b4032b5f2e25e7c55cadd69b5980cceab3cde275

The batch option and the find command confirm we have two objects: a blob and a tree.

git cat-file --batch-check --batch-all-objects
find .git/objects -type f

git show explained in-depth [Practical Examples]

 

Git commit

We can create a commit object from the tree using the plumbing command: git commit-tree. Check the status, make a commit and recheck the status.

git status
git commit-tree b4032b5f2e25e7c55cadd69b5980cceab3cde275 -m "Initial commit"
git status

git show explained in-depth [Practical Examples]

 

We have a new (commit) SHA1 of 34f94cac89e029f8d83d0a17dea58b6becaeb8ef, but the index and history did not get updated. Here is the reason.

We created a commit object without updating the current branch. So, git goes to check the HEAD file and finds that the latest commit lies in refs/heads/main. But the main branch does not exist yet.

Let's create the branch and reference the latest commit using the update-ref plumbing command.

git update-ref refs/heads/main 34f94cac89e029f8d83d0a17dea58b6becaeb8ef

The echo command

echo 34f94cac89e029f8d83d0a17dea58b6becaeb8ef > .git/refs/heads/main

would achieve similar results to the update-ref command.

Recheck the status and history.

git status
git log​

The index and history got updated.

git show explained in-depth [Practical Examples]

Now that you have a deep understanding of git objects and how to manipulate them using plumbing commands, let us git-show the objects using porcelain commands.

 

Lab setup to git-show objects using the git show command

I am copying the URL to the git_tags_lesson repository on GitHub.

git show explained in-depth [Practical Examples]

Clone it on my terminal. And cd into it.

git show explained in-depth [Practical Examples]

We can create, stage, and commit a file using the high-level porcelain commands: git stage and git commit. But there is no need for that because the cloned repo has objects and refs to practice the git-show command.

The refs include heads (branches) and tags. Like a branch, a tag tells more about a commit.

 

Example~1: git-show objects

List the objects.

git cat-file --batch-check --batch-all-objects

And check the details of the latest commit, blob, tag and tree.

git show 02bed804eaf26951a769491df9227e6756727aa9
git show 28fab796c76056ab246eaa479428c8aedcc9e836
git show 31a202f5ee4fa45a4487010e5cd509d2fe6ee925

git show explained in-depth [Practical Examples]

 

We can also view tag details by specifying its name instead of the SHA1.

git show v1.3

git-show tag

 

Example~2: git-show desired lines in a commit

You can git-show a commit object's output by controlling portions to view. For instance, the oneline decoration

git show --pretty=oneline

shows only the diffs data, ignoring the author and timestamp information. The full option

git show --pretty=full

shows the author information, commit message, and diffs of the latest commit.

git show explained in-depth [Practical Examples]

We can also use the --abbrev-commit options to control git-show latest commit SHA1 output characters. The --abbrev-commit reveals seven characters

git show --abbrev-commit

Whereas the --no-abbrev-commit option shows the forty characters.

git show --no-abbrev-commit

git show explained in-depth [Practical Examples]

 

Key Takeaway

The git-show command is crucial in exploring the contents of a git object. However, failure to understand git objects can prevent you from exploiting the full potential of the command.

Now that you have a deep understanding of git and git objects, go ahead and manipulate the objects using plumbing and porcelain git commands, as illustrated in this tutorial.

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X