ref: 752f5d9a8695460cf5cac1c921bf9481b2c4d4fc gpanders.com/content/blog/git-plumbing.md -rw-r--r-- 2.4 KiB
752f5d9aGreg Anders Move 'posts' to 'blog' 2 years ago

#title: Git Plumbing date: 2020-03-02 draft: true

#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.


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

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

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"