Git和权限

Git和权限,git,file-permissions,Git,File Permissions,因此,这似乎是一个常见的问题,有很多特别的解决方案,但我想了解为什么git通常是以这种方式构建的 问题:我克隆了一个存储库,其中的文件具有特定的权限,git状态立即显示我的大量文件已“更改”,因为权限不同。正如我所提到的,我不是在寻找一个临时修复程序,也不是要改变我默认linux权限的方式,我只是想了解git为什么这样做,以及问题的根本原因是什么 例如,对于我尚未提交的任何其他更改,我可以执行git签出以还原更改,但执行此操作时,不会更改文件的权限。如果git实际上在跟踪我的权限,并将权限更改视

因此,这似乎是一个常见的问题,有很多特别的解决方案,但我想了解为什么git通常是以这种方式构建的

问题:我克隆了一个存储库,其中的文件具有特定的权限,git状态立即显示我的大量文件已“更改”,因为权限不同。正如我所提到的,我不是在寻找一个临时修复程序,也不是要改变我默认linux权限的方式,我只是想了解git为什么这样做,以及问题的根本原因是什么

例如,对于我尚未提交的任何其他更改,我可以执行git签出以还原更改,但执行此操作时,不会更改文件的权限。如果git实际上在跟踪我的权限,并将权限更改视为对文件的更改,为什么我不能执行git签出以恢复到初始权限?如果git正在跟踪权限,那么除了我能够更改权限并使其他克隆或分叉我的存储库的人能够创建具有相同权限的文件之外,还有什么其他目的呢


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

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

更具体地说,当Git存储一个文件时,它以“模式”存储它。该模式可能正好是
100644
100755
。1此模式条目进入索引,Git使用该索引构建下一次提交,并且工作树中的文件(您可以查看和使用的文件)通过
chmod
系统调用设置为可执行或不可执行,如果您的操作系统和文件系统实际支持
chmod
操作

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

因此:索引通过存储
100755
(+x)或
100644
(-x)的
模式来保存+x或-x位。包括Windows在内的所有系统都是如此。同时,工作树保存操作系统和文件系统允许的任何内容。在Windows上,这通常什么都不是

如果工作树不包含任何内容,Git:

  • 在创建存储库时记下,然后
  • 只保留存储在索引中的模式
如果存储在索引中的模式来自于一些现有的提交,这是非常典型的,那么它大概是正确的,Git应该不去管它,所以它是这样做的

添加到索引get的新文件(我想,我没有测试过,也没有运行Windows)模式
100755
以防万一,但您可以使用
git update index--chmod=+x
git update index--chmod=-x
来更改它:
+x
表示
100755
-x
表示
100644

但是如果工作树包含有用的模式位,如果您可以运行
chmod+xsomefile
chmod-xsomefile
来更改工作树中
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
)但是,有一些存储库具有包含
100664
行的
模式的内部树对象,因此,
git fsck
秘密地允许一些额外的模式


哪里出了问题 正如我前面提到的,Git在运行
GitInit
时探测实际的文件系统(或者
GitClone
,它或多或少地在内部运行
GitInit
)。也就是说,Git正在创建一个新的存储库。这个新的存储库需要知道:如果我在文件上设置了可执行位,操作系统会正确地记住这一点吗

所以实际上是吉特