Commits

Anonymous committed 2e77666

URL: allow port specification in ssh:// URLs

Allow port specification in ssh:// URLs in the
usual notation:

ssh://[user@]host.domain[:<port>]/<path>

This allows git to be used over ssh-tunneling
networks.

Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

Comments (0)

Files changed (2)

Documentation/urls.txt

 - https://host.xz/path/to/repo.git/
 - git://host.xz/path/to/repo.git/
 - git://host.xz/~user/path/to/repo.git/
+- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/
 - ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/
 - ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/
 - ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git
 SSH is the default transport protocol over the network.  You can
 optionally specify which user to log-in as, and an alternate,
 scp-like syntax is also supported.  Both syntaxes support
-username expansion, as does the native git protocol. The following
+username expansion, as does the native git protocol, but
+only the former supports port specification. The following
 three are identical to the last three above, respectively:
 
 ===============================================================
 
 #define MAX_CMD_LEN 1024
 
+char *get_port(char *host)
+{
+	char *end;
+	char *p = strchr(host, ':');
+
+	if (p) {
+		strtol(p+1, &end, 10);
+		if (*end == '\0') {
+			*p = '\0';
+			return p+1;
+		}
+	}
+
+	return NULL;
+}
+
 /*
  * This returns 0 if the transport protocol does not need fork(2),
  * or a process id if it does.  Once done, finish the connection
 	pid_t pid;
 	enum protocol protocol = PROTO_LOCAL;
 	int free_path = 0;
+	char *port = NULL;
 
 	/* Without this we cannot rely on waitpid() to tell
 	 * what happened to our children.
 		*ptr = '\0';
 	}
 
+	/*
+	 * Add support for ssh port: ssh://host.xy:<port>/...
+	 */
+	if (protocol == PROTO_SSH && host != url)
+		port = get_port(host);
+
 	if (protocol == PROTO_GIT) {
 		/* These underlying connection commands die() if they
 		 * cannot connect.
 				ssh_basename = ssh;
 			else
 				ssh_basename++;
-			execlp(ssh, ssh_basename, host, command, NULL);
+
+			if (!port)
+				execlp(ssh, ssh_basename, host, command, NULL);
+			else
+				execlp(ssh, ssh_basename, "-p", port, host,
+				       command, NULL);
 		}
 		else {
 			unsetenv(ALTERNATE_DB_ENVIRONMENT);