Git Plumbing: Don’t Just Type ‘commit’ and ‘push’, Learn to ‘Dissect’ Git from the Inside

Git tutorial - IT technology blog
Git tutorial - IT technology blog

Git is More Than Just Common Commit or Push Commands

Have you ever broken out in a “cold sweat” because you accidentally ran git reset --hard on production? When I first started, I thought Git was just a fancy copy-paste tool. It wasn’t until I broke the structure of a large repository that I realized common commands are sometimes useless. At that moment, I was forced to dive into the depths of the .git directory to pick up every piece of data.

Most developers are only familiar with git status, git branch, or git checkout. In the Git world, these are called Porcelain commands. They are like a sink: polished, easy to use, and clean. However, for that system to operate, there needs to be a complex network of pipes underneath. Those are the Plumbing commands.

Mastering Plumbing commands helps you handle “tough” cases when Git fails. Additionally, it serves as the foundation for writing your own development tools specifically for your team.

Git is Actually a Content-Addressable Storage System (Key-Value)

Many people mistakenly believe Git stores changes (diffs) between versions. In reality, Git operates as a simple Key-Value system. The Key is a 40-character SHA-1 hash of the file content, and the Value is the data itself.

Suppose you change just a single comma in a 1GB file. Git creates a completely new object instead of just storing that comma. Thanks to zlib compression, the repository size remains optimized. To manipulate these objects directly, you need the trio: hash-object, cat-file, and rev-parse.

Hands-on with Git Plumbing

1. Git hash-object: Creating an Identifier for Data

This command takes a piece of data, calculates the SHA-1 hash, and can store it directly into the Git database. This is exactly what git add does behind the scenes every day.

# Calculate the hash only without storing
echo "itfromzero tutorial" | git hash-object --stdin

# Calculate and store directly into .git/objects
echo "hello world" | git hash-object -w --stdin

When you add the -w (write) flag, Git creates a file in .git/objects. If the hash is 3b18e512..., you will see the file at .git/objects/3b/18e512.... Splitting the first 2 characters into a directory helps prevent a single folder from containing tens of thousands of files, which would slow down the system.

Sometimes I need to check a file’s checksum quickly without typing commands, so I use the Hash Generator. This tool runs entirely in the browser, making it extremely safe for sensitive data.

2. Git cat-file: The Microscope for Objects

Once you have the hash, how do you read the content inside? git cat-file is the tool that helps you decode various types of objects from blobs and trees to commits.

# Check the object type
git cat-file -t 3b18e512dba79e4c8300dd08aeb37f8e728b8dad

# View the decompressed content
git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dad

The -p (pretty print) flag is a lifesaver when I need to debug a corrupted commit. It helps me trace which specific files that commit points to at a certain point in time.

3. Git rev-parse: The Interpreter for Computers

Humans prefer using memorable names like main, HEAD, or the v1.0 tag. In contrast, Git only understands raw SHA-1 hashes. git rev-parse acts as the interpreter between the two.

# Get the hash of the current branch
git rev-parse main

# Find the hash of the commit immediately before HEAD
git rev-parse HEAD~1

In CI/CD scripts, I often use git rev-parse HEAD. This command helps retrieve the exact version ID being deployed for logging purposes, regardless of the branch name.

Why Should You Care About These “Dry” Commands?

Using a GUI like GitKraken or VS Code is very convenient, but they don’t help you solve the root of the problem. Understanding Plumbing brings 3 practical benefits:

  • Data Recovery: I once recovered 90% of accidentally deleted code by scanning for dangling blobs. These are pieces of data floating around with no branch pointing to them.
  • Storage Optimization: You can write a script combining cat-file to find the heaviest files that are slowing down your repo’s clone speed.
  • Mastering the Game: When you understand that Git is just a bunch of Key-Value files, concepts like “detached HEAD” will no longer confuse you.

When processing logs or configuring Git hooks, I often use the JSON Formatter to clean up data. Combining good tools with a systems-thinking mindset will help you work significantly faster.

Conclusion

Learning Plumbing commands is like opening the hood of a car to see how the engine runs. You might not repair the engine every day, but that knowledge will save you when the car breaks down in the middle of the road. Try creating an empty repo and manually building a commit using low-level commands. You’ll see that Git is actually very logical and transparent, not a mysterious “black box”.

Share: