在Windows中克隆存储库时如何保留执行权限?

Kan*_*bot 3 git file-permissions git-bash

我有一个 gitlab 存储库,其中包含几个 shell 文件以及我认为是可执行文件的文件。(我知道构建的可执行文件最好不要包含在存储库中,但我没有构建存储库)(哦,还有 mk 文件)

当我从 Linux 机器上 git 克隆 repo 时,我这样做了

ls the/path/I/am/interested -l
Run Code Online (Sandbox Code Playgroud)

我可以看到 sh 文件和可执行文件都具有 x 权限。(还有 mk 文件!虽然我不知道 mk 文件是否应该)

但是,当我从 Windows bash shell 中 git clone 存储库时(为了克隆它,我做了

git clone -c core.symlinks=true  -c core.filemode=false therepo.git
Run Code Online (Sandbox Code Playgroud)

我也做了同样的事情

  • sh 文件保留其 x 权限

  • 可执行文件(和 mk 文件)失去权限。

我希望所有文件都保留其 X 权限。我能做些什么?

作为参考,我的 git 配置有

core.autocrlf=input
core.fscache=true
core.symlinks=true
core.editor=nano.exe

core.autocrlf=input
core.symlinks=true
core.filemode=false
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.symlinks=true
core.filemode=false
Run Code Online (Sandbox Code Playgroud)

PS 有没有办法检查 Gitlab 存储库本身的权限?

tor*_*rek 5

\n

我希望所有文件都保留其 X 权限。我能做些什么?

\n
\n

可能不多,除了安装和使用WSL(或Cygwin,但请注意它与其他 NTFS 用户不能很好地配合)。请务必使用 NFTS,而不是 FAT。(或者,只需安装并使用 Linux,也许是在虚拟机中。)继续阅读以了解使用这些东西的更痛苦的方法。

\n
\n

PS 有没有办法检查 Gitlab 存储库本身的权限?

\n
\n

有一种方法可以检查每次提交中每个文件的权限并更新它们,即使您没有使用 WSL。虽然有点痛。

\n

为了理解它是如何工作的,让我们从 Unix/Linux 权限本身在真正的 Linux/Unix 文件系统上如何真正工作开始。三个“模式位”分为三组:read、write 和 e xecute 是模式位,user、group 和othere 是这些组。

\n
    \n
  • 分组三元组rwx意味着无论谁获得此权限,都拥有底层文件的所有三个权限:他们可以读取、写入和执行该文件。

    \n

    一组三重---意味着无论谁得到它都没有任何权限。

    \n
  • \n
  • 通常,权限是rw-针对rwx用户的:文件可读可写但不可执行,或者具有完全权限。

    \n
  • \n
  • 通常,对于大多数其他人来说,权限是或者r--:r-x可读,但不可写或可执行;或只读。

    \n
  • \n
  • 在这之间,“组”\xe2\x80\x94 的成员每个文件都由一个用户 ID 拥有,而一个组 ID\xe2\x80\x94 可能是r--或r-x,这意味着该组被视为每个人而不是用户;或rw-或rwx,表示该组被视为所有者。这种组 ID 的东西的用处有限:大多数现代系统都使用ACL。但这解释了 Git 模式,因此值得一提。

    \n
  • \n
\n

这三组三个权限按以下顺序显示:user(文件的所有者)、group 等o。(注意:oforowner在这里更有意义,但o被用于 for other,所以这变成了ufor user。)因此文件通常是rw-r--r--,表示对用户读/写,但对其他人只读,或者rwxr-xr-x,表示读/写/为用户执行,但仅为其他人读取和执行。

\n

现在,这里是棘手的位:三组位以八进制或基数 8 表示法表示,其中位 2(值 4)代表位r,位 1(值 2)代表w位,位 0(值1) 代表x位。所以对于user权限为的文件rwx,其值为7(4+2+1);u对于Ser 权限为的用户rw-,该值为 6 (4+2)。g对于组权限为 的文件r-x,值为5(4+1);对于,它是 4。对于权限为 的r--文件,该值又是 5,对于 ,它又是 4`。or-xr--

\n

当我们按顺序将它们放在一起时,我们得到:

\n
755 (rwxr-xr-x)\n644 (rw-r--r--)\n
Run Code Online (Sandbox Code Playgroud)\n

这是在 Linux/Unix 风格的文件系统上的系统调用结果中最常见的两个数字,用于表示权限位。1 但任何组合在技术上都是可能的:用户可以设置他们的文件,以便只有其他人可以读取和写入它们,例如(或)。这不是很明智,但也是允许的。lstat---rw-rw-066

\n
\n

1请注意,对于目录,读权限意味着您可以列出目录中的名称,而执行权限意味着您可以使用目录中的名称,例如尝试lstat或文件。open因此,缺乏执行权限的目录是令人沮丧的:您可以看到其中的名称,但永远不会打开任何这些文件,无论它们的权限如何!这种特殊的怪癖在某些安全模型中具有奇怪且有时有用的效果,但安装点允许用户绕过该怪癖,因此在尝试使用此模型时必须非常小心。

\n
\n

那么这一切与 Git 有什么关系呢?

\n

当 Linus Torvalds最初编写Git 时,他决定完全支持这种Git 提交中每个文件的权限模型。因此,Git 的索引为每个文件存储一个mode,作为几个可能的数字之一,通常以八进制表示。mode 有一些额外的高阶位来区分常规文件 (mode 100xxx) 和符号链接 (mode 120xxx),他也是直接从内部 Unix/Linux 模型复制的。

\n

这使您可以存储签出时无法由您自己使用的文件,而只能由其他人(mode 100066例如)使用,因为 Git 会使用该确切模式创建文件:066或---rw-rw-。正如已经指出的,这在文件系统中基本上是无用的;它在Git中也被证明是无用且有害的,因此Git被修改,在最初的1.0版本之前我认为\xe2\x80\x94当然在Git 1.5\xe2\x80\x94之前禁止了这一点。现在常规文件允许的唯一模式是100644, or rw-r--r--, and 100755, or rwx-r-xr-x。但奇怪的编号仍然出现。

\n

git ls-tree -r HEAD例如,如果您运行 来查看HEAD提交中的文件是如何存储的,您将看到这些完全相同的数字。以下是 Git 的 Git 存储库中提交中的一些文件:

\n
755 (rwxr-xr-x)\n644 (rw-r--r--)\n
Run Code Online (Sandbox Code Playgroud)\n

请注意100755中间的:这是一个可执行文件。其余文件都是100644不可执行的。这些模式字符串实际上就是 Git 存储X权限的方式,您可以使用git ls-tree(记住使用-r和 提交哈希 ID;有关更多信息,请参阅文档)直接在任何现有提交中查看它们。

\n

现在,这仅显示存储在 commits 中的文件的模式。尚未提交的文件的模式存储在 Git 的索引(又名暂存区、又名缓存)中。要查看这些条目,请使用命令和git ls-files或--stage选项-s(同一事物的两种拼写)。这也打印出模式:100644或100755。

\n

暂存条目中的模式条目决定下一次提交的内容。 与您自己的文件系统中的文件的实际模式无关。但是,该git add命令可以更改存储在暂存区域中的模式。

\n

如何git add影响暂存模式

\n

当您运行、或、或或其他命令时,Git 将更新每个文件的索引副本以匹配该文件的工作树副本。这变得有点复杂:git add filegit add -ugit add .

\n
    \n
  • 首先,假设该文件已从文件系统中删除。在这种情况下,git add还会从索引中删除该文件。其他一切都变得无关紧要。但如果没有,我们可能会继续更新文件的模式。

    \n
  • \n
  • 假设core.filemode(或core.fileMode) 是true。然后 Git查看系统调用报告的模式lstat。如果该模式x设置了任何位,Git 会将索引的模式设置为100755. 否则,Git 会将索引的模式设置为100644.

    \n
  • \n
\n

这依赖于您的lstat系统调用正确报告可执行权限。如果您的lstat系统调用没有正确报告,您应该core.filemode设置为false. Git 现在忽略模式lstat结果:索引中条目的模式保持不变。不管之前说过什么git ls-files --stage,这仍然是模式。

\n

当您的文件系统不支持 co\xc3\xb6perate 时手动更新模式

\n

如果您想更改模式,您有两种选择:

\n
    \n
  • git add --chmod=...将从您的工作树副本更新索引并设置您指定的模式。这会覆盖lstat结果,并且还会覆盖core.filemode.

    \n
  • \n
  • git update-index会让你覆盖该模式。有很多方法可以做到这一点git update-index;仅覆盖模式的是git update-index --chmod=....

    \n
  • \n
\n

命令选项的参数--chmod应该是+x或-x。选项+x表示将模式设置为100755,-x选项表示将模式设置为100644。

\n

最后一点关于core.filemode

\n

每当您创建新的存储库时,Git 都会探测文件系统以查看其行为方式。Git 执行此操作的精确方式有点特殊,但本质上,它试图查看chmod在文件系统文件上设置和删除可执行性的 s 是否会“粘住”,即由以后的lstat系统调用反射回来。如果他们愿意,Git 会为你core.filemode设置。true如果他们不这样做,Git 会为你core.filemode设置false。 这可以确保 Git 正常运行。

\n

如果您覆盖此core.filemode设置,Git 可能会开始表现异常。如果您确实更改此设置,请确保您了解上述所有内容。

\n