"Patrick Ohly" <[email protected]> writes:

Hi Patrick,

> That may very well be the root problem. However, in my case "remote"
> typically isn't that remote: it's a local desktop connected to the same
> 2.5Gbit Ethernet switch as my laptop. A proper network filesystem should
> be pretty fast, but then I face the challenge of teaching Emacs where to
> run commands. TRAMP makes that transparent.

That's only half of the story. Many git calls require a new ssh
connection every call, with all the overhead. And due to the sshfs
specifics, ControlMaster optimization cannot be used.

> But it's not just magit. Just opening a file can take half a minute.

It's also magit. As reproducer, I've opened
"/sshfs:freebsd14:/home/albinus/src/emacs", calling 'M-x magit-status'
afterwards.

According to the traces, there are 14 'ssh -q -e none -t -t ...' calls
due to this.

>>> I am using Emacs 30.1 with Tramp 2.8.1.3, go-mode 20250311.156, 
>>> magit 20260401.2251 (all packages updated via elpa 
>>> yesterday). gopls is installed in /usr/local/bin on the remote 
>>> host.
>>>
>>> When I open a Go file, *Warnings* opens and I get:
>>>    ⛔ Warning (tramp): STDERR not supported
>>>
>>> I don't have a workaround. Because this takes up screen space 
>>> it's pretty annoying.

That's true. Tramp's sshfs make-process implementation doesn't support
stderr. You could suppress this warning by by eval'ing

--8<---------------cut here---------------start------------->8---
(setq warning-suppress-types '((tramp)))
--8<---------------cut here---------------end--------------->8---

But this will suppress also other Tramp warnings you need to see.

>>> That's because it doesn't find the gopls command (visible in 
>>> *lsp-log*). I found that I can work around that by creating a 
>>> symlink to it in /bin. The reasons seems to be
>>> https://emacs.stackexchange.com/questions/81829/tramp-sshfs-remote-command-execution-doesnt-respect-tramp-remote-path-or-tra
>>> I think it should work the same as ssh and use the remote path 
>>> settings.

tramp-remote-path is intended for methods of the tramp-sh backend like
"ssh", not for the "sshfs" method.

> Both the ssh and sshfs TRAMP methods support remote command execution
> through ssh. I found some prior discussion about whether the sshfs
> method should execute commands locally and the conclusion was that this
> would go against the goals of TRAMP. I concur, I am using TRAMP because
> all my tooling is installed on the remote host. In the case of sshfs,
> the mounted sshfs filesystem is only used for file transfers.
>
> My expectation was that both methods do remote command execution exactly
> the same way, with feature parity and perhaps even using the same
> code. But apparently that is not the case.

There is no feature parity. sshfs support for remote processes is
limited. There a no plans to improve it; at least no plans by me.

>>> magit gathers some information, but then fails with:
>>>
>>>    magit-rev-diff-count: Wrong type argument: stringp, nil
>>>
>>> This is after some more warnings about stderr, so maybe related?
>>
>> You've lost me here, sorry. Can you give an MRE? I think there 
>> might be too much going on.
>
> MRE = https://en.wikipedia.org/wiki/Meal,_Ready-to-Eat, i.e. a simple
> reproducer?

"Minimal reproducible example"

> A simple test would be to open a file in a remote git working tree with
> /sshfs:<host>/... instead of /ssh:<host>/... and then bringing up the
> magit status page.

That reproduces the error for me, my scenario is mentioned above. The
backtrace is

--8<---------------cut here---------------start------------->8---
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  split-string(nil "\11")
  magit-rev-diff-count("fatal: cannot describe 
'923aac2e4ec76b51891ba711c44ee08f7211ea2a'" nil)
  magit-get-next-tag(nil t)
  magit-insert-tags-header()
  magit-run-section-hook(magit-status-headers-hook)
  magit-insert-headers(magit-status-headers-hook)
  magit-insert-status-headers()
  magit-run-section-hook(magit-status-sections-hook)
  magit-status-refresh-buffer()
  #f(compiled-function () #<bytecode -0x1864b8c86a00967>)()
  magit-refresh-buffer(nil :initial-section magit-status-goto-initial-section 
:select-section nil)
  magit-setup-buffer-internal(magit-status-mode nil ((magit-buffer-diff-args 
("--no-ext-diff")) (magit-buffer-diff-files nil) (magit-buffer-log-args 
("-n256" "--decorate")) (magit-buffer-log-files nil)) :initial-section 
magit-status-goto-initial-section :select-section nil)
  magit-status-setup-buffer("/sshfs:freebsd14:/home/albinus/src/emacs/")
  magit-status("/sshfs:freebsd14:/home/albinus/src/emacs/" ((25 . 20) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-list" "--count" 
"--left-right" "fatal: cannot describe 
'923aac2e4ec76b51891ba711c44ee08f7211ea2a'...")) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "describe" "--contains" "HEAD") . 
"fatal: cannot describe '923aac2e4ec76b51891ba711c44ee08f7211ea2a'") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "describe" "--long" "--tags") . 
"emacs-30.1-180773-g923aac2e4ec") (("/sshfs:freebsd14:/home/albinus/src/emacs/" 
magit-get-push-branch "master" nil)) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--verify" 
"--abbrev-ref" "master") . "master") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "log" "--no-walk" "--format=%s" 
#("origin/master^{commit}" 0 13 (font-lock-face magit-branch-remote face 
magit-branch-remote)) "--") . "Merge branch 'master' of 
git.sv.gnu.org:/srv/git/emacs") (("/sshfs:freebsd14:/home/albinus/src/emacs/" 
magit-get-upstream-branch "master") . #("origin/master" 0 13 (face 
magit-branch-remote font-lock-face magit-branch-remote))) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--verify" 
"--abbrev-ref" "master@{upstream}") . "origin/master") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "symbolic-ref" "--short" "HEAD") 
. "master") (("/sshfs:freebsd14:/home/albinus/src/emacs/" "log" "--no-walk" 
"--format=%h %s" "HEAD^{commit}" "--") . "923aac2e4ec Merge branch 'master' of 
git.sv.gnu.org:/srv/git/emacs") (("/sshfs:freebsd14:/home/albinus/src/emacs/" . 
config) . #<hash-table equal 20/24 0xc3b3488 ...>) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--verify" "HEAD") . 
"923aac2e4ec76b51891ba711c44ee08f7211ea2a") 
("/sshfs:freebsd14:/home/albinus/src/emacs/" . "2.46.2") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" . magit-toplevel) . 
"/sshfs:freebsd14:/home/albinus/src/emacs/") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--show-cdup") . "") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--show-toplevel") . 
"/home/albinus/src/emacs") (("/home/albinus/" "config" "--default=_" 
"core.bare") . "_") (("/home/albinus/" . magit-toplevel)) (("/home/albinus/" 
"rev-parse" "--git-dir")) (("/home/albinus/" "rev-parse" "--show-toplevel"))))
  funcall-interactively(magit-status 
"/sshfs:freebsd14:/home/albinus/src/emacs/" ((25 . 20) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-list" "--count" 
"--left-right" "fatal: cannot describe 
'923aac2e4ec76b51891ba711c44ee08f7211ea2a'...")) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "describe" "--contains" "HEAD") . 
"fatal: cannot describe '923aac2e4ec76b51891ba711c44ee08f7211ea2a'") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "describe" "--long" "--tags") . 
"emacs-30.1-180773-g923aac2e4ec") (("/sshfs:freebsd14:/home/albinus/src/emacs/" 
magit-get-push-branch "master" nil)) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--verify" 
"--abbrev-ref" "master") . "master") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "log" "--no-walk" "--format=%s" 
#("origin/master^{commit}" 0 13 (font-lock-face magit-branch-remote face 
magit-branch-remote)) "--") . "Merge branch 'master' of 
git.sv.gnu.org:/srv/git/emacs") (("/sshfs:freebsd14:/home/albinus/src/emacs/" 
magit-get-upstream-branch "master") . #("origin/master" 0 13 (face 
magit-branch-remote font-lock-face magit-branch-remote))) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--verify" 
"--abbrev-ref" "master@{upstream}") . "origin/master") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "symbolic-ref" "--short" "HEAD") 
. "master") (("/sshfs:freebsd14:/home/albinus/src/emacs/" "log" "--no-walk" 
"--format=%h %s" "HEAD^{commit}" "--") . "923aac2e4ec Merge branch 'master' of 
git.sv.gnu.org:/srv/git/emacs") (("/sshfs:freebsd14:/home/albinus/src/emacs/" . 
config) . #<hash-table equal 20/24 0xc3b3488 ...>) 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--verify" "HEAD") . 
"923aac2e4ec76b51891ba711c44ee08f7211ea2a") 
("/sshfs:freebsd14:/home/albinus/src/emacs/" . "2.46.2") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" . magit-toplevel) . 
"/sshfs:freebsd14:/home/albinus/src/emacs/") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--show-cdup") . "") 
(("/sshfs:freebsd14:/home/albinus/src/emacs/" "rev-parse" "--show-toplevel") . 
"/home/albinus/src/emacs") (("/home/albinus/" "config" "--default=_" 
"core.bare") . "_") (("/home/albinus/" . magit-toplevel)) (("/home/albinus/" 
"rev-parse" "--git-dir")) (("/home/albinus/" "rev-parse" "--show-toplevel"))))
  command-execute(magit-status record)
  execute-extended-command(nil "magit-status" nil)
  funcall-interactively(execute-extended-command nil "magit-status" nil)
  command-execute(execute-extended-command)
--8<---------------cut here---------------end--------------->8---

Sorry, but I cannot say anything about. I don't use magit myself.

>>> All of this works with tramp over ssh. 
>>
>> This might come down to what I said earlier about sshfs not being 
>> an environment.
>
> What does "environment" mean in this case? Does that refer to how both
> methods are implemented?

Yes.

Perhaps you give the tramp-rpc backend a try. It is brand new, still in
alpha version, but acc. to my experience stable. And it has even some
magit-specific optimizations on board. See 
<https://github.com/ArthurHeymans/emacs-tramp-rpc>.

> Thanks, Patrick

Best regards, Michael.

Reply via email to