Lyte's Blog

Bad code, bad humour and bad hair.

Git Perms

Have you ever noticed that when git mentions a file it often shows an octal permission mode that doesn’t match with the permission on the file?

No? Try this, from an empty directory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Set umask to 0002 (i.e don't mask out user/group bits)
$ umask 0002
# create a new git repo in the current dir
$ git init .
# create a new file
$ touch foo
# get the octal perms on it
$ stat -c "0%a %n" foo
0664 foo
# add and commit
$ git add foo
$ git commit -m "bar"
[master (root-commit) 51dc083] bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo

So I just added a file to git that has octal perms of 0664 but git reported 100644 – it’s safe to ignore the prefix, but why has the second last digit changed?

Here’s something else to try:

1
2
3
4
5
6
7
8
# Create a file with every (practical) octal mode
$ for file in 0{4..7}{0..7}{0..7}; do touch $file; chmod $file $file; done
# Stage those files
$ git add 0???
# Look at what perms git has staged:
$ git diff --staged | grep '^new file mode ' | sort | uniq -c
    128 new file mode 100644
    128 new file mode 100755

So git took all 256 different combinations of modes we gave it and stored 100644 half the time and 100755 the other half.

This is because git is really only looking at the u+x (user execute aka & 0100) bit – it doesn’t care about the rest of the perms.

Comments