Never Mind the Esoteric Plumbing Commands – Stick to a Subset of the basics!

Git has more than 140 commands available to use, but do you really need them all? In this post I'll highlight which operations to learn by heart, and which to scrap completely!

Never Mind the Esoteric Plumbing Commands – Stick to a Subset of the basics!
Photo by petr sidorov / Unsplash

Being overwhelmed by Git's unusual rich command set is commonplace when starting out. The confusion gets even bigger whenever you're traversing Stack Overflow threads in search for Git related guidance, as users tend to boast with their knowledge of the more esoteric low-level commands.

In Git you have the possibility of using both high-level operations, known as "porcelain" commands, in combination with the low-level counterpart (known as "plumbing"). There's no clear distinction of what commands reside in each bucket (it's somewhat up to whoever is using them to decide), but digging through the official Git man page there are 78 commands listed as porcelain and 68 as plumbing.

Porcelain refers to operations ment for a user (you) to invoke, while plumbing commands are meant for scripting and automation (what happens under the hood) – similar to the relation between your toilet and its pipes.

The amount of times I've been forced to use a plumbing command, during my +10 years as a professional web developer, can be counted using my two arms! With that said, do you even need all 78 porcelain commands to get by on a day-to-day basis? Let's investigate!

Porcelain commands I use regularly

If we disregard the plumbing commands completely (as chances are you'll never have to use them), which of the 78 porcelain commands are worth remembering? I did a quick empirical study myself and ran through each command, marking them based on how frequent I use them – here's the result!

Sizing the commands

To size up my own usage of the porcelain commands, I used the following scale ranging from 0-5. 5 being equal to usage multiple times a day, and 0 closer to never (or almost never). I also tagged each command with either main or ancillary, depending on how crucial I believed them to be for my daily operations.

Freq. Description Comment
5 Multiple times a day Know by heart
4 At least once a day Know by heart
3 A couple of times per week Worth knowing by heart
2 A couple of times a month Keep in mind
1 Occasionally Look up when needed
0 Never (or almost never) Not relevant

I was a bit surprised by the result myself, as it turns out I only use roughly 17 commands frequently – that means only 25% of the available high-level commands. Even more interesting, 33 commands ended up in the Never (or almost never) column.

Chances are these 17 commands will be enough for you as well! Below is a breakdown of each category, starting with the most used commands first. If you feel overwhelmed by the overall available command set, I'd suggest familiarising yourself with the commands under category 5 and 4 – they'll take you a long way!

5 - Multiple times a day (know by heart)

Command Description Type
$ git add Add file contents to the index main
$ git checkout Switch branches or restore working tree files. main
$ git commit Record changes to the repository. main
$ git diff Show changes between commits, commit and working tree, etc. main
$ git gui A portable graphical interface to Git. main
$ git restore Restore working tree files. main
$ git status Show the working tree status. main
$ git switch Switch or create branches. main
$ gitk The Git repository browser. main

4 - At least once a day (know by heart)

Command Description Type
$ git fetch Download objects and refs from another repository. main
$ git help Display help information about Git. ancillary
$ git log Show commit logs. main
$ git merge Join two or more development histories together. main
$ git pull Fetch from and integrate with another repository or a local branch. main
$ git push Update remote refs along with associated objects. main
$ git rebase Reapply commits on top of another base tip. main
$ git stash Stash the changes in a dirty working directory away. main

3 - A couple of times per week (worth knowing by heart)

Command Description Type
$ git branch List, create, or delete branches. main
$ git difftool Show changes using common diff tools. ancillary
$ git mergetool Run merge conflict resolution tools to resolve merge conflicts. ancillary
$ git reflog Manage reflog information. ancillary
$ git reset Reset current HEAD to the specified state. main

2 - A couple of times a month (keep in mind)

Command Description Type
$ git blame Show what revision and author last modified each line of a file. ancillary
$ git cherry-pick Apply the changes introduced by some existing commits. main
$ git clone Clone a repository into a new directory. main
$ git init Create an empty Git repository or reinitialize an existing one. main
$ git mv Move or rename a file, a directory, or a symlink. main
$ git remote Manage set of tracked repositories. ancillary
$ git revert Revert some existing commits. main
$ git rm Remove files from the working tree and from the index. main
$ git tag Create, list, delete or verify a tag object signed with GPG. main

1 - Occasionally (look up when needed)

Command Description Type
$ git bisect Use binary search to find the commit that introduced a bug. main
$ git clean Remove untracked files from the working tree. main
$ git config Get and set repository or global options. ancillary
$ git describe Give an object a human readable name based on an available ref. ancillary
$ git filter-branch Rewrite branches. main
$ git gc Cleanup unnecessary files and optimize the local repository. main
$ git grep Print lines matching a pattern. ancillary
$ git prune Prune all unreachable objects from the object database. ancillary
$ git range-diff Compare two commit ranges (e.g. two versions of a branch). main
$ git rerere Reuse recorded resolution of conflicted merges. ancillary
$ git shortlog Summarize git log output. main
$ git show Show various types of objects. main
$ git show-branch Show branches and their commits. ancillary
$ git whatchanged Show logs with difference each commit introduces. ancillary

0 - Never, or almost never (not relevant)

Command Description Type
$ git am Apply a series of patches from a mailbox. main
$ git annotate Annotate file lines with commit information. ancillary
$ git archimport Import a GNU Arch repository into Git. ancillary
$ git archive Create an archive of files from a named tree. main
$ git bugreport Collect information for user to file a bug report. ancillary
$ git bundle Move objects and refs by archive. main
$ git count-objects Count unpacked number of objects and their disk consumption. ancillary
$ git cvsexportcommit Export a single commit to a CVS checkout. ancillary
$ git cvsimport Salvage your data out of another SCM people love to hate. ancillary
$ git cvsserver A CVS server emulator for Git. ancillary
$ git fast-export Git data exporter. ancillary
$ git fast-import Backend for fast Git data importers. ancillary
$ git format-patch Prepare patches for e-mail submission. main
$ git fsck Verifies the connectivity and validity of the objects in the database. ancillary
$ git imap-send Send a collection of patches from stdin to an IMAP folder. ancillary
$ git instaweb Instantly browse your working repository in gitweb. ancillary
$ git maintenance Run tasks to optimize Git repository data. main
$ git merge-tree Show three-way merge without touching index. ancillary
$ git notes Add or inspect object notes. main
$ git p4 Import from and submit to Perforce repositories. ancillary
$ git pack-refs Pack heads and tags for efficient repository access. ancillary
$ git quiltimport Applies a quilt patchset onto the current branch. ancillary
$ git repack Pack unpacked objects in a repository. ancillary
$ git replace Create, list, delete refs to replace objects. ancillary
$ git request-pull Generates a summary of pending changes. ancillary
$ git send-mail Send a collection of patches as emails. ancillary
$ git sparse-checkout Initialize and modify the sparse-checkout. main
$ git submodule Initialize, update or inspect submodules. main
$ git svn Bidirectional operation between a Subversion repository and Git. ancillary
$ git verify-commit Check the GPG signature of commits. ancillary
$ git verify-tag Check the GPG signature of tags. ancillary
$ git worktree Manage multiple working trees. main
$ gitweb Git web interface (web frontend to Git repositories). ancillary

Conclusion

If you're not part of the broader Unix community deliberately making improvements to its source code, are managing complex submodule configurations, or are interacting with other version control systems, chances are you'll be fine using only ~20 Git commands!

That said, knowing these ~20 commands by heart doesn't mean you should memorize the syntax, but rather learn when and how these commands should be used. To become truly self-propelled with Git, grasping the mental model and fusing it with above commands is vital for your success.

If you still feel a bit insecure on Git's fundamentals I'd suggest catching up by reading the series below, demystifying common commands and concepts.

Git Commands & Concepts – Demystified (part 1)
Being overwhelmed by Git’s commands & concepts is unfortunately not too uncommon. This post provides a mental model highlighting all key parts, making your life with Git more durable!

Finally, if you're not a plumber – Stick to the basics! 🚽

😎 Thanks for reading and good luck improving your source code management skills!