Powershell SSH remote handles single quotes literally: possible to disable auto-wrapping paths in quotes?

189 views
Skip to first unread message

Derek Lam

unread,
Dec 15, 2021, 5:44:33 PM12/15/21
to git-for-windows
I am trying to add a remote using git 2.23.0 on a Windows 10 PC, referencing a repo on a remote machine running Windows Server 2012 with git 2.34.1.

I set up OpenSSH on the remote using Win32-OpenSSH, so SSH logs into Powershell. However Powershell doesn't handle paths wrapped in single quotes like *nix shells do, instead treating single quotes in paths literally. I found out that the remote commands (git pull/fetch/ls-remote/etc.) wrap the paths they send to the remote in single quotes, as evidenced by trying to ls-remote:

$ GIT_TRACE=1 git ls-remote user@addr:path_to/repo
17:22:31.451511 exec-cmd.c:237 trace: resolved executable dir: C:/Users/me/Git/mingw64/bin
17:22:31.457170 git.c:440 trace: built-in: git ls-remote user@addr:/path_to/repo/
17:22:31.457170 run-command.c:663 trace: run_command: unset GIT_PREFIX; ssh user@addr 'git-upload-pack '\''/path_to/repo/'\'''
fatal: ''/path_to/repo/'' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.

Note the first fatal shows ''/path_to/repo'':

  • The outer quotes are from the error message.
  • The inner quotes are true quotes due to the command in the third trace: git-upload-pack '\''/path_to/repo/'\''.

I am sure that this is the case because if I make a directory literally called 'path_to, and a repo directory repo' within it, including the quotes, it works. Is there any git client option to disable these single quote wrappings, or a Powershell option to read paths wrapped with single quotes, or maybe even a later version of git-upload-pack that strips these quotes out?

Thanks,
Derek

Derek Lam

unread,
Dec 20, 2021, 12:40:38 PM12/20/21
to git-for...@googlegroups.com
I am trying to add a remote using git 2.23.0 on a Windows 10 PC, referencing a repo on a remote machine running Windows Server 2012 with git 2.34.1.

I set up OpenSSH on the remote using Win32-OpenSSH, so SSH logs into Powershell. However Powershell doesn't handle paths wrapped in single quotes like *nix shells do, instead treating single quotes in paths literally. I found out that the remote commands (git pull/fetch/ls-remote/etc.) wrap the paths they send to the remote in single quotes, as evidenced by trying to ls-remote:

$ GIT_TRACE=1 git ls-remote user@addr:path/to/repo
17:22:31.451511 exec-cmd.c:237          trace: resolved executable dir: C:/Users/me/Git/mingw64/bin
17:22:31.457170 git.c:440               trace: built-in: git ls-remote user@addr:/path_to/repo/
17:22:31.457170 run-command.c:663       trace: run_command: unset GIT_PREFIX; ssh user@addr 'git-upload-pack '\''/path_to/repo/'\'''

fatal: ''/path_to/repo/'' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Note the first fatal shows ''/path/to/repo'':

Konstantin Khomoutov

unread,
Dec 21, 2021, 7:12:00 AM12/21/21
to Derek Lam, git-for...@googlegroups.com
On Wed, Dec 15, 2021 at 02:04:52AM +0000, Derek Lam wrote:

> I am trying to add a remote using git 2.23.0 on a Windows 10 PC, referencing
> a repo on a remote machine running Windows Server 2012 with git 2.34.1.
>
> I set up OpenSSH on the remote using
> [Win32-OpenSSH](https://github.com/PowerShell/Win32-OpenSSH), so SSH logs
> into Powershell. However Powershell doesn't handle paths wrapped in single
> quotes like *nix shells do, instead treating single quotes in paths
> literally. I found out that the remote commands (git
> pull/fetch/ls-remote/etc.) wrap the paths they send to the remote in single
> quotes, as evidenced by trying to ls-remote:
>
> $ GIT_TRACE=1 git ls-remote user@addr:path/to/repo
> 17:22:31.451511 exec-cmd.c:237 trace: resolved executable dir: C:/Users/me/Git/mingw64/bin
> 17:22:31.457170 git.c:440 trace: built-in: git ls-remote user@addr:/path_to/repo/
> 17:22:31.457170 run-command.c:663 trace: run_command:
>
> unset
>
> GIT_PREFIX; ssh user@addr
>
> 'git-upload-pack '
[...]
> Note the first fatal shows ''/path/to/repo'':
>
> - The outer quotes are from the error message.
> - The inner quotes are true quotes due to the command in the third trace:
> git-upload-pack '\''/path_to/repo/'\''.
>
> I am sure that this is the case because if I make a directory literally
> called 'path_to, and a repo directory repo' within it, including the quotes,
> it works. Is there any git client option to disable these single quote
> wrappings, or a Powershell option to read paths wrapped with single quotes,
> or maybe even a later version of git-upload-pack that strips these quotes
> out?

I'd try to play with the GIT_SSH or - may be better - GIT_SSH_COMMAND
environment variables: they allow you to redefine the the command Git calls
to carry out the task of logging into the remote server and running
appropriate Git commands there. You could set it to some program which would
take the command-line options submitted to it by Git, do whatever it thinks is
sensible with reformatting them to make the PS in the remote end of the
session happy and then call out to the actual SSH client.

For a start, you could just run

GIT_TRACE=1 GIT_SSH_COMMAND="cmd.exe /c echo OK" git fetch origin

and see what the trace prints.

Konstantin Khomoutov

unread,
Dec 21, 2021, 7:40:13 AM12/21/21
to Derek Lam, git-for...@googlegroups.com
On Tue, Dec 21, 2021 at 03:12:15PM +0300, Konstantin Khomoutov wrote:

> On Wed, Dec 15, 2021 at 02:04:52AM +0000, Derek Lam wrote:
> > I am trying to add a remote using git 2.23.0 on a Windows 10 PC, referencing
> > a repo on a remote machine running Windows Server 2012 with git 2.34.1.
[...]
> > 17:22:31.457170 run-command.c:663 trace: run_command:
> >
> > unset
> >
> > GIT_PREFIX; ssh user@addr
> >
> > 'git-upload-pack '
[...]
> I'd try to play with the GIT_SSH or - may be better - GIT_SSH_COMMAND
> environment variables: they allow you to redefine the the command Git calls
> to carry out the task of logging into the remote server and running
> appropriate Git commands there. You could set it to some program which would
> take the command-line options submitted to it by Git, do whatever it thinks is
> sensible with reformatting them to make the PS in the remote end of the
> session happy and then call out to the actual SSH client.
[...]

Well, another idea is to somehow configure the SSH server you're using to
simply use the Windows port of Bash - always included in the Git for Windows
installation - as the login shell of the user you're using for Git session.
Bash has native support for single quotes so you should be OK without any
tweaks on the client's side.

Of course, it might be inconvenient if this is the same user you're using
for interactive logins to that box but I'd say using SSH for day-to-day chores
on Windows is rare - one usually uses RDP anyway.

Erik Cervin Edin

unread,
Dec 23, 2021, 1:18:34 PM12/23/21
to git-for-windows
I would also investigate the sshd logs on the remote

Erik Cervin Edin

unread,
Dec 23, 2021, 3:27:10 PM12/23/21
to git-for-windows
Ok so I tried this out myself and was able to get it working.
I don't think it's a bug, at least not a show stopper.
The problem you're facing is most likely due to shell escaping and other trickery.

I tried this in an environment where the two machines are on different domains.

Ie: I connect on ssh using
  DOMAIN\erik@machine

Backslash get's escaped in bash (or something), so I usually just
  DOMAIN/erik@machine
Since Windows is typically agnostic about this stuff

Git however didn't like this. It would try interpret the whole string as the path of the repository :(

Then I tried using
  DOMAIN\erik@machine:repos/foo
This didn't work as `\` would be treated as an escape character
  DOMAINerik@machine
:(

Then I tries using
  git ls-remote DOMAIN\\erik@machine:repos/foo
which became
DOMAIN\\\\erik@machine:repos/foo
:((

The solution was quoting the string in single quotes (in bash, same in PS/cmd I believe)
  git ls-remote 'DOMAIN\erik@machine:repos/foo' 
(a relative path to ~)

For an absolute path, we again venture into the fun land of Windows/Nix incompatibilities.
Fails
  git ls-remote DOMAIN\erik@machine:/users/erik/repos/foo
  git ls-remote DOMAIN\erik@machine:C/users/erik/repos/foo
  git ls-remote DOMAIN\erik@machine:C:/users/erik/repos/foo
Succeeds
  git ls-remote DOMAIN\erik@machine:c:/users/erik/repos/foo (wtf)
  git ls-remote DOMAIN\erik@machine:C:\users\erik\repos\foo
  git ls-remote DOMAIN\erik@machine:c:\users\erik\repos\foo

TDLR
Make sure to quote the string to git ls-remote
Provide the path according to the secret rules of the wonky cloud wizards that make internets work

Erik Cervin Edin

unread,
Dec 23, 2021, 3:36:39 PM12/23/21
to git-for-windows
I should mention this was running

client-side:
git version 2.34.1.windows.1
GNU bash, version 4.4.23(1)-release (x86_64-pc-msys)

server-side:
PowerShell 7.2.0
git version 2.34.1.windows.1
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2
Reply all
Reply to author
Forward
0 new messages