Fix Bitbucket branch and commit URLs

Bitbucket Cloud needs different paths than the shared defaults:

- Commits live at /commits/<sha>, not /commit/<sha> (the singular 404s).
- /src/<ref> 404s when the branch name contains a slash (e.g.
  release/9.12.x), because Bitbucket reads the first path segment as the
  ref. Browse via /src/HEAD/?at=<ref> with the slash percent-encoded;
  plain refs keep the simpler /src/<ref>.

Both changes are scoped to bitbucket.org, so GitHub, CodeCommit, and
Bitbucket Server are unaffected. Adds bats coverage for the commit URL
and the slash-branch source view.
This commit is contained in:
Max Kostovetski 2026-09-03 18:55:03 -07:00
parent 63c0e77aaf
commit 7b347954bf
2 changed files with 23 additions and 4 deletions

View file

@ -199,7 +199,14 @@ else
fi fi
if [[ "$domain" == 'bitbucket.org' ]]; then if [[ "$domain" == 'bitbucket.org' ]]; then
providerBranchRef="/src/$remote_ref" # Bitbucket Cloud 404s on /src/<ref> when the branch name contains a slash: it reads the
# first path segment as the ref. Browse via HEAD and pass the real branch through ?at=
# (slashes percent-encoded); plain refs keep the simpler /src/<ref>.
if [[ "$remote_ref" == */* && -n "$branch" ]]; then
providerBranchRef="/src/HEAD/?at=${remote_ref//\//%2F}"
else
providerBranchRef="/src/$remote_ref"
fi
elif [[ "${#pathargs[@]}" -ge 3 && ${pathargs[${#pathargs[@]} - 3]} == 'scm' ]]; then 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 # 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 # Anything before the 'scm' is part of the server's root context
@ -269,7 +276,11 @@ openurl="$protocol://$domain/$urlpath"
if (( is_commit )); then if (( is_commit )); then
sha=$(git rev-parse HEAD) sha=$(git rev-parse HEAD)
openurl="$openurl/commit/$sha" if [[ "$domain" == 'bitbucket.org' ]]; then
openurl="$openurl/commits/$sha"
else
openurl="$openurl/commit/$sha"
fi
elif [[ $remote_ref != "master" || "$file" ]]; then elif [[ $remote_ref != "master" || "$file" ]]; then
# simplify URL for master # simplify URL for master
openurl="$openurl$providerBranchRef" openurl="$openurl$providerBranchRef"

View file

@ -385,6 +385,13 @@ setup() {
assert_output "https://bitbucket.org/paulirish/crbug-extension/src/mytag" assert_output "https://bitbucket.org/paulirish/crbug-extension/src/mytag"
} }
@test "bitbucket: commit" {
git remote set-url origin "git@bitbucket.org:paulirish/crbug-extension.git"
sha=$(git rev-parse HEAD)
run ../git-open "--commit"
assert_output "https://bitbucket.org/paulirish/crbug-extension/commits/${sha}"
}
@test "bitbucket: non-origin remote" { @test "bitbucket: non-origin remote" {
# https://github.com/paulirish/git-open/pull/4 # https://github.com/paulirish/git-open/pull/4
git remote add bbclone "git@bitbucket.org:rwhitbeck/git-open.git" git remote add bbclone "git@bitbucket.org:rwhitbeck/git-open.git"
@ -401,13 +408,14 @@ setup() {
assert_output "https://bitbucket.org/kisom/consbri/src/devel" assert_output "https://bitbucket.org/kisom/consbri/src/devel"
} }
@test "bitbucket: open source view with a slash/branch" { @test "bitbucket: slash branch source view via ?at=" {
# https://github.com/paulirish/git-open/pull/26 # https://github.com/paulirish/git-open/pull/26
# see https://github.com/paulirish/git-open/issues/80 for feat/branchname issues # see https://github.com/paulirish/git-open/issues/80 for feat/branchname issues
# /src/bugfix/conftest_fix 404s (Bitbucket reads 'bugfix' as the ref), so browse HEAD?at=<branch>
git remote set-url origin "https://bitbucket.org/guyzmo/git-repo.git" git remote set-url origin "https://bitbucket.org/guyzmo/git-repo.git"
git checkout -B "bugfix/conftest_fix" git checkout -B "bugfix/conftest_fix"
run ../git-open run ../git-open
assert_output "https://bitbucket.org/guyzmo/git-repo/src/bugfix/conftest_fix" assert_output "https://bitbucket.org/guyzmo/git-repo/src/HEAD/?at=bugfix%2Fconftest_fix"
} }
@test "bitbucket: ssh:// clone urls" { @test "bitbucket: ssh:// clone urls" {