Repository Discovery and Server Switching¶
Why this matters¶
When you run bb inside a local git repository, the CLI can infer PROJECT/slug and host
from matching remotes. This reduces repeated --repo flags while still keeping behavior explicit.
Repository discovery behavior¶
Discovery runs only when a command has a --repo flag and you did not set it.
bb inspects git remotes and tries to parse Bitbucket-style URLs such as:
https://bitbucket.acme.corp/scm/PLAT/payments-api.gitssh://git@bitbucket.acme.corp:7999/scm/PLAT/payments-api.gitgit@bitbucket.acme.corp:scm/PLAT/payments-api.git
If a remote endpoint matches an authenticated/stored server context or one of its aliases, bb infers:
BITBUCKET_URLBITBUCKET_PROJECT_KEYBITBUCKET_REPO_SLUG- and sets the effective
--repovalue toPROJECT/slug
Human mode emits a banner on stderr:
Using repository context from git remote "origin": PLAT/payments-api on https://bitbucket.acme.corp
JSON mode suppresses that banner to preserve machine output contracts on stdout.
bb ai mcp serve is the one command that never inherits discovery. Its --repo and --project are confinement flags (see ADR-062), so the server is scoped only when the flags are passed explicitly — never by the repository of the directory it starts in.
Precedence and safety¶
Repository selection precedence for repo-scoped commands:
- Explicit
--repo(acceptsPROJECT/slug, personal repos~username/slug, or full Bitbucket URLs likehttps://bitbucket.acme.corp/projects/PROJECT/repos/slugandssh://...) - Git remote discovery (if exactly one matching remote context exists)
BITBUCKET_PROJECT_KEY+BITBUCKET_REPO_SLUG
Host and auth source precedence remains:
- CLI flags
- Environment variables /
.env - Git remote inference host override (when
--repois inferred from a matching authenticated remote) - Stored config (
~/.config/bb/config.yaml) + keyring-backed credentials - Built-in defaults
Ambiguity and fallback behavior¶
- If several remotes map to different repositories and one of them is
origin,originwins. A fork or a mirror alongsideoriginis ordinary —bb pr checkoutadds one itself — and git's own convention is thatoriginis the repository the clone belongs to. - An
upstreamremote is the exception. It conventionally outranksorigin, so a repository with both is genuinely ambiguous: discovery fails with a validation error and asks you to pass--repoand/or choose a server. - If several remotes map to different repositories and none is
origin, discovery fails the same way. - If you are outside a git repository, discovery is skipped.
- If remotes do not match authenticated server hosts, discovery is skipped.
Host aliases¶
Many Bitbucket instances use different endpoints for browser/API access and git clone traffic. For example:
- canonical Bitbucket URL:
https://bitbucket.acme.corp - SSH clone host:
git.acme.corp:7999
bb stores one canonical server context and can attach one or more aliases to it. Alias matching is
endpoint-aware and normalizes values as host:port.
Examples:
https://bitbucket.acme.corp->bitbucket.acme.corp:443http://bitbucket.acme.corp->bitbucket.acme.corp:80ssh://git@git.acme.corp:7999/scm/PLAT/payments-api.git->git.acme.corp:7999git@git.acme.corp:scm/PLAT/payments-api.git->git.acme.corp:22
Manual alias management:
bb auth alias list --host https://bitbucket.acme.corp
bb auth alias add --host https://bitbucket.acme.corp git.acme.corp:7999
bb auth alias remove --host https://bitbucket.acme.corp git.acme.corp:7999
Automatic alias discovery:
printf '%s' "$BITBUCKET_TOKEN" | bb auth login https://bitbucket.acme.corp --token-stdin
bb auth alias discover --host https://bitbucket.acme.corp
Discovery is best-effort. It requests only a small repository page and stops at the first accessible repository that exposes clone links. Login still succeeds when discovery finds no aliases.
Discovery adds to the aliases already stored; it never removes one. That matters because
discovery cannot find every alias — an instance whose SSH clone host differs from its web URL is
exactly the case for adding one by hand, and it would otherwise be undone by the next discovery run,
or by the next bb auth login. Re-authenticating keeps stored aliases for the same reason.
To store only what discovery finds, ask for it explicitly. Anything dropped is named in the output:
bb auth alias discover --host https://bitbucket.acme.corp --replace
Server switching workflow¶
Use server contexts to control which host is active by default:
bb auth server list
bb auth server use --host https://bitbucket.acme.corp
bb auth status
Expected human output:
Active server set to https://bitbucket.acme.corp
Target Bitbucket: https://bitbucket.acme.corp (expected version 10.4.3, auth=token, source=stored)
Expected JSON output (example):
{
"data": {
"defaultHost": "https://bitbucket.acme.corp"
},
"meta": {
"bbVersion": "v4.1.0"
}
}
Two identities on one host¶
Stored credentials belong to the configuration file they were stored with. To keep two
identities for one Bitbucket host — a personal account and a service account, say — give
each its own file through BB_CONFIG_PATH:
export BB_CONFIG_PATH="$HOME/.config/bb/service-account.yaml"
printf '%s' "$SERVICE_TOKEN" | bb auth login https://bitbucket.acme.corp --token-stdin
bb auth status
A login is found only through the path it was made with, so after moving or renaming a configuration file, log in again from its new location.
Recommended team pattern¶
- Keep one stored context per server (
bb auth login <host>). - Let
bb auth loginauto-discover clone-host aliases when possible. - Add explicit aliases for non-default SSH endpoints when discovery does not surface them.
- Switch active context with
bb auth server use --host ...before running automation. - Still pass
--repoin CI for maximal explicitness.