Git Plumbing vs Porcelain Commands
Summary:
Understand the low-level (plumbing) and high-level (porcelain) commands.
Git is an incredibly powerful distributed version control system. As you dig deeper into its inner workings, you may come across two terms: plumbing and porcelain. These metaphors, coined by Git’s creator Linus Torvalds, refer to the two broad classes of commands in Git. Knowing the difference empowers you to troubleshoot issues, automate workflows, and better understand what's happening under the hood.
In this article, we'll dive into what plumbing and porcelain commands mean, explore examples of each, and discuss when and why you might want to use them.
What are Plumbing and Porcelain Commands?
Porcelain Commands (High-Level)
Porcelain commands are the familiar, user-facing commands. They're designed to be easy to use and provide a user-friendly interface for common Git operations. Think of them as the pretty, clean outer surface of your version control system: the porcelain on your bathroom fixtures that's comfortable to touch.
Examples:
git add
git commit
git status
git push
git pull
git clone
git branch
git checkout
git merge
Porcelain commands do a lot of work behind the scenes to make your workflow as intuitive as possible. They handle details like object creation, index management, and more.
Plumbing Commands (Low-Level)
Plumbing commands are the low-level, internal commands that Git porcelain commands often use behind the scenes. They’re powerful, precise, but not always intuitive or user-friendly. These commands expose Git’s under-the-hood objects and mechanisms—the plumbing that makes everything flow.
Examples:
git hash-object
git cat-file
git update-index
git write-tree
git ls-tree
git read-tree
git rev-parse
git update-ref
Plumbing commands are generally stable and designed to be scripted or used by other programs, not necessarily by end-users during daily work.
Analogy: A Plumbing and Porcelain Bathroom
Torvalds' metaphor is perfect: in your bathroom, porcelain is what you touch—the sink and the toilet—but all the real work is handled by the plumbing out of sight. Most people interact with the porcelain, but the plumbing is essential to making the whole thing function.
Similarly, most Git users stick with porcelain commands, but power users and tooling authors may sometimes dip into the plumbing for more control.
Why Does This Distinction Matter?
When to Use Porcelain
If you are:
- Making everyday commits and merges
- Navigating branches or repositories
- Collaborating with others
- Unfamiliar with Git internals
Just stick with porcelain commands. They protect you from accidental data loss, take care of housekeeping, and (usually) only show you what you need.
When to Use Plumbing
Consider using plumbing commands when:
- You are scripting custom Git workflows
- You need granular control over repository objects and references
- You’re debugging tricky problems
- You want to understand or manipulate Git's raw data structures
For example, a script to gather commit statistics might use git rev-list
and git cat-file
to enumerate and examine objects directly.
Note: While plumbing commands are powerful, they can also be dangerous. They don't protect you from mistakes and won’t warn you about overwriting or deleting important data.
Examples: Porcelain vs Plumbing
Let’s see how you might perform a simple operation using both approaches:
Adding a File to the Repository
-
Porcelain:
git add README.md git commit -m "Add README"
-
Plumbing:
# Store the file in the object database git hash-object -w README.md # Add the file to the index git update-index --add README.md # Write the current index as a new tree git write-tree # Create a new commit object git commit-tree <tree_hash> -m "Add README"
As you can see, the plumbing approach is much more involved and exposes the process that git add
and git commit
perform under the hood.
Viewing Commit Content
-
Porcelain:
git show <commit>
-
Plumbing:
# Get tree hash of the commit git cat-file commit <commit> # Then, show content of tree or blob git cat-file -p <tree_or_blob_hash>
A List of Common Plumbing vs Porcelain Commands
Porcelain | Plumbing | Purpose |
---|---|---|
git add | git update-index | Add file to staging area (index) |
git commit | git commit-tree | Record changes in the repository |
git log | git rev-list | Show commit history |
git status | (no direct equiv) | Show repository status |
git checkout | git read-tree | Update working directory |
git branch | git update-ref | Manage branch references |
git show | git cat-file | Display object contents |
Tips for Using Plumbing Commands
- Always make backups. Plumbing commands can alter data irreversibly.
- Use in scripts, not manually. Scripted use reduces the chance of mistakes.
- Consult the documentation. Plumbing commands have many options and expect exact input/output formats.
Conclusion
Whether you stick to the comfort of porcelain or occasionally need the flexibility of plumbing, understanding the distinction reveals much about how Git works. For day-to-day work, keep to porcelain commands—they’re safer and more user-friendly. When you need full control, or are creating powerful workflows, plumbing commands let you harness Git’s true power.
Either way, the combination of both is what makes Git so versatile—a tool for casual users and power users alike.
Further Reading:
- Git Internals — Plumbing and Porcelain
git help -a
and search for “plumbing” vs “porcelain” commands- "Plumbing & Porcelain" in the Pro Git Book
Happy Gitting!