问题:
我有一个通过 sshfs 安装的 git 存储库,无法提交更改,并显示以下错误消息:
fatal: cannot update the ref 'HEAD': unable to append to '.git/logs/HEAD': Permission denied
请注意,我可以
cp -a .git/logs/HEAD .git/logs/HEAD.bu
printf foo > .git/logs/HEAD
mv .git/logs/HEAD.bu .git/logs/HEAD
没有问题,但是
printf foo >> .git/logs/HEAD
也给了我“权限被拒绝”。
问题:
我需要对配置进行哪些更改才能从本地计算机提交到远程存储库?
我尝试过的:
鉴于上述症状,我认为问题在于附加到文件。我发现SSHFS 上的 Git 存储库:无法附加到“.git/logs/HEAD”:参数无效这是指https://github.com/libfuse/sshfs/issues/82建议问题(注意略有不同的错误消息)可以通过使用writeback_cache=no
.后一个来源引用了引用man
以下警告/解决方法的页面:
CAVEATS / WORKAROUNDS [...] O_APPEND When writeback caching is enabled, SSHFS cannot reliably support the O_APPEND open flag and thus signals an error on open. To enable support for unreliable O_APPEND (which may overwrite data if the file changes on the server at a bad time), mount the file system with -o unreliable_append.
但是,此部分不在我的手册页中:
sshfs -V
SSHFS version 3.7.0
FUSE library version 3.9.1
using FUSE kernel interface version 7.31
fusermount3 version: 3.9.1
我发现我尝试禁用的写回缓存功能,实际上已被删除(之后被残疾人和重新启用 不止一次前)。所以我想我应该很好,但显然(仍然)存在问题。
我可能应该提到的另一个复杂问题是,我在远程系统上的用户名和 ID 与本地系统上的用户名和 ID 不匹配,因此我需要使用该idmap
功能。
这是相应的fstab
条目:
<remote-user>@<remote-machine>: /mnt/ssh/<remote-machine> sshfs _netdev,user,idmap=user,allow_other 0 0
另外,我的/etc/fuse.conf
包含
user_allow_other
背景:
为了避免回答,只是告诉我不要这样做:
- 我知道 git 是如何工作的。
- 我知道我可以在本地克隆存储库,在那里提交,然后通过 ssh 推送到远程存储库。
为什么我不做呢? - 因为我跟踪只能在远程计算机上测试的代码,并且我确实想在提交之前对其进行测试。因此,在某种程度上,这“只是”一个方便问题,以避免:
- 在本地副本上编辑代码。
- 将更改提交到本地副本。
- 推送到远程副本。
- 通过 SSH 连接到远程计算机(或切换终端)。
- 在远程机器上测试代码。
- 签出另一个分支(以允许强制推送)。
- 结束 SSH 会话(或切换[返回]终端)。
- 编辑代码。
- 修改本地副本上的先前提交。
- 强制推送到远程副本。
- 通过 SSH 连接到远程计算机(或切换终端)。
- 检查强制推送的分支。
- 重复步骤 5 - 11(七个步骤!),直到我满意为止。
相反,我想:
- 通过 SSH 连接到远程计算机(或切换终端)。
- 从远程计算机上编辑远程副本上的代码。
- 在远程机器上测试代码。
- 从远程计算机上编辑远程副本上的代码。
- 重复步骤 3 - 4(两步!),直到我满意为止。
- 结束 SSH 会话(或切换[返回]终端)。
- 从本地机器将更改提交到远程副本。
为什么我不直接从远程机器提交? - 因为我想签署我的提交,但无法将私钥委托给远程计算机。所以我能想到的最好的选择是:
- 通过 SSH 连接到远程计算机(或切换终端)。
- 从远程计算机上编辑远程副本上的代码。
- 在远程机器上测试代码。
- 从远程计算机上编辑远程副本上的代码。
- 重复步骤 3 - 4(两步!),直到我满意为止。
- 从远程计算机提交对远程副本的更改。
- 签出另一个分支(以允许强制推送)。
- 结束 SSH 会话(或切换[返回]终端)。
- 从远程副本中拉取。
- 修改(签署)本地副本上的先前提交。
- 强制推送到远程副本。
- 通过 SSH 连接到远程计算机(或切换终端)。
- 检查强制推送的分支。
因此,一方面,我想摆脱这些额外的步骤(添加功能分支时事情会变得更加复杂,因为需要在两个副本上正确检查这些分支并配置正确的跟踪),另一方面我想理解为什么它不能“正常工作”(tm)。
更新:
- 使用调试输出安装远程:
mount -o sshfs_debug MOUNTPOINT
SSHFS version 3.7.0
executing <ssh> <-x> <-a> <-oClearAllForwardings=yes> <-2> <USER@SERVER> <-s> <sftp>
USER@SERVER's password:
Server version: 3
Extension: versions <2,3,4,5,6>
Extension: [email protected] <1>
Extension: [email protected] <1>
Extension: [email protected] <2>
Extension: [email protected] <2>
Extension: [email protected] <1>
remote_uid = 0
- 在不同的终端中,访问已安装的共享:
cd MOUNTPOINT/DIR_WITH_WRITE_PERMISSIONS
[00002] LSTAT
[00002] ATTRS 45bytes (188ms)
- 验证常规写作作品:
echo foo > foobar
[00003] LSTAT
[00003] STATUS 38bytes (46ms)
[00004] LSTAT
[00004] STATUS 38bytes (32ms)
[00005] LSTAT
[00005] ATTRS 45bytes (242ms)
[00006] OPENDIR
[00006] HANDLE 29bytes (31ms)
[00007] READDIR
[00008] READDIR
[00007] NAME 668bytes (58ms)
[00009] READDIR
[00010] READDIR
[00008] NAME 483bytes (65ms)
[00011] READDIR
[00012] READDIR
[00009] STATUS 37bytes (27ms)
[00010] STATUS 37bytes (27ms)
[00013] CLOSE
[00014] LSTAT
[00011] STATUS 37bytes (27ms)
[00012] STATUS 37bytes (27ms)
[00013] STATUS 28bytes (26ms)
[00014] STATUS 38bytes (31ms)
[00015] OPEN
[00016] LSTAT
[00015] HANDLE 29bytes (153ms)
[00016] ATTRS 45bytes (158ms)
[00017] FSTAT
[00017] ATTRS 45bytes (29ms)
[00018] WRITE
[00018] STATUS 28bytes (28ms)
[00019] CLOSE
[00019] STATUS 28bytes (28ms)
- 尝试附加时触发错误:
echo bar >> foobar
[00020] LSTAT
[00020] STATUS 38bytes (74ms)
[00021] LSTAT
[00021] STATUS 38bytes (57ms)
[00022] LSTAT
[00022] ATTRS 45bytes (52ms)
[00023] OPENDIR
[00023] HANDLE 29bytes (53ms)
[00024] READDIR
[00025] READDIR
[00024] NAME 668bytes (68ms)
[00026] READDIR
[00027] READDIR
[00025] NAME 597bytes (77ms)
[00028] READDIR
[00029] READDIR
[00026] STATUS 37bytes (47ms)
[00030] CLOSE
[00027] STATUS 37bytes (47ms)
[00031] OPEN
[00032] LSTAT
[00028] STATUS 37bytes (47ms)
[00029] STATUS 37bytes (47ms)
[00030] STATUS 28bytes (26ms)
[00031] STATUS 43bytes (28ms)
[00032] ATTRS 45bytes (29ms)
zsh: permission denied: foobar
希望这有助于找到我的问题的根本原因。
注:基于答案经过@德维达斯(即使在绝望的寻求关注的赏金周之后也缺乏解决方案),我将其交叉发布到相应的 GitHub 问题。
答案1
这么大而详细的问题。让我们一步步解决这个问题。错误是“权限被拒绝”
Linux error code
EACCES 13 /* Permission denied */
当我在 sshfs repo 中搜索时,EACCES
我发现文件中只有两个实例[sshfs.c][1]
一是关于本地上下文中的文件权限。你所展示的那个。
其他是SSH_FX_PERMISSION_DENIED
由于 ssh 权限被拒绝而导致的错误。
根据我掌握的数据,我几乎可以肯定地说。当您在本地计算机上拥有权限时
案例
printf foo >> .git/logs/HEAD
这给予许可被拒绝的原因而不是
printf foo > .git/logs/HEAD
您没有远程计算机的权限或不支持引用O_APPEND
的远程服务器第117期
你可以使用 strace 来验证它。
这就是为什么部分。如何解决取决于您的回复。是哪一种情况?
请告诉我,以便我可以进一步帮助您。
如果您不同意,请随时发表评论。