Git Tree Object

In Git, the term "tree" refers to a tree object. A tree object represents a directory and serves as a container for other tree objects and blob objects (files). It functions as a mapping between file/folder names and the corresponding blob/tree objects. A tree object is essentially the equivalent of a directory in a filesystem.

When you create a commit, Git generates a tree object to represent the state of the repository at that moment. The tree object contains the file names, their mode (indicative of file type, permissions), and a pointer to the blob or another tree (in case of a directory within a directory).

Git mktree Command

The git mktree command reads the index or object information from the standard input to create a tree object. This is a lower-level operation and is generally not used in daily development workflows. However, it can be useful for understanding the internals of Git.

Workshop Exercise

The exercise below will help you to understand the concept of Git tree objects better. This exercise assumes that you already have Git installed and know the basics of using it.

  1. Initialize a Git Repository and Add a File

     mkdir git_tree_demo
     cd git_tree_demo
     git init
     echo "Hello, Git" > hello.txt
     git add hello.txt
     git commit -m "Initial commit"
    
  2. Inspect the Latest Commit

     git log --pretty=oneline
    

    Note the commit hash for the latest commit.

  3. View the Tree Object of the Commit

     git cat-file -p b830c9^{tree}
    

    Note the output, which should include the blob for hello.txt.

  4. Manually Create a Blob

     echo "This is another file" | git hash-object -w --stdin
    

    This will return a SHA-1 hash for the blob 77d8517569c4f7bdf90fb77cafc8c93c7353e0db.

  5. Manually Create a Tree Object

    Use the git mktree command to create a new tree object. Make sure to use the blob hash generated in the previous step (77d851).

     echo -e "100644 blob 77d8517569c4f7bdf90fb77cafc8c93c7353e0db\tanother.txt" | git mktree
    

    The -e option for echo enables interpretation of backslash escapes, which is needed to interpret the \t as a tab character.

    This will output another SHA-1 hash, 0ecc46485fd04f0a2f72f5565e57495c4fc59ec6, representing the tree object.

  6. Create a New Commit Using the Tree

     git commit-tree 0ecc46485fd04f0a2f72f5565e57495c4fc59ec6 -p b830c92 -m "Commit using manual tree"
    

    This will create a new commit with the parent as b830c92 and tree as 0ecc46. Note down the new commit hash, 905b26aebe25ada5c14e832ce21f286c1791ec64.

  7. Update HEAD and Checkout

     git update-ref HEAD 905b26aebe25ada5c14e832ce21f286c1791ec64
     git checkout HEAD
    

Check your working directory; it should now include the another.txt file with content "This is another file".

Through this exercise, you have manually created a blob and a tree object, then used them to make a new commit. This should give you a better understanding of what tree objects are and how they function within Git.

Reference

  1. https://git-scm.com/docs/git-mktree