Linux

git over sshfs(使用 idmap):無法附加到“.git/logs/HEAD”:權限被拒絕

  • June 30, 2020

問題:

我有一個通過 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 推送到遠端儲存庫。

為什麼我不這樣做?- 因為我跟踪只能在遠端機器上測試的程式碼,並且我確實想在送出之前對其進行測試。所以在某種程度上,這“只是”一個方便的問題,以避免不得不:

  1. 在本地副本上編輯程式碼。
  2. 將更改送出到本地副本。
  3. 推送到遠端副本。
  4. SSH 到遠端機器(或切換終端)。
  5. 在遠端機器上測試程式碼。
  6. 簽出另一個分支(以允許強制推送)。
  7. 結束 SSH 會話(或切換$$ back $$終端)。
  8. 編輯程式碼。
  9. 修改本地副本上的先前送出。
  10. 強制推送到遠端副本。
  11. SSH 到遠端機器(或切換終端)。
  12. 簽出強制推送的分支。
  13. 重複步驟 5 - 11(七個步驟!),直到我滿意為止。

相反,我想:

  1. SSH 到遠端機器(或切換終端)。
  2. 從遠端電腦編輯遠端副本上的程式碼。
  3. 在遠端機器上測試程式碼。
  4. 從遠端電腦編輯遠端副本上的程式碼。
  5. 重複步驟 3 - 4(兩步!),直到我滿意為止。
  6. 結束 SSH 會話(或切換$$ back $$終端)。
  7. 從本地電腦送出對遠端副本的更改。

為什麼我不簡單地從遠端機器送出?- 因為我想簽署我的送出但不能用私鑰委託遠端機器。所以我能想到的最好的選擇是:

  1. SSH 到遠端機器(或切換終端)。
  2. 從遠端電腦編輯遠端副本上的程式碼。
  3. 在遠端機器上測試程式碼。
  4. 從遠端電腦編輯遠端副本上的程式碼。
  5. 重複步驟 3 - 4(兩步!),直到我滿意為止。
  6. 從遠端電腦送出對遠端副本的更改。
  7. 簽出另一個分支(以允許強制推送)。
  8. 結束 SSH 會話(或切換$$ back $$終端)。
  9. 從遠端副本中拉取。
  10. 修改(簽名)本地副本上的先前送出。
  11. 強制推送到遠端副本。
  12. SSH 到遠端機器(或切換終端)。
  13. 簽出強制推送的分支。

因此,一方面,我想擺脫這些額外的步驟(添加功能分支時事情變得更加複雜,因為需要在兩個副本上正確簽出並配置正確跟踪),另一方面我想了解為什麼它不能“正常工作”(tm)。


更新:

跟進@tukan的評論,我用調試輸出重現了錯誤:

  1. 使用調試輸出掛載遠端:
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: fsync@openssh.com <1>
Extension: posix-rename@openssh.com <1>
Extension: statvfs@openssh.com <2>
Extension: fstatvfs@openssh.com <2>
Extension: hardlink@openssh.com <1>
remote_uid = 0
  1. 在不同的終端中,訪問掛載的共享:
cd MOUNTPOINT/DIR_WITH_WRITE_PERMISSIONS
[00002] LSTAT
 [00002]          ATTRS       45bytes (188ms)
  1. 驗證正常寫作作品:
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)
  1. 通過嘗試追加觸發錯誤:
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

希望這有助於找到我的問題的根本原因。


注意:基於@Devidas的回答(即使在一個令人絕望的尋求關注的賞金周之後也缺乏解決方案),我將其交叉發佈到相應的 GitHub 問題

這麼大而詳細的問題。讓我們一步一步解決這個問題。錯誤是“權限被拒絕”

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 進行驗證。

這就是為什麼部分。如何解決取決於您的回复。是哪種情況?

請讓我知道,以便我可以進一步幫助您。

如果您不同意,請隨時發表評論。

引用自:https://unix.stackexchange.com/questions/593649