WSL + Samba + Git: "错误:没有足够的权限将对象添加到存储库数据库 .git/objects" / git-clone / git-add 权限错误

3

我正在使用WSL1(Windows Linux子系统)和Ubuntu 20.04.1 LTS在Win10上工作。我有一个Samba(1.0)网络共享,我想通过我的Ubuntu终端在其中创建git仓库。

christian@my_pc:~/p/git_test$ ll
total 2048
drwxr-xr-x 1 christian christian  512 Jan 19 11:13 ./
drwxr-xr-x 1 christian christian  512 Jan 19 10:11 ../
-rwxr--r-- 1 christian christian    0 Jan 19 10:12 my_code_file.rb

我可以无问题地运行git init,但是一旦我尝试git add文件,就会出现以下错误:

christian@my_pc:~/p/git_test$ git add my_code_file.rb
error: insufficient permission for adding an object to repository database .git/objects
error: my_code_file.rb: failed to insert into database
error: unable to index file 'my_code_file.rb'
fatal: adding files failed

就我所知,权限都没问题。所有文件都属于christian:christian。目录树如下:

.git
├── [-rwxr--r--]  HEAD
├── [drwxr-xr-x]  branches
├── [-rwxr--r--]  config
├── [-rwxr--r--]  description
├── [drwxr-xr-x]  hooks
│   ├── [-rwxr--r--]  applypatch-msg.sample
│   ├── [-rwxr--r--]  commit-msg.sample
│   ├── [-rwxr--r--]  fsmonitor-watchman.sample
│   ├── [-rwxr--r--]  post-update.sample
│   ├── [-rwxr--r--]  pre-applypatch.sample
│   ├── [-rwxr--r--]  pre-commit.sample
│   ├── [-rwxr--r--]  pre-merge-commit.sample
│   ├── [-rwxr--r--]  pre-push.sample
│   ├── [-rwxr--r--]  pre-rebase.sample
│   ├── [-rwxr--r--]  pre-receive.sample
│   ├── [-rwxr--r--]  prepare-commit-msg.sample
│   └── [-rwxr--r--]  update.sample
├── [drwxr-xr-x]  info
│   └── [-rwxr--r--]  exclude
├── [drwxr-xr-x]  objects
│   ├── [drwxr-xr-x]  e6
│   │   └── [-r-xr--r--]  tmp_obj_mZzHwy
│   ├── [drwxr-xr-x]  info
│   └── [drwxr-xr-x]  pack
└── [drwxr-xr-x]  refs
    ├── [drwxr-xr-x]  heads
    └── [drwxr-xr-x]  tags

10 directories, 17 files

奇怪的是,在执行 git add my_code_file.rb 命令后,我再也无法删除.git目录,会提示权限错误:

christian@my_pc:~/p/git_test$ rm -rf .git
rm: cannot remove '.git/objects/e6/tmp_obj_mZzHwy': Permission denied

似乎git创建了名为tmp_obj_mZzHwy的文件,但我没有删除它的权限,这应该不是正常情况。
在执行git add my_code_file.rb之后,再次查看.git文件夹的权限。
christian@my_pc:~/p/git_test$ ls -lahR .git
.git:
total 0
drwxr-xr-x 1 christian christian 512 Jan 19 11:14 .
drwxr-xr-x 1 christian christian 512 Jan 19 11:13 ..
drwxr-xr-x 1 christian christian 512 Jan 19 11:14 objects

.git/objects:
total 0
drwxr-xr-x 1 christian christian 512 Jan 19 11:14 .
drwxr-xr-x 1 christian christian 512 Jan 19 11:14 ..
drwxr-xr-x 1 christian christian 512 Jan 19 11:13 e6

.git/objects/e6:
total 1.0M
drwxr-xr-x 1 christian christian 512 Jan 19 11:13 .
drwxr-xr-x 1 christian christian 512 Jan 19 11:14 ..
-r-xr--r-- 1 christian christian   0 Jan 19 11:13 tmp_obj_mZzHwy

我正在处理的Samba共享在Win10上被挂载为磁盘(带有P:的字母)。在我的WSL Ubuntu上,我通过以下行在/etc/fstab中挂载它:

//192.168.X.X/sharename /mnt/sharename cifs username=user,password=pass 0 0
P:▸ /mnt/p▸ drvfs▸defaults,metadata,rw,exec,uid=christian,gid=christian,umask=22,fmask=11▸0 0

这是我的存储库的.git/config文件。

[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true

我尝试解决问题的方法:

  • chmod -R u+rwx .
  • git init --shared=all
  • umask 0000

在我的主目录(或非samba驱动器)上,git init/add没有问题。


更新

我发现samba共享未正确挂载,缺少元数据选项被忽略,每当我挂载它时。我认为这可能是问题所在!然而,对我来说不清楚为什么会被忽略,或者是否有一种方式强制执行?

TARGET                       SOURCE      FSTYPE      OPTIONS
/                            rootfs      wslfs       rw,noatime
...
├─/mnt/p                     P:          drvfs       rw,noatime,uid=1000,gid=1000,case=off
└─/mnt/c                     C:\         drvfs       rw,noatime,uid=1000,gid=1000,metadata,case=off
2个回答

0

除了WSL2之外,由于最近的Git中包含了内置文件系统监视器,您可能仍会遇到另一个错误。

在Git 2.38(2022年第三季度)中,内置的fsmonitor拒绝在网络挂载的存储库上工作;为用户引入了一个配置开关来覆盖此问题。

请参见提交85dc0da(2022年8月11日),作者是Eric DeCosta(edecosta-mw
(由Junio C Hamano -- gitster --合并于提交0479138,2022年9月13日)

fsmonitor:允许 fsmonitor 运行在网络挂载的仓库上的选项

签名作者:Eric DeCosta

虽然不常见,但有些用户有大型的网络挂载仓库。
能够在网络路径上运行 fsmonitor 将使这些用户受益。

大多数基于 Samba 的现代文件服务器都具备必要的支持,以便在网络挂载的仓库上启用 fsmonitor。
为了使 fsmonitor 能够在网络挂载的仓库上工作,首先引入一个配置选项 'fsmonitor.allowRemote'。
将此选项设置为 true 将覆盖默认行为(报错),当 fsmonitor 检测到网络挂载的仓库时。


这来自于 Git 2.37 (Q2 2022),澄清了与网络驱动器不兼容的问题:

请查看提交 3294ca6提交 53fcfbc提交 eb29901提交 00991e1提交 9915e08提交 d6d58ff提交 caa9c37提交 f954c7b提交 7667f9d提交 b533708提交 95a4e78提交 de7e0b5提交 6504cfd提交 90a70fa提交 d060555提交 207534e提交 802aa31提交 39664e9提交 8e8f4b8提交 9968ed7提交 ddc5dac提交 d989b26提交 1e7be10提交 a85ad67提交 5c58fbd提交 d33c804提交 62a62a2提交 49b398a提交 27b5d41提交 40f865d(2022年5月26日)由 Jeff Hostetler (Jeff-Hostetler)
请查看提交 852e2c8(2022年3月25日)由 Junio C Hamano (gitster)
(由 Junio C Hamano -- gitster --提交 9e496ff 中合并,2022年6月10日)

fsmonitor-settings:MacOS上的NTFS和FAT32不兼容

签名作者:Jeff Hostetler

在MacOS上,将NTFS或FAT32卷上的存储库标记为不兼容。

内置的FSMonitor在MacOS上使用Unix域套接字与客户端进行IPC。
这些套接字保存在.git目录中。
NTFS和FAT32不支持Unix套接字,因此守护程序无法启动。

在我们的兼容性检查期间对此进行测试,以便客户端命令不会一直尝试启动守护程序。

完整评论

远程工作目录对FSMonitor来说是有问题的。
服务器机器上的底层文件系统和/或远程挂载类型(NFS、SAMBA等)决定了是否可以向远程客户端机器提供通知事件。
服务器和客户端机器之间的内核差异也决定了事件如何(缓冲、频率、去重)传递到客户端机器进程。
客户端机器(例如笔记本电脑)可能选择暂停/恢复,如果没有进行大量测试,则不清楚观察程序是否可以在恢复后重新同步。 我们可以将其视为正常的“内核丢失事件”,并执行我们的正常的“刷新和重新同步”操作,或者需要关闭现有的(僵尸?)通知fd并创建一个新的通知fd。
理论上,无论我们使用Hook还是IPC API,都需要解决上述问题。
对于内置的FSMonitor,我们在.git目录中创建Unix域套接字以用于IPC。
如果工作目录是远程的,则套接字将在远程文件系统上创建。如果远程文件系统不支持UDS文件类型(例如smbfs到Windows服务器),或者远程内核不允许非本地进程绑定()套接字,则此操作可能会失败。(这些问题可以通过将UDS移出.git目录并移到客户端机器上的一个众所周知的本地目录中来解决,但应注意确保$HOME实际上是本地而不是受管理的文件共享)。
因此(至少现在),将远程工作目录标记为不兼容。
FAT32和NTFS工作目录也有问题。
内置的FSMonitor在.git目录中使用Unix域套接字进行IPC。这些Windows驱动器格式不支持Unix域套接字,因此将它们标记为守护程序不兼容。
从 Git 2.39 (Q4 2022) 开始,默认情况下禁用在网络文件系统上的存储库上使用 fsmonitor。
添加旋钮以使其在 macOS 上可用。

请查看提交 c4f9490(2022年10月10日)由Jeff King (peff)提交。
请查看提交 5aa9e32, 提交 25c2cab, 提交 12fd27d, 提交 8f44976, 提交 6beb268, 提交 508c1a5(2022年10月4日)由Eric DeCosta (edecosta-mw)提交。
(由Junio C Hamano -- gitster --合并于提交 7b8cfe3,2022年10月17日)

fsmonitor:添加allowRemote和socketDir选项的文档

签名作者:Eric DeCosta

添加“fsmonitor.allowRemote”和“fsmonitor.socketDir”的文档。
强调“fsmonitor.allowRemote”的实验性质以及“fsmonitor.socketDir”对文件系统的有限支持。

git config现在包含在其手册页面中:

fsmonitor.allowRemote

默认情况下,fsmonitor守护程序拒绝针对网络挂载的存储库进行操作。将fsmonitor.allowRemote设置为true会覆盖此行为。仅在core.fsmonitor设置为true时才受到尊重。

git fsmonitor--daemon现在在其手册页面中包含以下内容:

默认情况下,fsmonitor守护程序拒绝针对网络挂载的存储库进行操作;通过将fsmonitor.allowRemote设置为true可以覆盖此限制。但是,请注意,fsmonitor守护程序不能保证与所有网络挂载的存储库正确工作,因此此类使用被视为实验性。


Git 2.39(2022年第4季度)修复了一个问题,即在macOS上core.fsmonitor无法注意到创建或修改的符号链接。

请参见提交 ee0e7fc(2022年11月8日),作者为srz_zumix(srz-zumix
(由Junio C Hamano -- gitster --提交8d7b35b中合并,2022年11月23日)

fsmonitor--daemon:在 macOS 上支持符号链接

签名作者:srz_zumix
签名作者:Taylor Blau

Resolves a problem where symbolic links were not showing up in diff when created or modified.

kFSEventStreamEventFlagItemIsSymlink is also treated as a file update.
This is because kFSEventStreamEventFlagItemIsFile is not included in FSEvents when creating or deleting symbolic links.
For example:

$ ln -snf t test
    fsevent: '/path/to/dir/test', flags=0x40100 ItemCreated|ItemIsSymlink|
$ ln -snf ci test
    fsevent: '/path/to/dir/test', flags=0x40200 ItemIsSymlink|ItemRemoved|
    fsevent: '/path/to/dir/test', flags=0x40100 ItemCreated|ItemIsSymlink|

在等待2.38版本发布期间,是否有任何解决方法? - GGirard
实际上,我的问题是由于某些文件夹所有权未正确设置为我的WSL用户在.git/objects下(我认为这是由于VS Code远程扩展的行为变更所致)。 通过https://github.com/microsoft/WSL/issues/5179#issuecomment-979014877解决。 - GGirard
@GGirard 好的,发现得好。Git 2.38 应该会在两周内的十月初发布。 - VonC

-1

解决方案:升级到WSL2

我发现,解决方案是从WSL1升级到WSL2,这样挂载就可以正常工作了。现在我可以无错误地进行git-add或git-clone操作。

打开PowerShell查看您当前的版本:

PS C:\Users\christian> wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Stopped         1

如果它是1,你可以升级它,但首先要检查WSL2的要求(只是为了安全起见)。

升级指南

来自指南/我必须执行的步骤摘录:

  • 检查WSL2要求 Windows版本需要达到一定的构建标准才能满足要求
  • 下载并执行:x64机器的WSL2 Linux内核更新包
  • 启用Windows虚拟机平台功能:dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
  • 重新启动计算机
  • 将您的发行版升级到WSL2:打开PowerShell并输入wsl --set-version <distribution name> <versionNumber>,在我的情况下是wsl --set-version Ubuntu 2。要查看您的发行版名称,请键入wsl -l -v
  • 使用wsl -l -v验证升级

为了提供完整信息,这里还有挂载选项/etc/fstab

P:      /mnt/p  drvfs   rw,noatime,uid=christian,gid=christian,metadata,case=off        0 0

相比之下

christian@my_pc:~$ findmnts
...
├─/mnt/p                        P:           9p          rw,noatime,dirsync,aname=drvfs;path=P:;uid=1000;gid=1000;metadata;case=off;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=3,wfd=3
└─/mnt/c                        C:\          9p          rw,noatime,dirsync,aname=drvfs;path=C:\;uid=1000;gid=1000;uid=1000;gid=1000;metadata;case=off;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=8,wfd=8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接