Plumbing commands (hash-object, cat-file, write-tree, commit-tree, update-ref, rev-parse) do one low-level job with stable output; Git 1,932 's first commit contained little else. Porcelain commands (add, commit, log, status, switch) are the friendly layer on top, and their output may change between releases:
| Porcelain | Plumbing equivalent |
|---|---|
| git add file | hash-object -w, then update-index --add |
| git commit | write-tree, commit-tree, then update-ref HEAD |
| git switch branch | read-tree, checkout-index, symbolic-ref HEAD |
| git branch name | update-ref refs/heads/name HEAD |
Scripts should use plumbing, or porcelain with a stable format such as the confusingly named --porcelain:
echo 'draft' > notes.txt; echo 'x' >> README.md
git status --porcelain --branchOutput
## main M README.md ?? notes.txt
It uses the two-column codes of status --short, and --porcelain=v2 adds modes and hashes. Parse these, never the human output, which is translated and reworded between releases.