【问题标题】:Git and PermissionsGit 和权限
【发布时间】:2020-03-28 07:49:24
【问题描述】:

所以这似乎是一个常见问题,并且有很多临时解决方案,但我想了解为什么 git 通常是这样构建的。

问题:我克隆了一个文件具有特定权限的存储库,并且由于权限不同,git status 立即显示我的大量文件已“更改”。正如我所提到的,我不是在寻找临时修复程序或更改我执行默认 linux 权限的方式,我希望了解 git 为什么这样做以及问题的根本根源是什么。

例如,对于我尚未提交的任何其他更改,我可以执行 git checkout 来恢复更改,但是当我这样做时,它不会更改文件的权限。如果 git 实际上正在跟踪我的权限并认为权限更改是对文件的更改,为什么我不能执行 git checkout 以恢复到初始权限?如果 git 正在跟踪权限,除了让我能够更改我的权限并使其克隆或分叉我的存储库的其他人可以创建具有相同权限的文件之外,还有什么目的?

我想我的问题归结为,如果 git 在文件更改时跟踪权限更改,为什么 git 不让我使用任何用于确保我的项目与其他合作者保持最新的正常命令权限就像它对内容一样?为什么每次提交人设置了不同的默认文件权限时,我都需要通过临时绷带来避免我的存储库被文件权限更改提交填满?如果这是一个生产项目,我们该怎么做才能使权限更改提交真正进入项目?例如,假设我们想限制一个文件,以便只有组可以在生产中读取它,为什么开发人员不能进行此更改和提交/推送/拉取请求,因为他们会满足项目的任何其他要求?顺便说一句,这都是在 linux 上,所以我不讨论从不同文件系统提交。

【问题讨论】:

  • 我认为问题不在于 git。如果更改与权限有关,则问题可能出在底层 FS 及其安装方式上。我在 Windows 上工作时看到了这类问题,我用 git for windows 检查了一个项目,然后我在 cygwin 上用 git 进入了项目(反之亦然)。

标签: git file-permissions


【解决方案1】:

Git 只为文件保留一个权限位。在大多数情况下,Git 只存储 文件——它不存储目录(或文件夹,如果你喜欢这个术语),它只是按需创建它们。虽然 Git 确实存储了符号链接,但符号链接没有关联的权限——至少在 Git 中没有(通常也不在操作系统中)。

更具体地说,当 Git 存储文件时,它会以“模式”存储它。该模式正好是 1006441007551 这个模式条目进入 index——Git 用来构建 next 提交——work-tree 中的文件,即您可以看到和使用的文件,使用chmod 系统设置为可执行或不可执行调用,前提是您的操作系统和文件系统实际上支持 chmod 操作。

当 Git 设置这些模式位时(如果可以的话)它会根据您的 umask 设置 +x 位,前提是您使用的是 Unix 或 Linux 类型系统。 umask 告诉系统要设置哪些位002 的 umask 表示文件是rwxrwxr-xrw-rw-r--,因为002清除007 的 umask 表示文件是 rwxrwx---rw-rw----,因为 007清除:我们取消了“其他”的读取、写入和执行权限。 (三个字段分别是“所有者”、“组”和“其他”,其中 4 = 读取、2 = 写入、1 = 执行。)

所以:index 通过存储mode100755 (+x) 或100644 (-x) 来保存+x 或-x 位。这适用于所有系统,包括 Windows。同时,工作树包含操作系统和文件系统允许的任何内容。在 Windows 上,这通常什么都没有

如果工作树没有任何内容,Git:

  • 在您创建存储库时记下这一点,并且
  • 只保留存储在索引中的模式。

如果存储在索引中的模式来自某个现有的提交——这很典型——那么它可能是正确的,Git 应该不理会它,所以它确实如此。

新文件添加索引获取(我想,我没有测试过并且不运行Windows)模式100755以防万一,但你可以使用git update-index --chmod=+x或@987654339 @ 更改它:+x 表示 100755-x 表示 100644

但如果工作树包含 有用 模式位 - 如果您可以运行 chmod +x somefilechmod -x somefile更改在您的工作树——然后 Git 已经记下了这一点,早在您第一次创建存储库时,现在 git add复制 +x-x状态进入索引中的100755100644 设置。同时,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 @。

【讨论】:

  • 非常感谢您的彻底回复,这非常有意义!
猜你喜欢
  • 2014-09-05
  • 2011-09-07
  • 2012-10-26
  • 2012-10-11
  • 2013-04-14
  • 2014-04-20
  • 1970-01-01
  • 2013-03-29
  • 2013-07-17
相关资源
最近更新 更多