Repository navigation
v5.0.0
v5.0.0
bb v5.0.0 works with every Bitbucket Data Center release Atlassian supports, completes what you type from your own Bitbucket, and makes its MCP server something you work with: it asks you before it merges, takes the pull request or file you hand it, and shows what it found as a view in your client.
It is a major release. Seven changes can break a script, a pipeline or an MCP configuration. They are under "Before you upgrade", each with what to change, and are the part to read first if bb runs in CI, in scripts or under an AI agent. What is deprecated keeps working until v6.0.0 and is listed at the end.
New at the command line
-
Every Bitbucket Data Center release Atlassian supports (ADR-088, #307):
bb was built against the newest Bitbucket release and tested against that one alone. It now works with every release Atlassian supports, each tested against a real instance of it, and a release keeps working after Atlassian's support for it ends.
An older release behaves like the newest except where it lacks something a later one added. There bb answers as the newest release would where it can, and otherwise refuses before it sends anything, naming the release that can do it:
$ bb branch restriction create --repo PROJ/app --type no-creates --matcher-id refs/heads/main unsupported: a no-creates branch restriction is not supported by this Bitbucket version (9.2.1); it needs 9.4.0 or laterBefore, Bitbucket accepted such a request and dropped the part it did not know, so a required build meant to spare pull requests blocked every one of them.
unsupported, exit14, is a new error kind: a script that lists the kinds or exit codes it handles gains one. Bitbucket Versions lists the four places where a release differs. -
Tab completion that knows your Bitbucket (ADR-089, #407, #397):
Press tab after
bb pr mergeand bb lists the open pull requests of the repository you are in, by number and title. Afterbb branch deleteit lists the branches, each with its latest commit message. Projects, repositories, tags, reviewers, file paths and the values a flag accepts complete the same way, read from your Bitbucket with your own credentials, in bash, zsh, fish and PowerShell.Homebrew and the
.deband.rpmpackages set it up for bash, zsh and fish when they install bb, and Scoop sets it up for PowerShell, along with the agent skill. Anywhere else one command does it, andbb doctorsays whether it is in place:bb completion install
-
bb pr createneeds no flags in a checkout, andbb pr mergetakes a strategy (ADR-102, #705):Standing on a pushed branch,
bb pr createis enough. The source is the branch that is checked out, the target is the repository's default branch, and the title is the commit's subject when the branch holds exactly one commit. At a terminal each is offered for you to accept or change. With nobody to ask they are used as they are and named on stderr, and a branch that holds several commits still needs--title. It prints the pull request's link, which every reported pull request now carries asurl.git push -u origin feature/refunds bb pr create bb pr merge 42 --strategy squash
--strategytakes any strategy the repository enables, and its default applies without it.--dry-runsays so first when the repository has not enabled the one asked for. -
bb search prstakes a period, so it can answer "what did I work on" (#697):What it lists has not changed. Without
--repothat is every pull request you are involved in across every repository, whether you wrote it, are a reviewer on it or took part in it, and--rolepicks one of the three. What is new is the period:--sinceand--untilbound the listing on the created, updated or closed date that--date-fieldnames, and--group-by weekorrepoarranges the text output. With--sincethe listing holds the whole period rather than the first 25.bb search prs --role author --state all --since 2026-07-20 --until 2026-09-27 --group-by week
-
--statetakesmergedanddeclined, inbb pr listtoo, andallandclosedno longer fail across repositories. -
A pull request reports
closedDateonce it is merged or declined, and the issue keys its title and source branch mention:{ "data": { "pullRequests": [ { "id": 6, "title": "PAY-12: retry a declined refund", "state": "MERGED", "open": false, "closed": true, "repository": { "projectKey": "PAY", "slug": "ledger" }, "sourceRepository": { "projectKey": "PAY", "slug": "ledger" }, "version": 2, "author": "Administrator", "authorUsername": "admin", "sourceBranch": "feature/refunds", "targetBranch": "master", "sourceCommit": "6b9cb2216ad56a58f976325627a2d87ad41d6a2a", "createdDate": 1790758330929, "updatedDate": 1790758331777, "closedDate": 1790758331777, "url": "https://bitbucket.example.com/projects/PAY/repos/ledger/pull-requests/6", "issueKeys": ["PAY-12"], "commentCount": 0, "openTaskCount": 0, "resolvedTaskCount": 0 } ] }, "meta": { "command": "search prs", "limitReached": true, "bbVersion": "..." } }
-
-
bb branch list --detailsprints the details. It lists what Bitbucket's branch page shows beside each branch: how far it is ahead of and behind the default branch, its last commit, its builds and its pull requests.--basemeasures against another branch, tag or commit, and asks for the details by itself. Both flags used to be accepted and change nothing.$ bb branch list --repo PAY/ledger --details feature/refunds refs/heads/feature/refunds 6b9cb2216ad56a58f976325627a2d87ad41d6a2a default=false ahead=2 behind=1 2026-09-28 alice pr=#42 OPEN builds=1 successful, 1 failed master refs/heads/master 0d4e1c7a9b3f52e86a1d7c40b9e2f35a6c8d1e07 default=true 2026-09-27 bobUnder
--jsoneach branch gainsahead,behind,lastCommit,buildsandpullRequests, each left out when Bitbucket has nothing to report: the base has no counts, and a branch nobody built has nobuilds. Bitbucket names the pull request when a branch has exactly one, asonly, and gives the counts alone when it has more:{ "data": { "repository": { "projectKey": "PAY", "slug": "ledger" }, "branches": [ { "id": "refs/heads/feature/refunds", "displayId": "feature/refunds", "latestCommit": "6b9cb2216ad56a58f976325627a2d87ad41d6a2a", "default": false, "ahead": 2, "behind": 1, "lastCommit": { "id": "6b9cb2216ad56a58f976325627a2d87ad41d6a2a", "displayId": "6b9cb2216ad", "message": "PAY-12: retry a declined refund", "author": { "name": "alice", "emailAddress": "alice@example.com" }, "authorTimestamp": 1790586000000, "committer": { "name": "alice", "emailAddress": "alice@example.com" }, "committerTimestamp": 1790586000000, "parents": ["0d4e1c7a9b3f52e86a1d7c40b9e2f35a6c8d1e07"] }, "builds": { "successful": 1, "failed": 1, "inProgress": 0, "unknown": 0, "cancelled": 0 }, "pullRequests": { "open": 1, "merged": 0, "declined": 0, "only": { "id": 42, "title": "PAY-12: retry a declined refund", "state": "OPEN" } } } ] }, "meta": { "command": "branch list", "limitReached": false, "bbVersion": "..." } } -
Every command that takes
--jsontakes--yaml, and prints the same document as YAML, for a pipeline that keeps its data in YAML or for reading a long answer at a terminal.--dry-runand--describefollow it too.bb --yaml branch list --repo PAY/ledger --filter develop:data: repository: projectKey: PAY slug: ledger branches: - id: refs/heads/develop displayId: develop latestCommit: f62bfb84cba2a12ef7f2437dfc8c084ac61c489d default: false meta: command: branch list limitReached: false bbVersion: "..."
-
Examples in every
--help, and a reference page per command (#604, #701):The help of every command ends with examples to copy, showing the values a flag's description leaves you to guess. The command reference on the site has a page per command in place of one long page, with each flag under the command it comes from.
New in the MCP server
The server also asks you before a tool merges, or decides what merges. That changes an existing setup, so it is under "Before you upgrade".
-
Put a pull request, a diff or a file in front of the AI yourself (ADR-099, #685):
Until now the AI only saw what it went and fetched through bb's tools, so you had to hope it found the right pull request or file. Now you can hand it Bitbucket content yourself, the way you attach a file to a message: the pull request you are reviewing, its diff or its open comments, a file on any branch, tag or commit, or a single commit. Your MCP client helps you find it, suggesting projects, repositories, pull requests, paths and branches as you type, and it lists your own open pull requests and the ones waiting on your review, so the one you want is usually a click away.
In VS Code, for example, choose Add Context > MCP Resources, pick the diff of pull request 42 in PAYMENTS/ledger, and ask what could break. Or type
/bitbucket.review_pull_requestto attach a pull request with its diff and open comments and ask for a review in one step. It works the same in any MCP client, including chat apps without a terminal, and everything still goes through bb, with its token, its--projectand--reposcope and its audit trail. Your client never talks to Bitbucket itself. -
See a pull request, a list or a diff as a view in your MCP client (ADR-101, #686):
In clients that render MCP Apps, such as Claude Desktop, VS Code and Goose, the AI can now put what it found in front of you instead of describing it: a pull request with its reviewers' avatars and decisions, its builds and the ones its target branch requires, open tasks, its formatted description and its activity, comments included; a list of pull requests; or its diff, a file at a time, highlighted, with each comment on its line. It looks and reads like Bitbucket, and anything you click opens there.
Ask for PAYMENTS/ledger#42 and the answer comes with its card; open the card for the full overview and its activity, or its diff. In the diff, select lines to add them to the chat, to ask about them or to comment on them; reply to a comment, and approve or request changes, without leaving the conversation. Ask the AI to open a pull request and it opens it; when you want a say in its description or reviewers first, it hands you its draft as a form to finish and submit, with the default reviewers and code owners filled in as Bitbucket's create page does. A view carries what it shows, so it still renders when you come back to the conversation, even without bb running, and it says when it was read. While it is on screen it keeps itself current: watch a build finish or a comment arrive without asking again, and the AI is told what changed. Terminal agents such as Claude Code show the usual text.


Views in your agent shows all five: the card, the overview with its activity, a list, the diff and the form.
-
Files reach the AI in a format it can ingest (ADR-094):
get_file_contentpassed every file as one string, whatever its size, and a file that is not text as unreadable characters. It now converts the file on the server: text as a window of numbered lines, so a long file is read a part at a time; an image as an image; a Word, PowerPoint or Excel file as its text; an archive as a list of its entries. Anything else is described by its type and size, with its page in Bitbucket. This is the MCP server's tool;bb repo catstill prints a file as it is.
For administrators
-
Administrators decide whether bb, or its MCP server, may be used at all (ADR-100, #690):
Three new system policy settings, which no flag, environment variable or user configuration overrides:
Setting Registry value Effect disable_mcp_serverDisableMCPServerbb ai mcp serveis refused; the rest of bb keeps working.read_onlyReadOnlyCommands that change Bitbucket are refused, bb apisends onlyGETandHEAD, and the MCP server offers only the tools that read.disable_bbDisableBBEvery command is refused except help, --describe,--version,bb doctorand the completion scripts.Set them in
/etc/bb/config.yaml, or%ProgramData%\bb\config.yamlon Windows:policy: read_only: true
Or through Group Policy, as the registry value set to
1underHKLM\Software\Policies\bb. -
Running and auditing the MCP server (ADR-098, ADR-099, ADR-101):
-
A tool that asks records the answer: the audit record has
confirmation(accepted,declined,cancelledorunavailable), and a call the confirmation stops isstatus: denied. The question is a record of its own,status: asked, written before the person answers, so an agent that asks and never answers still leaves a trace. -
The audit trail redacts credentials wherever they appear in an argument or a resource URI (#731). An argument was redacted only when its name marked it secret or its whole value was a URL, and the
resourcefield not at all, so a credential inside a path, a ref or a title was written to the audit file. Both now get the redactionerror_messagegets, which also catchestoken=...as Bitbucket quotes it back andBITBUCKET_TOKEN=.... A redacted URL reads[REDACTED]rather than%5BREDACTED%5D. -
--toolsand--excludedecide which resources and prompts are offered, as they decide the tools. The audit trail records reads, the resource list and prompts asmcp_resource_read,mcp_resource_listandmcp_prompt_get, withresourceorpromptin place oftool; completions are not recorded. A SIEM rule that expects every record to name a tool needs to allow for them:{"timestamp":"2026-08-29T09:32:40Z","event":"mcp_resource_read","resource":"bitbucket://projects/PAYMENTS/repos/ledger/pull-requests/42/diff","project":"PAYMENTS","repo":"ledger","status":"success","duration_ms":61,"user_identity":"alice","host":"https://bitbucket.example.com","scope":"PAYMENTS"} -
A view has no network access; bb fetches the avatars with its own credentials and puts them in the result.
--exclude showturns views off. A view keeps current by callingrefresh_view, and the form suggests values throughsuggest_form_values: read-only tools only views are offered, each call recorded in the audit log like any other;--exclude refresh_viewkeeps views as they were drawn. What you do in a view goes through the AI's own tools, with their confirmations, and a view has no connection of its own to Bitbucket. The server tells agents to show views only to a person who is there, never in unattended work. Of Svelte, ERB, PHTML, Go HTML and Jinja templates only the markup is highlighted;--highlight-templateshighlights the code in them too, with lexers a crafted file can keep busy for seconds, though no view waits for them. -
For MCP clients: every tool declares all four MCP hints and a title as the specification defines them, so a client that decides its own prompts from the hints may prompt for different tools.
openWorldHintis false on every tool, andupdate_pull_requestanddisable_auto_mergeare destructive.bb ai mcp toolshasasks(always,neverorwhen-setting-draft) and takes--read-only.bb ai mcp tools --jsonfor one tool:{ "name": "merge_pull_request", "description": "Merge a pull request. All required build checks must pass and all reviewers must have approved. Asks the person to confirm in the client before it runs.", "writes": true, "asks": "always", "safe": true, "exposure": "SAFE" }
-
-
bb updateon premises (ADR-092, #637, #633):bb updateinstalls the new binary itself before it exits, on every operating system. On Windows it used to leave the swap to a PowerShell helper that ran after bb had exited. Application control such as AppLocker or WDAC blocked the helper, and bb had already reported success.Behind a release mirror, every download now goes through the mirror, with the CA and the client certificate it was configured with, and a mirror whose certificate this host does not trust is reported as a failure to fix, no longer as one to retry.
bb update --dry-runverifies the release the mirror serves, its signature, its checksums and the archive itself, also when nothing newer is there. That makes it the check to run on a host after a rollout. A slow link no longer fails the download at the request timeout. -
Requests name bb (#702). Every request carries
User-Agent: bb/<version> (<os>/<arch>), ending inmcpwhen the MCP server sends it, so an administrator can find bb's traffic, and an agent's, in Bitbucket's access log or at a proxy.
Before you upgrade
If you consume bb inside CI/CD pipelines, shell scripts, or AI agent toolchains, review this checklist before upgrading:
bb pr checksgates on CI the waygh pr checksdoes (ADR-091, #646):- Without
--json,bb pr checksandbb pr build statusexit1when a build failed, and8when none failed and one is still in progress or has no result. They used to exit0whatever the builds said, so a gate written forgh,bb pr checks 42 || exit 1, let every pull request through. - A failed build wins over one still running, and a cancelled build counts as neither. The exit status covers every build, not only the
--limitshown. When it is not0, a line on stderr says how many builds failed or are still running. - Exit
8is new tobb. It is not an error kind, and only these two commands use it. - Under
--jsonboth commands still exit0, with each build's state indata.statuses, asgh pr checks --jsondoes. - A script that runs either command for its output and relies on exit
0adds|| true, or passes--json.
- Without
bb bulkis gone, as the v4.1.0 notes announced (ADR-084, #608):bb bulk plan,bb bulk applyandbb bulk statusno longer exist, nor doBB_BULK_STATUS_DIRand the bulk policy, plan and apply-status schemas.- Set permissions, webhooks, default tasks and branch restrictions once on the project, with
bb project permissions,bb project webhook,bb project default-taskandbb project branch-restriction. Bitbucket applies them to every repository in the project. - For a setting Bitbucket keeps per repository, loop over
bb repo list --project PROJ --jsonand run thebb repo settingscommand for each, previewing with--dry-run. The loop is safe to run again: a webhook create that finds its webhook already there reports it rather than adding a second. - The bb-bulk agent skill is gone too, so
bb ai skill install bulkexits2. Delete any copy an earlier bb installed, in.agents/skills/bb-bulkor.claude/skills/bb-bulk, in a project or in your home directory.bb doctornames every copy it finds.
--dry-runanswers with a verdict, in its own member (ADR-096, #616):-
Under
--json, a dry run answers inpreviewrather thandata: atier, one effect per change with itsaction,target,outcome(would-apply,no-oporwould-fail) andreasons, and theerrorthe real run would fail with.dryRun,planningMode,capability,summary, and per itemintent,predictedAction,supported,confidence,requiredStateandblockingReasonsare gone; a script readingsummaryreadseffectsinstead.bb --json pr merge 42 --dry-run, for a pull request that is already merged:{ "preview": { "tier": "preconditions-checked", "effects": [ { "action": "update", "target": { "id": "42", "repository": "PROJ/app" }, "outcome": "would-fail", "reasons": ["pull request is already merged"] } ], "error": { "kind": "conflict", "message": "pull request is already merged", "exitCode": 5 } }, "meta": { "command": "pr merge", "bbVersion": "..." } } -
A command that only reads still runs, and its data is in
preview.data. A failure the check runs into, such as invalid arguments or a missing pull request, ispreview.errorrather than a top-levelerror, which under--dry-runnow means only that no verdict was reached:10Bitbucket did not answer,12interrupted,1a bug in bb. -
Without
--json, a dry run that finds the run would fail exits with the code the real run would, sobb pr merge 42 --dry-run && bb pr merge 42stops at the check. It used to exit0. Under--jsonor--yamla verdict exits0, with the verdict in the document. -
The text output names each change and why it would or would not go through, in place of the
intent=... action=...lines. -
bb ai mcp serveno longer takes--dry-run. -
There is no warning period: one document cannot carry the old preview beside the new one.
-
--describedescribes the whole document, for a run and for a dry run (ADR-097, #616):- Under
--jsonit answers indescriptionrather thandata.run.outputSchemais the JSON Schema of the whole document a run writes, meta and the error included, anddryRun.outputSchemathe one--dry-runwrites, besidedryRun.behaviouranddryRun.tier.describedis gone,commandismeta.commandandreasonisrun.reason. A script readingschemareadsrun.outputSchema.oneOf[0].properties.data, or better, validates the whole document againstrun.outputSchema. - Without
--jsonor--yamlit prints an outline of the fields for people, rather than the JSON Schema. bb <group> --describeandbb --describelist their commands with what--dry-rundoes for each, rather than saying a group has nothing to describe. A path that names no command answers withdescription.error, exiting0under--json.- There is no warning period: one document cannot carry the old description beside the new one.
- Under
- The MCP server asks your permission in your MCP client, and offers every tool by default (ADR-098, #620):
bb ai mcp servemoves to MCP's newer way of asking for permission, elicitation: the server asks, and your MCP client shows you the question. By default it offers every tool, as it did with--yolo, but a tool that merges, or decides what merges or gets released, asks you first. That covers merging, turning auto-merge on or off, approving or requesting changes, reporting a build status, creating a tag, and moving a pull request into or out of draft. Your client shows what the call will do, and it runs only once you accept. Before, the server hid most of these unless it started with--yolo, and then nobody was asked.- Locking the server down is now opt-in: with
--read-onlyit offers only the tools that read.--yoloand--allow-writesdo nothing, and warn. - You accept the pull request you were shown. If someone pushes to it before you accept, the merge or auto-merge is refused.
- Those tools need a client that supports elicitation. One that does not gets error
-32021for them, and nothing changes in Bitbucket. - What changes in the audit record, in the hints a client reads and in
bb ai mcp toolsis under "For administrators".
bb apiauthenticates like every other command (ADR-083, #707):-Hwith anAuthorization,Proxy-AuthorizationorCookieheader exits2, and so does a user or password in the endpoint URL or--host. A secret on the command line is readable in the process list and lands in shell history.- A script that passed its token that way stores it once with
bb auth login https://bitbucket.example.com --token-stdin, or setsBITBUCKET_TOKENin the environment.
- A stored credential goes only to the host it was stored for (#730):
- A credential
bb auth loginstored for one Bitbucket is sent to that host alone. A command pointed at another host, by--host,BITBUCKET_URL, a.env, a workspace.bb/config.yamlor a full URL given tobb api, sends that host no credential unless one is stored for it too, and Bitbucket answers401for anything that is not public. The same holds for the fork lookup afterbb repo cloneof another host's URL, which also no longer shows that host your default host's client certificate. An alias of the stored host still counts as the same host. - A host profile in a workspace
.bb/config.yamlgives that host itsurlandusername, and nothing that acts as you: it never makes bb send a stored token or password, and itsclient_certandclient_keyare ignored. A profile keyed to another host with itsurlset to your Bitbucket, or one naming another host as an alias of yours, was handed your token. If a workspace file set a client certificate, set it with--client-certand--client-keyonbb auth login, or inBB_CLIENT_CERTandBB_CLIENT_KEY. - A credential stored for
https://is not sent to the same host overhttp://, so a.envor.bb/config.yamlnaming your Bitbucket overhttp://can no longer send your token in the clear, andbb cloneno longer passes it to git for anhttp://clone link. A login stored forhttp://still answers overhttps://. - Before v4.1.0 a host with nothing stored for it got the default host's credential, which sent your token to whatever host a cloned repository's
.envor workspace file named. v4.1.0 closed that everywhere butbb apiand the clone's fork lookup, without saying so in its notes; v5.0.0 closes those two. - A script that relied on the old fallback logs in to each host it talks to,
bb auth login <host>, or setsBITBUCKET_TOKENfor the run.
- A credential
- A credential goes into the configuration file in plaintext only when you ask (ADR-047):
- Where the OS keyring cannot hold the secret, on a headless server, in most containers, or in WSL without
gnome-keyring,bb auth loginexits1and stores nothing. It used to write the secret into the configuration file in plaintext, with a warning on stderr, without being asked. - This affects a login on a machine with no keyring. Where a keyring works, nothing changes. The token
bb repo cloneasks for when nothing is stored for the host is then used for that clone and not stored. - To keep the old behaviour, pass
--allow-insecure-storagetobb auth login. Better, in CI and containers, setBITBUCKET_TOKENin the environment and do not log in at all.BB_REQUIRE_KEYRING=1and therequire_keyringpolicy refuse plaintext even with the flag, and--require-keyringcannot be combined with it. - A credential already stored in plaintext keeps working, with its warning, so nobody is locked out by the upgrade. Only a new login needs the flag.
- Where a keyring is required, by
BB_REQUIRE_KEYRING=1or therequire_keyringpolicy, a credential stored in plaintext is refused wherever it is read: git no longer gets it frombb auth git-credentialand falls through to its own prompt, andbb repo clonesays to log in again where the keyring works.
- Where the OS keyring cannot hold the secret, on a headless server, in most containers, or in WSL without
--yesis refused unless the repository is on the command line (ADR-073, #752):- A command that deletes, removes, revokes or clears something in a repository, given
--yeswith the repository fromBITBUCKET_PROJECT_KEYandBITBUCKET_REPO_SLUG, now refuses: it exits2, changes nothing, and says how to name the repository. It used to go ahead in the repository the variables named. A repository from the git remote was already refused this way. - What to do: add
--repo PROJ/repoto the command, for examplebb branch delete feature/x --repo PROJ/repo --yes. Forbb reviewer-group,bb reviewer conditionandbb repo ssh-key,--project PROJdoes it too;BITBUCKET_PROJECT_KEYno longer does. An argument that names the repository also counts: thePROJECT/slugofbb repo delete, or a pull request's URL. - Without
--yesnothing changes: a person at a terminal is still asked to type back what is about to be destroyed, and with nobody to ask the command still refuses.
- A command that deletes, removes, revokes or clears something in a repository, given
Other fixes worth knowing
-
A project key or repository slug cannot carry a path. A slug such as
repo/pull-requests/7/merge?version=3#turned a request into one for another endpoint, so through the MCP server a tool that never asks could merge a pull request. A key or slug holding a slash,?,#,%or whitespace is refused. -
A repository command no longer changes what its project defines (#657). A repository's branch restrictions, default reviewer conditions and default tasks include the ones it inherits from its project.
bb branch restriction delete --repo, given the id of an inherited one, deleted it from the project, and so from every repository in it. These commands now refuse an inherited entry and name the project command that changes it, and the listings mark what is inherited. -
A branch restriction survives an update that is refused, and
--userand--access-key-idwork. An update deleted the old restriction before it created the new one, so a refusal, for a user name that does not exist for instance, left the branch unprotected. The two flags had failed on every call. -
A long transfer is no longer cut off.
bb clonewas stopped after 60 seconds whatever it was doing, andbb repo archive,bb repo catand the download inbb updatehad to finish withinrequest_timeout. Each now runs for as long as it makes progress, and a failedbb repo archiveleaves no partial file. -
bb ai skill installreaches Claude Code. It wrote the skill to.agents/skills, which Claude Code does not read. It writes.claude/skillsas well now, andbb ai skill removetakes out both. -
Git authenticates as the login
bb auth setup-gitset up (#733). The helper line named bb and nothing else, so git pushed as whichever configuration fileBB_CONFIG_PATHnamed when git ran, and two logins for one host could not be kept apart. The line now names the configuration file setup-git read, andbb auth git-credentialtakes it as--config. Runbb auth setup-gitagain to pin an existing setup; it replaces bb's own earlier line without--force. -
bb pr checkoutkeeps the credential off git's command line, where any local account could read it while git ran, asbb clonealready did. -
--projectinside a clone means the project (#725). In a clone, bb filled in the clone's repository beside--project, sobb reviewer-groupandbb repo ssh-keyrefused it for naming both, andbb reviewer conditionacted on the repository instead:create --projectwrote the condition there.bb search prs --rolewas refused the same way. A scope you name now keeps the clone out of it.bb reviewer conditionrefuses--projectand--repotogether, asbb reviewer-groupdoes. -
bb build required delete --dry-runfinds the check wherever it is (#728). The preview looked for the check among the first--limitchecks only, 25 by default, and predictedno-op, "not found", for one further down, which the real run then deleted. It reads every check now. -
An
https://URL for a server that speaks plain HTTP ispermanent(exit1) (#704). It wastransient(exit10) and tried three times, though the answer cannot change. The message says to check whether the URL should begin withhttp://. -
Creating a webhook that is already there reports it (#729). Bitbucket stores a second webhook with the name, URL and settings of one it has, and both fire, so a setup script run twice made two.
bb webhook create,bb project webhook createandbb repo settings workflow webhooks createnow report the webhook that is there and exit0, withcreated: falseunder--json. One with the same name and URL and other settings is refused as aconflict(exit5) that names it and what differs; change it withupdate.--dry-runpredicts both. Bitbucket never returns a webhook's endpoint password, so a password you pass is not compared, and a note on stderr says so.{ "data": { "status": "ok", "repository": { "projectKey": "PROJ", "slug": "repo" }, "webhook": { "id": 12, "name": "ci", "url": "https://ci.example.com/hooks/bitbucket", "active": true, "events": ["repo:refs_changed"], "sslVerificationRequired": true, "scopeType": "repository", "secretConfigured": false }, "created": false }, "meta": { "command": "webhook create", "bbVersion": "..." } } -
An HTML error page is reported by its title (#704). The message used to show the page's first 300 characters, which were all markup. Now it says what the page is:
validation: bitbucket API returned 400: an HTML page titled "Bad request - Bitbucket" (18389 characters; pass --full-error-body to see all of it) -
bb auth git-credentialhonoursBB_DISABLE_STORED_CONFIG=1. With it set, git gets no stored credential from bb, the same as every other command. -
bb cloneandbb repo cloneask for no token under--no-input. They report that no credential is stored for the host instead. -
Repository inference honours the global flags. It loaded its configuration from the environment alone, so a
--request-timeoutgiven beside a brokenBB_REQUEST_TIMEOUTturned inference off without a word. -
Output that was wrong, for a script that reads it:
bb pr getlists a pull request's reviewers. It listed everyone who took part, so whoever merged it or commented in passing appeared as a reviewer, and the review summary counted a real approval as missing.- A resolved comment thread counts as resolved, in
bb pr comment listand in the unresolved count of a pull request. bb branch listmarks the default branch (#658). Every branch readdefault: false.bb diff pr --name-onlyprints each path as it is, no longer asdst://path, and names binary files.bb diff refs --statcounts the change the diff shows; it counted the reverse.--pathonbb diff commitandbb diff refsprints a unified diff; it printed JSON.bb deployment getreports the commit that was deployed astoCommit.fromCommitis the commit the previous deployment deployed, which is what Bitbucket means by it.bb api --jsoncarries a body that is not text as base64 and says so inmeta.encoding. It used to replace every byte that was not valid text.bb clonereports"meta": {"command": "repo clone"}, the command it is an alias of, as every alias does. It reportedclone.
Deprecation
bb update --json:scheduled,staged,paths.stagedandpaths.swapResultare deprecated and are removed in v6.0.0 (ADR-084, ADR-092).bb updateinstalls the new binary itself before it exits, on every operating system, so these fields are always false or empty. Readappliedinstead.
bb ai mcp serve --yoloand--allow-writes,bb ai mcp tools --safe-only, and thesafeandexposurefields ofbb ai mcp tools --jsonare deprecated and are removed in v6.0.0 (ADR-084, ADR-098).- Every tool is exposed without
--yolo, so the flags do nothing,--safe-onlylists every tool,safeis always true andexposurealwaysSAFE. Pass--read-onlyfor a server that only reads, and readasksandwritesinstead of the fields.
- Every tool is exposed without
--matcher-displayonbb branch restriction createandupdateand onbb project branch-restriction createandupdate, and--include-uniqueonbb build status stats,getandset, are deprecated and are removed in v6.0.0 (ADR-084).- Neither ever changed a result. Bitbucket works out a matcher's display name from the matcher and ignores the one it is sent, and bb printed the same build counts with
--include-uniqueand without it. Both are still accepted and print a warning on stderr; remove them from scripts.bb build status getlists each build with its state.
- Neither ever changed a result. Bitbucket works out a matcher's display name from the matcher and ignores the one it is sent, and bb printed the same build counts with
--limitand--allonbb build required deleteare deprecated and are removed in v6.0.0 (ADR-084).- They bounded the checks the preview looked through, and it looks through all of them now. Both are still accepted and print a warning on stderr; remove them from scripts.
The complete list of breaking changes, commit references, and full change ledger is itemized below.
Changes since v4.1.0.
Compare: v4.1.0...v5.0.0
⚠ Breaking Changes
- let --yes apply only to a repository named on the command line (2a9e249) — a destructive command given --yes with its repository from BITBUCKET_PROJECT_KEY and BITBUCKET_REPO_SLUG exits 2; pass --repo.
- store a credential in plaintext only when asked to (d681004)
- tools that decide a merge ask the person through the client (4ba9aa1) — bb ai mcp serve lists every tool, and a client that cannot show an elicitation gets error -32021 for the tools that ask instead of not seeing them. --yolo no longer makes them run unasked.
- --describe describes the whole document in every mode (7141b0a) — --describe --json answers in description rather than data, and command, described, schema and reason are gone; without --json it prints an outline rather than JSON Schema.
- --dry-run answers with a verdict, in its own member (0064ca0) — under --json, --dry-run answers in preview rather than data; dryRun, planningMode, capability, summary and the per-item intent, predictedAction, supported, confidence, requiredState and blockingReasons are gone. A text dry run that finds the run would fail exits with the real run's code rather than 0. bb ai mcp serve rejects --dry-run.
- exit as gh pr checks does when a build failed or is running (000b68a) —
bb pr checksandbb pr build statuswithout --json exit 1 when a build failed and 8 when one is in progress or has no result, asgh pr checksdoes, where they exited 0. A script that ran them for their output and relied on exit 0 adds|| trueor passes --json, which still exits 0. - remove bb bulk, and the skill that taught agents to use it (1d79484) —
bb bulk(plan, apply and status) no longer exists, nor do the bb-bulk agent skill (bb ai skill install|show|remove bulk), BB_BULK_STATUS_DIR, or the bulk policy, plan and apply-status schemas. Set permissions, webhooks, default tasks and branch restrictions once on the project withbb project permissions,bb project webhook,bb project default-taskandbb project branch-restriction, where Bitbucket cascades them to every repository in it. For a setting Bitbucket scopes only to a repository, loop overbb repo list --project PROJ --jsonand run thebb repo settingscommand for each, previewing with--dry-run. Delete the bb-bulk skill wherever an earlier bb installed it --.agents/skills/bb-bulkand.claude/skills/bb-bulk, in a project or in your home directory;bb doctornames every copy.
All 500 changes
Features
- auth: store a credential in plaintext only when asked to (d681004)
- branch: list --details prints the details (bddfdc4)
- cli: deprecate --matcher-display and --include-unique (5029d82)
- search: take a period as ISO 8601 writes a date (3f7d731)
- search: list your pull requests by state and by period (4864bb3)
- pr: work out pr create's branches and title from the checkout (136df3c)
- pr: say where a pull request is, and merge with a chosen strategy (e850ef3)
- mcp: say how to go on when a view is not drawn (dfcebe5)
- mcp: open a pull request asked for, and show the form for a say (bff970c)
- mcp: tell agents that views are for a person who is there (7fa884e)
- mcp: keep the reviewer search beside the form's last chip (b3c35c1)
- mcp: leave the author out of the form's reviewers, whoever names them (15932cc)
- mcp: pick the form's branches and reviewers as Bitbucket does (e03204a)
- mcp: fill in the form's reviewers as Bitbucket's create page does (824da2c)
- mcp: count a card's builds as its pull request page does (31e07f2)
- mcp: highlight the lines a comment in the activity is shown among (322a793)
- mcp: put comments where Bitbucket has them, and drop the file viewer (de5a938)
- mcp: highlight a template's markup, and its code on request (258c6f2)
- mcp: highlight the code in diffs and files (12ef8e0)
- mcp: tokenize code for the views to highlight (3717272)
- mcp: show the builds a pull request must pass on its card (272a857)
- mcp: work out the builds a pull request must pass (1034d80)
- mcp: show a file as what it is (3e2fc35)
- mcp: hand the person a pull request to finish and submit (78e89de)
- mcp: approve or request changes from the overview and the diff (169b596)
- mcp: draw a diff's comments on their lines and comment on one (ea5caef)
- mcp: reply to a thread and comment from the comments view (9e1aff5)
- mcp: open a pull request's diff and comments in the same view (99ac9e7)
- transport: name bb in the User-Agent of every request (f15c587)
- mcp: check a view in motion every 15 seconds (5b1cb52)
- mcp: keep a view current while it is on screen (b6d14d1)
- mcp: list a threads card's comments where they are (679585d)
- mcp: show a pull request's comment threads as a view (d19ca8e)
- mcp: read whether a client opens links before asking it to (6f47fc7)
- mcp: say when a client will not open a link, and ask about fullscreen (f543219)
- mcp: make the inline views glanceable (ad85c8c)
- mcp: lay the views out tighter and clearer (7cf803e)
- mcp: keep views true at any size and draw Markdown descriptions (3052471)
- mcp: show pull requests, lists and diffs as views in MCP clients (1dfde81)
- policy: let administrators switch bb off, switch its MCP server off, or make it read-only (67d6c4f)
- mcp: serve pull requests, diffs, files and commits as resources, with prompts and completions (1e74130)
- mcp: tools that decide a merge ask the person through the client (4ba9aa1)
- describe: --describe describes the whole document in every mode (7141b0a)
- outline: one sentence per field, on lines up to 120 columns (5d5ff71)
- outline: print a JSON Schema as an outline of fields (491d523)
- dry-run: --dry-run answers with a verdict, in its own member (0064ca0)
- jsonoutput: encode a document as YAML that means the same as its JSON (80265b4)
- output: --yaml prints the document --json prints, as YAML (b4e94f9)
- mcp: list bzip2-compressed tar archives (7608828)
- mcp: convert BMP and TIFF images to PNG or JPEG (77c25c4)
- mcp: turn a photograph upright from its EXIF orientation (7d4e85a)
- mcp: return short audio and video as media, and describe the rest (753aaa0)
- mcp: extract the text of Word, PowerPoint and Excel files, and list archives (ba7c66e)
- mcp: return an image file as an image, scaled to fit, and say so (3712330)
- mcp: read a file in numbered windows, and describe what is not text (1e92978)
- update: deprecate the --json fields of a swap left for later (60a436e)
- pr: exit as gh pr checks does when a build failed or is running (000b68a)
- doctor: report a skill this bb no longer carries (03c736e)
- bulk: remove bb bulk, and the skill that taught agents to use it (1d79484)
- doctor: report shell completion and agent skills (eb12b5d)
- skill: install the skill where Claude Code reads it too (a656e9a)
- completion: set shell completion up with bb completion install (cb07323)
- completion: describe every branch by its latest commit (219b929)
- completion: offer the bulk runs saved on this machine (fa5dc13)
- completion: complete the values that come from a fixed vocabulary (cbbbc9f)
- completion: follow --matcher-type when completing --matcher-id (a2047e7)
- completion: complete the ids a person cannot remember (7d7c268)
- completion: complete the keys on a commit and on your account (6eae307)
- completion: complete a path one segment at a time (2352859)
- completion: complete repositories and projects (1e24130)
- completion: offer the people a slot can actually name (abbc55b)
- completion: complete branches, tags, refs and commit-ish values (6160e8a)
- completion: complete the values that need nothing asked (dd5223c)
- completion: declare what every argument and flag accepts (767ae8e)
- compat: make an older Bitbucket release answer as the newest does, or refuse what it cannot do (5e8d7ca)
- errors: report what a Bitbucket release cannot do as unsupported, exit 14 (6ff86e0)
Fixes
- release: keep the release body under GitHub's limit, and stop before the tag when it is not (89036c3)
- cli: refuse a malformed --repo before asking to confirm a delete (a080963)
- cli: let --yes apply only to a repository named on the command line (2a9e249)
- network: hand a body cut short back cut short under the error recorder (75eb470)
- cli: infer the repository with the host and flags the command was given (b5356f5)
- clone: register bb clone as the alias of bb repo clone (d897907)
- clone: refuse the token prompt under --no-input (71801a7)
- auth: answer git from no stored credential under BB_DISABLE_STORED_CONFIG (cbd583e)
- config: refuse a plaintext credential to git and a clone under the keyring requirement (599a39a)
- repo: suggest only what names the repository when --yes is refused (e8e3c84)
- clone: use a token the keyring cannot hold for that clone, not fail it (6c132b6)
- config: never let a workspace host profile release a credential (ff88306)
- webhook: report a webhook a create finds already there (b47cbfd)
- cli: declare the status field the output carries (7f1ed99)
- mcp: audit the question a tool that asks puts, answered or not (3c6bd5a)
- mcp: redact credentials in audit arguments and resources as free text (ff69a7d)
- auth: pin the login git authenticates as in the setup-git helper line (9aee5a6)
- config: never send a credential stored for https over plain http (db21902)
- git: keep the credential off git's command line in a fetch (53bea88)
- build: find a required check past --limit in the delete preview (8d1ba3a)
- cli: keep the checkout out of a scope named with --project (70559e8)
- auth: report a failed user lookup in bb auth token by its cause (7467e71)
- pr: merge, decline and reopen again when the version just moved (faed97f)
- mcp: fill in the default reviewers on the pull request form (5071e8c)
- repo: show a clone host only the client certificate meant for it (273a606)
- transport: say when an https:// URL meets a plain-HTTP server (164a91e)
- repo: ask a clone host about forks with its own credential (cf3d28e)
- auth: let token-url name its host before any login (f52a0e2)
- api: refuse a credential in a URL, and never repeat one in an error (d38cab2)
- api: refuse a header that carries a credential (79f5a36)
- api: refuse an endpoint URL's second host before a dry run (ce2dbdf)
- api: send an endpoint URL only its own host's credential (34ff3f5)
- mcp: count a task once on the pull request card (1286238)
- pr: count a resolved comment thread as resolved (33872fa)
- pr: report a pull request's reviewers, not everyone who took part (c0ff9d0)
- mcp: hold auto-merge to the version shown, and let a late refusal stand (42d290c)
- repo: refuse a project key or slug that would leave its path segment (e0f5a6a)
- git: a clone runs while it makes progress, and a stopped git says why (b9d8ecb)
- describe: bb update's dry-run schema holds its report (0bd9bc6)
- describe: wrap the prose around an outline at its width (49945ad)
- describe: a preview whose verdict is predicted predicts (8788746)
- describe: bb api's dry run carries data, and its description says so (4831d79)
- update: a dry run names the binary it would replace (59383c8)
- dry-run: predict the failure a real run meets where no-op was predicted (f04d86f)
- output: meta.command names the canonical command for a shallow alias (f0a9360)
- dry-run: declare the tier each stateful command's preview reaches (6e66584)
- dry-run: refuse a project name already in use (481ec33)
- dry-run: stop refusing a duplicate webhook, and name a missing task (96355ed)
- dry-run: follow who Bitbucket lets change a comment (c6c5d2a)
- dry-run: check reviewer groups the way Bitbucket does (44a37f1)
- dry-run: predict what Bitbucket does with a reviewer condition (155c70e)
- dry-run: give each pull request effect the reason a verdict prints (0e45307)
- dry-run: write branch delete's verdict through the preview writer (80d1932)
- dry-run: predict the upsert a matching restriction create is (225043f)
- dry-run: name the kind a refused pull request change fails with (1b13c4f)
- output: hint about a gh field list only when the command took it as one (a320afc)
- api: carry a body that is not text as base64 under --json (61ba58b)
- mcp: stop converting a file when the call is cancelled (15d4bf9)
- browse: escape a file path once, so a name with a space opens its page (4a72922)
- api: write a body that is not text byte for byte (d4b07d4)
- repo: stream bb repo cat and browse raw, and report a failed write (fcd54ee)
- repo: stream bb repo archive without a deadline, and leave no partial file (5a46ae3)
- update: download a release without a deadline on the transfer, capped and retried (ad49cb9)
- update: replace the file a symbolic link to bb names, and keep the link (9d71e3c)
- update: replace the running bb.exe before bb update exits (3c052ad)
- update: replace the binary on Linux and macOS with one rename (650f96f)
- update: say that a mirror wanting a login is not supported (f83f52e)
- update: keep bb update on its mirror, with the TLS and trust it was given (3ee9b7e)
- errors: send again an idempotent request whose answer Bitbucket failed to write (89545a7)
- webhook: show the secret --reveal-secret asks for as text (78efb9d)
- webhook: publish the webhook a read returns after a create or update (de37163)
- update: fail a dry run whose mirror serves an older release (d091183)
- update: verify the release a mirror serves on every dry run (4f43f25)
- branch: mark the default branch in bb branch list (0669e1b)
- keep a repository's commands off what its project defines (3465be4)
- repo: list every default task, not the first 25 (2510b8e)
- skill: take the skill's emptied directory out on remove (72c979a)
- doctor: count a quoted path to bb as completion set up by hand (6a1a740)
- completion: stop waiting for a shell that does not answer (816a6e9)
- completion: change a startup file where it is rather than replace it (7730a61)
- completion: read a Windows SHELL path the same on every OS (0a8d46d)
- doctor: find a project's skills from anywhere in its repository (6f10061)
- completion: take out a PowerShell profile that held only bb's block (7d3cc67)
- completion: say when a branch category is switched off (4ddb900)
- completion: describe an instance logged in with a token (e6333ca)
- completion: keep fish from adding a space after a list element (660abcb)
- completion: describe what each log level adds, not what the flag is for (537680b)
- completion: cut a description between characters, not bytes (8839dbd)
- completion: let an argument that takes a path ask the shell for one (d759750)
- docs-lint: fold the version wrapper into the function that takes one (f9e20ad)
- completion: make a tab press behave in PowerShell (16088f7)
- completion: stop refusing every positional completion (9355e13)
- default-task: say which kind of ref each matcher of a default task matches (fb318d2)
- deployment: report the commit a deployment deployed (f86ccad)
- commit: let bb commit get read a branch whose name has a slash in it (03d2aee)
- repo: let auto-decline set --enabled=false switch the policy off (746b157)
- comment: report a draft comment as pending and an inline comment as anchored (46dfc7c)
- restriction: refuse a restriction id that is not a number instead of failing as transient (5219d1f)
- diff: name changed files by their path in bb diff pr --name-only, not as dst://path (f65e4ee)
- diff: print a unified diff from bb diff commit --path and bb diff refs --path (41604bb)
- diff: bb diff refs --stat counts the change the diff shows, not its reverse (9733cd6)
- project: report access to a project whose name is part of another project's name (0d52c1c)
- project: refuse a dry-run project create to an account that may not create projects (53cca7b)
- restriction: keep a restriction when its update is refused (1e3f506)
- restriction: make --user and --access-key-id work on branch restrictions (ec4ed7a)
Refactors
- jsonoutput: remove EnvelopeSchemaFor, which only tests used (bbbc0e6)
- jsonoutput: derive the published meta member from EnvelopeMeta (ab0dee1)
- config: drop the system-file CA fallback nothing could reach (5e3833f)
- auth: write setup-git's helper through the git backend factory (e1eea16)
- jsonoutput: derive the published error member from EnvelopeError (0c33164)
- reviewer: remove SelectMembers (8c5fcb0)
- completion: list projects, repositories and directories from one place (53a09c2)
- transport: add a downloader that waits on silence, not on the whole body (7750442)
- completion: read the checkout's remotes through the invocation (f6874a0)
- cli: name each positional argument after what it accepts (d89f671)
Docs
- security: update threat model for v5.0.0 release (#724) (4545212)
- release: say the --yes change refuses, and what to do about it (adc8ea7)
- release: name the credential, clone and inference fixes in the v5 notes (daaca75)
- state the rule in the transport and openapi-spec package comments (bb562b4)
- adr: list every governance test in ADR-067 (c2c276f)
- adr: merge four groups of records that state one rule (1a0f452)
- adr: say each thing once, and restore the rules the review found missing (c9363b4)
- adr: refuse a record that names what replaced it, and say each thing once (0df41a4)
- adr: restore what the rewrite dropped, and trim (e9c7e5e)
- adr: state the process and release records as the rules that hold now (33e6c4c)
- adr: restore what the rewrite dropped, and trim (2037639)
- say linear history is enforced, and fix comments that name what is gone (2e9ad9c)
- adr: state the testing and quality records as the rules that hold now (814da38)
- adr: restore three points the MCP rewrite dropped (a82779f)
- adr: restore what the rewrite dropped, and trim (1ac7d21)
- harness: name no Bitbucket release in the Dockerfile's comments (fbf1dae)
- adr: state the release, transport and distribution records as the rules that hold now (7add7df)
- adr: restore what the rewrite dropped, and trim (418504f)
- drop stale CRLF advice and name the comment decoder that exists (c03566b)
- adr: state the interactivity and command-tree records as the rules that hold now (46dac44)
- adr: restore what the rewrite dropped, and trim (04b4b93)
- adr: say a workspace host profile releases no credential (96d6d54)
- stop describing a --token flag in comments (ade9599)
- adr: state the auth and configuration records as the rules that hold now (a9cf34e)
- adr: restore what the rewrite dropped, and trim (dcbab35)
- drop the --token flag and the history from two comments (933b813)
- adr: state the output, error and dry-run records as the rules that hold now (dbc0a68)
- name no release in the README and skill output examples (96b9fd2)
- adr: state the MCP records as the rules that hold now (53db452)
- release: place what next fixed since the restructure (d95f53b)
- adr: stop describing bb bulk, which v5 removed (0928d5c)
- adr: keep the decision records as Markdown pages (99ee98e)
- release: announce that a stored credential goes only to its own host (faeabb0)
- reference: name each MCP tool for people, and keep the model's text as it is (ca2364f)
- split the hardening guide into the four things it covers (243bf6d)
- state the security pages' claims as facts, not guarantees (38d86f9)
- say what a token lets bb do, and what a refused one looks like (32bb0e8)
- help: say where bb api --raw-field puts its parameter (0fbb919)
- help: shorten bb doctor's help, and stop bb api's repeating its flags (df544d5)
- agents: give coverage artifacts and the gates a section each (b1f9bd4)
- quickstart: say how to keep bb up to date (22685f4)
- one example host and project across the pages (1b38b42)
- contributing: make the rules CONTRIBUTING and AGENTS.md both state agree (693b942)
- explain each topic on the page that owns it, and link from the rest (aafda60)
- reference: one page for where every setting comes from (58032f1)
- threat-model: say when the analysis was made, and what changed since (193eefe)
- help: say what takes, and shorten bb ai mcp serve's help (e12c971)
- help: describe --repo, --start and --host the same way wherever they mean the same (2a1f1c0)
- help: say what each command group lets you do (3f40a81)
- describe what is, where the docs told how it came to be (b914501)
- skill: offer the MCP server when a view would serve the person better (e9d7212)
- contributing: tell what is needed from what helps, and how a long branch lands (b433722)
- say that the MCP server passes a file in a format the AI can ingest (a292dbd)
- release: gather what administrators need, and show the views (ee5dd3a)
- release: open the v5.0.0 notes with what is new, and cover the whole milestone (342a032)
- correct what the docs say that is not so (ac666fd)
- help: say what is, not what was, and document bb completion install (622e434)
- help: show what an argument takes, and leave --yes to scripts (6a327df)
- adr: say why bb has no browser login (4b60af1)
- help: give every command an example (d3f87c2)
- reference: give each top-level command a page, and each flag its source (44b64c3)
- search: say that search prs lists what you are involved in (ff07218)
- record that a value read from the checkout may stand in for its flag (c7601ab)
- mcp: say when a tool and when a view, and how views work (ef2b86a)
- mcp: describe the form as Bitbucket's create page (030402c)
- adr: record where a card's builds come from, and letter case (29ae99e)
- mcp: show comments in the overview and the diff, as Bitbucket does (0d78474)
- mcp: show the views as they are now, and the form and the file viewer (d76326b)
- adr: record what views are for, what is not refreshed, and sending without forms (272aa5b)
- release-notes: note the plain-HTTP answer, HTML error titles and the User-Agent (320b865)
- mcp: say that views keep themselves current (2748c5c)
- mcp: show the comment threads view in the guide (ec57319)
- mcp: point the MCP reference at the guide and its examples (ef59d63)
- mcp: show the views in the MCP server's guide (d9b4dc4)
- mcp: show the views in the docs and the README (38497f8)
- mcp: frame ADR-101 as adopting MCP Apps (9921c7c)
- mcp: say what the views show, how they stay safe, and why show is a tool of its own (bad25d9)
- policy: give the levers as a table in the v5 notes (355cbfc)
- policy: say what the three levers do, what they leave, and what they do not govern (4ffb8c8)
- mcp: tell the story of attaching Bitbucket content in the v5 notes (ddde2a7)
- mcp: say what attaching Bitbucket content means for a user, with an example (6a8c6b2)
- adr: record how other MCP servers put resources in tool results (083deda)
- mcp: say what the resources are for, what the scope does to them, and how they are audited (e2805d6)
- mcp: say what the new permission model means for a user (b4257d0)
- mcp: say what a confirmation holds a call to, and which tools were withheld (4b31bc0)
- mcp: say which tools ask, and what --read-only is for (f51b299)
- adr: let a record name every record that amends it (2163bbf)
- describe: show the description document on the machine-mode page (9329b46)
- release-notes: say where --describe's command and reason went (785c146)
- dry-run: show the preview document, in the notes and on the machine-mode page (51ce8dc)
- adr: accept ADR-096, now that --dry-run answers with a verdict (894d4b5)
- adr: propose the v5 output contract for #606 and #616 (18f9fd1)
- release: announce the deprecated bb update fields in the v5 notes (98427d9)
- update: say what update_tuf_url has to point at (697fdc0)
- adr: record ADR-094, MCP results a model can use without files or a shell (4f6fa74)
- adr: record ADR-093, one downloader for binary and large bodies (6f628cc)
- update: record that bb update installs the new binary itself (10c24a6)
- release: add the bb bulk removal to the v5 upgrade checklist (f24f718)
- dry-run: hold ADR-034 and ADR-070 to the registries that exist (635c934)
- dry-run: say a command that changes this machine is previewed (bc9c302)
- release: tell v5 upgraders that bb pr checks gates on CI (5d4e148)
- webhook: drop the paragraph announcing the read-back (552d14f)
- update: say what a dry run verifies, and when it fails (7c86dce)
- adr: drop ADR-036's instruction for the bulk apiVersion (c19cf7f)
- skill: make Cline's skill directory before writing the skill into it (4237461)
- completion: say that bb doctor checks completion and the skill (3a27688)
- completion: lead with bb completion install, and record who sets up what (e6565ce)
- completion: say how to turn it on, and what to do when it offers nothing (f3f43d1)
- adr: renumber the completion decision to 089 (4cd88ea)
- completion: say where the shells differ (3c25154)
- say what tab completion offers and how it behaves (79a9785)
- docker: say again that releases run side by side (307a8ab)
- openapi: point the fix registry at where a release difference is recorded instead (2d4fac1)
- say which Bitbucket releases bb serves, and where an older one differs (a0e111c)
- reviewer-group: say bb reviewer-group users lists only the members who can see the repository (d7305e2)
- name v4.1.0 in the examples that show bb's version (88092f2)
Tests
- cli: make the non-repository inference case reach git (a47b56d)
- testsupport: seal the variables that say nobody is there (c4525eb)
- cli: name the repository with --repo where a test passes --yes (00f8229)
- cli: prove the default loaders without publishing BITBUCKET_URL (7b11d5c)
- cli: keep tests inside the process and off the real stdout (67936a9)
- cli: assert the failure each test is about, not one a missing host shares (df56959)
- outcome: let the refused handshake's alert reach the client (2f4a1d8)
- network: restore BB_BLOCK_EXTERNAL_NETWORK after TestSafeTransport (65afe52)
- config: stop setting BB_DISABLE_STORED_CONFIG=1 where the seal has (b9b367b)
- testsupport: anchor the seal detector on internal/config, not a count (89746a8)
- testsupport: seal every variable bb reads (39872b7)
- repo: pass configuration through the seams, not the environment (738550f)
- api: pass configuration through the seams, not the environment (91c95d4)
- auth: pass configuration through the seams, not the environment (3bd76d9)
- browse: pass configuration through the seams, not the environment (919af87)
- project: pass configuration through the seams, not the environment (0028d25)
- insights: pass configuration through the seams, not the environment (63acbee)
- pr: pass configuration through the seams, not the environment (061359e)
- diff: pass configuration through the seams, not the environment (71e2af2)
- commit: pass configuration through the seams, not the environment (18f1070)
- branch: pass configuration through the seams, not the environment (7d3a406)
- tag: pass configuration through the seams, not the environment (9a7c3e4)
- bb: pass configuration through the seams, not the environment (3306f5d)
- pullrequest: pass configuration through the seams, not the environment (c73ca0c)
- config: pass configuration through the seams, not the environment (c549ba2)
- config: drop clears the seal already makes (9b556bd)
- cli: pass configuration through the seams, not the environment (c3a9a1e)
- testsupport: keep a sealed test away from the developer's configuration (bee5323)
- live: hold repo admin create, fork and delete to the canonical output (d341c47)
- live: end the live TestMain in gittest.Guard (08a239d)
- git: fail rather than skip without git, a checkout or a shell (04d57da)
- quality: let the oldest release served be older than the oldest tested (3c55e2c)
- live: run the search by state and period test on its own (9cd03c6)
- hold the hand-written configuration and exit-code tables to the code (933ec75)
- live: complete labels in a test that does not run in parallel (e5dc486)
- webhook: expect the preview of a webhook already there to be no-op (fe57084)
- mcp: prove the audit trail redacts what Bitbucket echoes back (6bc4d2a)
- auth: cover setup-git with no configuration file to name (487bb8f)
- config: run the host-credential cases away from any .env (8e86348)
- keep every unit test binary off the network (8a63b92)
- mcp: expect every kind a server shows among a view's offers (b2f7d1f)
- mcp: number a comment on a line on the side Bitbucket numbers it (7b94bee)
- mcp: give Chrome a minute to start in the browser tests (ff0c394)
- mcp: cover the stand-in host's page outside a browser (9c6751f)
- mcp: call show in the live conformance sweep (2767198)
- live: wait for the rescope before reading the version a refused rebase keeps (5994850)
- live: list what a read-only server exposes, and everything under --safe-only (b8e5e41)
- git: every test that relies on git's own answer keeps the default timeout (3e06773)
- describe: hold real documents to the schema --describe publishes (210877f)
- live: read bb api's dry run of a mutation as a verdict (7e15dce)
- live: prove each dry-run refusal against the real run (81d9df6)
- live: read dry runs as verdicts, and hold each to its declared tier (bbdf9e2)
- git: keep the backend's own timeout where git must succeed (380c257)
- output: run the commands that change this machine before the others (1771194)
- output: compare the hint's message, not the error value (1816c10)
- update: update a bb built from this tree from a mirror of a published release (e6d81fb)
- dry-run: point a local writer at the registry that previews it (ae17dcb)
- live: keep the machine's shells and the checkout's skills out of the doctor test (dd2eb96)
- live: read each push's own delivery in the webhook password test (9a82552)
- skill: compare paths as macOS reports the working directory (9815421)
- completion: install the .deb and .rpm and check where completion lands (a870df2)
- completion: prove each shell completes from what install writes (8cc8115)
- completion: drive bash, zsh, fish and PowerShell against the real scripts (fd2dced)
- completion: stop the local-kind check reading this machine's config (c1f3414)
- completion: hold the vocabulary at its edges (07e3508)
- completion: cover the instances a machine is logged in to (788dbed)
- completion: cover the failure paths, which are most of a source (8ee37a2)
- usage: cover the placeholder the vocabulary is keyed by (78c8883)
- completion: rename a git helper that shadowed the package (15d045c)
- docs-lint: stop the fixture tests reading the machine's git tags (3da2aca)
- compat: cover the narrowing and the scope reporting a newer release never reaches (b41a001)
- live: run the oldest release and the newest by default, not the whole window (a7b185f)
- live: send a seeding git push again when Bitbucket answers 5xx (b9e17c5)
- live: prove bulk operations, paged listings and the git round trip store and return exactly what was sent (ad8abe2)
- live: prove the flags alias, browse, clone and search commands send are the ones their answers reflect (df5e6c9)
- live: prove the states dry-run predictions are read from were stored, and the changes they predict were not made (2973b2f)
- live: prove every MCP write tool stores its arguments and every MCP read answers about what it named (921c94a)
- live: prove withheld MCP tools change nothing, and MCP reviews, comments and scoped listings keep what was sent (76e55c5)
- live: prove commit comments, build statuses, reports and a refused duplicate branch keep what was sent (c38f02b)
- live: prove reviewer conditions, reviewer group renames and group grants keep what was sent (5783f23)
- live: prove build statuses, code insights and required builds keep what was sent (e251f60)
- live: prove webhook secrets, endpoint credentials and TLS settings are stored as sent (7f505b6)
- live: prove a webhook create stores the name, url and events it sends (1138449)
- live: prove webhook test pings the webhook and url it names (2527cdb)
- live: prove policy-scoped listings and clones reach the project and repository they name (5b1332e)
- live: prove an access token's name, permissions, expiry, rename and revocation are stored (fa85bc0)
- live: prove a GPG key reaches Bitbucket intact and remove and clear take it away (865f766)
- live: prove SSH key labels, key text and access key permissions are stored as sent (158ba8b)
- live: prove a deployment keeps every field, and get and delete find only it (1b23e31)
- live: prove a tag is made at its start point and keeps its message (d265b39)
- live: prove build statuses and code insights keep what they are set with (619462a)
- live: prove repo edit, archive and default tasks store what they send (8b6d831)
- live: prove repo sync DISCARD makes the fork's master upstream's again (47bdc43)
- live: prove webhook fields and granted permissions are stored, not just printed (9fc726d)
- live: prove repository settings services store the permissions, webhooks and pull request settings they write (489599c)
- live: prove repository create, rename, fork and delete by reading the repository back (37c7744)
- live: prove repository auto-merge is stored, and gone after its delete (64267ef)
- live: prove pr default-reviewers sends each repository id for its own side (13f7613)
- live: prove governance writes are stored and their dry runs change nothing (ed4c895)
- live: prove the code owners a pull request is given are the reviewers Bitbucket stores (d854945)
- live: prove default reviewer conditions and the reviewers they assign are stored (e310769)
- live: prove reviewer group members, names and descriptions are stored on both scopes (3159a8b)
- live: prove the reviewer condition and reviewer group lifecycles keep what they send (c167247)
- live: prove the pull requests the harness opens for the review tests come from the branch they name (21157f2)
- live: prove the review tests open their pull requests with the title and branches they send (2a76384)
- live: prove the overclaim fixture is one ordinary open comment and the partial tally reads zero tasks (b8f70da)
- live: count the review visibility threads exactly and read back what each was created with (9961dfa)
- live: prove the review surfaces are read from reviewers, comments and anchors stored as sent (0ee9bad)
- live: prove a refused review completion leaves the status, the drafts and the comments as they were (d9ae5f5)
- live: check the review status no-op under a token alone, and read back the reviewer and the token (7fbd57f)
- live: prove pending reviews, reactions, replies, suggestions and blockers are stored as sent (e5281de)
- live: prove branch restrictions are stored on the project or repository they were sent to (14467e0)
- live: prove branch and branch restriction commands store what they send and dry runs change nothing (3e9a6c4)
- live: prove project default tasks and branch restrictions store what bb sends (1dc4a7d)
- live: prove project create, update, delete and the --name filter reach Bitbucket (d455792)
- live: prove branch restrictions store the matcher type and exactly the exemptions sent (043ac65)
- live: read back the diffs, build statuses, insights, tags, pull request filters and credentials the command coverage tests send (d1b6f92)
- live: prove the pull requests comment tests open keep their title and branch (cde650c)
- live: prove bb pr comment add keeps the line type and parent it is given (b739731)
- live: prove repo comment anchors, limits, replies and commit comment versions are what Bitbucket keeps (9c40a8d)
- live: prove comment text, severity, state, reactions and deletes are what Bitbucket keeps (7256229)
- live: prove commit list, get, compare and ref resolve use the values they send (945dd68)
- live: prove bb diff uses both refs it is given and the pull request it names (0f12495)
- live: prove the draft flag, description and reviewer pr create sends before pr ready relies on them (57bb25b)
- live: say why pr jira's empty answer cannot identify the pull request it read (aa95617)
- live: prove auto-merge without --strategy merges no-ff by the commit it makes (5e76a6f)
- live: prove pr status leaves out what others opened and what the caller already approved (3137c98)
- live: state precisely why the activity and --state all listing checks can fail (384978e)
- live: prove the read access pull request tests grant their reviewers is the access held (8c8cac6)
- live: prove build statuses, pull request inspection and checkout against exact read-backs (227774f)
- live: prove pr ready, auto-merge settings and the auto-merge strategy by reading them back (d891624)
- live: prove pull request state changes, previews and listing filters by what reads back (98667a9)
- live: prove pr create and pr update store the title, refs, description and reviewers they send (fa5b7de)
- live: correct what two comments in the repo cli tests say (229b45d)
- live: prove pr watch and unwatch change whether the pull request is watched (184161e)
- live: prove pull request comments keep a removed or context line, and comment, activity and permission listings honour --limit (f53a3bb)
- live: prove commit prs and participant search filter, and comment and rebase dry runs change nothing (ef045fe)
- live: prove pull request dry runs preview changes a real run would make and leave them unmade (db97e3b)
- live: prove repository permissions, webhooks and pull request settings store what bb sends (ac940b3)
- live: prove repo comments store their text, anchor, parent and version, and repo list honours --project and --limit (615647d)
- live: prove permissions show looks past a project named like the one asked about (b056e8d)
- live: read back the pull request a refused comment update is aimed at (6757919)
- live: prove each permission boundary with a licensed account and read back what it refused (a3febe8)
- live: keep the refused reviewer-group delete proven when its subtest runs alone (90adfb4)
- live: prove the version a pull request update names reaches Bitbucket (be43f1b)
- live: prove the branch decoys fill the first page the existence check reads (ed9e5e5)
- live: prove a rebase at a stale version is reported as a conflict (a2948cf)
- live: prove every value the mutating coverage tests send is stored (3a5df77)
- live: prove a build required only for the merge queue leaves pull requests mergeable (77cbecb)
- live: point the auth status test at the instance under test (b98c057)
- docs-lint: check the output-example fixtures against the release they name (8aacacc)
Build
- error-registry: keep the registry beside the live suite that produces it (8756bce)
- call the product Bitbucket Data Center in package metadata and the config schema (f495a04)
- docs-lint: read a quoted message that begins with bb as a message (d86624d)
- stack: prune only instances that have stopped (4037352)
- docs-lint: leave a release's notes to the release they describe (ee21f71)
- stack: take stopped instances down, so they give their network back (8228a9d)
- release: set PowerShell completion and the agent skill up from Scoop (541eb3c)
- release: install shell completion with the .deb, .rpm and Homebrew (7d752fc)
- docs-lint: check a documented completion request against what it completes (bbf0238)
- quality: hold the window of Bitbucket releases to what the code and the page say (8528fd8)
- format the Go tree the same way under every gofmt release (b7a5d99)
- record the participants operation the permission tests read approvals through (9b735ee)
- stack: restart an instance for its licence's age from Git Bash on Windows too (dc2895f)
- stack: run the stack and the live suite against another Bitbucket release (8d3ac72)
CI
- release-flow: refuse every pull request into main (dd75ef3)
- release: refuse a pushed commit CI has not passed (98a3906)
Chores
- deps: Bump urllib3 in /docs in the uv group across 1 directory (c407602)
- deps: Bump github.com/dlclark/regexp2/v2 (f76353b)
- mcp: preview the form with drafted reviewers (d9c8179)
- quality: count the pull request file diff the views now read (a122dab)
- mcp: read a preview frame's kind without trusting its type (955f8e8)
- mcp: preview the overview in place, and drive a preview from a script (1493d64)
- mcp: preview some kinds only, and a long view whole (5fb51d3)
- mcp: preview the pull request form, the file viewer and the views' buttons (50c3613)
- deps: Bump the gomod-minor-patch group with 5 updates (2e716a3)
- view-preview: capture each view alone, in either theme (02f21fc)
- stack: serve https from Bitbucket itself, not from a proxy (a0a3b37)
- stack: serve the instance over https for clients that open only https links (bd8dbb9)
- view-preview: capture every frame from one steady layout (a5f8c09)
- deps: Bump the gomod-minor-patch group with 2 updates (dab2170)
- deps: Bump astral-sh/setup-uv from 10.1.0 to 10.2.0 (656bce6)
- deps: Bump codecov/codecov-action from 7.0.0 to 7.1.1 (62b8d93)
- deps: Bump the gomod-minor-patch group across 1 directory with 4 updates (862e1e9)
- quality: record the operations the id completions reach (2bce854)
- quality: record the commit-changes call the comment completion makes (d8350ab)
- quality: record the browse endpoint the path completion reaches (919f16a)
- deps: Bump actions/attest from 4.1.0 to 4.2.2 (eb5c096)