1

TortoiseHg (Mercurial) normally uses TortoisePLink/plink to connect via SSH. Different SSH hosts have different settings, including private keys and ports to connect to.

In its global hgrc settings, TortoiseHg lets you specify different logins and passwords for different hosts, but not private keys nor ports.

How to override SSH port/private key globally, but only for some hosts and not others?

himself
  • 4,806
  • 2
  • 27
  • 43

1 Answers1

2

I'll list a number of imperfect approaches for completeness, then give the one I've found that I think is better:

ssh setting

Mercurial ssh setting can be used to pass additional params to plink globally:

ssh=path\to\TortoisePLink.exe -i "private1.key" -i "private2.key" -P port

But the same ssh string is used for all hosts, so different ports cannot be configured. And while you can list several private keys, some servers will refuse all but the first one.

putty's saved sessions

plink comes from putty package, and putty can store server configurations (sessions) in the registry, HKEY_CURRENT_USER\SOFTWARE\SimonTatham\PuTTY\Sessions. plink can use these if you use a session name in the host place, e.g. ssh://session-name/path/to/repository.

But for some reason plink ignores stored port settings and will use the default SSH port. Probably a bug, but it's unfixed.

Local hgrcs

You can override ssh for each repository by creating a local .hgrc file, but it's unwieldy if you have lots of repos.

  • You have to remember to do this every time
  • Cannot just "clone repo from address"
  • What if your repo can be synced to two different servers?
  • What if one of the servers changes its SSH port, you'll have to find and update every repo everywhere.
Explicit ports

You can specify ports explicitly in the remote repository address:

ssh://server.name:port/path/to/repository

Same problems as with local hgrcs.

PLink script wrapper

After struggling with this for a while, I have finally thought of something that seems to work. We can wrap TortoisePLink in a script that adds per-server params:

ssh=path\to\TortoisePLinkWrapper.cmd <all the normal common params>

Create a file called username@host.name.cfg for every host you want to override, and its contents should be additional params to pass to TortoisePLink, e.g.:

-P 1234 -i "path\to\key.file"

Place this in the same dir:

@echo off
set SERVER_PARAMS=
set SERVER_NAME=
call :find_server %*
if "%SERVER_NAME%"=="" goto :call_plink
set "SERVER_CONFIG_FILE=%~dp0%SERVER_NAME%.cfg"
if NOT EXIST "%SERVER_CONFIG_FILE%" goto :call_plink
set /p SERVER_PARAMS=<"%SERVER_CONFIG_FILE%"

:call_plink
rem TortoisePLink ignores some params if you pass them after the ssh command, so add extra commands before the bulk of them
"%ProgramFiles%\TortoiseHg\lib\TortoisePLink.exe" %SERVER_PARAMS% %*
exit /B

:find_server
if [%1]==[] exit /B
rem Known arguments which eat some more positions
rem https://putty.org.ru/htmldoc/chapter7.html
if [%1]==[-P] shift & shift & goto :find_server
if [%1]==[-l] shift & shift & goto :find_server
if [%1]==[-pw] shift & shift & goto :find_server
if [%1]==[-proxycmd] shift & shift & goto :find_server
if [%1]==[-sercfg] shift & shift & goto :find_server
if [%1]==[-D] shift & shift & goto :find_server
if [%1]==[-L] shift & shift & goto :find_server
if [%1]==[-R] shift & shift & goto :find_server
if [%1]==[-i] shift & shift & goto :find_server
if [%1]==[-hostkey] shift & shift & goto :find_server
if [%1]==[-m] shift & shift & goto :find_server
if [%1]==[-nc] shift & shift & goto :find_server
if [%1]==[-sshlog] shift & shift & goto :find_server
if [%1]==[-sshrawlog] shift & shift & goto :find_server
set "PARAM=%~1"
rem Other flag argument:
if "%PARAM:~0,1%"=="-" shift & goto :find_server
rem First positional argument
set "SERVER_NAME=%~1"
exit /B
himself
  • 4,806
  • 2
  • 27
  • 43