Git mktree: Build Tree Objects from ls-tree Data
Build Git tree objects from ls-tree-formatted input, verify the referenced objects, and understand the boundary between reading and constructing tree objects.
Advanced
What a Git tree contains
A tree object records directory entries: each entry has a mode, object type, object ID, and pathname. `git mktree` takes the non-recursive output format produced by `git ls-tree` and writes a new tree object. The command prints the resulting object ID.
git ls-tree HEAD^{tree} | git mktreeQuick check
What does `git mktree` create?
The input format comes from `git ls-tree`
The normal input is the non-recursive `git ls-tree` format. For each entry, Git receives the object mode, object type, object ID, a tab, and the pathname. `mktree` normalizes entry ordering, so the input does not have to be pre-sorted.
git ls-tree HEAD^{tree} > tree.txt
git mktree < tree.txtQuick check
Must you sort the `git ls-tree` input yourself before passing it to `git mktree`?
Existing objects are checked by default
By default, every referenced object must already exist. This makes `mktree` validate the object IDs named by the input before writing the tree. If an entry names a missing object, the command fails instead of silently creating a tree that points at that missing object.
printf '100644 blob <missing-object-id>\tmissing.txt\n' | git mktreeQuick check
What happens by default when an input entry refers to a missing object?
`--missing` deliberately relaxes that check
`--missing` allows tree entries to name objects that are not currently present. This is a deliberate change to the default validation rule; it is useful for low-level object construction, but it should not be confused with making the missing object available.
git mktree --missing < tree-with-missing-object.txtQuick check
What does `--missing` do?
NUL-delimited input with `-z`
Use `-z` when the input is NUL-terminated `git ls-tree -z` output. This avoids newline-based parsing for pathnames containing unusual characters.
git ls-tree -z HEAD^{tree} | git mktree -zBuild multiple trees with `--batch`
`--batch` lets one invocation build more than one tree. In normal input, separate trees with a blank line. With `-z`, each entry is NUL-terminated and the trees are separated according to the NUL-delimited batch format.
printf '%s\n\n%s\n' "$(git ls-tree HEAD^{tree})" "$(git ls-tree HEAD^{tree})" | git mktree --batchQuick check
What is `--batch` for?
Do not confuse `mktree` with `read-tree`
`git mktree` writes a tree object into the object database. `git read-tree` instead reads tree information into the index. `git ls-tree` inspects an existing tree. These commands operate at different layers and are intentionally taught separately.
Quick check
Which command reads tree information into the index rather than creating a tree object?
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.