我的 Ubuntu 22.04 系统上的主文件夹中有一个 Git 存储库。系统实用程序用户“gremlin”需要检查这是否是一个真正的 Git 存储库。我发现最好的方法是使用命令git ls-remote
a la
$ git ls-remote -h /home/me/path/to/repo.git &> /dev/null ; echo $?
如果目录是 Git 存储库,则(在理想情况下)返回退出代码 0,如果不是,则返回其他代码(通常为 128)。
问题是,当 'gremlin' 为有效的 repo 运行此命令时,
$ sudo -u gremlin git ls-remote -h /home/me/path/to/repo.git &> /dev/null ; echo $?
退出代码是128
,表示存储库无效。0
当我以自己的身份运行它时,我得到了这个错误。
我认为问题是权限问题,但我说不出问题是什么。我不知道git ls-remote
具体是如何工作的,但我最好的猜测是它从目标存储库读取.git/refs/remotes/
。我已经确认,整个文件路径(.git/refs/remotes/
从/
一直到其中的内容)都r
对“其他”用户具有权限(相当于$ sudo chmod -R o+r /
对相关文件集的权限),因此“gremlin”应该能够毫无问题地从此文件夹读取。
这个问题显然更复杂,但我不知道从哪里开始。理想情况下,这里有人对git ls-remote
工作原理有足够的了解,知道用户需要什么权限才能执行它。
答案1
系统实用程序用户“gremlin”需要检查这是否是一个真正的 Git 存储库
如果您想检查它是否是一个裸存储库,或者是否有一个工作树等,那么的各种选项git rev-parse
也可能适合。
git rev-parse --resolve-git-dir /home/me/path/to/repo.git
git --git-dir=/home/me/path/to/repo.git rev-parse --git-dir
git --git-dir=/home/me/path/to/repo.git rev-parse HEAD
我不知道问题是什么
使用该strace
命令查看进程执行的特定系统调用。如果您认为这是文件权限问题,请查找失败并显示EACCES
[sic] 的系统调用。
strace -f git ls-remote /home/me/path/to/repo.git
我最好的猜测是它从目标 repo 的 .git/refs/remotes/ 读取
它读取整个.git/refs/
(加上.git/packed-refs
,但即使所有引用都已打包,'refs' 目录也必须存在)。它不会在该远程中查找嵌套的远程。它还需要其他文件,我相信至少需要.git/config
和.git/HEAD
,再加上 处的对象存储.git/objects/
。
对“其他”用户具有 r 权限(对于相关文件集,相当于 $ sudo chmod -R o+r /),因此“gremlin”应该能够毫无问题地从该文件夹读取。
阅读文件夹是不够的。您还需要权限横穿它可以访问其中的任何对象(即,除了获取文件名列表之外,还可以执行任何操作),这会重复使用权限+x
位。例如,为了以.git/refs/
任何方式进行访问,用户必须拥有+x
父.git
目录的权限。
用于namei -l <absolute_path>
检查所有权限。