Parse remotes as URLs or SCP-style paths

Instead of trying to strip on ':' and '/' to simplify a URL, actually
switch based on whether the remote path is a URL ("scheme://host:port/path")
or an SCP-style path (user@host:path) and parse them separately.

This allows us to handle custom ports in HTTP and HTTPS, but ignore
custom ports in an SSH url and HTTP remotes, instead of always upgrading
them to HTTPS.
This commit is contained in:
Edward Thomson 2017-07-26 16:23:45 +01:00
parent 363d054386
commit c956af1b63
2 changed files with 47 additions and 10 deletions

View file

@ -62,17 +62,37 @@ fi
# ftp[s]://host.xz[:port]/path/to/repo.git/
# [user@]host.xz:path/to/repo.git/ - scp-like but is an alternative to ssh.
# Trim "/" and ".git" from the end of the url
giturl=${giturl%/} giturl=${giturl%.git}
# Determine whether this is a url (https, ssh, git+ssh...) or an scp-style path
if [[ "$giturl" =~ ^[a-z\+]+://.* ]]; then
# Trim URL scheme and possible username
gitprotocol=${giturl%%://*}
uri=${giturl#*://}
uri=${uri#*@}
# Trim before last '@' and protocol (*://) from beginning
uri=${giturl##*@} uri=${uri##*://}
# Split on first '/ to get server name and path
domain=${uri%%/*}
urlpath=${uri#*/}
# If there isn't a protocol, we can assume it's using the scp syntax which uses ':' to seperate the path.
[[ $giturl =~ :// ]] && pathsep='/' || pathsep=':'
# Remove port number from non-http/https protocols (ie, ssh)
if [[ $gitprotocol != 'https' && $gitprotocol != 'http' ]]; then
domain=${domain%:*}
fi
else
# Trim possible username from SSH path
uri=${giturl##*@}
# Seperate the domain and the urlpath on the first {pathsep}. This also removes the gitport from the domain.
domain=${uri%%[:$pathsep]*} urlpath=${uri#*$pathsep}
# Split on first ':' to get server name and path
domain=${uri%%:*}
urlpath=${uri#*:}
fi
# Trim "/" from beginning of URL; "/" and ".git" from end of URL
urlpath=${urlpath#/} urlpath=${urlpath%/} urlpath=${urlpath%.git}
# If the URL is provided as "http", preserve that
if [[ $gitprotocol == 'http' ]]; then
protocol='http'
fi
# Allow config options to replace the server or the protocol
openurl="$protocol://$domain"

View file

@ -144,6 +144,24 @@ setup() {
assert_output "https://github.com/paulirish/git-open"
}
@test "basic: https url can contain port" {
git remote set-url origin "https://github.com:99/user/repo.git"
run ../git-open
assert_output "https://github.com:99/user/repo"
}
@test "basic: ssh url has port removed from http url" {
git remote set-url origin "ssh://github.com:22/user/repo.git"
run ../git-open
assert_output "https://github.com/user/repo"
}
@test "basic: http url scheme is preserved" {
git remote set-url origin "http://github.com/user/repo.git"
run ../git-open
assert_output "http://github.com/user/repo"
}
##
## Bitbucket
@ -299,8 +317,7 @@ setup() {
git remote set-url origin "https://git.example.com:7000/XXX/YYY.git"
run ../git-open
assert_output "https://git.example.com/XXX/YYY"
refute_output --partial ":7000"
assert_output "https://git.example.com:7000/XXX/YYY"
}
teardown() {