Git Plumbing
Porcelain and Plumbing
git commit
Plain English: Create a new tree object from the current index and create a new commit object from that tree. The commit object combines a commit message, parent, date, author, committer, and the tree. Update the ref pointed to by HEAD with the hash of the new commit object.
Plumbing
Once files are in the index (using git add
or git update-index
) use git write-tree
to create a new tree object:
$ git write-tree
8c3c7fbcd903744b20fd7567a1fcefa99133b5bc
Before creating the commit object, a commit message must be created. Usually,
this is done by invoking the default editor. The file the editor opens is
called COMMIT_EDITMSG
in the .git
directory and is pre-populated with the
output of git diff-index --patch HEAD
:
$ echo "\n# ------------------------ >8 ------------------------" > .git/COMMIT_EDITMSG
$ git diff-index --patch HEAD >> .git/COMMIT_EDITMSG
$ ${GIT_EDITOR:-${EDITOR:-vi}} .git/COMMIT_EDITMSG
The first line above is called a “scissor line” (the >8
looks like a pair of
scissors). That line and everything below it is automatically deleted by git commit
, but when using plumbing commands we must do it manually:
$ tmp=$(mktemp)
$ sed -n '/>8/q;p' .git/COMMIT_EDITMSG > "$tmp"
$ mv "$tmp" .git/COMMIT_EDITMSG
Finally, we can create the commit object.
$ tree="$(git write-tree)"
$ commit="$(git commit-tree -p HEAD -F .git/COMMIT_EDITMSG "$tree")"
$ git update-ref HEAD "$commit"