gitfile-permissionsgit-checkoutumask

How to prevent Git from using 'umask' upon 'checkout' (or otherwise preserve the existing file and directory permissions)?


I have a repository where some files should have 600 permissions. That is chmod 600 <file>, and even though umask 022, if I edit that file again and write it (e.g. via Emacs), the 600 permissions are preserved and not reset according to umask. That's correct behavior in my opinion or at least desired from my side.

Now, when I decide that those changes are bad and I want to discard them, I can issue git checkout -- <file>. However, in this case, Git somehow forces umask 022 on this file and permissions become 644. Why?

How can I get rid of this intrusive behavior? Is this editor (e.g. Emacs) being smart on preserving permissions or Git forcing umask 022 on me? git config --add core.sharedrepository 0077 also had no effect so far.


Solution

  • When Git writes a file into the working tree, it always deletes the file and replaces it. This is unlike the way that many editors work, where they truncate and rewrite the file from the beginning, but has the benefit that it's much easier to detect failure cases like out-of-disk conditions without corrupting the working tree.

    When Git does this, it always uses the umask setting, so there's no way to control this setting. That's what the operating system does by default anyway, so you'd have this problem any time the file is rewritten. Note that core.sharedrepository only controls files in the .git directory, not the working tree.

    You can try using a post-checkout hook to set the permissions of the file, but note that you'll probably also want to run git update-index since Git will think those files are potentially dirty otherwise and re-read them the next time you run git status.