build-git / lesson-16.md
Lesson 16 · The index and write-tree

The executable-bit mode

Git tracks one permission distinction: whether a file is executable. An executable file gets mode 100755 instead of 100644, and that mode is part of the tree hash. Today you detect it when staging.

The goal

Record mode 100755 for an executable working file and 100644 otherwise.

Start here - the target
TO DO
Scenario: An executable file is staged with mode 100755
Givena working file build.sh whose owner-executable bit is set, and a non-executable file notes.txt
Wheneach is staged with Add
Thenbuild.sh is recorded in the index with mode 100755
Andnotes.txt is recorded with mode 100644, the two being the only file modes Git uses
Background

Git deliberately tracks almost nothing about file permissions: not the group or world bits, not ownership, not timestamps. The single exception is whether a file is executable. A regular file is mode 100644 and an executable one is 100755. These are the only two blob modes you will ever see in a tree (the third mode, 40000, is for subdirectories).

This matters because the mode is part of the tree entry, and therefore part of the tree’s hash. Flip a file’s executable bit and re-commit, and the tree id changes even though the file’s content, and so its blob id, is identical. Detect the owner-execute bit when staging and record the right mode; everything downstream, write-tree included, just uses whatever the index says.

Make it work
// check the owner-execute bit of the file's permissions
info, _ := os.Stat(full)
mode := "100644"
if info.Mode().Perm()&0o100 != 0 {
mode = "100755"
}
CheckpointDONE
add records the executable bit. Commit and stop here.