Compare commits

..

No commits in common. "master" and "1.1.1" have entirely different histories.

18 changed files with 150 additions and 6793 deletions

View file

@ -1,11 +0,0 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false

View file

@ -1,33 +0,0 @@
name: CI
on:
push:
branches: [master]
pull_request: # run on all PRs, not just PRs to a particular branch
jobs:
basics:
runs-on: ubuntu-latest
steps:
- name: git clone
uses: actions/checkout@v3
with:
fetch-depth: 100
- uses: actions/setup-node@v3
with:
node-version: latest
- run: npm ci
- name: Setup BATS
uses: mig4/setup-bats@v1
with:
bats-version: 0.4.0 # This is the version i have locally. looks like an upgrade is in order, though…
- run: git submodule update --init
name: pull in bats assertion libs
- run: npm run lint
- run: npm run shellcheck
- run: npm run unit

2
.gitignore vendored
View file

@ -1,3 +1 @@
node_modules/
sandboxrepo
git-open.1

6
.gitmodules vendored
View file

@ -1,6 +0,0 @@
[submodule "test/test_helper/bats-assert"]
path = test/test_helper/bats-assert
url = https://github.com/ztombol/bats-assert
[submodule "test/test_helper/bats-support"]
path = test/test_helper/bats-support
url = https://github.com/ztombol/bats-support

View file

@ -1,5 +0,0 @@
node_modules/
sandboxrepo
git-open.1
bats-assert
bats-support

View file

@ -1,22 +0,0 @@
MIT License
===========
Copyright (c) 2013-2017 Jason McCreary, Paul Irish and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

140
README.md
View file

@ -1,69 +1,50 @@
# git-open [![Build Status](https://img.shields.io/travis/paulirish/git-open/master.svg)](https://travis-ci.org/paulirish/git-open)
# git-open
Type `git open` to open the repo website (GitHub, GitLab, Bitbucket) in your browser.
Type `git open` to open the repo website (Github, Gitlab, Bitbucket) in your browser.
![Demo of git open in action](https://user-images.githubusercontent.com/39191/33507513-f60041ae-d6a9-11e7-985c-ab296d6a5b0f.gif)
![git open2015-01-24 13_51_18](https://cloud.githubusercontent.com/assets/39191/5889192/244a0b72-a3d0-11e4-8ab9-55fc64228aaa.gif)
## Usage
```sh
git open [remote-name] [branch-name]
# Open the page for this branch on the repo website
git open --commit
git open -c
# Open the current commit in the repo website
git open --issue
git open -i
# If this branch is named like issue/#123, this will open the corresponding
# issue in the repo website
git open --print
git open -p
# Only print the url at the terminal, but don't open it
git open issue
```
(`git open` works with these [hosted repo providers](#supported-remote-repositories), `git open --issue` currently only works with GitHub, Visual Studio Team Services and Team Foundation Server)
(`git open` works with these [hosted repo providers](#supported-remote-repositories), `git open issue` currently only works with Github)
### Examples
```sh
$ git open
# opens https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/tree/CURRENT_BRANCH
# opens https://github.com/REMOTE_ORIGIN_USER/CURRENT_REPO/tree/CURRENT_BRANCH
$ git open someremote
# opens https://github.com/PROVIDED_REMOTE_USER/CURRENT_REPO/tree/CURRENT_BRANCH
$ git open upstream
# opens https://github.com/REMOTE_UPSTREAM_USER/CURRENT_REPO/tree/CURRENT_BRANCH
$ git open someremote somebranch
# opens https://github.com/PROVIDED_REMOTE_USER/CURRENT_REPO/tree/PROVIDED_BRANCH
$ git open upstream master
# opens https://github.com/REMOTE_UPSTREAM_USER/CURRENT_REPO/tree/master
$ git open --issue
# If branches use naming convention of issues/#123,
# opens https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/issues/123
$ git open --print
# prints https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/tree/CURRENT_BRANCH
$ git open --suffix pulls
# opens https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/pulls
$ git open issue
# If branches use naming convention of issues/#123,
# opens https://github.com/REMOTE_UPSTREAM_USER/CURRENT_REPO/issues/123
```
## Installation
### Installation
### Basic install
#### Without using a framework
The preferred way of installation is to simply add the `git-open` script
somewhere into your path (e.g. add the directory to your `PATH` environment
or copy `git-open` into an existing included path like `/usr/local/bin`).
### Install via NPM:
You can use also `npm` to install this package:
```sh
npm install --global git-open
```
### Windows Powershell
#### Using Windows Powershell
Save git-open anywhere, say as ~/Documents/Scripts/git-open.sh and define
a function in your Powershell profile (see ~/Documents/WindowsPowerShell/profile.ps1) like this:
@ -73,13 +54,9 @@ function git-open { cmd /c "C:\Program Files\Git\usr\bin\bash.exe" "~/Documents/
Set-Alias -Name gop -Value git-open
```
### Windows with `cmd` terminal
#### Using a ZSH Framework
Save the `git-open` script in any place accessible via your `%PATH%` environment var.
### ZSH
#### [Antigen](https://github.com/zsh-users/antigen)
##### [Antigen](https://github.com/zsh-users/antigen)
Add `antigen bundle paulirish/git-open` to your `.zshrc` with your other bundle
commands.
@ -89,34 +66,25 @@ start zsh, and periodically checking for updates to the git repository. You can
also add the plugin to a running zsh with `antigen bundle paulirish/git-open`
for testing before adding it to your `.zshrc`.
#### [Oh-My-Zsh](http://ohmyz.sh/)
##### [Oh-My-Zsh](http://ohmyz.sh/)
1. `git clone https://github.com/paulirish/git-open.git $ZSH_CUSTOM/plugins/git-open`
2. Add `git-open` to your plugin list - edit `~/.zshrc` and change
`plugins=(...)` to `plugins=(... git-open)`
3. `source ~/.zshrc`
1. `cd ~/.oh-my-zsh/custom/plugins`
1. `git clone git@github.com:paulirish/git-open.git`
1. Add `git-open` to your plugin list - edit `~/.zshrc` and change
`plugins=(...)` to `plugins=(... git-open)`
#### [Zgen](https://github.com/tarjoilija/zgen)
##### [Zgen](https://github.com/tarjoilija/zgen)
Add `zgen load paulirish/git-open` to your .zshrc file in the same function
you're doing your other `zgen load` calls in. ZGen will take care of cloning
the repository the next time you run `zgen save`, and will also periodically
check for updates to the git repository.
#### [zplug](https://github.com/zplug/zplug)
##### [zplug](https://github.com/zplug/zplug)
`zplug "paulirish/git-open", as:plugin`
`zplug "paulirish/git-open", as:command`
### Bash
#### [Oh-My-Bash](https://github.com/ohmybash/oh-my-bash)
1. `git clone https://github.com/paulirish/git-open.git $OSH_CUSTOM/plugins/git-open`
2. Add `git-open` to your plugin list - edit `~/.bashrc` and change
`plugins=(...)` to `plugins=(... git-open)`
3. `source ~/.bashrc`
## Supported remote repositories
### Supported remote repositories
git-open can automatically guess the corresponding repository page for remotes
(default looks for `origin`) on the following hosts:
@ -124,19 +92,20 @@ git-open can automatically guess the corresponding repository page for remotes
- github.com
- gist.github.com
- gitlab.com
- GitLab custom hosted (see below)
- Gitlab custom hosted (see below)
- bitbucket.org
- Atlassian Bitbucket Server (formerly _Atlassian Stash_)
- Visual Studio Team Services
- Team Foundation Server (on-premises)
- AWS Code Commit
- cnb.cool
## Configuration
#### Gitlab support
See the [man page](git-open.1.md) for more information on how to configure `git-open`.
To configure gitlab support you need to set `gitopen.gitlab.domain`:
## Alternative projects
```sh
# use --global to set across all repos, instead of just the local one
git config [--global] gitopen.gitlab.domain [yourdomain.here]
```
## Related projects / alternatives
See [hub](https://github.com/github/hub) for complete GitHub opening support.
It's the official GitHub project and provides `hub browse`.
@ -155,25 +124,10 @@ from which this plugin was forked.
[jasonmccreary](https://github.com/jasonmccreary/) did [the initial hard work](https://github.com/jasonmccreary/gh). Since then, [many contributors](https://github.com/paulirish/git-open/graphs/contributors) have submitted great PRs.
## Contributing & Development
## Contributing
Please provide examples of the URLs you are parsing with each PR.
### Testing:
You'll need to install [bats](https://github.com/sstephenson/bats#installing-bats-from-source), the Bash automated testing system. It's also available as `brew install bats`
```sh
git submodule update --init # pull in the assertion libraries
# Run the test suite once:
bats test # or `npm run unit`
# Run it on every change with `entr`
brew install entr
npm run watch
```
## Related projects
- [`git recent`](https://github.com/paulirish/git-recent) - View your most recent git branches
@ -186,17 +140,9 @@ Copyright Jason McCreary & Paul Irish. Licensed under MIT.
## Changelog
- **2018-12-03** - [2.1.0 shipped](https://github.com/paulirish/git-open/releases/tag/v2.1.0).
- **2017-12-01** - [2.0 shipped](https://github.com/paulirish/git-open/releases/tag/v2.0.0). Breaking change: [Gitlab configuration](https://github.com/paulirish/git-open#configuration) handled differently.
- **2017-12-01** - Configuration for custom remote added
- **2017-11-30** - Support for VSTS Added
- **2017-10-31** - `--issue` and `-h` added
- **2017-10-30** - Configuration for custom domains added
- **2017-10-30** - WSL support added
- **2017-06-16** - Introduced a test suite in BATS
- **2017-06-15** - Entire script rewritten and simplified by @dermagia
- **2016-07-23** - Readme: fix oh-my-zsh install instructions
- **2016-07-22** - 1.1.0 shipped. update and add linters for package.json, readme.
- **2016-07-11** - Readme formatting and installation instructions updated. Changelog started
- **2016-07-23** - readme -- fix oh-my-zsh install instructions
- **2016-07-22** - 1.1.0, update and add linters for package.json, readme.
Re-publish to NPM.
- **2016-07-11** - Changelog started (readme formatting and installation
instructions updated)

View file

@ -1,26 +0,0 @@
## [Version 2.1.0](https://github.com/paulirish/git-open/releases/tag/v2.1.0) (2018-12-3)
[Full changelog](https://github.com/paulirish/git-open/compare/v2.0.0...v2.1.0)
### New features
- Support opening current tag / commit: [#130](https://github.com/paulirish/git-open/pull/130)
- Add man page: [#110](https://github.com/paulirish/git-open/pull/110)
- Add support for sshconfig expansion: [#109](https://github.com/paulirish/git-open/pull/109)
- Add support for Bitbucket Server with different root context: [#113](https://github.com/paulirish/git-open/pull/113)
- Add support for AWS Code commit.: [#128](https://github.com/paulirish/git-open/pull/128)
### Bug fixes
- Fix bug with open -i on default VSTS project repo: [`67b72ac`](https://github.com/paulirish/git-open/commit/67b72ac), [`aea6e3e`](https://github.com/paulirish/git-open/commit/aea6e3e)
- Use ls-remote --get-url to get remote url: [`740222b`](https://github.com/paulirish/git-open/commit/740222b)
- Fix shellcheck: [`775361b`](https://github.com/paulirish/git-open/commit/775361b)
- Fix incompatability with bash < 4: [`895240f`](https://github.com/paulirish/git-open/commit/895240f)
- Swap uppercase/lowercase for ssh feature: [`995e915`](https://github.com/paulirish/git-open/commit/995e915) ([#123](https://github.com/paulirish/git-open/issues/123))
- Remove openopt, allow spaces in $BROWSER: [`96c80ff`](https://github.com/paulirish/git-open/commit/96c80ff)
- readme: One liner install for oh-my-zsh: [`29434cd`](https://github.com/paulirish/git-open/commit/29434cd)
- deps: change markdownlint to markdownlint-cli: [`702b8a6`](https://github.com/paulirish/git-open/commit/702b8a6), [`5b815cb`](https://github.com/paulirish/git-open/commit/5b815cb)
---
Generated by [changelog.md](https://github.com/egoist/changelog.md)

393
git-open
View file

@ -1,323 +1,128 @@
#!/usr/bin/env bash
# Use git-sh-setup, similar to git-rebase
# https://www.kernel.org/pub/software/scm/git/docs/git-sh-setup.html
# https://github.com/git/git/blob/master/git-rebase.sh
# shellcheck disable=SC2034
OPTIONS_STUCKLONG=t
# shellcheck disable=SC2034
OPTIONS_KEEPDASHDASH=
# shellcheck disable=SC2034
OPTIONS_SPEC="\
git open [options]
git open [remote] [branch]
--
Opens the GitHub page for a repo/branch in your browser.
https://github.com/paulirish/git-open/
# Opens the github page for a repo/branch in your browser.
# https://github.com/paulirish/git-open/
#
# git open
# git open [remote] [branch]
Available options are
c,commit! open current commit
i,issue! open issues page
s,suffix= append this suffix
f,file= append this file
p,print! just print the url
"
# https://github.com/koalaman/shellcheck/wiki/SC1090
# shellcheck source=/dev/null
SUBDIRECTORY_OK='Yes' . "$(git --exec-path)/git-sh-setup"
# Defaults
is_commit=0
is_issue=0
protocol="https"
print_only=0
suffix_flag=""
file_flag=""
while test $# != 0; do
case "$1" in
--commit) is_commit=1;;
--issue) is_issue=1;;
--suffix=*) suffix_flag="$1";;
--file=*) file_flag="$1";;
--print) print_only=1;;
--) shift; break ;;
esac
shift
done
# parse suffix from suffix=value
IFS='=' read -ra suffix_flag <<< "$suffix_flag"
function join_by { local IFS="$1"; shift; echo "$*"; }
suffix=$(join_by "=" "${suffix_flag[@]:1}")
# parse file from file=value
IFS='=' read -ra file_flag <<< "$file_flag"
file=$(join_by "=" "${file_flag[@]:1}")
# are we in a git repo?
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
git rev-parse --is-inside-work-tree &>/dev/null
if [[ $? != 0 ]]; then
echo "Not a git repository." 1>&2
exit 1
fi
# choose remote. priority to: provided argument, default in config, detected tracked remote, 'origin'
branch=${2:-$(git symbolic-ref -q --short HEAD)}
upstream_branch_full_name=$(git config "branch.$branch.merge")
upstream_branch=${upstream_branch_full_name#"refs/heads/"}
tracked_remote=$(git config "branch.$branch.remote")
default_remote=$(git config open.default.remote)
remote=${1:-$default_remote}
remote=${remote:-$tracked_remote}
remote=${remote:-"origin"}
giturl=$(git ls-remote --get-url "$remote")
# assume origin if not provided
# fallback to upstream if neither is present.
remote="origin"
if [ -n "$1" ]; then
if [ "$1" == "issue" ]; then
currentBranch=$(git symbolic-ref -q --short HEAD)
regex='^issue'
if [[ $currentBranch =~ $regex ]]; then
issue=${currentBranch#*#}
else
echo "'git open issue' expect branch naming to be issues/#123" 1>&2
exit 1
fi
else
remote="$1"
fi
fi
if [[ -z "$giturl" ]]; then
echo "Git remote is not set for $remote" 1>&2
remote_url="remote.${remote}.url"
giturl=$(git config --get "$remote_url")
if [ -z "$giturl" ]; then
echo "$remote_url not set." 1>&2
exit 1
fi
ssh_config=${ssh_config:-"$HOME/.ssh/config"}
# Resolves an ssh alias defined in ssh_config to it's corresponding hostname
# echos out result, should be used within subshell $( ssh_resolve $host )
# echos out nothing if alias could not be resolved
function ssh_resolve() {
domain="$1"
ssh_found=true
# Filter to only ssh_config lines that start with "Host" or "HostName"
resolved=$(while read -r ssh_line; do
# Split each line by spaces, of the form:
# Host alias [alias...]
# Host regex
# HostName resolved.domain.com
read -r -a ssh_array <<<"${ssh_line}"
ssh_optcode="$(echo "${ssh_array[0]}" | tr '[:lower:]' '[:upper:]')"
if [[ $ssh_optcode == HOST ]]; then
# Host
ssh_found=false
# Iterate through aliases looking for a match
for ssh_index in $(seq 1 $((${#ssh_array[@]} - 1))); do
ssh_host=${ssh_array[$ssh_index]}
# shellcheck disable=SC2053
if [[ $domain == $ssh_host ]]; then
# Found a match, next HostName entry will be returned while matched
ssh_found=true
break
fi
done
elif $ssh_found && [[ $ssh_optcode == HOSTNAME ]]; then
# HostName, but only if ssh_found is true (the last Host entry matched)
# Replace all instances of %h with the Host alias
echo "${ssh_array[1]//%h/$domain}"
fi
done < <(grep -iE "^\\s*Host(Name)?\\s+" "$ssh_config"))
# Take only the last resolved hostname (multiple are overridden)
tail -1 <<<"$resolved"
}
# From git-fetch(5), native protocols:
# ssh://[user@]host.xz[:port]/path/to/repo.git/
# git://host.xz[:port]/path/to/repo.git/
# http[s]://host.xz[:port]/path/to/repo.git/
# ftp[s]://host.xz[:port]/path/to/repo.git/
# [user@]host.xz:path/to/repo.git/ - scp-like but is an alternative to ssh.
# [user@]hostalias:path/to/repo.git/ - handles host aliases defined in ssh_config(5)
# 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#*@}
# Split on first '/ to get server name and path
domain=${uri%%/*}
urlpath=${uri#*/}
# Remove port number from non-http/https protocols (ie, ssh)
if [[ $gitprotocol != 'https' && $gitprotocol != 'http' ]]; then
domain=${domain%:*}
fi
# get current branch
if [ -z "$2" ]; then
branch=$(git symbolic-ref -q --short HEAD)
else
# Trim possible username from SSH path
uri=${giturl##*@}
branch="$2"
fi
# Split on first ':' to get server name and path
domain=${uri%%:*}
urlpath=${uri#*:}
# Make # and % characters url friendly
# github.com/paulirish/git-open/pull/24
branch=${branch//%/%25} && branch=${branch//#/%23}
# Resolve sshconfig aliases
if [[ -e "$ssh_config" ]]; then
domain_resolv=$(ssh_resolve "$domain")
if [[ -n "$domain_resolv" ]]; then
domain="$domain_resolv"
fi
# 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 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://}
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
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"
function getConfig() {
config=$(git config --get-urlmatch "open.$1" "$openurl")
echo "${config:-${!1}}"
}
domain=$(getConfig "domain")
protocol=$(getConfig "protocol")
forge=$(getConfig "forge")
# Remote ref to open
remote_ref=${upstream_branch:-${branch:-$(git describe --tags --exact-match 2>/dev/null || git rev-parse HEAD)}}
# Split arguments on '/'
IFS='/' read -r -a pathargs <<<"$urlpath"
if (( is_issue )); then
# For issues, take the numbers and preprend 'issues/'
[[ $remote_ref =~ [0-9]+ ]]
providerBranchRef="/issues/${BASH_REMATCH[0]}"
# Gitlab
else
# Make # and % characters url friendly
# github.com/paulirish/git-open/pull/24
remote_ref=${remote_ref//%/%25} remote_ref=${remote_ref//#/%23}
if [[ $forge == 'gitea' ]]; then
providerBranchRef="/src/branch/$remote_ref"
else
providerBranchRef="/tree/$remote_ref"
fi
fi
if [[ "$domain" == 'bitbucket.org' ]]; then
providerBranchRef="/src/$remote_ref"
elif [[ "${#pathargs[@]}" -ge 3 && ${pathargs[${#pathargs[@]} - 3]} == 'scm' ]]; then
# Bitbucket server always has /scm/ as the third to last segment in the url path, e.g. /scm/ppp/test-repo.git
# Anything before the 'scm' is part of the server's root context
# If there are other context parts, add them, up to (but not including) the found 'scm'
pathPref=("${pathargs[*]:0:${#pathargs[@]} - 3}")
# Replace the 'scm' element, with 'projects'. Keep the first argument, the string 'repos', and finally the rest of the arguments.
# shellcheck disable=SC2206
pathargs=(${pathPref[@]} 'projects' ${pathargs[${#pathargs[@]} - 2]} 'repos' "${pathargs[@]:${#pathargs[@]} - 1}")
IFS='/' urlpath="${pathargs[*]}"
providerBranchRef="/browse?at=$remote_ref"
elif [[ "$domain" == *"bitbucket"* ]] && [[ $gitprotocol == 'ssh' ]]; then
# bitbucket repo cloned with ssh will not have /scm/ segment in url path
# e.g. /ppp/test-repo.git
# Build the repo url starting with 'projects' and then keep the first argument, the string 'repos', and finally the rest of the arguments.
# shellcheck disable=SC2206
pathargs=('projects' ${pathargs[${#pathargs[@]} - 2]} 'repos' "${pathargs[@]:${#pathargs[@]} - 1}")
IFS='/' urlpath="${pathargs[*]}"
providerBranchRef="/browse?at=$remote_ref"
elif [[ "${#pathargs[@]}" -ge '2' && ${pathargs[${#pathargs[@]} - 2]} == '_git' ]]; then
# Visual Studio Team Services and Team Foundation Server always have /_git/ as the second to last segment in the url path
if (( is_issue )); then
# Switch to workitems, provide work item id if specified
urlpath="${urlpath%%/_git/*}/_workitems"
# Handle case for the default repository url
urlpath="${urlpath#_git\/*}"
providerBranchRef="?id=${remote_ref//[^0-9]/}"
else
# Keep project and repository name, append branch selector.
providerBranchRef="?version=GB$remote_ref"
fi
elif [[ "$domain" =~ amazonaws\.com$ ]]; then
# AWS Code Commit
if (( is_issue )); then
echo "Issue feature does not supported on AWS Code Commit." 1>&2
exit 1
fi
# Take region name from domain.
region=${domain#*.}
region=${region%%.*}
# Replace domain.
# Ex. git-codecommit.us-east-1.amazonaws.com -> us-east-1.console.aws.amazon.com
domain="${region}.console.aws.amazon.com"
# Replace URL path.
# Ex. v1/repos/example -> codecommit/home?region=us-east-1#/repository/example/browse/
urlpath="codecommit/home?region=${region}#/repository/${urlpath##*/}/browse/"
# Replace branch ref.
# Ex. /tree/foobar -> foobar/--/
providerBranchRef="${providerBranchRef##*/}/--/"
elif [[ "$domain" =~ cnb\.cool$ ]]; then
# cnb.cool
# Replace URL path.
# Ex. repos/example -> repos/example/-
urlpath="$urlpath/-"
if [[ $remote_ref = "master" ]]; then
# repos/example/tree/master -> repos/example/-/tree/master
urlpath="$urlpath$providerBranchRef"
fi
fi
openurl="$protocol://$domain/$urlpath"
if (( is_commit )); then
sha=$(git rev-parse HEAD)
openurl="$openurl/commit/$sha"
elif [[ $remote_ref != "master" || "$file" ]]; then
# simplify URL for master
openurl="$openurl$providerBranchRef"
fi
if [ "$file" ]; then
absfile=$(git ls-tree --full-name --name-only "$branch" "$file")
if [[ -z "$absfile" ]]; then
echo "File $file is not in repository" 1>&2
exit 1
# custom gitlab
gitlab_domain=$(git config --get gitopen.gitlab.domain)
if [ -n "$gitlab_domain" ]; then
if grep -q "$gitlab_domain" <<<$giturl; then
giturl=${giturl/git\@${gitlab_domain}:/https://${gitlab_domain}/}
providerUrlDifference=tree
fi
openurl="$openurl/$absfile"
# hosted gitlab
elif grep -q gitlab <<<$giturl; then
giturl=${giturl/git\@gitlab\.com\:/https://gitlab.com/}
providerUrlDifference=tree
fi
fi
giturl=${giturl%\.git}
if [ -n "$issue" ]; then
giturl="${giturl}/issues/${issue}"
elif [ -n "$branch" ]; then
giturl="${giturl}/${providerUrlDifference}/${branch}"
fi
if [ "$suffix" ]; then
openurl="$openurl/$suffix"
fi
# simplify URL for master
giturl=${giturl/tree\/master/}
# get current open browser command
case $( uname -s ) in
Darwin) open='open';;
MINGW*) open='start';;
MSYS*) open='start';;
CYGWIN*) open='cygstart';;
*) # Try to detect WSL (Windows Subsystem for Linux)
if uname -r | grep -q -i Microsoft; then
open='/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -NoProfile Start'
else
open='xdg-open'
fi;;
Darwin) open=open;;
MINGW*) open=start;;
CYGWIN*) open=cygstart;;
MSYS*) open="powershell.exe NoProfile Start";;
*) open=${BROWSER:-xdg-open};;
esac
if (( print_only )); then
printf '%s\n' "$openurl"
exit 0
fi
# open it in a browser
if [[ -n "$BROWSER" ]]; then
if [[ -x "$BROWSER" ]]; then
"$BROWSER" "$openurl"
exit $?
fi
if command -v -- "$BROWSER" >/dev/null 2>&1; then
"$BROWSER" "$openurl"
exit $?
fi
fi
"$open" "$openurl"
$open "$giturl" &> /dev/null
exit 0

View file

@ -1,178 +0,0 @@
# git-open - Open the repository's website in your browser.
## SYNOPSIS
`git open` [--issue] [--commit] [--suffix some_suffix] [remote-name] [branch-name]
## DESCRIPTION
`git open` opens the repository's website in your browser. The major well known
git hosting services are supported.
## OPTIONS
`-c`, `--commit`
Open the current commit. See `EXAMPLES` for more information.
Only tested with GitHub & GitLab.
`-i`, `--issue`
Open the current issue. When the name of the current branch matches the right pattern,
it will open the webpage with that issue. See `EXAMPLES` for more information.
This only works on GitHub, GitLab, Visual Studio Team Services and Team Foundation Server at the moment.
`-s`, `--suffix` some_suffix
Append the given suffix to the url
`-p`, `--print`
Just print the URL. Do not open it in browser.
`-h`
Show a short help text.
## EXAMPLES
```sh
git open
```
It opens https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/
```sh
git open someremote
```
It opens https://github.com/PROVIDED_REMOTE_USER/CURRENT_REPO/
```sh
git open someremote somebranch
```
It opens https://github.com/PROVIDED_REMOTE_USER/CURRENT_REPO/tree/PROVIDED_BRANCH
```sh
git open --issue
```
If branches use naming convention of `issues/#123`, it opens
https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/issues/123
```sh
git open --suffix pulls
```
It opens the URL https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/pulls
```sh
git open --print
```
It prints the URL https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/
```sh
git open --commit
```
Supposing that the current sha is `2ddc8d4548d0cee3d714dcf0068dbec5b168a9b2`, it opens
https://github.com/TRACKED_REMOTE_USER/CURRENT_REPO/commit/2ddc8d4548d0cee3d714dcf0068dbec5b168a9b2
## SUPPORTED GIT HOSTING SERVICES
git-open can automatically guess the corresponding repository page for remotes
on the following git hosting services:
- github.com
- gist.github.com
- gitlab.com
- GitLab CE/EE (self hosted GitLab, see `CONFIGURATION`)
- bitbucket.org
- Atlassian Bitbucket Server (formerly _Atlassian Stash_)
- Visual Studio Team Services
- Team Foundation Server (on-premises)
## CONFIGURATION
To configure git-open you may need to set some `git config` options.
You can use `--global` to set across all repos, instead of just the current repo.
```sh
git config [--global] option value
```
### Configuring which remote to open
By default, `git open` opens the remote named `origin`. However, if your current branch is remotely-tracking a different remote, that tracked remote will be used.
In some instances, you may want to override this behavior. When you fork a project
and add a remote named `upstream` you often want that upstream to be opened
rather than your fork. To accomplish this, you can set the `open.default.remote` within your project:
```sh
git config open.default.remote upstream
```
This is equivalent to always typing `git open upstream`.
### Gitea options
To configure Gitea support you need to set the following option.
`open.[gitdomain].forge`
The git forge present at the git domain. This only needs to be set for Gitea because it uses another branch URL format.
**Example**
```sh
git config [--global] "open.https://gitea.internal.biz.forge" "gitea"
```
### GitLab options
To configure GitLab support (or other unique hosting situations) you may need to set some options.
`open.[gitdomain].domain`
The (web) domain to open based on the provided git repo domain.
`open.[gitdomain].protocol`
The (web) protocol to open based on the provided git repo domain. Defaults to `https`.
```sh
git config [--global] open.[gitdomain].domain [value]
git config [--global] open.[gitdomain].protocol [value]
```
**Example**
- Your git remote is at `ssh://git@git.internal.biz:7000/XXX/YYY.git`
- Your hosted gitlab is `http://repo.intranet/subpath/XXX/YYY`
```sh
git config [--global] "open.https://git.internal.biz.domain" "repo.intranet/subpath"
git config [--global] "open.https://git.internal.biz.protocol" "http"
```
## DEBUGGING
You can run `git-open` in `echo` mode, which doesn't open your browser, but just prints the URL to stdout:
```sh
env BROWSER='echo' ./git-open
```
## AUTHORS
Jason McCreary did the initial hard work. Paul Irish based his project on his work.
Since then many contributors have submitted great PRs.
## SEE ALSO
git(1), git-remote(1), git-config(1), [Project page](https://github.com/paulirish/git-open)

View file

@ -1,6 +0,0 @@
# This plugin is MIT licensed to match the git-open license.
#
# Make git-open easy to install and keep up to date if you're using a
# Bash framework like oh-my-bash.
export PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )":${PATH}

View file

@ -1,9 +0,0 @@
If an incorrect URL is opened, please provide the following so we can write a test:
#### Example clone url:
#### Example branch name:
#### Expected web URL:

View file

@ -9,7 +9,6 @@
"MD013": false,
"MD026": false,
"MD033": false,
"MD034": false,
"MD036": false,
"MD041": false
}

5324
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "git-open",
"version": "3.1.0",
"version": "1.1.1",
"description": "Type `git open` to open the GitHub/GitLab/Bitbucket homepage for a repository.",
"author": "Paul Irish (http://paulirish.com/)",
"license": "MIT",
@ -10,7 +10,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/paulirish/git-open.git"
"url": "https://github.com/paulirish/git-open.git"
},
"contributors": [
"Paul Irish (http://paulirish.com/)",
@ -30,22 +30,14 @@
"git-open": "git-open",
"git-home": "git-open"
},
"man": "./git-open.1",
"scripts": {
"lint:editorconfig": "eclint check ./git-open *.md *.yml",
"lint:readme": "markdownlint --config markdownlint.json README.md",
"lint:man": "markdownlint --config markdownlint.json git-open.1.md",
"man": "marked-man --version \"git-open $npm_package_version\" --manual \"Git manual\" --section 1 git-open.1.md > git-open.1",
"unit": "bats test/",
"shellcheck": "shellcheck ./git-open",
"lint": "npm run lint:readme && npm run lint:man && npm run lint:editorconfig",
"test": "npm run unit && npm run lint",
"watch": "find . -maxdepth 2 -iname '*bats' -o -iname 'git-open' | entr bats test/",
"prepublishOnly": "npm run man && npm run test"
"lint:package": "echo \"\nLinting package.json\" && node ./node_modules/package-json-validator/bin/pjv --recommendations --warnings && echo \"OK\n\n\"",
"lint:readme": "echo \"\nLinting README.md\" && node ./node_modules/markdownlint/lib/markdownlint.js --config markdownlint.json README.md && echo \"OK\n\n\"",
"test": "npm run --silent lint:package && npm run --silent lint:readme"
},
"dependencies": {},
"devDependencies": {
"eclint": "^2.1.0",
"markdownlint-cli": "^0.32.0",
"marked-man": "^0.7.0"
"markdownlint": "^0.2.0",
"package-json-validator": "^0.6.1"
}
}

View file

@ -1,761 +0,0 @@
#!/usr/bin/env bats
load "test_helper/bats-support/load"
load "test_helper/bats-assert/load"
foldername="sandboxrepo"
setup() {
create_git_sandbox
export BROWSER=echo
}
##
## Test environment
##
@test "test environment" {
assert_equal "$BROWSER" "echo"
cd ..
assert [ -e "$foldername" ]
assert [ -e "$foldername/.git" ]
}
##
## Help
##
@test "help text" {
run ../git-open -h
assert_output --partial "usage: git open"
}
@test "invalid option" {
run ../git-open --invalid-option
assert_output --partial "error: unknown option \`invalid-option'"
assert_output --partial "usage: git open"
}
##
## Print
##
@test "print url" {
git remote set-url origin "git@github.com:user/repo.git"
git checkout -B "master"
BROWSER="assert_failure" run ../git-open -p
assert_output "https://github.com/user/repo"
}
##
## url handling
##
@test "url: insteadOf handling" {
git config --local url.http://example.com/.insteadOf ex:
git remote set-url origin ex:example.git
git checkout -B master
run ../git-open
assert_output "http://example.com/example"
}
##
## GitHub
##
@test "gh: basic" {
git remote set-url origin "git@github.com:user/repo.git"
git checkout -B "master"
run ../git-open
assert_output "https://github.com/user/repo"
}
@test "gh: branch" {
git remote set-url origin "git@github.com:user/repo.git"
git checkout -B "mybranch"
run ../git-open
assert_output "https://github.com/user/repo/tree/mybranch"
}
@test "gh: upstream branch" {
git remote set-url origin "git@github.com:user/repo.git"
git remote add upstreamRemote "git@github.com:user/upstream-repo.git"
git checkout -B "mybranch"
git config --local "branch.mybranch.merge" "refs/heads/myupstream/mybranch"
git config --local "branch.mybranch.remote" "upstreamRemote"
run ../git-open
assert_output "https://github.com/user/upstream-repo/tree/myupstream/mybranch"
}
@test "gh: upstream branch from param" {
git remote set-url origin "git@github.com:user/repo.git"
git remote add upstreamRemote "git@github.com:user/upstream-repo.git"
git checkout -B "mybranch"
git config --local "branch.mybranch.merge" "refs/heads/upstreamBranch"
git config --local "branch.mybranch.remote" "upstreamRemote"
git checkout master
run ../git-open upstreamRemote mybranch
assert_output "https://github.com/user/upstream-repo/tree/upstreamBranch"
}
@test "gh: tag" {
git remote set-url origin "git@github.com:user/repo.git"
git tag mytag
echo a > a
git add a
git commit -m a
git checkout mytag
run ../git-open
assert_output "https://github.com/user/repo/tree/mytag"
}
@test "gh: non-origin remote" {
git remote set-url origin "git@github.com:user/repo.git"
git remote add upstream "git@github.com:upstreamorg/repo.git"
run ../git-open "upstream"
assert_output "https://github.com/upstreamorg/repo"
git checkout -B "mybranch"
run ../git-open "upstream" "otherbranch"
assert_output "https://github.com/upstreamorg/repo/tree/otherbranch"
}
@test "gh: without git user" {
# https://github.com/paulirish/git-open/pull/63
git remote set-url origin "github.com:paulirish/git-open.git"
run ../git-open
assert_output "https://github.com/paulirish/git-open"
}
@test "gh: ssh origin" {
git remote set-url origin "ssh://git@github.com/user/repo"
run ../git-open
assert_output "https://github.com/user/repo"
# https://github.com/paulirish/git-open/pull/30
git remote set-url origin "ssh://git@github.com/user/repo.git"
run ../git-open
assert_output "https://github.com/user/repo"
}
@test "gh: git protocol origin" {
git remote set-url origin "git://github.com/user/repo.git"
git checkout -B "master"
run ../git-open
assert_output "https://github.com/user/repo"
}
@test "gh: git open --issue" {
# https://github.com/paulirish/git-open/pull/46
git remote set-url origin "github.com:paulirish/git-open.git"
git checkout -B "issues/#12"
run ../git-open "--issue"
assert_output "https://github.com/paulirish/git-open/issues/12"
git checkout -B "fix-issue-37"
run ../git-open "--issue"
assert_output "https://github.com/paulirish/git-open/issues/37"
git checkout -B "fix-issue-38"
run ../git-open "-i"
assert_output "https://github.com/paulirish/git-open/issues/38"
}
@test "gh: git open --commit" {
git remote set-url origin "github.com:paulirish/git-open.git"
sha=$(git rev-parse HEAD)
run ../git-open "--commit"
assert_output "https://github.com/paulirish/git-open/commit/${sha}"
}
@test "gh: git open --suffix anySuffix" {
run ../git-open "--suffix" "anySuffix"
assert_output "https://github.com/paulirish/git-open/anySuffix"
}
@test "gh: git open --suffix anySuffix?hello=world" {
run ../git-open "--suffix" "anySuffix?hello=world"
assert_output "https://github.com/paulirish/git-open/anySuffix?hello=world"
}
@test "gh: gist" {
git remote set-url origin "git@gist.github.com:2d84a6db1b41b4020685.git"
run ../git-open
assert_output "https://gist.github.com/2d84a6db1b41b4020685"
}
@test "gh: --file option" {
run ../git-open -f readme.txt
assert_output "https://github.com/paulirish/git-open/tree/master/readme.txt"
# and now a new file in a subdirectory.
mkdir -p subdir
touch subdir/howdy.txt
git add subdir
git commit -am add-in-howdy
run ../git-open -f subdir/howdy.txt
assert_output "https://github.com/paulirish/git-open/tree/master/subdir/howdy.txt"
}
@test "basic: # and % in branch names are URL encoded" {
# https://github.com/paulirish/git-open/pull/24
git checkout -B "issue-#42"
run ../git-open
assert_output "https://github.com/paulirish/git-open/tree/issue-%2342"
git checkout -B "just-50%"
run ../git-open
assert_output "https://github.com/paulirish/git-open/tree/just-50%25"
}
@test "basic: tracked remote is default" {
# https://github.com/paulirish/git-open/issues/65
# create a local git repo I can push to
remote_name="sandboxremote"
remote_url="git@github.com:userfork/git-open.git"
# ideally we'd set a real upstream branch, but that's not possible without
# pull/push'ing over the network. So we're cheating and just setting the
# branch.<branch>.remote config
# https://github.com/paulirish/git-open/pull/88#issuecomment-339813145
git remote add $remote_name $remote_url
git config --local --add branch.master.remote $remote_name
run ../git-open
assert_output "https://github.com/userfork/git-open"
git config --local --add branch.master.remote origin
run ../git-open
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"
# ignore any local config like: `url.https://github.com/.insteadof=http://github.com/`
GIT_CONFIG_NOSYSTEM=1 run ../git-open
assert_output "http://github.com/user/repo"
}
@test "basic: open.default.remote configuration" {
git remote set-url origin "git@github.com:paulirish/git-open.git"
git remote add upstream "git@github.com:upstreamorg/repo.git"
git config --local open.default.remote upstream
run ../git-open
assert_output "https://github.com/upstreamorg/repo"
}
##
## SSH config
##
@test "sshconfig: basic" {
create_ssh_sandbox
# Basic
git remote set-url origin "basic:user/repo.git"
run ../git-open
assert_output --partial "https://basic.com/user/repo"
# With git user
git remote set-url origin "git@nouser:user/repo.git"
run ../git-open
assert_output "https://no.user/user/repo"
}
@test "sshconfig: no action on no match" {
create_ssh_sandbox
git remote set-url origin "git@nomatch:user/repo.git"
run ../git-open
assert_output "https://nomatch/user/repo"
# No match due to improper casing
}
@test "sshconfig: check case sensitivity" {
create_ssh_sandbox
# Host and HostName keywords should be case insensitive
# But output URL will be case sensitive
git remote set-url origin "malformed:user/repo.git"
run ../git-open
assert_output "https://MaL.FoRmEd/user/repo"
# SSH aliases (hosts) are case sensitive, this should not match
git remote set-url origin "git@MALFORMED:user/repo.git"
run ../git-open
refute_output "https://MaL.FoRmEd/user/repo"
}
@test "sshconfig: multitarget host" {
create_ssh_sandbox
for i in $(seq 1 3); do
git remote set-url origin "multi$i:user/repo.git"
run ../git-open
assert_output "https://multi.com/user/repo"
done
}
@test "sshconfig: host substitution in hostname" {
create_ssh_sandbox
for i in $(seq 1 3); do
git remote set-url origin "sub$i:user/repo.git"
run ../git-open
assert_output "https://sub$i.multi.com/user/repo"
done
}
@test "sshconfig: host wildcard * matches zero or more chars" {
create_ssh_sandbox
# Normal *
for str in "" "-prod" "-dev"; do
git remote set-url origin "zero$str:user/repo.git"
run ../git-open
assert_output "https://zero.com/user/repo"
done
# * with substitution
for str in "" "-prod" "-dev"; do
git remote set-url origin "subzero$str:user/repo.git"
run ../git-open
assert_output "https://subzero$str.zero/user/repo"
done
}
@test "sshconfig: host wildcard ? matches exactly one char" {
create_ssh_sandbox
# Normal ?
for i in $(seq 1 3); do
git remote set-url origin "one$i:user/repo.git"
run ../git-open
assert_output "https://one.com/user/repo"
done
# Refute invalid match on ?
for str in "" "-test"; do
git remote set-url origin "one:user/repo.git"
run ../git-open
refute_output "https://one$str.com/user/repo"
done
# ? with substitution
for i in $(seq 1 3); do
git remote set-url origin "subone$i:user/repo.git"
run ../git-open
assert_output "https://subone$i.one/user/repo"
done
# Refute invalid match on ? with substitution
for str in "" "-test"; do
git remote set-url origin "subone$str:user/repo.git"
run ../git-open
refute_output "https://subone$str.one/user/repo"
done
# Refute invalid match on ? with substitution
}
@test "sshconfig: overriding host rules" {
create_ssh_sandbox
git remote set-url origin "zero-override:user/repo.git"
run ../git-open
assert_output "https://override.zero.com/user/repo"
}
##
## Bitbucket
##
@test "bitbucket: basic" {
git remote set-url origin "git@bitbucket.org:paulirish/crbug-extension.git"
run ../git-open
assert_output --partial "https://bitbucket.org/paulirish/crbug-extension"
}
@test "bitbucket: tag" {
git remote set-url origin "git@bitbucket.org:paulirish/crbug-extension.git"
git tag mytag
echo a > a
git add a
git commit -m a
git checkout mytag
run ../git-open
assert_output "https://bitbucket.org/paulirish/crbug-extension/src/mytag"
}
@test "bitbucket: non-origin remote" {
# https://github.com/paulirish/git-open/pull/4
git remote add bbclone "git@bitbucket.org:rwhitbeck/git-open.git"
run ../git-open "bbclone"
assert_output "https://bitbucket.org/rwhitbeck/git-open"
}
@test "bitbucket: open source view" {
# https://github.com/paulirish/git-open/pull/26
git remote set-url origin "https://bitbucket.org/kisom/consbri.git"
git checkout -B "devel"
run ../git-open
refute_output --partial "//kisom"
assert_output "https://bitbucket.org/kisom/consbri/src/devel"
}
@test "bitbucket: open source view with a slash/branch" {
# https://github.com/paulirish/git-open/pull/26
# see https://github.com/paulirish/git-open/issues/80 for feat/branchname issues
git remote set-url origin "https://bitbucket.org/guyzmo/git-repo.git"
git checkout -B "bugfix/conftest_fix"
run ../git-open
assert_output "https://bitbucket.org/guyzmo/git-repo/src/bugfix/conftest_fix"
}
@test "bitbucket: ssh:// clone urls" {
# https://github.com/paulirish/git-open/pull/36
git remote set-url origin "ssh://git@bitbucket.org/lbesson/bin.git"
run ../git-open
assert_output "https://bitbucket.org/lbesson/bin"
}
@test "bitbucket: no username@ in final url" {
# https://github.com/paulirish/git-open/pull/69
git remote set-url origin "https://trend_rand@bitbucket.org/trend_rand/test-repo.git"
run ../git-open
refute_output --partial "@"
}
@test "bitbucket: Bitbucket Server" {
# https://github.com/paulirish/git-open/issues/77#issuecomment-309044010
git remote set-url origin "https://user@mybb.domain.com/scm/ppp/rrr.git"
run ../git-open
# any of the following are acceptable
assert_output "https://mybb.domain.com/projects/ppp/repos/rrr" ||
assert_output "https://mybb.domain.com/projects/ppp/repos/rrr/browse/?at=master" ||
assert_output "https://mybb.domain.com/projects/ppp/repos/rrr/browse/?at=refs%2Fheads%2Fmaster"
}
@test "bitbucket: Bitbucket Server branch" {
# https://github.com/paulirish/git-open/issues/80
git remote set-url origin "https://user@mybb.domain.com/scm/ppp/rrr.git"
git checkout -B "develop"
run ../git-open
# The following query args work with BB Server:
# at=refs%2Fheads%2Fdevelop, at=develop, at=refs/heads/develop
# However /src/develop does not (unlike bitbucket.org)
assert_output "https://mybb.domain.com/projects/ppp/repos/rrr/browse?at=develop" ||
assert_output "https://mybb.domain.com/projects/ppp/repos/rrr/browse?at=refs%2Fheads%2Fdevelop" ||
assert_output "https://mybb.domain.com/projects/ppp/repos/rrr/browse?at=refs/heads/develop"
refute_output --partial "/src/develop"
}
@test "bitbucket: Bitbucket Server private user repos" {
# https://github.com/paulirish/git-open/pull/83#issuecomment-309968538
git remote set-url origin "https://mybb.domain.com/scm/~first.last/rrr.git"
git checkout -B "develop"
run ../git-open
assert_output "https://mybb.domain.com/projects/~first.last/repos/rrr/browse?at=develop" ||
assert_output "https://mybb.domain.com/projects/~first.last/repos/rrr/browse?at=refs%2Fheads%2Fdevelop" ||
assert_output "https://mybb.domain.com/projects/~first.last/repos/rrr/browse?at=refs/heads/develop"
}
@test "bitbucket: Bitbucket Server with different root context" {
# https://github.com/paulirish/git-open/pull/15
git remote set-url origin "https://user@bitbucket.example.com/git/scm/ppp/test-repo.git"
run ../git-open
assert_output "https://bitbucket.example.com/git/projects/ppp/repos/test-repo" ||
assert_output "https://bitbucket.example.com/git/projects/ppp/repos/test-repo/?at=master" ||
assert_output "https://bitbucket.example.com/git/projects/ppp/repos/test-repo/?at=refs%2Fheads%2Fmaster"
}
@test "bitbucket: Bitbucket Server with different root context with multiple parts" {
# https://github.com/paulirish/git-open/pull/15
git remote set-url origin "https://user@bitbucket.example.com/really/long/root/context/scm/ppp/test-repo.git"
run ../git-open
assert_output "https://bitbucket.example.com/really/long/root/context/projects/ppp/repos/test-repo" ||
assert_output "https://bitbucket.example.com/really/long/root/context/projects/ppp/repos/test-repo/?at=master" ||
assert_output "https://bitbucket.example.com/really/long/root/context/projects/ppp/repos/test-repo/?at=refs%2Fheads%2Fmaster"
}
@test "bitbucket: Bitbucket Server private user repos with different root context" {
# https://github.com/paulirish/git-open/pull/83#issuecomment-309968538
git remote set-url origin "https://mybb.domain.com/root/context/scm/~first.last/rrr.git"
git checkout -B "develop"
run ../git-open
assert_output "https://mybb.domain.com/root/context/projects/~first.last/repos/rrr/browse?at=develop" ||
assert_output "https://mybb.domain.com/root/context/projects/~first.last/repos/rrr/browse?at=refs%2Fheads%2Fdevelop" ||
assert_output "https://mybb.domain.com/root/context/projects/~first.last/repos/rrr/browse?at=refs/heads/develop"
}
@test "bitbucket: Selfhosted Bitbucket Server with ssh:// clone urls" {
# https://github.com/paulirish/git-open/pull/174
git remote set-url origin "ssh://git@bitbucket.domain.com/ppp/rrr.git"
run ../git-open
assert_output "https://bitbucket.domain.com/projects/ppp/repos/rrr"
}
##
## GitLab
##
@test "gitlab: default ssh origin style" {
# https://github.com/paulirish/git-open/pull/55
git remote set-url origin "git@gitlab.example.com:user/repo"
run ../git-open
assert_output "https://gitlab.example.com/user/repo"
}
@test "gitlab: ssh://git@ origin" {
# https://github.com/paulirish/git-open/pull/51
git remote set-url origin "ssh://git@gitlab.domain.com/user/repo"
run ../git-open
assert_output "https://gitlab.domain.com/user/repo"
refute_output --partial "//user"
}
@test "gitlab: separate domains" {
# https://github.com/paulirish/git-open/pull/56
git remote set-url origin "git@git.example.com:namespace/project.git"
git config --local --add "open.https://git.example.com.domain" "gitlab.example.com"
run ../git-open
assert_output "https://gitlab.example.com/namespace/project"
}
@test "gitlab: special domain and path" {
git remote set-url origin "ssh://git@git.example.com:7000/XXX/YYY.git"
git config --local --add "open.https://git.example.com.domain" "repo.intranet/subpath"
git config --local --add "open.https://git.example.com.protocol" "http"
run ../git-open
assert_output "http://repo.intranet/subpath/XXX/YYY"
refute_output --partial "https://"
}
@test "gitlab: different port" {
# https://github.com/paulirish/git-open/pull/76
git remote set-url origin "ssh://git@git.example.com:7000/XXX/YYY.git"
run ../git-open
assert_output "https://git.example.com/XXX/YYY"
refute_output --partial ":7000"
git remote set-url origin "https://git.example.com:7000/XXX/YYY.git"
run ../git-open
assert_output "https://git.example.com:7000/XXX/YYY"
}
@test "gitlab: issue" {
git remote set-url origin "git@gitlab.example.com:user/repo"
git checkout -B "10-bump-up-to-v2.0"
run ../git-open "--issue"
assert_output "https://gitlab.example.com/user/repo/issues/10"
}
##
## Visual Studio Team Services
##
@test "vsts: https url" {
git remote set-url origin "https://gitopen.visualstudio.com/Project/_git/Repository"
run ../git-open
assert_output --partial "https://gitopen.visualstudio.com/Project/_git/Repository"
}
@test "vsts: ssh url" {
git remote add vsts_ssh "ssh://gitopen@gitopen.visualstudio.com:22/Project/_git/Repository"
run ../git-open "vsts_ssh"
assert_output "https://gitopen.visualstudio.com/Project/_git/Repository"
}
@test "vsts: on-premises tfs http url" {
git remote set-url origin "http://tfs.example.com:8080/Project/_git/Repository"
run ../git-open
assert_output --partial "http://tfs.example.com:8080/Project/_git/Repository"
}
@test "vsts: branch" {
git remote set-url origin "ssh://gitopen@gitopen.visualstudio.com:22/_git/Repository"
git checkout -B "mybranch"
run ../git-open
assert_output "https://gitopen.visualstudio.com/_git/Repository?version=GBmybranch"
}
@test "vsts: on-premises tfs branch" {
git remote set-url origin "http://tfs.example.com:8080/Project/Folder/_git/Repository"
git checkout -B "mybranch"
run ../git-open
assert_output "http://tfs.example.com:8080/Project/Folder/_git/Repository?version=GBmybranch"
}
@test "vsts: issue" {
git remote set-url origin "http://tfs.example.com:8080/Project/Folder/_git/Repository"
git checkout -B "bugfix-36"
run ../git-open "--issue"
assert_output "http://tfs.example.com:8080/Project/Folder/_workitems?id=36"
}
@test "vsts: default project repository - issue" {
git remote set-url origin "https://gitopen.visualstudio.com/_git/Project"
git checkout -B "bugfix-36"
run ../git-open "--issue"
assert_output "https://gitopen.visualstudio.com/Project/_workitems?id=36"
}
##
## AWS Code Commit
##
@test "aws: https url" {
git remote set-url origin "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo"
git checkout -B "master"
run ../git-open
assert_output "https://us-east-1.console.aws.amazon.com/codecommit/home?region=us-east-1#/repository/repo/browse/"
}
@test "aws: ssh url" {
git remote set-url origin "ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo"
git checkout -B "master"
run ../git-open
assert_output "https://us-east-1.console.aws.amazon.com/codecommit/home?region=us-east-1#/repository/repo/browse/"
}
@test "aws: branch " {
git remote set-url origin "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo"
git checkout -B "mybranch"
run ../git-open
assert_output "https://us-east-1.console.aws.amazon.com/codecommit/home?region=us-east-1#/repository/repo/browse/mybranch/--/"
}
@test "aws: issue" {
git remote set-url origin "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo"
git checkout -B "issues/#12"
run ../git-open "--issue"
[ "$status" -eq 1 ]
assert_output "Issue feature does not supported on AWS Code Commit."
}
##
## cnb.cool
##
@test "cnb: https url" {
git remote set-url origin "https://cnb.cool/repos/repo"
git checkout -B "master"
run ../git-open
assert_output "https://cnb.cool/repos/repo/-/tree/master"
}
@test "cnb: branch " {
git remote set-url origin "https://cnb.cool/repos/repo"
git checkout -B "mybranch"
run ../git-open
assert_output "https://cnb.cool/repos/repo/-/tree/mybranch"
}
@test "cnb: issue" {
git remote set-url origin "https://cnb.cool/repos/repo"
git checkout -B "issues/10"
run ../git-open "--issue"
assert_output "https://cnb.cool/repos/repo/-/issues/10"
}
teardown() {
cd ..
rm -rf "$foldername"
rm -rf "$ssh_config"
refute [ -e "$ssh_config" ]
unset ssh_config
}
# helper to create a test git sandbox that won't dirty the real repo
function create_git_sandbox() {
rm -rf "$foldername"
mkdir "$foldername"
cd "$foldername"
# safety check. Don't muck with the git repo if we're not inside the sandbox.
assert_equal $(basename $PWD) "$foldername"
git init -q
assert [ -e "../$foldername/.git" ]
git config user.email "test@runner.com" && git config user.name "Test Runner"
# newer git auto-creates the origin remote
if ! git remote add origin "github.com:paulirish/git-open.git"; then
git remote set-url origin "github.com:paulirish/git-open.git"
fi
git checkout -B "master"
echo "ok" > readme.txt
git add readme.txt
git commit -m "add file" -q
}
# helper to create test SSH config file
function create_ssh_sandbox() {
export ssh_config=$(mktemp)
refute [ -z "$ssh_config" ]
# Populate ssh config with test data
echo "$ssh_testdata" >$ssh_config
assert [ -e "$ssh_config" ]
}
# Test SSH config data
ssh_testdata="
# Autogenerated test sshconfig for paulirish/git-open BATS tests
# It is safe to delete this file, a new one will be generated each test
Host basic
HostName basic.com
User git
Host nomatch
User git
Host nouser
HostName no.user
host malformed
hOsTnAmE MaL.FoRmEd
User other
# Multiple targets
Host multi1 multi2 multi3
HostName multi.com
User git
Host sub1 sub2 sub3
HostName %h.multi.com
User git
# Wildcard * matching (zero or more characters)
Host zero*
HostName zero.com
User git
Host subzero*
HostName %h.zero
User git
# Wildcard ? matching (exactly one character)
Host one?
HostName one.com
User git
Host subone?
HostName %h.one
User git
# Overrides rule zero*
Host zero-override
HostName override.zero.com
User git
"

@ -1 +0,0 @@
Subproject commit 9f88b4207da750093baabc4e3f41bf68f0dd3630

@ -1 +0,0 @@
Subproject commit 004e707638eedd62e0481e8cdc9223ad471f12ee