From: Wesley Schwengle Date: Thu, 26 Mar 2026 23:37:35 GMT Subject: [PATCH 0/3] Add support for per-remote and per-namespace SSH options Message-ID: <20260326233739.2911354-1-wesleys@opperschaap.net> With this changeset applied git is now aware of `sshIdentityFiles' and `sshOpts'. This allows users to have multiple accounts on the same forges. A common problem within the developer community. This problem is often solved by hacking in one's `.ssh/config' and changing hostname URIs to ensure the correct key is being used. For years I had zsh wrapper script that was used as the `core.sshCommand' and is a reference implementation of this change. In order of importance: Configuration on the remotes itself. This is easy, straight forward and should allow people to get it to work quickly: * `remote.*.sshIdentityFile' and `remote.*.sshOpts' Configuration set on owner/path style. This is to support `includeIf` configuration management. For example, a git-forge that host both employer/client repo's. Eg, `git@gitlab.com/waterkip/git.git' and `git@gitlab.com/corp/git.git' would have something configured as: * `core.sshIdentityFile.*', eg [core "sshIdentityFile"] waterkip = ~/.ssh/id_ed25519_me corp = ~/.ssh/id_ed25519_corporate And finally, a global override for everything: * `core.sshIdentityFile' and `core.sshOpts' I stayed within the `core' namespace, mainly because `core.sshCommand'. I'm happy to move it to `ssh' or something similar. It would perhaps make `ssh.*.sshIdentifyFile' more structured, because now that's split between two core subsections. The following assumptions have been made to make it safe and sound for users. When an `sshIdentityFile' is used and no `sshOpts' are configured git will inject `-F /dev/null' to prevent cycling over all sshIdentityFiles a user has in their `.ssh/config'. When a user configures `sshOpts', these take precedence and a user itself is responsible for setting `-F /dev/null'. Separate push/pull URIs are not supported by the feature. The biggest problem with this is that I don't know how to properly configure them with the namespace constraints. `remote.*.xyz' is as deep as git can go and a push/pull would require additional configuration. I filed it under edge-case. There are two new structs introduced: `ssh_options' and `cnx_context'. They are there to limit the amount of argument passing down the wire. And this is especially true for `ssh_options' because it keeps `push_ssh_options' dumb. Wesley Schwengle (3): connect: Rename name to command in connect_git() connect: Add transport->remote->name to git_connect() connect: Add support for per-remote and per-namespace SSH options Documentation/config/core.adoc | 22 ++++ Documentation/config/remote.adoc | 9 ++ builtin/fetch-pack.c | 2 +- builtin/send-pack.c | 2 +- connect.c | 144 ++++++++++++++++++++-- connect.h | 2 +- t/t57xx-ssh-options-config.sh | 198 +++++++++++++++++++++++++++++++ transport.c | 9 +- 8 files changed, 375 insertions(+), 13 deletions(-) create mode 100755 t/t57xx-ssh-options-config.sh -- 2.53.0.722.g8e572876c5