How Git Treats Changes in File Permissions.

Tah Teche
3 min readApr 22, 2017

--

I got a new laptop and had to move my data from my old laptop. After copying all necessary files including code repos (data is expensive in my country so I wanted to avoid cloning the repos from my GitHub) from my old laptop to an external HDD and into the new machine I noticed that
git status stated that I had unstaged changes on ALL the files in those repos. Wondering what was going on I ran a git diff and realized all the changes were about old mode 100755 being changed to new mode 100644. After some searching, I realized it had to do with file permission changes as I moved files to the HDD and into the new PC (I’m guessing it had to do with the exFAT file system of my HDD). This post is basically an accumulation of what I learned about Git and file permissions on Stack Overflow and with the Git command line interface.

Git Tracks ONLY the Executable Bit of the Permissions for the User Who Owns the File.

This means the only change in file permissions Git notices is whether the file’s owner (u when using chmod in symbolic mode, the first digit when using chmod in octal mode with 3 digits or the second digit when using chmod in octal mode with 4 digits) has executable permission or not. This means the following permissions are NOT tracked:

  • Other permissions (write and read) for the file's owner are not tracked
  • All permissions (execute, write and read) for other users in the file’s group (g) and other users not in the files group (o) are not tracked.

So how does Git show file permission changes of the executable bit in
git diff? Git gives files that are NOT executable a file mode of 100644 and files that are executable a file mode of 100755 e.g if you change the permission of a file from 7xx (or any other permission with the owner having executable rights) to 6xx (or any other permission with the owner denied executable rights) then Git will notify you that the file mode has changed from 100755 to 100644.

100755 for executable and 100644 for non-executable are the only file modes Git records.

Checking Files Out

When you check out files into your working area permissions are set based on the umask so if you copy a repo from one PC to another, permissions can be different on checkout because of different umask settings.

Turning Off Tracking of Executable Bit Change

Turns out there are very few instances when you really do need to track file permissions and tracking file permissions can easily be a problem if some contributors to the repo use Windows so its generally advised that you turn this off.

First to check if it's turned on in your repo run the following command from within the repo:

git config --get --local  core.filemode

To check the status of the config globally on your PC as opposed to just the repo you are in use the --global flag instead of --local in the command above.

Now if its set to true and you will like to turn it off for your repo, use the command below from within the repo:

git config --local core.fileMode false

Remember to use --global flag instead of --local in the command above if you want it to be used as the default setting for any repos which have not explicitly set it.

As usual, let me know anything I may have missed in the comments.

--

--