52

I performed a git commit command and it gave me the following reply:

7 files changed, 93 insertions(+), 15 deletions(-)
mode change 100644 => 100755 assets/internal/fonts/icomoon.svg
mode change 100644 => 100755 assets/internal/fonts/icomoon.ttf
mode change 100644 => 100755 assets/internal/fonts/icomoon.woff

I know files can have user / group / other rwx permissions and those can be expressed as three bytes, like "644" or "755". But why is git showing six bytes here?

I've read the following articles but didn't find an answer:

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
That Brazilian Guy
  • 4,383
  • 9
  • 25
  • 35

2 Answers2

67

The values shown are the 16-bit file modes as stored by Git, following the layout of POSIX types and modes:

  32-bit mode, split into (high to low bits)

    4-bit object type
      valid values in binary are 1000 (regular file), 1010 (symbolic link)
      and 1110 (gitlink)

    3-bit unused

    9-bit unix permission. Only 0755 and 0644 are valid for regular files.
    Symbolic links and gitlinks have value 0 in this field.

That file doesn’t mention directories; they are represented using object type 0100.

Each digit in the six-digit value is in octal, representing three bits; 16 bits thus need six digits, the first of which only represents one bit:

Type|---|Perm bits

1000 000 111101101
1 0   0   7  5  5

1000 000 110100100
1 0   0   6  4  4

Git doesn’t store arbitrary modes, only a subset of the values are allowed, from the usual POSIX types and modes (in octal, 12 for a symbolic link, 10 for a regular file, 04 for a directory) to which git adds 16 for Git links. The mode is appended, using four octal digits. For files, you’ll only ever see 100755 or 100644 (although 100664 is also technically possible); directories are 040000 (permissions are ignored), symbolic links 120000. The set-user-ID, set-group-ID and sticky bits aren’t supported at all (they would be stored in the unused bits).

See also this related answer.

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • What is 1110 git link? Is it kind of like non-submodule inner git repositories, or what is that? – SOFe Apr 15 '20 at 07:02
  • They’re used for [submodules](https://github.com/git/git/blob/master/Documentation/gitsubmodules.txt). – Stephen Kitt Apr 15 '20 at 07:04
  • in this answer https://stackoverflow.com/a/16581096/3990767 it says 160 instead of 111 – SOFe Apr 15 '20 at 07:05
  • 2
    1600 is the commit object at the tip of the submodule (you can compare the hashes to verify, and `git ls-tree` itself lists this as a commit). The submodule itself is stored as a gitlink with mode 1110. – Stephen Kitt Apr 15 '20 at 07:49
  • 2
    For the lazy, `0755` is [basically](http://permissions-calculator.org/decode/0755/) **restricting writes to user**, and leaving all other perms open. `0644` is [basically](http://permissions-calculator.org/decode/0644/) the same, except **without any execute perms** for anyone. – ijoseph Jan 18 '21 at 23:57
  • Why is it that they allocate 32 bits but only use 16 bits for the mode? When I go into my own .git/index and check I see that they use the lower bits to store them (for `100644` it's `0000 0000 0000 0000 1000 0001 1010 0100`) – RexYuan Jun 26 '21 at 21:41
  • 1
    @RexYuan probably because `mode_t`, the type used to store this information in `stat`’s results, is 32 bits in size as well. – Stephen Kitt Jun 27 '21 at 18:54
  • If you want to change `100644` to `100755`, you need to run `chmod 755 my_file`. – questionto42 Apr 25 '22 at 13:59
9

Traditionally, Unix file systems used 16 bits to hold the type in 4 bits (e.g. regular file, directory, character special device... ) 9 bits of user/group/other permissions, the sticky bit, the SUID bit and the SGID bit.

You are seeing this in octal, so the rightmost 5 digits can have the values 0 - 7 (representing 3 bits for a total of 15) and the left digit is 0 or 1 for the last bit.

On a Linux system man -s 7 inode (i.e. inode(7)) should tell you about this in the file type and mode section.

Matthias Braun
  • 7,797
  • 7
  • 45
  • 54
icarus
  • 17,420
  • 1
  • 37
  • 54