Git 只为文件保留一个权限位。在大多数情况下,Git 只存储 文件——它不存储目录(或文件夹,如果你喜欢这个术语),它只是按需创建它们。虽然 Git 确实存储了符号链接,但符号链接没有关联的权限——至少在 Git 中没有(通常也不在操作系统中)。
更具体地说,当 Git 存储文件时,它会以“模式”存储它。该模式正好是 100644 或 100755。1 这个模式条目进入 index——Git 用来构建 next 提交——work-tree 中的文件,即您可以看到和使用的文件,使用chmod 系统设置为可执行或不可执行调用,前提是您的操作系统和文件系统实际上支持 chmod 操作。
当 Git 设置这些模式位时(如果可以的话)它会根据您的 umask 设置 +x 位,前提是您使用的是 Unix 或 Linux 类型系统。 umask 告诉系统要设置哪些位不:002 的 umask 表示文件是rwxrwxr-x 或rw-rw-r--,因为002 被清除。 007 的 umask 表示文件是 rwxrwx--- 或 rw-rw----,因为 007 被清除:我们取消了“其他”的读取、写入和执行权限。 (三个字段分别是“所有者”、“组”和“其他”,其中 4 = 读取、2 = 写入、1 = 执行。)
所以:index 通过存储mode 或100755 (+x) 或100644 (-x) 来保存+x 或-x 位。这适用于所有系统,包括 Windows。同时,工作树包含操作系统和文件系统允许的任何内容。在 Windows 上,这通常什么都没有。
如果工作树没有任何内容,Git:
- 在您创建存储库时记下这一点,并且
- 只保留存储在索引中的模式。
如果存储在索引中的模式来自某个现有的提交——这很典型——那么它可能是正确的,Git 应该不理会它,所以它确实如此。
新文件添加到索引获取(我想,我没有测试过并且不运行Windows)模式100755以防万一,但你可以使用git update-index --chmod=+x或@987654339 @ 更改它:+x 表示 100755 和 -x 表示 100644。
但如果工作树包含 有用 模式位 - 如果您可以运行 chmod +x somefile 或 chmod -x somefile 来更改在您的工作树——然后 Git 已经记下了这一点,早在您第一次创建存储库时,现在 git add 将复制 +x 或 -x状态进入索引中的100755 或100644 设置。同时,git checkout 会根据需要更新存储在工作树中的 实际 模式。
1很久以前,Git 存储了更多位。结果证明这是一个错误并已更改,因此现在它仅存储 644 或 755 模式。 (前面的100 表示文件,其余位是Linux 风格的权限:644 表示rw-r--r-- 和755 表示rwx-r-x-r-x。)有一些存储库但是,内部 tree 对象的 mode 行包含 100664,因此 git fsck 秘密允许一些额外的模式。
哪里出错了
如上所述,Git 会在您运行git init(或git clone,或多或少在内部运行git init)时探测实际文件系统。也就是说,Git 正在创建一个 new 存储库。这个新的存储库需要知道:如果我在文件上设置可执行位,操作系统会正确记住吗?
所以 Git 实际上设置或清除操作系统提供的文件系统中文件的可执行位。2 如果设置和/或清除“坚持”,Git 知道操作系统正确处理可执行位.
如果操作系统确实正确处理 +x 和 -x,Git 会将新存储库中的 core.filemode 设置为 true。如果它没有正确处理 +x 和 -x,Git 会将新存储库中的 core.filemode 设置为 false。
稍后,Git 将咨询 core.filemode 以了解操作系统的 chmod 是否真的在工作树上正常工作。 如果您将存储库从一个文件系统移动到另一个文件系统,记录的core.filemode 可能不正确。在这种情况下,您可以手动调整core.filemode。
如果某个同事或同事的文件系统不能正确处理chmod,并且该同事不正确地摆弄他或她的core.filemode,则该同事将创建具有错误mode 条目的新提交。 对此您无能为力(嗯,除了教育他们):提交一旦创建,就永远无法更改。您可以删除错误的提交并进行良好的替换——伴随着随之而来的所有痛苦——或者只是在下一次提交中修复模式而不用担心它,但你必须让同事或同事-工人停止这样做。
如果你有一个不会停止这样做的同事并且权限与你并不真正相关,你可以故意对你自己的 Git 撒谎.只需将core.filemode 设置为false,这样您自己的操作系统正确跟踪的chmod 设置就会被忽略。这不是一个很好的解决方案,它只是一种解决方法,直到您可以教育将虚假模式位放入存储库的人。
2此文件是 Git 正在为新存储库构建的 .git/config 文件。该测试也可以在编译时禁用:也就是说,有人可以构建一个 Git,假设 chmod 不起作用,只需将core.filemode 设置为@987654379 @。