mirror of
https://github.com/paulirish/git-open.git
synced 2026-09-10 07:26:15 -04:00
141 lines
4 KiB
Bash
Executable file
141 lines
4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# Opens the GitHub page for a repo/branch in your browser.
|
|
# https://github.com/paulirish/git-open/
|
|
#
|
|
# git open
|
|
# git open [remote] [branch]
|
|
|
|
|
|
# are we in a git repo?
|
|
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
|
|
echo "Not a git repository." 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
is_issue=0
|
|
|
|
# If the first argument is 'issue', we want to load the issue page
|
|
if [[ "$1" == 'issue' ]]; then
|
|
is_issue=1
|
|
|
|
# Allow the user to provide other args, aka `git open issue upstream 79`
|
|
shift
|
|
fi
|
|
|
|
# assume remote origin if not provided
|
|
remote=${1:-"origin"}
|
|
|
|
# @TODO ls-remote will also expand "insteadOf" items `giturl=$(git ls-remote --get-url $remote)``
|
|
giturl=$(git config --get "remote.${remote}.url")
|
|
|
|
if [[ -z "$giturl" ]]; then
|
|
echo "Git remote is not set for $remote" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
# Initial case examples: 'git@example.com:user/project', 'https://example.com:8080/scm/user/project.git/'
|
|
# Trim "/" and ".git" from the end of the url
|
|
giturl=${giturl%/} giturl=${giturl%.git}
|
|
|
|
# Trim before last '@' and protocol (*://) from beginning
|
|
uri=${giturl##*@} uri=${uri##*://}
|
|
|
|
# Trims before first ':' or '/' to get path
|
|
urlpath=${uri#*[/:]}
|
|
|
|
# Make # and % characters url friendly
|
|
# github.com/paulirish/git-open/pull/24
|
|
branch=${branch//%/%25} && branch=${branch//#/%23}
|
|
|
|
# URL normalization
|
|
# GitHub gists
|
|
if grep -q gist.github <<<"$giturl"; then
|
|
giturl=${giturl/git\@gist.github\.com\:/https://gist.github.com/}
|
|
providerUrlDifference=tree
|
|
|
|
# GitHub
|
|
elif grep -q github <<<"$giturl"; then
|
|
giturl=${giturl/git\@github\.com\:/https://github.com/}
|
|
|
|
# handle urls with the git user
|
|
giturl=${giturl/#github\.com\:/https://github.com/}
|
|
|
|
# handle urls without the github domain with git user
|
|
giturl=${giturl/#github\:/https://github.com/}
|
|
|
|
# handle urls without the github domain
|
|
giturl=${giturl/#ssh\:\/\/git\@github\//https://github.com/}
|
|
|
|
# handle SSH protocol (links like ssh://git@github.com/user/repo)
|
|
giturl=${giturl/#ssh\:\/\/git\@github\.com\//https://github.com/}
|
|
|
|
providerUrlDifference=tree
|
|
|
|
# Bitbucket
|
|
elif grep -q bitbucket <<<"$giturl"; then
|
|
giturl=${giturl/git\@bitbucket\.org\:/https://bitbucket.org/}
|
|
# handle SSH protocol (change ssh://https://bitbucket.org/user/repo to https://bitbucket.org/user/repo)
|
|
giturl=${giturl/#ssh\:\/\/git\@/https://}
|
|
|
|
# remove username
|
|
giturl=${giturl//\/\/*@bitbucket.org///bitbucket.org}
|
|
|
|
rev="$(git rev-parse HEAD)"
|
|
git_pwd="$(git rev-parse --show-prefix)"
|
|
providerUrlDifference="src/${rev}/${git_pwd}"
|
|
branch="?at=${branch}"
|
|
|
|
# Atlassian Bitbucket Server
|
|
elif grep -q "/scm/" <<<"$giturl"; then
|
|
re='(.*)/scm/(.*)/(.*)\.git'
|
|
if [[ $giturl =~ $re ]]; then
|
|
giturl=${BASH_REMATCH[1]}/projects/${BASH_REMATCH[2]}/repos/${BASH_REMATCH[3]}
|
|
providerUrlDifference=browse
|
|
branch="?at=refs%2Fheads%2F${branch}"
|
|
fi
|
|
|
|
# GitLab
|
|
else
|
|
# Make # and % characters url friendly
|
|
# github.com/paulirish/git-open/pull/24
|
|
branch=${branch//%/%25} branch=${branch//#/%23}
|
|
providerBranchRef="tree/$branch"
|
|
fi
|
|
|
|
if [[ "$server" == 'bitbucket.org' ]]; then
|
|
# Bitbucket, see https://github.com/paulirish/git-open/issues/80 for why ?at is needed.
|
|
providerBranchRef="src?at=$branch"
|
|
elif [[ ${pathargs[0]} == 'scm' ]]; then
|
|
# Bitbucket server, which starts with 'scm'
|
|
# Replace the first element, 'scm', with 'projects'. Keep the first argument, the string 'repos', and finally the rest of the arguments.
|
|
pathargs=('projects' ${pathargs[1]} 'repos' "${pathargs[@]:2}")
|
|
IFS='/' urlpath="${pathargs[*]}"
|
|
providerBranchRef="browse?at=$branch"
|
|
fi
|
|
|
|
# @TODO: support non-https?
|
|
openurl="https://$server/$urlpath"
|
|
|
|
# simplify URL for master
|
|
if [[ $branch != "master" ]]; then
|
|
openurl="$openurl/$providerBranchRef"
|
|
fi
|
|
|
|
# get current open browser command
|
|
case $( uname -s ) in
|
|
Darwin) open='open';;
|
|
MINGW*) open='start';;
|
|
MSYS*) open='start';;
|
|
CYGWIN*) open='cygstart';;
|
|
*) open='xdg-open';;
|
|
esac
|
|
|
|
# Allow printing the url if BROWSER=echo
|
|
if [[ $BROWSER != "echo" ]]; then
|
|
exec &>/dev/null
|
|
fi
|
|
|
|
# open it in a browser
|
|
${BROWSER:-$open} "$openurl"
|